GUID Collection/Account Prestaging VBScript Example


GUID Collection Tool

This tool will assist you in collecting GUIDs from your lab and faculty/staff computers. It is a simple VB Script that creates a CSV file per machine and makes a single entry into a cumulative CSV file in a ‘collect’ directory. After running the script on each of your target computers you will be able to take the contents of the cumulative CSV file and easily format it to the layout required by the pre-staging tool (below).

Example output file (guid_list.csv):

   labdesktop1444-01,4C4C4544-0054-3112-8035-A9C04F593731
   labdesktop1444-02,4C4C4544-0047-4D12-8043-F6C04F593731
   labdesktop1444-03,4C4C4544-0054-3112-8035-F6C04F593731
   labdesktop1444-04,4C4C4544-0047-4D12-8043-F7C04F593731
   labdesktop1444-05,4C4C4544-0047-4D12-8043-G4C04F593731
   labdesktop1444-06,4C4C4544-0048-4D12-8043-R6C04F593731

The code:

[vb]

‘—————————————————————————–

‘ Purpose: This script writes out the computer name & GUID to two csv files
‘ (in a ‘collect’ directory beneath the current working directory):

‘ A single file of the same name as the computer and a collective
‘ file with the name of the GUID_LIST_FILE constant.

‘ If the GUID has already been written to the individual file, then
‘ the script will not re-create the file or append the entry to the
‘ list file.

‘ *Note: This script has not been tested for thread/process safety
‘ and therefore unexpected results may occur if multiple instances
‘ of the script try to access the GUID_LIST_FILE simultaneously.

‘ Author: Ryan Leap & Kris Tesh, College of Textiles

‘—————————————————————————–

‘ Originally from: http://support.microsoft.com/kb/302467
‘ The sample uses WMI to return the UUID on the system.
‘ If a UUID can not be found on the system it returns all F’s.
‘ What RIS does in this case is it uses a zero’d out version of the MAC
‘ address of the NIC the machine is booting off of.
‘ This sample will return the value required to set the
‘ netbootGUID attribute
‘ MSFT Script Repository ‘how to get UUID’ routine

‘—————————————————————————–

Option Explicit
Dim objFSO, objFolder, objTextFile, objShell
Dim objNTInfo, objSystemSet, objSystemItem
Dim strDirectory, strFile, strText
Dim szComputerName, szUUID
Dim WSHShell

‘Declare constants
CONST ForReading = 1
CONST ForWriting = 2
CONST ForAppending = 8
CONST GUID_LIST_FILE = “guid_list.csv”

‘Set Directory for Data file here:
Set objShell = CreateObject(“WScript.Shell”)
strDirectory = objShell.CurrentDirectory & “\” & “collect”
Set objShell = nothing

‘Get Computer Name
Set objNTInfo = CreateObject(“WinNTSystemInfo”)
szComputerName = lcase(objNTInfo.ComputerName)
strFile = szComputerName & “.csv”
Set objNTInfo = nothing

‘Get GUID
Set objSystemSet = GetObject(“winmgmts:”).InstancesOf (“Win32_ComputerSystemProduct”)
For Each objSystemItem In objSystemSet
szUUID = objSystemItem.UUID
Next
Set objSystemSet = nothing

‘Create the File System Object
Set objFSO = CreateObject(“Scripting.FileSystemObject”)

‘Check that the target folder exists
If objFSO.FolderExists(strDirectory) Then
Set objFolder = objFSO.GetFolder(strDirectory)
Else
Set objFolder = objFSO.CreateFolder(strDirectory)
End If
Set objFolder = nothing

‘Comma separated entry
strText = szComputerName & “,” & szUUID

‘Prevent duplicate entries:
‘Only create the file & append to the collective file if needed
If objFSO.FileExists(strDirectory & “\” & strFile) = False Then

‘Open Individual file
Set objTextFile = objFSO.OpenTextFile _
(strDirectory & “\” & strFile, ForWriting, True)
objTextFile.WriteLine(strText)
objTextFile.Close

‘Open Collective file
Set objTextFile = objFSO.OpenTextFile _
(strDirectory & “\” & GUID_LIST_FILE, ForAppending, True)
objTextFile.WriteLine(strText)
objTextFile.Close
Set objTextFile = nothing

End If

Set objFSO = nothing
WScript.Quit

[/vb]

Account Prestaging Tool

This tool will allow you to pre-stage managed computers into the WolfTech AD OU of your choice (assuming you have the necessary permissions to the OU etc.) for use with RIS from an Excel spreadsheet. The VB Script (PrestagRISClnt.vbs) provided below is a modified version of a script provided by Microsoft as part of their Windows Server 2003 Deployment Kit in the Sample_RIS_Scripts.zip file found here:

Windows Server 2003 Deployment Kit

The script has been modified to accept one additional argument – a container (OU) of your choice to stage the computers. The script, as provided by Microsoft, will only stage the computers into the default ‘Computers’ AD group. The Computer Account Prestaging Tool includes a sample excel file containing a list of computers & a batch file that will run the script with the necessary arguments.

Instructions for using the Pre-staging tool:

  1. Copy the code below, saving it as PrestagRISClnt.vbs, download the remaining components and unzip the them to a WinXP computer in the WolfTech domain w/the following prerequisites:
    1. .NET Framework 2.0
    2. Microsoft Office (Excel) – the script uses an Excel COM object
  2. Register the GUIDConvert.dll (see Cannot prestage RIS Clients in Active Directory by using the Windows Server 2003 Deployment Kit for details):
    1. Run register_guid_dll.bat
    2. If Pre-staging script issues this error:
    3.     'Error0x80070002 occurred creating GUIDConvert object'
      

      Try the following command to fix the GUIDConvert.dll registration:

          %windir%\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe /codebase GUIDConvert.dll
      
  3. Modify ‘sample_computers.xls’ to a list of computers & corresponding GUIDs that you would like to pre-stage
  4. Modify ‘prestage_sample_computers.bat’ /Server argument to reference the RIS server of your choice. *Note: you can specify /Server:ignore to leave this attribute blank
  5. Modify ‘prestage_sample_computers.bat’ /Container argument to the desired computer staging OU
  6. Run ‘prestage_sample_computers.bat’ to stage the computers in your excel spreadsheet. *Note: The following error message is issued, but the computers are still staged into AD:
  7.  Error0x80004005 occurred while processing "{computername}" !
    

The code:

[vb]

‘*********************************************************************************
‘*
‘* Modified
‘*
‘** NOTE: Script modifed from the original by Ryan Leap, College of Textiles.
‘** Changes are denoted with ‘sRL’ tags.
‘**
‘** DATE: June 2008
‘**
‘** SOURCE: Original script downloaded from:
‘** http://www.microsoft.com/downloads/details.aspx?familyid=aaf0a7a4-71c1-4ee9-b974-66214651a23b&displaylang=en
‘** Sample_RIS_Scripts.zip
‘*
‘*********************************************************************************

‘*********************************************************************************
‘*
‘*
‘*
‘* Disclaimer
‘*
‘** This sample script is not supported under any Microsoft standard support program
‘** or service. This sample script is provided AS IS without warranty of any kind.
‘** Microsoft further disclaims all implied warranties including, without limitation,
‘** any implied warranties of merchantability or of fitness for a particular purpose.
‘** The entire risk arising out of the use or performance of this sample script and
‘** documentation remains with you. In no event shall Microsoft, its authors, or
‘** anyone else involved in the creation, production, or delivery of the script be
‘** liable for any damages whatsoever (including, without limitation, damages for
‘** loss of business profits, business interruption, loss of business information,
‘** or other pecuniary loss) arising out of the use of or inability to use this
‘** sample script or documentation, even if Microsoft has been advised of the
‘** possibility of such damages.
‘**
‘**
‘** Copyright 2003, Microsoft Corporation
‘**
‘**
‘********************************************************************************

‘********************************************************************************
‘** DESCRIPTION: Sample script showing how to prestage RIS clients in Active
‘** Directory directory service.
‘**
‘** REFERENCE: Chapter 4 “Designing RIS Installations” in the Windows Server 2003
‘** Deployment Kit: Automating and Customizing Installations
‘**
‘** SAMPLE Script Name: PrestagRISClnt.txt
‘**
‘** This sample script shows how to prestage client computers in Active Directory
‘** directory service. This sample script relies on a .dll (GUIDConvert.dll) which
‘** you must create. For information about how to create this .dll, see article Q829032
‘** “Cannot Prestage RIS Clients in Active Directory By Using the Windows Server 2003
‘** Deployment Kit” in the Microsoft Knowledge Base. This script also relies on a
‘** spreadsheet which contains the UUIDs/GUIDs, computer names, and other information that
‘** you need to add to Active Directory. You can create this spreadsheet manually
‘** or you can use the sample script “GetRISBIOSInfo.txt” to create this spreadsheet.
‘** If you modify the spreadsheet, be sure that the data entry starts in Row 4 (Rows 1 – 3 are
‘** reserved for headings and other information). The columns in this spreadsheet can
‘** contain the following information, which correspond to computer object
‘** properties/attributes in Active Directory:
‘**
‘** Column 1 – Computer Account Name
‘** Column 2 – Computer System UUID/GUID
‘** Column 3 – Computer Location
‘** Column 4 – Domain\Username
‘** Column 5 – Computer Description
‘** Column 6 – Startup File Path
‘**
‘** This sample script reads the values from the spreadsheet and adds them to Active
‘** Directory. You must specify values in Columns 1 and 2 to prestage clients. Columns
‘** 3, 4 and 5 are optional and do not require data for the script to run. If you
‘** specify a value for Column 4,the script will configure the specified user account
‘** with “Full Control” permissions on the prestaged computer account and will create
‘** a password using the machine account name with “$” appended to it. Column 6 is used
‘** to specify the path to the startup file that you want a client to use: either
‘** startrom.com for interactive installations, or startrom.n12 for automated
‘** installations. If you want to require all clients to use the same startup file,
‘** you can leave Column 6 blank and use the /command switch to specify an installation
‘** method.
‘**
‘** NOTES:
‘**
‘** There cannot be any blank rows between computer account listings
‘** in the spreadsheet, starting with Row 4.
‘**
‘** Before prestaging, delete existing computer accounts from the Active Directory
‘** default Computers container (after creating the Excel spreadsheet with the
‘** prestaging data).
‘**
‘** Do not prestage the RIS server computer account. Remove it from the Excel
‘** spreadsheet if you used the sample script “GetRISBIOSInfo.txt” to populate
‘** the spreadsheet.
‘**
‘** Make sure that GUIDConvert.dll is registered on the system where the script
‘** runs, so it can be accessed as a COM object from the script.
‘**
‘** SYNTAX:
‘**
‘** Cscript.exe PreStagRISClnt.vbs /InputFile:InputFilePathAndName /Server:ServerName
‘** [/Command:[automate | interactive]] ‘**
‘** /InputFile:InputFilePathAndName
‘** Specifies the path and file name of the Excel file containing the computer
‘** names, UUIDs/GUIDs, and startup file path for the computers you want to prestage
‘** in Active Directory.
‘**
‘** /Server:ServerName
‘** Specifies the name of the RIS server that contains the startup files.
‘** ServerName must not contain \\.
‘**
‘** [/Command:[automate | interactive]] ‘** Specifies whether you want all RIS clients to use startrom.com (interactive
‘** installation) or startrom.n12 (automated installation). This is an
‘** optional setting. If you do not use this setting then you must specify
‘** the installation type for each client in the Excel spreadsheet. If you use
‘** this option, you must use the /Server option.
‘**
‘** [/Container] – added by sRL
‘** Specifies the container (OU) where you want to prestage the computers
‘**
‘********************************************************************************

‘********************************************************************************
OPTION EXPLICIT

Dim strSpace
Dim strRetValHst
Dim intRetVal
Dim lFlag
Dim Fso
Dim objADsArrayConvert
Dim objArgs
Dim objNamed
Dim strXLFileName
Dim strCommand
Dim strServer
Dim strContainer ‘added by sRL
Dim intConfirm
Dim objExcel
Dim strExcelPath
Dim objSheet
Dim objRange
Dim x
Dim intFormat
Dim intMsg

‘** Declare constants used in defining the default location for the machine
‘** account, flags to identify the object as a machine account, and security
‘** flags:
CONST ADS_GUID_COMPUTRS_CONTAINER = “aa312825768811d1aded00c04fd8d5cd”
CONST UF_WORKSTATION_TRUST_ACCOUNT = &H1000
CONST UF_ACCOUNTDISABLE = &H2
CONST UF_PASSWD_NOTREQD = &H20
CONST ADS_ACETYPE_ACCESS_ALLOWED = 0
CONST ADS_ACEFLAG_INHERIT_ACE = 2

‘** Declare “invalid input” constants:
CONST KINVALID_1 = 1
CONST KINVALID_2 = 2
CONST KINVALID_3 = 3
CONST KINVALID_4 = 4
CONST KINVALID_5 = 5
CONST KINVALID_6 = 6
CONST KINVALID_7 = 7
CONST KINVALID_8 = 8
CONST KINVALID_9 = 9 ‘added by sRL

‘** Declare “input command” constants:
CONST KUNSPECIFIED = “unspecified”
CONST KAUTOMATE = “automate”
CONST KINTERACTIVE = “interactive”

‘** Ignore specified server option – added by sRL
‘** Thought some script users would prefer not to specify a RIS Server
‘** but rather use any RIS server available
CONST IGNORE_SERVER_SWITCH = “ignore”

‘** Declare various other constants:
CONST KNOERROR = 0
CONST KMSG_CANCEL = 2
CONST KRETVAL_YES = 6
CONST KRETVAL_NO = 7
CONST KFORMAT_10 = 10
CONST KFORMAT_11 = 11
CONST KUNDETERMINED = “undetermined”
CONST KERROR = “error”
CONST KSUCCESS = “success”
CONST KFAILURE = “failure”
CONST KQUOTE = “”””
CONST KTRUE = True
CONST KFALSE = False

lFlag = UF_WORKSTATION_TRUST_ACCOUNT Or UF_ACCOUNTDISABLE Or UF_PASSWD_NOTREQD

ON ERROR RESUME NEXT

‘**
‘** Main execution begins:
‘**

‘** ////////////////////////////////////////////
‘** Create spacer for formatting output message:

If Len(Time) = 10 Then
strSpace = ” ”
ElseIf Len(Time) = 11 Then
strSpace = ” ”
End If

‘** ////////////////////////////////////////////////////
‘** Call the function to detect the default script host:
strRetValHst = IsHostCScript()

‘** ////////////////////////////////////
‘** Check return value of IsHostCScript:

Select Case strRetValHst

Case KERROR
intRetVal = Msgbox _
(“The default WSH script host was not detected” & vbcrlf & _
“since Error0x” & Hex(Err.Number) & _
” occurred unexpectedly !” & vbcrlf & _
“Error description: ” & Err.Description & vbcrlf & vbcrlf & _
“If you continue, the script might fail to execute. . ” & vbcrlf & _
“Do you want to continue anyway ?”, 20, “Script Host Error”)

If intRetVal = KRETVAL_YES Then
‘** Do nothing and proceed with script execution…
Err.Clear

ElseIf intRetVal = KRETVAL_NO Then
Err.Clear
WScript.Quit()
End If

Case KUNDETERMINED
Msgbox “Could not determine default script host, ” & _
“the script may behave” & vbcrlf & “unexpectedly. . .”, _
64, “Script Host Message”

Case KFAILURE
‘** If default script host is set to WScript, if the script is launched
‘** by double-clicking it, or if user happens to run the script with
‘** WScript.exe at the command line, then send a message to the user to
‘** change the default host:

Msgbox “Script requires CSCRIPT.EXE to execute !” & vbcrlf & _
“Either specify cscript.exe in the command line” & vbcrlf & _
“or change the default script host to cscript.exe” & vbcrlf & _
“by running the following command:” & vbcrlf & vbcrlf & _
“cscript.exe //H:cscript //S”, 64, “Script Host Message”

WScript.Quit()

Case KSUCCESS
‘** Do nothing to proceed…

Case Else
Msgbox “Could not determine default script host, ” & _
“the script may behave” & vbcrlf & “unexpectedly. . .”, _
64, “Script Host Message”

End Select

‘** //////////////////////
‘** Create global objects:

‘** Create FileSystemObject:
Set Fso = CreateObject(“Scripting.FileSystemObject”)

‘** Create GUIDConvert object:
Set objADsArrayConvert = CreateObject(“GUIDConvert.Convert”)

If Err.Number <> KNOERROR Then
WScript.Echo “Error0x” & Hex(Err.Number) & _
” occurred creating GUIDConvert object. . .”

If Err.Description > “” Then
WScript.Echo Err.Description
WScript.Echo “Make sure guid.dll is registered on your system !”
End If

Err.Clear
WScript.Quit()
End If

‘** Create Named arguments object:
Set objArgs = WScript.Arguments
Set objNamed = objArgs.Named

‘** /////////////////////////////////
‘** Check if user is asking for Help:

If objArgs.Count <> 0 Then

If objArgs.Item(0) = “?” OR _
objArgs.Item(0) = “/?” OR _
objArgs.Item(0) = “-h” OR _
objArgs.Item(0) = “-H” OR _
objArgs.Item(0) = “-help” OR _
objArgs.Item(0) = “-Help” OR _
objArgs.Item(0) = “help” OR _
objArgs.Item(0) = “Help” OR _
objArgs.Item(0) = “/help” OR _
objArgs.Item(0) = “/Help” Then

ShowUsage()
WScript.Quit(1)
End If

ElseIf objArgs.Count = 0 Then
Call Abort(KINVALID_1)

End If

‘** ///////////////////////////////////////
‘** Check the input argument configuration:

‘** If the user is setting the same startup file for all prestaged RIS
‘** clients, get the input action command. .
If objNamed.Exists(“Command”) Then
strCommand = LCase(objNamed(“Command”))

If strCommand = KINTERACTIVE or strCommand = KAUTOMATE Then

‘** Get server name for specifying path to startup boot file to
‘** use on all clients prestaged with this script:
‘sRL – Commented out code below because this appeared to be a bug. When the \\ prefix was prepended on the
‘sRL – strServer argument it prevented the specified server from being properly placed in the computer object in AD
If objNamed.Exists(“Server”) Then ‘sRL
strServer = LCase(objNamed(“Server”)) ‘sRL

If strServer = “” OR InStr(strServer, “\\”) <> 0 Then ‘sRL
Call Abort(KINVALID_5) ‘sRL
End If ‘sRL
Call CheckServer(KFORMAT_11) ‘sRL
‘sRL strServer = “\\” & LCase(objNamed(“Server”))

‘sRL If strServer = “\\” OR InStr(strServer, “\\\\”) <> 0 Then
‘sRL Call Abort(KINVALID_5)
‘sRL End If

‘** Call procedure to check if a connection to the specified server can be made:
‘sRL Call CheckServer(KFORMAT_10)

Else
Call Abort(KINVALID_3)
End If

‘** Get path to input file:
If objNamed.Exists(“InputFile”) Then
strXLFileName = LCase(objNamed(“InputFile”))

If strXLFileName = “” Then
Call Abort(KINVALID_2)

ElseIf InStr(strXLFileName, “.xls”) = 0 Then
Call Abort(KINVALID_6)
End If

Else
Call Abort(KINVALID_2)

End If

‘** Get Container name – added by sRL
If objNamed.Exists(“Container”) Then
strContainer = objNamed(“Container”)

If strContainer = “” Then
Call Abort(KINVALID_9)
End If

End If

Else
Call Abort(KINVALID_4)

End If

‘** /////////////////////////////////////////////////////////////////////
‘** . . or if the user is not specifying a command, get the path to input
‘** file and get the server name (minimum input argument configuration). .

ElseIf objArgs.Count = 2 AND _
objNamed.Exists(“InputFile”) AND _
objNamed.Exists(“Server”) Then

strXLFileName = LCase(objNamed(“InputFile”))

If InStr(strXLFileName, “.xls”) = 0 Then
Call Abort(KINVALID_6)
End If

strServer = LCase(objNamed(“Server”))

If strServer = “” OR InStr(strServer, “\\”) <> 0 Then
Call Abort(KINVALID_5)
End If

‘** Call procedure to check if a connection to the specified server can be made:
Call CheckServer(KFORMAT_11)

strCommand = KUNSPECIFIED

‘** Added by sRL to support ‘Container’ argument
ElseIf objArgs.Count = 3 AND _
objNamed.Exists(“InputFile”) AND _
objNamed.Exists(“Server”) AND _
objNamed.Exists(“Container”) Then

strXLFileName = LCase(objNamed(“InputFile”))

If InStr(strXLFileName, “.xls”) = 0 Then
Call Abort(KINVALID_6)
End If

strServer = LCase(objNamed(“Server”))

If strServer = “” OR InStr(strServer, “\\”) <> 0 Then
Call Abort(KINVALID_5)
End If

‘** Call procedure to check if a connection to the specified server can be made:
Call CheckServer(KFORMAT_11)

strContainer = objNamed(“Container”)

If strContainer = “” Then
Call Abort(KINVALID_9)
End If

strCommand = KUNSPECIFIED

Else
‘** . . otherwise, the input argument configuration is incorrect:
Call Abort(KINVALID_8)

End If

‘** ///////////////////////////////////////////////////////////////////
‘** Call procedure to check if specified input file actually exists and
‘** get count for number of computer accounts being added:
Call CheckInputFile(x, strXLFileName)

If x > 0 Then

‘** Prompt user with a continuation message:
intConfirm = Msgbox _
(“You are about to add ” & x & ” machine accounts to Active ” & _
“Directory. Click OK to” & vbcrlf & “continue, or press ” & _
“Cancel if you do not want to add these accounts now. . .”, _
vbOkCancel, “Add Machine Accounts ?”)

If intConfirm = KMSG_CANCEL Then
WScript.Echo Time & “: Aborted prestaging process !”
WScript.Quit()

Else
WScript.Echo Time & “: Processing prestaging data. . .”
WScript.Echo “”

Call CreateComputerAccts()

End If

Else
Call Abort(KINVALID_7)
End If

‘** Release object references:
Set objNamed = Nothing
Set objArgs = Nothing
Set objADsArrayConvert = Nothing
Set Fso = Nothing

‘**
‘** End main execution
‘**

‘********************************************************************************
Function IsHostCScript()

‘** Detects if WSH default host is cscript.exe. .

Dim strHostPath
Dim strHostName

ON ERROR RESUME NEXT

‘** Initialize string variables:
strHostPath = “”
strHostName = “”

‘** Get default script host name:
strHostPath = LCase(WScript.FullName)

‘** Check if any errors occurred (may happen if WSH is not installed):
If Err.Number <> KNOERROR Then
IsHostCScript = KERROR
Exit Function

‘** In case strHostPath variable was not set by WScript.FullName:
ElseIf strHostPath = “” OR IsEmpty(strHostPath) Then
IsHostCScript = KUNDETERMINED
Exit Function

ElseIf InStr(strHostPath, “cscript”) = 0 Then
IsHostCScript = KFAILURE
Exit Function

ElseIf InStr(strHostPath, “cscript”) <> 0 Then
strHostName = Trim(Right(strHostPath, 11))

If strHostName = “cscript.exe” Then
IsHostCScript = KSUCCESS

Else
IsHostCScript = KFAILURE
End If

End If

End Function

‘********************************************************************************
Sub Abort(intMsg)

‘** Displays appropriate message if user specifies an incorrect input
‘** argument, command configuration, or other invalid input data . . .

If intMsg = 1 Then
WScript.Echo “Aborted, input arguments required, see script Help. .”

ElseIf intMsg = 2 Then
WScript.Echo “Input file required to run the script, see script Help. .”

ElseIf intMsg = 3 Then
WScript.Echo “Aborted, server name required, see script Help. .”

ElseIf intMsg = 4 Then
WScript.Echo “Aborted, invalid action command, see script Help. .”

ElseIf intMsg = 5 Then
WScript.Echo “Aborted, invalid servername format, see script Help. .”

ElseIf intMsg = 6 Then
WScript.Echo “Aborted, please specify the .xls extension ” & _
“for your input Excel file !”
WScript.Quit()

ElseIf intMsg = 7 Then
WScript.Echo “The input file ” & KQUOTE & strXLFileName & KQUOTE & _
” has no valid data for prestaging computer accounts. . .”
WScript.Quit()

ElseIf intMsg = 8 Then
WScript.Echo “Aborted, invalid input argument configuration, see script Help. .”

ElseIF intMsg = 9 Then ‘added by sRL to support ‘Container’ argument
WScript.Echo “Aborted, invalid/missing ‘Container’ input argument configuration, see script Help. .”

End If

WScript.Echo “”
ShowUsage()
WScript.Quit()

End Sub

‘********************************************************************************
Sub CheckInputFile(ByRef x, strXLFileName)

‘** Checks for the presence of the input file and gets the count of the
‘** number of computer accounts in the Excel spreadsheet. . .

Dim u
Dim Item

ON ERROR RESUME NEXT

‘** Check for existence of input file:
If Not (Fso.FileExists(strXLFileName)) Then
WScript.Echo “The input file ” & KQUOTE & strXLFileName & KQUOTE & _
” is missing. Please locate the file and place it ” & _
vbCrLf & _
“in the appropriate directory location before ” & _
“running this script. .”
WScript.Quit()
End If

‘** Create object instance of the Excel application for verifying the
‘** input data:
Set objExcel = CreateObject(“Excel.Application”)

‘** Check for success of creating object instance:
If Err.Number <> KNOERROR Then
WScript.Echo “Error0x” & Hex(Err.Number) & ” occurred creating Excel ” & _
“object. . ” & vbcrlf & _
“You may not have Excel installed on your system !”

Err.Clear
WScript.Quit()
End If

strExcelPath = Fso.GetAbsolutePathName(strXLFileName)
objExcel.Workbooks.Open(strExcelPath)
Set objSheet = objExcel.ActiveWorkbook.Worksheets(1)

‘** Create cell collection and count cell values in first column to get
‘** number of computer accounts being added from the Excel spreadsheet
‘** and verify that the UUID/GUID for each computer is valid:

Set objRange = objSheet.Cells

u = 4

For Each Item in objRange

‘** Exit loop when a blank cell in the first column is encountered
‘** after the listings start in the 4th Row.
‘** Exit program if an invalid UUID is found:

If objRange.Cells(u, 1) = “” Then
x = u – 4
Exit For
ElseIf Len(objRange.Cells(u,2)) <> 36 Then
WScript.Echo “The input file ” & KQUOTE & strXLFileName & KQUOTE & _
” contains” & vbCrLf & “an invalid computer system UUID.” & _
vbCrLf & “UUIDs must be in the following hexadecimal form: ” & _
vbCrLf & “XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.”
WScript.Quit()
End If

u = u + 1
Next

Set objRange = Nothing

End Sub

‘********************************************************************************
Sub CheckServer(intFormat)

‘** Checks if a connection can be made to the specified RIS server and verifies
‘** whether a remote installation share (REMINST) exists there. .

Dim intSlshPos
Dim strRISServer
Dim objService
Dim objShare
Dim Share
Dim blnShareExists

ON ERROR RESUME NEXT

blnShareExists = KFALSE

If (strServer = IGNORE_SERVER_SWITCH) Then ‘option to ignore added by sRL
WScript.Echo vbcrlf & Time & “: Ignoring server switch. Remote install” & _
vbcrlf & “server attribute will not be set for computer account(s).” & vbcrlf
Else

‘** Get the server name in the correct format for GetObject:
If intFormat = KFORMAT_10 Then
intSlshPos = InStr(strServer, “\\”)

If intSlshPos <> 0 Then
strRISServer = Mid(strServer, intSlshPos + 2, Len(strServer) – (intSlshPos + 1))
End If

ElseIf intFormat = KFORMAT_11 Then
strRISServer = strServer
End If

‘** Connect with CIM repository on RIS server and get instance of
‘** Winmgmts service:
Set objService = GetObject(“Winmgmts:\\” & strRISServer & “\root\cimv2”)

If Err.Number <> KNOERROR Then
WScript.Echo Time & “: Error0x” & Hex(Err.Number) & ” occurred attempting to ” & _
“connect with Winmgmts on ” & UCase(strServer) & “. . .”

If Err.Description > “” Then
WScript.Echo vbTab & strSpace & Err.Description & ” !”
End If

Err.Clear
WScript.Quit()

Else
‘** Get instance of Win32_Share class:
Set objShare = objService.ExecQuery(“Select * from Win32_Share”)

For Each Share in objShare

If Share.Name = “REMINST” Then
blnShareExists = KTRUE
Exit For
End If

Next

If blnShareExists = KFALSE Then
WScript.Echo Time & “: The server you specified does not ” & _
“have a ” & KQUOTE & “REMINST” & KQUOTE & _
” share ! ” & vbcrlf & _
vbTab & strSpace & “Please check the server name. . .”
WScript.Quit()
End If

End If
End If

End Sub

‘********************************************************************************
Sub CreateComputerAccts()

‘** Creates prestaged computer accounts in Active Directory along with
‘** configuration of the netbootGUID attribute, the RIS server that services
‘** the client, and the netbootSIFFile attribute (startupfile). . .

Dim bolErrFlag
Dim strCompFail
Dim u
Dim Item
Dim strMAOName
Dim strUUID
Dim strLocation
Dim strUser
Dim strDescription
Dim strStartup
Dim rootDSE
Dim compContainer
Dim arrayByteOctel
Dim objComputer
Dim secDescriptor
Dim dACL
Dim ACE

ON ERROR RESUME NEXT

‘** Create cell collection:
Set objRange = objSheet.Cells

bolErrFlag = False
strCompFail = “”
u = 4

For Each Item in objRange

If objRange.Cells(u, 1) = “” Then
Exit For

Else

strMAOName = objRange.Cells(u, 1)
strUUID = Replace(objRange.Cells(u, 2), “-“,””)
strLocation = objRange.Cells(u, 3)
strUser = objRange.Cells(u, 4)
strDescription = objRange.Cells(u, 5)

If strCommand = KINTERACTIVE Then
strStartup = strServer & “\REMINST\OSChooser\i386\startrom.com”

ElseIf strCommand = KAUTOMATE Then
strStartup = strServer & “\REMINST\OSChooser\i386\startrom.n12”

ElseIf strCommand = KUNSPECIFIED Then
strStartup = objRange.Cells(u, 6)
End If

End If

‘** ///////////////////////////////////////////////////////////////////
‘** Establish a path to the container in the Active Directory where the
‘** machine account will be created. The following code automatically
‘** locates a domain controller for the domain, reads the distinguished
‘** name, and binds to the default “Computers” container:

‘sRL – Set rootDSE = GetObject(“LDAP://RootDSE”)
‘sRL – Set compContainer = GetObject(“LDAP://<WKGUID=” & ADS_GUID_COMPUTRS_CONTAINER & _
‘sRL – “,” & rootDSE.Get(“defaultNamingContext”) & “>”)
‘sRL – Set compContainer = GetObject(“LDAP://” & compContainer.Get(“distinguishedName”))

‘————————————————————————————
‘ sRL – Modified to support ‘Container’ argument
Set rootDSE = GetObject(“LDAP://RootDSE”)
If strContainer <> “” Then
Set compContainer = GetObject(“LDAP://” & strContainer & “,” & rootDSE.Get(“defaultNamingContext”))
Else ‘sRL – use the default AD ‘Computers’ container
Set compContainer = GetObject(“LDAP://<WKGUID=” & ADS_GUID_COMPUTRS_CONTAINER & _
“,” & rootDSE.Get(“defaultNamingContext”) & “>”)
Set compContainer = GetObject(“LDAP://” & compContainer.Get(“distinguishedName”))
End If
‘————————————————————————————

‘sRL If Err.Number <> KNOERROR AND Hex(Err.Number) <> 80071392 Then
‘sRL WScript.Echo Time & “: Error0x” & Hex(Err.Number) & _
‘sRL ” occurred getting AD default ” & KQUOTE & _
‘sRL “Computers” & KQUOTE & ” object !”
‘sRL
‘sRL If Err.Description > “” Then
‘sRL WScript.Echo vbTab & strSpace & Err.Description
‘sRL End If

‘————————————————————————————
‘sRL – Error message modified to include message for non-default container

If Err.Number <> KNOERROR AND Hex(Err.Number) <> 80071392 Then
If strContainer = “” Then
WScript.Echo Time & “: Error0x” & Hex(Err.Number) & _
” occurred getting AD default ” & KQUOTE & _
“Computers” & KQUOTE & ” object !”

If Err.Description > “” Then
WScript.Echo vbTab & strSpace & Err.Description
End If
Else
WScript.Echo Time & “: Error0x” & Hex(Err.Number) & _
” occurred getting AD container ” & KQUOTE & _
strContainer & KQUOTE & ” object !”

If Err.Description > “” Then
WScript.Echo vbTab & strSpace & Err.Description
End If
End If
‘————————————————————————————
Err.Clear
WScript.Quit()
End If

‘** //////////////////////////////////////////////////////////////////////
‘** Create the computer account and set attributes with appropriate values
‘** before calling SetInfo to commit changes to Active Directory:

‘** Convert UUID/GUID to a byte array:
arrayByteOctel = objADsArrayConvert.MakeGUIDByteArray(strUUID)

‘** Create computer account attributes:
Set objComputer = compContainer.Create(“computer”, “CN=” & strMAOName)
objComputer.Put “samAccountName”, strMAOName + “$”
objComputer.Put “userAccountControl”, lFlag
If (strServer <> IGNORE_SERVER_SWITCH) Then ‘option added by sRL
objComputer.Put “netbootMachineFilePath”, strServer
End If
objComputer.Put “netbootGUID”, arrayByteOctel
objComputer.Put “description”, strDescription
objComputer.Put “location”, strLocation
If (strServer <> IGNORE_SERVER_SWITCH) Then ‘option added by sRL
objComputer.Put “netbootSIFFile”, strStartup
End If
objComputer.AccountDisabled = FALSE

objComputer.SetInfo

‘** Check if any errors occur when calling the SetInfo method:
If Hex(Err.Number) = 80071392 Then
WScript.Echo Time & “: Error0x” & Hex(Err.Number) & ” occurred while ” & _
“processing ” & KQUOTE & strMAOName & KQUOTE & _
vbcrlf & _
vbTab & strSpace & “The computer object already exists !”
WScript.Echo “”
bolErrFlag = True
strCompFail = strCompFail & vbTab & strSpace & strMAOName & vbcrlf
Err.Clear

ElseIf Err.Number <> KNOERROR Then
WScript.Echo Time & “: Error0x” & Hex(Err.Number) & _
” occurred while processing ” & _
KQUOTE & strMAOName & KQUOTE & ” !”

If Err.Description > “” Then
WScript.Echo vbTab & strSpace & Err.Description
End If

WScript.Echo “”
bolErrFlag = True
strCompFail = strCompFail & vbTab & strSpace & strMAOName & vbcrlf
Err.Clear
End If

‘** //////////////////////////////////////////////////
‘** Create a default password for the machine account:
objComputer.SetPassword LCase(strMAOName & “$”)

‘** //////////////////////////////////////////////////////////////////
‘** Bind to the Discretionary ACL on the newly created computer account
‘** and create an Access Control Entry (ACE) that gives the specified
‘** user or group full control on the machine account:

Set secDescriptor = objComputer.Get(“ntSecurityDescriptor”)
Set dACL = secDescriptor.DiscretionaryAcl
Set ACE = CreateObject(“AccessControlEntry”)

‘** Set an AccessMask of “-1” to grant Full Control:
ACE.AccessMask = -1
ACE.AceType = ADS_ACETYPE_ACCESS_ALLOWED
ACE.AceFlags = ADS_ACEFLAG_INHERIT_ACE

‘** Grant this control to the appropriate user or group. This uses
‘** the downlevel naming convention (as in DOMAIN\User):
ACE.Trustee = strUser

‘** Add the ACE to the DACL on the machine account:
dACL.AddAce ACE
secDescriptor.DiscretionaryAcl = dACL

‘** Commit the security changes to the machine account:
‘** The following line is generating an error:
objComputer.Put “ntSecurityDescriptor”, Array(secDescriptor)
objComputer.SetInfo

‘** Enable the account:
objComputer.AccountDisabled = False
objComputer.SetInfo

u = u + 1

Err.Clear

Next

‘** Close spreadsheet:
objExcel.ActiveWorkbook.Close

Set objRange = Nothing
Set objSheet = Nothing
Set objExcel = Nothing

‘** //////////////////////////////////////////////////////////////
‘** Echo success if no errors occurred (bolErrFlag will be False):

If bolErrFlag = False Then
WScript.Echo Time & “: Success creating new computer accounts in ” & _
“Active Directory based on UUIDs !”

ElseIf bolErrFlag = True Then
WScript.Echo Time & “: The following computer accounts could not be” & _
” created in Active Directory:” & vbcrlf & vbcrlf & strCompFail
End If

End Sub

‘********************************************************************************
Sub ShowUsage()

WScript.Echo “*********************** PreStagRISClnt.txt **********************”
WScript.Echo “”
WScript.Echo “SCRIPT HELP. . .”
WScript.Echo “”
WScript.Echo “PURPOSE:”
WScript.Echo “1. Prestage computer accounts in the default Computers container in”
WScript.Echo ” Active Directory.”
WScript.Echo “2. Explicitly specify a startup file for all prestaged RIS clients.”
WScript.Echo “”
WScript.Echo “ARGUMENTS:”
WScript.Echo “/InputFile:Value Value specifies the path to an Excel spreadsheet”
WScript.Echo ” file containing the prestaging and startup file”
WScript.Echo ” data.”
WScript.Echo “/Server:Value Value specifies name of remote RIS server that”
WScript.Echo ” contains the startup boot files.”
WScript.Echo ” *Note: if you use ‘ignore’ for the server value”
WScript.Echo ” the script will not set the RIS server attribute”
WScript.Echo ” in the AD computer account”
WScript.Echo “[/Command:Value] Value specifies the action command to run:”
WScript.Echo ” “”interactive”” — sets all prestaged RIS clients”
WScript.Echo ” to use default startrom.com.”
WScript.Echo ” “”automate”” —– sets all prestaged RIS clients”
WScript.Echo ” to use startrom.n12.”
WScript.Echo “[/Container:Value] Value specifies the AD container (OU) to stage”
WScript.Echo ” the computers listed in the InputFile”
WScript.Echo “/? Displays script usage instructions.”
WScript.Echo “”
WScript.Echo “USAGE EXAMPLE:”
WScript.Echo “cscript.exe prestagRisclnt.vbs /InputFile:filepath /Server:servername”
WScript.Echo ” [/Command:automate | interactive]”
WScript.Echo “”
WScript.Echo “NOTES:”
WScript.Echo “1. Do not use double backslashes (\\) when specifying servername.”
WScript.Echo “2. Use quotes for any named argument values that contain spaces.”
WScript.Echo “3. You must generate the input file (spreadsheet) manually or by ”
WScript.Echo ” using the sample script GetRISBIOSInfo.txt.”
WScript.Echo “4. If Command is specified, it overrides the “”startup file path”””
WScript.Echo ” in the input spreadsheet and configures all clients with the same”
WScript.Echo ” startup file.”
WScript.Echo “5. Script requires WSH version 5.6.”
WScript.Echo “6. Admin privileges required in the RIS domain.”
WScript.Echo “”
WScript.Echo “*********************************************************************”

End Sub

[/vb]