Login Nwe gen.

Wim Verveen, e-mail: wim@win2kwereld.nl

Wie met kantooromgevingen werkt, werkt met loginscripts. Dat was vroeger zo, met eerst UNIX en VMS (Pathworks) servers, later met Novell Netware. Toen Windows NT een plekje begon te veroveren in de markt ontstond er een wonderlijk probleem. Windows NT server bleek niet te beschikken over een fatsoenlijke scripttaal zoals de meesten van ons gewend waren met Novell Netware. Natuurlijk was er Batch, maar dat blijft toch altijd een beetje droevig als je beter gewend bent. Gelukkig was daar de redding in Windows NT land, en wel in de vorm van Kixtart. Kixtart, een gratis tool geschreven door een Medewerker van Microsoft, Ruud van Velzen bleek een bijzonder handige login script intrepeter te wezen en veroverde dan ook al snel een toppositie. Vandaag de dag bestaat het nog steeds en heeft een trouwe aanhang. Met Kixtart werd het mogelijk de complexe scripts te schrijven die je nu eenmaal nodig hebt om een even complexe omgeving te beheren. Natuurlijk zijn er policies, natuurlijk zijn er profiles . Echter, deze middelen blijken het keer op keer niet te halen bij de flexibiliteit van een script. Voor een goed ingerichte kantooromgeving is het gebruik van scripts nu eenmaal onontbeerlijk voor het regelen van de niet-statische instellingen op een desktop, denk bijvoorbeeld aan het aanmaken van schijf en printerverbindingen.
Vaak is wel mogelijk om dit met een policy structuur op te lossen, echter dit is minder flexibel dan een script oplossing.
Met name sinds de introductie van Windows 2000 heeft Microsoft het licht gezien en heeft het uitgebreide middelen ontwikkeld om scriptoplossingen te creëren voor allerhande activiteiten in het systeem. Loginscripts is een van deze belangrijke activiteiten en hier zullen we in dit artikel wat verder op ingaan. Het doel van dit artikel is de ontwikkeling van een standaard loginscript waarmee de meest belangrijke taken kunnen worden vervuld en de basis biedt voor verdere ontwikkelingen.

Met de introductie van group policies (GPO's) is er onder Windows wel wat verandert met de manier waarop loginscripts worden gestart. Voorheen stond in de eigenschappen van een account vermeld (figuur 1) wat voor script kon worden gestart en dat was het dan. Tegenwoordig kan naast dit script middels een GPO (figuur 2) meerdere scripts worden gestart en is er onderscheid in startup/shutdown en logon/logoff scripts. Het gebruik van scripts in een GPO heeft wel als nadeel dat eerdere besturingssystemen hier niet mee om kunnen gaan. Voor omgevingen met Windows 2000 of Windows XP is dit echter geen probleem. Bij het gebruik van vbscript als loginscript intrepeter ondervinden we ook nog een aanvullend probleem, veel ouder clients ondersteunen standaard geen ADSI (nodig voor groepsinformatie) of hebben zelfs helemaal geen vbscript standaard geïnstalleerd. In dit soort omgevingen moet een product als Kixtart serieus overwogen worden of een hybride situatie worden gecreëerd.

Figuur 1: Klassieke loginscript instelling

Wanneer we kiezen voor vbscript is het zaak dit gestructureerd aan te pakken. Standaard is vbscript vrij beperkt. We zullen dus functionaliteit moeten creëren. Een van de belangrijkste functies van een loginscript is het gebruik van groepsinformatie (member of) om beslissingen te nemen. In voorbeeld 1 zien we een functie die de basis legt voor een ismember commando. In dit voorbeeld maken we gebruik van ADSI om een verbinding te leggen met de AD of de SAM van een server of Windows NT 4 domein. We vragen alle groeps informatie op en plaatsen deze dan in een zogenaamd dictionairy object. Hieruit kunnen we het later dan weer terugvragen met deze functie:

    Function MemberOf(strName)
     MemberOf = CBool(oUserGroups.Exists(strName))
    End Function 'memberoff

U ziet gelijk waarom we dit type object gebruiken, het is vrij eenvoudig om hier de door ons gewenste informatie uit op te vragen.

Met deze belangrijke functie is een belangrijke basis gelegd voor het script. We kunnen ons nu gaan afvragen welke functies nog meer belangrijk zijn in een basis loginscript. Er zijn in elk geval 2 in het oog springende functies: Het creëren van schijf en printer verbindingen. Veel bedrijven hebben hieraan al meer dan voldoende. We kunnen echter nog verder gaan, in ons voorbeeld voegen we ook de mogelijkheid toe om registry wijzigingen te plegen en om snelkoppelingen aan te maken. Hierdoor introduceren we een rudimentaire vorm van desktop management.
Voordat we overgaan tot het creëren van iets daadwerkelijks uitvoerbaars moeten we de basis van ons script nog wat verder uitbreiden. We hebben namelijk ook een voorziening nodig om de gebruiker te voorzien van informatie. Dit kan door in een dosbox gewoon met wscript.echo informatie naar het scherm te schrijven maar dat ziet er toch niet mooi genoeg uit. We schakelen daarom internet explorer in om ons te voorzien van de gewenste interface.

VBScript ondersteund het gebruik van ActiveX componenten en ook internet explorer is op deze wijze aan te sturen. Met het volgende commando maken we eerst een internet explorer object:

Set oMSIE = CreateObject("InternetExplorer.Application")

Mocht u nog niet zo bekend zijn met vbscript. Dit type commando wordt zeer vaak gebruikt. Vbscript kent weinig functies van zichzelf maar op deze manier is de functionaliteit drastisch uit te breiden. Met dit commando creeeren we een internet explorer object wat we middels zogenaamde methods, zeg maar functies en properties, ofwel instellingen kunnen beïnvloeden Als eerste gaan we een aantal van zulke properties instellen om een door ons gewenst venster op het scherm te creëren.

  • MSIE.Navigate "About:Blank"
  • MSIE.ToolBar = False
  • MSIE.StatusBar = False
  • MSIE.Resizable = False
  • MSIE.Visible = True

Met de method 'oMSIE.Document.Write' kunnen we vervolgens ons script informatie laten tonen. Het leuke van een object is dat we er eigenlijk helemaal niet zoveel van hoeven te weten om deze te kunnen gebruiken. De write method schrijft de informatie in het internet explorer window zonder dat we iets te zien krijgen van de daadwerkelijke activiteit.

Figuur 2: Loginscripts in een policy

Om onze manier van informatievoorziening wat flexibeler te maken creëren we hiervoor ook een aparte functie, zo kunnen we later eenvoudig in een andere 'interface' voorzien. Als laatste voorziening maken we nog wat foutafhandelings routines om alles netjes te kunnen afsluiten als er iets mis gaat. In voorbeeld 3 zit u de afhandeling van een fatale fout. Bewust gebruiken we hier niet de internet explorer interface, we weten immers niet eens of deze nog wel functioneert. Voor de zekerheid geven we wel een sluitcommando aan het IE object om er zeker van te zijn dat deze gestopt wordt als het nodig is.
Nu we de basis hebben gelegd gaan we als eerste gaan we de ondersteuning voor het aanmaken van schijfletters inbouwen. Voorbeeld 2 laat de functie zien die we hiervoor gaan gebruiken. De functie is relatief eenvoudig en gebruikt het commando oWSHNetwork.MapNetworkDrive strDrive,strShare om de verbinding te leggen. De overige 80% van de code is voor de afhandeling van foutcondities en rapportage. Via een bijna gelijkwaardige constructie maken we ook de functie voor het aansturen van de printers : owshNetwork.AddWindowsPrinterConnection strPrinter
De volgende stap is het aanpassen van de registry. Hiervoor gebruiken we een van de standaard methods van VBScript : oWSHShell.RegWrite strKey,strValue. Ook dit is een redelijk recht toe recht aan functie.
Het aanmaken van snelkoppelingen is iets meer complex. We moeten er niet alleen zorg voor dragen dat we de snelkoppeling maken maar deze ook weer verwijderen wanneer dit nodig is. Voorbeeld 5 laat de routines zien die we nodig hebben. Met de method oWshShell.CreateShortcut maken we de snelkoppeling aan. Natuurlijk moet de snelkoppeling ook weer worden verwijdert wanneer deze niet meer nodig is dus we voegen een delete commando toe om dit te verzorgen.
Eenmaal alle functies gecreeerd kunnen we ons script functioneel maken. We controleren met onze memberof functie steeds weer of de gebruiker daadwerkelijk lid is van de gewenste groep en roepen dan de juiste functie aan. Dat ziet er ongeveer zo uit:

    if memberof("administrators") then
      Mapdrive "X:",strLogonServer & "\sysvol","Important share"
    end if

In dit geval wordt gecontroleerd of de gebruiker lid is van de groep 'administrators' waarna de mapdrive functie wordt aangeroepen die een verbinding maakt van sysvol op de domain controller waar we ons hebben aangemeld.

Functioneel gezien is het loginscript nu af en kunnen we het voorzien van alle juiste verbindingen en instellingen. Wanneer u enige ervaring hebt opgedaan met deze manier van scripten kunt u zelf op analoge wijze functionaliteit toevoegen door steeds nieuwe functies te creeeren. U zielt zien dat VBScript een uitermate krachtige taal kan zijn, ook voor het toepassen van loginscripts.

Voorbeeld 1: Function GetGroups

Dim oUser, oGroup
  on Error Resume Next
  Set oUserGroups = CreateObject("Scripting.Dictionary")
  oUserGroups.CompareMode = vbTextCompare
  'use ADSI WINNT provider for simplicity
  Set oUser = GetObject("WinNT://" & strLogonDomain & "/" & strUser & ",user")
  For Each oGroup In oUser.Groups
   oUserGroups.Add oGroup.Name, "-"
  Next
  Set oUser = Nothing
  if Err.number then
    Getgroups=false
  else
    Getgroups=true
  end if
End Function 'Getgroups

Voorbeeld 2: mapdrives

Sub MapDrive(strDrive,strShare,strdescription)
  on error resume next
  oWSHNetwork.RemoveNetworkDrive strDrive
  Err.Clear
  writeOutput "<BR>Mapping " & strDrive & " to " & strShare & " (" & strdescription & ")"
  oWSHNetwork.MapNetworkDrive strDrive,strShare
  if Err.number Then
    NonFatalError("<BR><FONT COLOR=#FF6666>ERROR! Mapping network drive " & strDrive & " Reason: " & Err.Description & "</FONT>")
  else
   writeoutput "Drive" & strDrive & " (" & strDescription &  ") has been added "
  End if
  on error goto 0
End Sub

Voorbeeld 3: foutenafhandeling

Sub FatalError(strMessage)
Dim strOutput

  strOutput="Loginscript Processing has been halted because of a fatal error."_
      & "The following error occured: " & strMessage
  oWshShell.Logevent 1, strOutput
  wscript.echo strOutput
  oMSIE.Quit
  wscript.quit
end sub 'Fatal Error

Voorbeeld 4: registry

Sub Setreg(strkey,strvalue,strdescription)
 


 writeoutput "Writing value for " & strDescription & " to the registry"
  oWSHShell.RegWrite strKey,strValue
  if Err.number then
    NonFatalError("<BR><FONT COLOR=#FF6666>ERROR! key" & strkey & "has NOT been changed" & Err.number & ":" & Err.Description & "</font>")
    Err.clear
  else
    writeoutput "Registry Key " & strKey & ") has been changed "
  end if
End Sub

Voorbeeld 5 : snelkoppeling maken

Sub MakeLink (strShortCut,strTargetpath,strWindowStyle,strIconlocation,strDescription,strWorkingdirectory)
Dim oShell
  set oShell = oWshShell.CreateShortcut(oWshShell.SpecialFolders("Desktop") & "\Notepad.lnk")
  oShell.TargetPath = strTargetpath
  oShell.WindowStyle = strWindowStyle
  oShell.IconLocation = strIconlocation
  oShell.Description = strDescription
  oShell.WorkingDirectory = strWorkingdirectory
  oShell.Save
  if Err.number then
    NonFatalError("<BR><FONT COLOR=#FF6666>ERROR! shortcut" & strshortcut & "has NOT been created" & Err.number & ":" & Err.Description & "</font>")
    Err.clear
  else
    writeoutput "Shortcut " & strShortcut & ") has been created "
  end if
end sub

Sub RemoveFile(strTheFile)

Dim oFSO
  Set oFSO = CreateObject("Scripting.FileSystemObject")
  if (oFSO.FileExists(strTheFile)) then
    oFSO.DeleteFile strTheFile
    if Err.number then
      NonFatalError("<BR><FONT COLOR=#FF6666>ERROR! File " & strTheFile & "Could not be deleted" & Err.number & ":" & Err.Description & "</font>")
      Err.clear
    end if
  end if
End Sub

Download

W. Verveen is verbonden aan de Ormer groep als Consultant, daarnaast beheert hij Windows 2000 Wereld
E-mail: w.verveen@ormer.nl
Web: http://www.ormer.nl en http://www.win2kwereld.nl

 

privacy policy