Link to home
Start Free TrialLog in
Avatar of SDJ_1
SDJ_1

asked on

VB Script Assistance

Hello,

Was wondering if someone could assist me with merging new code into and existing script see attachment AD_Join.vbs

The scrip currently copies the required files I need to all devices but I need the script to run the following command once files are copied  'ADJoin.cmd'.   See attachment ADJ(2).vbs for code I was attempting to add.


Thanks.
AD-Join.vbs
ADJ--2-.vbs
Avatar of sirbounty
sirbounty
Flag of United States of America image

You need AD-join.vbs to launch, then AD-2.vbs, then AD-join.cmd?
Avatar of SDJ_1
SDJ_1

ASKER

I need AD-Join.vbs to launch then that will launch the AD-Join.cmd once files are copied to required location on devices.   The ADJ-2.vbs is just the code I was putting together to to add into the AD-Join.vbs.
Scanning AD-Join.vbs, all you need is a shell reference, which you have in g_objShell.

So at the point you'd need to launch that cmd script, just use

g_objShell.Run "c:\path to script\AD-Join.cmd"
Avatar of SDJ_1

ASKER

ok, let me give this a shot.  Will let you know.  Thanks.
Avatar of SDJ_1

ASKER

Hello, where in the script should I add this line?
ASKER CERTIFIED SOLUTION
Avatar of sirbounty
sirbounty
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of SDJ_1

ASKER

Thanks for the assistance.  I'm running into another issue and can't seem to locate the mis directed brackets  

C:\Temp\SCCM_ADJoin\AD_Join.vbs(685, 1) Microsoft VBScript compilation error: Sy
ntax error

Below is copy of script:
Option Explicit
On Error Resume Next

' Establish global variables.

' Numbers.
Dim g_intMain, g_intLocale, g_intResult, g_strResult, g_intPendingCode, g_intSuccessCode

' Strings.
Dim g_strProjectName, g_strLogFolder, g_strLogFile, g_strServerName, g_strCurrentPath, g_strHosts
Dim g_strCSVFileTemp, g_strWinDir, g_strCSVFile, g_strUtils, g_strServerIPAddress, g_strVersion, g_strAVDefName, g_strAVDefDate, g_strCont, g_strEnvType	

' Objects.
Dim g_objFS, g_objShell, g_objCSV, g_objDevices, g_objNetwork

' Boolean.
Dim g_blnMain, g_blnRemoteWare, g_blnWQL, g_blnWebPC, g_blnFlag


' Main script instructions should run by default.
g_blnMain = True
g_blnFlag = False

' Define constants.
Const HKLM = &H80000002
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
Const MinWindow = 7
Const SuccessCode = 555
Const PendingCode = 777
Const LocaleUSA = 1033
Const WebPC1 = 219
Const WebPC2 = 218
Const AppName = 3
Const AppVersion = 4
Const AppRunning = 5
Const AppDef = 6
Const LastCheck = 7
Const Win2000 = "5.00.2195"
Const WinXP = "5.1.2600"
Const Win2003 = "5.2.3790"
Const Win2008 = "6.0.6002"
Const RegisterThreshold = 0.75

' Set version.
g_strVersion = "v1.0"

' Set global object variables.
Set g_objFS = CreateObject("Scripting.FileSystemObject")
Set g_objShell = CreateObject("WScript.Shell")
Set g_objDevices = CreateObject("Scripting.Dictionary")
Set g_objNetwork = CreateObject( "WScript.Network" )

' Establish US date and time formats.
g_intLocale = SetLocale(LocaleUSA)

' Project name.
g_strProjectName = "SCCM_ADJoin_" & g_strVersion

' Standard system variables.
g_strCurrentPath = g_objFS.GetAbsolutePathName(".")

' Capture Hosts file for processing later.
g_strHosts = GetOutput("Type %SystemRoot%\System32\Drivers\Etc\Hosts")

' Controller folder.
g_strCont = "C:\Temp\SSCM_ADJoin"

' Determine Windows operating system home and Utils folder.
g_strWinDir = ""
g_strUtils = ""
If g_objFS.FileExists("D:\XPS\xpsctrl.exe") Then
    If g_objFS.FileExists("C:\Windows\System32\ServerManagerCmd.exe") Then
        g_strWinDir = "Windows" ' Windows 2008.
		g_strUtils = "C:\progra~1\Utils" 
    Else
        g_strWinDir = "WinNT"   ' Windows 2000.
		g_strUtils = "C:\Utils" 
    End If
ElseIf g_objFS.FileExists("C:\Gstr\iSTORE\Bin\DownloadProc.exe") Then
    g_strWinDir = "Windows"
	g_strUtils = "C:\Utils" 
End If

' Sub-task: Interrogate deployment service properties for administrator rights to system.
g_blnRemoteWare = True
If WScript.Arguments.Named.Exists("RemoteWareService") Then
    g_intResult = ServiceLogOn("RemoteWare Client", "Cambridge")
    If g_intResult <> 0 Then
        g_blnRemoteWare = False
    End If
    WScript.Quit ' Don't run anything else after checking the RemoteWare service.
End If

' Establish location for log and CSV files.
g_strLogFolder = "C:\TJXLogs"

If Not g_objFS.FolderExists(g_strLogFolder) Then
    g_objFS.CreateFolder(g_strLogFolder)
End If

g_strLogFile = g_strLogFolder & Chr(92) & g_strProjectName & ".log"
g_strCSVFile = g_strLogFolder & Chr(92) & g_strProjectName & ".csv"
g_strCSVFileTemp = g_strCSVFile & ".temp"

If Not WScript.Arguments.Named.Exists("Target") And Not WScript.Arguments.Named.Exists("Controller") And Not WScript.Arguments.Named.Exists("WebPC") And Not WScript.Arguments.Named.Exists("Register") Then
    g_strLogFile = g_strLogFolder & Chr(92) & g_strProjectName & ".log"
    g_strCSVFile = g_strLogFolder & Chr(92) & g_strProjectName & ".csv"	
Else
	g_blnFlag = True
	g_strLogFile = g_strLogFolder & Chr(92) & g_strProjectName & "_Target.log"
	g_strCSVFile = g_strLogFolder & Chr(92) & g_strProjectName & "_Target.csv"
End If

' Clear any existing logs.
For Each g_strResult In Array(g_strLogFile, g_strCSVFile, g_strCSVFileTemp)
    If g_objFS.FileExists(g_strResult) Then
       Call g_objFS.DeleteFile(g_strResult, True)
    End If
Next

' Run the main script instructions.
If g_blnMain Then
    Call WriteToLog("Start ---> SCCM Active Directory Domain Join" & Chr(32) & g_strVersion & ".")
    g_intMain = Main()
    Call WriteToLog("End ---> SCCM Active Directory Domain Join" & Chr(32) & g_strVersion & ".")
End If

' Prepare CSV file with results.
If g_objFS.FileExists(g_strCSVFileTemp) Then
    Call g_objFS.CopyFile(g_strCSVFileTemp, g_strCSVFile, True)
	Call g_objFS.DeleteFile(g_strCSVFileTemp, True)
End If

If g_blnFlag Then
	Call g_objFS.DeleteFile(g_strCSVFile, True)
End If


' Exit and return result code to any calling application.
g_intLocale = SetLocale(g_intLocale)
Call KillProcess("sftpg3.exe")
Call KillProcess("sshg3.exe")
WScript.Quit(g_intMain)

' Start :: Main Script Function :: Start

Function Main()

    ' Function: Carry out the primary instructions of the script.
    ' Arguments: None
    ' Return Value: 0 = Script ran all the way through without incident.
    ' Return Value: Integer other than 0 = Script encountered an error and aborted.  Review script logs for additional details.

    Dim intResult, intCount, intRow
    Dim strTool, strCommand, strResult, strTime, strDevice, strIP, strType, strDef, strOutput
    Dim strFolderToPush, strScriptToRun, strFileToPull, strOSType
    Dim arrTool, arrAV, arrResult, arrExec, arrEnvType
    Dim objDevice, objSFTP, objSSH, objData, objInstall, objResult, objCSV, strCSV, strCSVTemp, objRegister
	Dim blnDone, blnEnvType, blnController, blnRegister, blnWebPC

    Dim intMinIP, intMaxIP
    Dim strIPRange
    Dim arrIPRange

    On Error Resume Next

    Main = 1

    ' Assume local system OS is XP or later.
    g_blnWQL = True
    
    ' Assume Web PC exists on local network.
    g_blnWebPC = True

    ' Define default IP address range.
    intMinIP = 1
    intMaxIP = 60    
	
	blnController = True
    blnRegister = True
	blnWebPC = True
    
    If WScript.Arguments.Named.Exists("Controller") Then
		blnRegister = False
		blnWebPC = False			
    End If
	
	If WScript.Arguments.Named.Exists("WebPC") Then        
        blnController = False
		blnRegister = False
    End If

    If WScript.Arguments.Named.Exists("Register") Or WScript.Arguments.Named.Exists("Target") Then
        blnController = False
		blnWebPC = False
    End If
	
    ' Acquire the local server name.
    
    ' First use server name passed from calling script argument if desired.
    If WScript.Arguments.Named.Exists("ServerName") And Len(WScript.Arguments.Named("ServerName")) > 1 Then

        g_strServerName = UCase(WScript.Arguments.Named("ServerName"))
        Call WriteToLog("Server name passed in as a script argument:" & Chr(32) & g_strServerName & ".")

    ' Otherwise obtain name from the system itself.
    Else
        
        ' Obtain the server's name.
        g_strServerName = UCase(g_objShell.ExpandEnvironmentStrings("%COMPUTERNAME%"))
        
        ' If first name acquisition method failed, try another one to get the system name.
        If g_strServerName = "" Or IsNull(g_strServerName) Then
            g_strServerName = g_objNetwork.ComputerName
        End If
    
        ' If second attempt fails, something is wrong and we are done here for now.
        If g_strServerName = "" Or IsNull(g_strServerName) Then
            Call WriteToLog("Problem identifying local server name, exiting script.")
            Main = 5
            Exit Function
        End If    
    
    End If

    ' Determine operating system type.
    strOutput = GetOutput("ver")
    
    If InStr(strOutput, Win2000) > 0 Then
        strOSType = "Windows 2000"
        g_blnWQL = False
    ElseIf InStr(strOutput, WinXP) > 0 Then
        strOSType = "Windows XP"
    ElseIf InStr(strOutput, Win2003) > 0 Then
        strOSType = "Windows 2003"
    ElseIf InStr(strOutput, Win2008) > 0 Then
        strOSType = "Windows 2008"
    Else
        strOSType = "Unknown"
    End If
    
    If strOSType = "Unknown" Then
        Call WriteToLog("Error: Problem identifying host OS.  Exiting script.")
        Main = 6
        Exit Function
    Else
        Call WriteToLog("The host operating system is" & Chr(32) & strOSType & ".")
    End If
    
    ' Obtain the local system IP address.
    g_strServerIPAddress = GetIPAddress()
    
    If g_strServerIPAddress = "Unknown" Or g_strServerIPAddress = "" Or IsNull(g_strServerIPAddress) Then
        Call WriteToLog("Problem identifying local server IP address, exiting script.")
        Main = 7
        Exit Function
    End If

    ' Create support tools folder.
    If Not g_objFS.FolderExists(g_strUtils) Then
        Call g_objFS.CreateFolder(g_strUtils)
    End If
    
    ' Copy support tools to host utils folder.
    arrTool = Array("psexec.exe", "psexec.reg", "pskill.exe", "pskill.reg")
    For Each strTool In arrTool
        If g_objFS.FileExists(g_strCurrentPath & Chr(92) & strTool) Then
            Call g_objFS.CopyFile(g_strCurrentPath & Chr(92) & strTool, g_strUtils & Chr(92) & strTool, True)
        End If
    Next
    
    ' Prepare support tools for batch mode operation.
    arrTool = Array("psexec.reg", "pskill.reg")
    For Each strTool In arrTool
        If g_objFS.FileExists(g_strUtils & Chr(92) & strTool) Then
            strCommand = "%ComSpec% /c regedit /s" & Chr(32) & g_strUtils & Chr(92) & strTool
            intResult = g_objShell.Run(strCommand, MinWindow, True)
        End If      
    Next    

    ' Log system name and IP.
    Call WriteToLog("The host system name is" & Chr(32) & Chr(34) & g_strServerName & Chr(34) & ".")
    Call WriteToLog("The host system IP address is" & Chr(32) & Chr(34) & g_strServerIPAddress & Chr(34) & ".")

    ' Fetch current time details.
    strTime = CurrentTimeStamp()
    
    ' Populate CSV file with baseline Controller details.
    Set g_objCSV = g_objFS.OpenTextFile(g_strCSVFileTemp, ForAppending, True)

    ' Administrative rights confirmation.
    If g_blnRemoteWare Then
        strOutput = "Unknown"
    Else
        strOutput = "RemoteWare"
    End If    
	
	g_strAVDefName = "UnKnown"
	g_strAVDefDate = "UnKnown"

    ' Determine AV Def File Name and File Date on the Controller.

    'Dim path, file, recentDate, recentFile

    'Set recentFile = Nothing

    'For Each file in g_objFS.GetFolder("C:\AVDefUpdate\CurrentDef").Files
    
    'If Right(LCase(file.name), 3)="jdb" Then          
        'If (recentFile is Nothing) Then
            'Set recentFile = file            
        'ElseIf (file.DateLastModified > recentFile.DateLastModified) Then        
            'Set recentFile = file                    
        'End If
    'End If

    'Next

	'If recentFile is Nothing Then  		
		'Call WriteToLog("No Recent AV Def files in C:\AVDefUpdate\CurrentDef Folder.")
    'Else
		'Call WriteToLog("Recent AV Def file is " & recentFile.Name & " " & recentFile.DateLastModified)
		'Dim FinalFD
		'Set FinalFD = g_objFS.GetFile(recentfile)
		'g_strAVDefName = FinalFD.Name
		'g_strAVDefDate = FinalFD.DateLastModified
    'End If                    
    
    For Each strResult In Array(g_strServerName, g_strServerName, g_strServerIPAddress, "False", g_strAVDefName, g_strAVDefDate, strTime)
        Call g_objCSV.Write(Chr(34) & strResult & Chr(34))
        If strResult <> strTime Then
            Call g_objCSV.Write(Chr(44))
        End If
    Next
    Call g_objCSV.WriteLine()
    
    ' Close CSV file for now.
    g_objCSV.Close
    Set g_objCSV = Nothing
    
    ' We are done here if we do not have administrative rights to system.
    If Not g_blnRemoteWare And WScript.Arguments.Named.Exists("RemoteWareService") Then
        Call WriteToLog("Warning: The" & Chr(32) & Chr(34) & "RemoteWare Client" & Chr(34) & Chr(32) &_
                        "service is not running with Administrative rights, please fix.")
        Call WriteToLog("Exiting script.")
        Main = 8
        Exit Function
    ElseIf g_blnRemoteWare And WScript.Arguments.Named.Exists("RemoteWareService") Then
        Call WriteToLog("The" & Chr(32) & Chr(34) & "RemoteWare Client" & Chr(34) & Chr(32) &_
                        "service is running with Administrative rights.")
        Call WriteToLog("Exiting script.")
        Main = 200
        Exit Function        
    End If
	
	  ' Determine software environment.
    blnEnvType = False
    arrEnvType = Array("DEV", "QA", "PROD") 
    If WScript.Arguments.Named.Exists("EnvType") Then
        For Each g_strEnvType In arrEnvType
            If UCase(WScript.Arguments.Named("EnvType")) = g_strEnvType Then
                Call WriteToLog("Software environment marked as" & Chr(32) & EnvType(g_strEnvType) & ".")
                blnEnvType = True
                Exit For
            End If
        Next
    End If
    
    ' Software environment must be detected to proceed.
    If Not blnEnvType Then
		Call WriteToLog("WARNING: Environment Flag not entered as an Argument.")
		Call WriteToLog("Software Environment defaulted to PRODUCTION.")		
    End If
	
	'Push the Latest AV Def files to the required location on Controller.
	
    If blnController Then
		Call WriteToLog("Sending required files to Required location on Controller" & Chr(32) & g_strServerName & ".")
        Err.Clear
		g_objFS.CopyFile "C:\Temp\SCCM_ADJoin\*", "C:\Temp\SCCM_ADJoin", True
		If Err.Number = 0 Then
			Call WriteToLog("SUCCESS: Copying the SCCM Active Directory Domain Join files to the Required location on Controller")   
            Call UpdateCSV(g_strServerIPAddress, "True")
			Main = 0
		Else	
			Call WriteToLog("ERROR: Copying the SCCM Active Directory Domain Join files to the Required location on Controller")
		End If
	Else
        Call WriteToLog("NOTICE: SCCM Active Directory Domain Join files will be skipped on Controller.")
    End If		
	
	If blnRegister = False And blnWebPC = False Then
		Call WriteToLog("NOTICE: SCCM Active Directory Domain Join will be skipped on Registers & WebPC.")
		Exit Function
	End If	
	
	If blnRegister And Not WScript.Arguments.Named.Exists("Target") Then
	
			' Scan network for all Registers.  Detection is based on ARP cache for Windows 2000 and Ping Queries for OS >= Windows XP.
			Call WriteToLog("Detecting available Registers on the local network.")
			If EnvType(g_strEnvType) = "Development" And Not WScript.Arguments.Named.Exists("IPRange") Or EnvType(g_strEnvType) = "QA" And Not WScript.Arguments.Named.Exists("IPRange") Then				
				intResult = GenerateRegisterTable()
			Else
				' Allow definable IP range address.
				If WScript.Arguments.Named.Exists("IPRange") Then
					arrIPRange = Split(WScript.Arguments.Named("IPRange"), "-")
					If IsNumeric(arrIPRange(0)) Then
						intMinIP = arrIPRange(0)
					End If
					If IsNumeric(arrIPRange(1)) Then
						intMaxIP = arrIPRange(1)
					End If
				Call WriteToLog("Custom IP range defined:" & Chr(32) & intMinIP & Chr(32) & "to" & Chr(32) & intMaxIP & ".")	
				End If			
			intResult = GenerateRegisterTableNew(intMinIP, intMaxIP)
			End If
			
			If intResult > 0 Then
				Call WriteToLog("Register detection complete," & Chr(32) & intResult & Chr(32) & "Register(s) detected.")
			Else
				Call WriteToLog("Problem detecting Registers on network.")
				Call WriteToLog("Exiting installation script.")
				Main = 10
				Exit Function
			End If
			
	ElseIf WScript.Arguments.Named.Exists("Target") Then ' Determine if specific Registers are targetted for the installation.
        
		blnController = False
        Dim strDeviceList, arrDevices, strDeviceName, strDeviceIP, dicTarget, strDeviceNB
        Set dicTarget = CreateObject("Scripting.Dictionary")
        Call WriteToLog("Register Target switch specified, Push AV Definitions to select Registers.")
        strDeviceList = WScript.Arguments.Named("Target")
        Call WriteToLog("Arguments:" & Chr(32) & strDeviceList)
        strDeviceList = Replace(strDeviceList, Chr(32), "")
        arrDevices = Split(strDeviceList, ",")
        
		intCount = 0
        For Each strDeviceName In arrDevices
            strDeviceIP = ConvertToIP(strDeviceName)
            strDeviceNB = ResolveIPToHostName(strDeviceIP)
	        If UCase(strDeviceNB) <> UCase(g_strServerName) And strDeviceName <> "127.0.0.1" And g_strServerIPAddress <> strDeviceIP Then
		        If strDeviceIP <> "Unknown" Then
		            If IsDuplicate(strDeviceIP, dicTarget) = 0 Then
		                intCount = intCount + 1
						Call WriteToLog("Adding device to valid target list:" & Chr(32) & strDeviceNB & Chr(32) & "(" & strDeviceIP & ").")
						Set objRegister = New PosDevice
						Call objRegister.SetIP(strDeviceIP)
						Call objRegister.SetName(strDeviceNB)
						Call objRegister.SetType("Register")
						Call dicTarget.Add(intCount, objRegister)						
                    Else
                        Call WriteToLog("Warning:" & Chr(32) & strDeviceName & Chr(32) & "already in target list, skipping duplicate value.")
                    End If
                Else
                    Call WriteToLog("Device" & Chr(32) & strDeviceName & Chr(32) & "not recognized on network, omitting from target list.")
                End If
		    End If
	    Next

        If dicTarget.Count > 0 Then            
			Set g_objDevices = dicTarget
        Else
            Call WriteToLog("No valid devices exist as targets, exiting script.")
            Main = 7
            Exit Function
        End If
            
        Set dicTarget = Nothing
    Else
        Call WriteToLog("NOTICE: SCCM Active Directory Domain Join will be skipped on Registers.")
    End If
	
	If blnWebPC Then	
		' Scan network for Web PCs.
		Call WriteToLog("Detecting available Web PCs on the local network.")
		intResult = GenerateWebPCTable()
				
		If intResult > 0 Then
			Call WriteToLog("Web PC detection complete," & Chr(32) & intResult & Chr(32) & "Web PC(s) detected.")
		Else
			Call WriteToLog("Problem detecting Web PCs on network.")
			Set objDevice = New PosDevice
			strResult = Left(g_strServerName, 7) & "N"
			Call objDevice.SetIP(strResult)
			Call objDevice.SetName(strResult)
			Call objDevice.SetType("WebPC")
			intResult = g_objDevices.Count + 1
			Call g_objDevices.Add(intResult, objDevice)
			g_blnWebPC = False
		End If
		
	Else
		Call WriteToLog("NOTICE: SCCM Active Directory Domain Join will be skipped on WebPC.")
	End If   
	
    ' Populate CSV file with baseline Register and Web PC details.
    Set g_objCSV = g_objFS.OpenTextFile(g_strCSVFileTemp, ForAppending, True)
    For intResult = 1 To g_objDevices.Count Step 1
        Set objDevice = g_objDevices.Item(intResult)
        strTime = CurrentTimeStamp()        
        For Each strResult In Array(g_strServerName, objDevice.GetName(), objDevice.GetIP(), "False", g_strAVDefName, g_strAVDefDate, strTime)
            Call g_objCSV.Write(Chr(34) & strResult & Chr(34))
            If strResult <> strTime Then
                Call g_objCSV.Write(Chr(44))
            End If
        Next
        Call g_objCSV.WriteLine()
    Next
   
    ' Close CSV file for now.
    g_objCSV.Close
    Set g_objCSV = Nothing
    
	' Stop if there is no JDB file to push.
	'If g_strAVDefName = "UnKnown" Then
		'Call WriteToLog("Unable to detect a valid AV Def .JDB file for delivery, exiting script.")
		'Main = 15
		'Exit Function
	'End If
	
    ' Issue SFTP connectivity test to all Registers and Web PCs.
    Call WriteToLog("Performing SFTP connectivity test to all detected devices.")
    Call WriteToLog("Killing any existing SFTP processes before proceeding.")
    intResult = KillProcess("sftpg3.exe")
    Call WriteToLog("Waiting to finish SFTP test.")
    
    ' Establish return codes for current procedure.
    g_intPendingCode = 777
    g_intSuccessCode = 0
    
    ' Run test procedure.
    Set objSFTP = TestSFTP(g_objDevices)
    intResult = KillProcess("sftpg3.exe")
    Call WriteToLog("SFTP tests complete, proceeding.")    
    
    ' Establish return codes for current procedure.
    g_intPendingCode = 777
    g_intSuccessCode = 0    
       
    ' Report the SFTP/SSH test results.    
	Call WriteToLog("SFTP test results:")
    For intResult = 1 To g_objDevices.Count Step 1
        Set objDevice = g_objDevices.Item(intResult)
        strDevice = objDevice.GetName()
        strIP = objDevice.GetIP()
        strType = objDevice.GetType()        
               
        Call WriteToLog("SFTP test for" & Chr(32) & strType & Chr(32) & strDevice & Chr(32) & "(" & strIP & ")" & Chr(32) &_
                        "evaluated as" & Chr(32) & objSFTP.Item(strIP) & ".")        
						
		If objSFTP.Item(strIP) = "False" Then
            If strType = "Register" Then
                Call WriteToLog(strType & Chr(32) & strDevice & Chr(32) & "(" & strIP & ")" & Chr(32) &_
                     "will be attempted using alternate methods.")          
            End If
        End If
    
    Next

    ' Deliver files to the Registers and Web PCs.
    Call WriteToLog("Delivering Files:")
    
    ' Establish return codes for current procedure.
    g_intPendingCode = 777
    g_intSuccessCode = 0
    
    ' Run procedure.
	Set objData = PushFolder(g_objDevices, objSFTP)

    ' Report the file delivery results.
    Call WriteToLog("File delivery results:")	
    For intResult = 1 To g_objDevices.Count Step 1
        Set objDevice = g_objDevices.Item(intResult)
        strDevice = objDevice.GetName()
        strIP = objDevice.GetIP()
        strType = objDevice.GetType()      
		
        Call WriteToLog("File delivery for" & Chr(32) & strType & Chr(32) & strDevice & Chr(32) & "(" & strIP & ")" & Chr(32) &_
                        "evaluated as" & Chr(32) & objData.Item(strIP) & ".")
						
		If objData.Item(strIP) = "True" Then			
			Call UpdateCSV(strDevice, "True")			
        End If				
		
    Next
	
	' Install the software on qualified Registers.
    Call WriteToLog("Performing software installation on all qualified Registers.")
    Set objInstall = InstallSoftware(g_objRegister, objSSH, objData)
    Call WriteToLog("Software installation Register results:")
    intSuccess = 0
    For Each strRegister in objInstall
        Call WriteToLog("Software installation on Register" & Chr(32) & strRegister & Chr(32) & "(" & g_objRegister.Item(strRegister) & ")" & Chr(32) &_
                        "evaluated as" & Chr(32) & objInstall.Item(strRegister) & ".")
        If objInstall.Item(strRegister) = "True" Then
            Call UpdateCSV(g_objRegister.Item(strRegister), "True", "True")
            intSuccess = intSuccess + 1
        End If
    Next
    Call WriteToLog(intSuccess & Chr(32) & "of" & Chr(32) & g_objRegister.Count & Chr(32) & "Registers successfully installed the software.")
    intResult = intSuccess / g_objRegister.Count
    Call WriteToLog(FormatPercent(intResult, 2) & Chr(32) & "of the Registers are complete.")
	
	
	
	' Install the software on WebPC.
	
	Call UpdateCSV(g_strServerIPAddress, "True", "False")
	intSuccessC = 0
	If blnWebPC Then
		Call WriteToLog("Performing software installation on WebPC" & Chr(32) & g_strServerName & "N")			
		strCommand = "%ComSpec% /v:on /c (start /wait /min" & Chr(32) & g_strController & "\ADJoin.CMD WebPC) & exit !errorlevel!" & Chr(32) & "> nul 2>&1"        
		Set objResult = g_objShell.Exec(strCommand)
		strThen = Now
		intTimeOut = 30 'Time-out threshold in minutes.
		Do
			WScript.Sleep(10000)
			strNow = Now
			intTimer = DateDiff("n", strThen, strNow)
		Loop Until objResult.Status = 1 Or intTimer > intTimeOut
			
		' Process results of software installation on WebPC.
		If objResult.ExitCode = SuccessCode Then
			Call WriteToLog("Software installation on WebPC" & Chr(32) & g_strServerName & Chr(32) &_
							"(" & g_strServerIPAddress & ") evaluated as True.")
			Call UpdateCSV(g_strServerIPAddress, "True", "True")			
			intSuccessC = 1
		Else
			If intTimer > intTimeOut Then
				Call WriteToLog("Warning: Software installation on WebPC" & Chr(32) & g_strServerName & Chr(32) &_
								"(" & g_strServerIPAddress & ") exceeded the" & Chr(32) & intTimeOut & Chr(32) & "minute time-out threshold.")
			End If
			Call WriteToLog("Software installation on WebPC" & Chr(32) & g_strServerName & Chr(32) &_
							"(" & g_strServerIPAddress & ") evaluated as False.")
			Call UpdateCSV(g_strServerIPAddress, "True", "False")
		End If
	Else
		Call WriteToLog("Skipping WebPC software installation - Register Switch Specified.")
	End If
    
	' Install the software on Controller.
	
	Call UpdateCSV(g_strServerIPAddress, "True", "False")
	intSuccessC = 0
	If blnController Then
		Call WriteToLog("Performing software installation on Controller" & Chr(32) & g_strServerName & ".")		
		strCommand = "%ComSpec% /v:on /c (start /wait /min" & Chr(32) & g_strController & "\ADJoin.CMD Controller) & exit !errorlevel!" & Chr(32) & "> nul 2>&1"        
		Set objResult = g_objShell.Exec(strCommand)
		strThen = Now
		intTimeOut = 30 'Time-out threshold in minutes.
		Do
			WScript.Sleep(10000)
			strNow = Now
			intTimer = DateDiff("n", strThen, strNow)
		Loop Until objResult.Status = 1 Or intTimer > intTimeOut
			
		' Process results of software installation on Controller.
		If objResult.ExitCode = SuccessCode Then
			Call WriteToLog("Software installation on Controller" & Chr(32) & g_strServerName & Chr(32) &_
							"(" & g_strServerIPAddress & ") evaluated as True.")
			Call UpdateCSV(g_strServerIPAddress, "True", "True")			
			intSuccessC = 1
		Else
			If intTimer > intTimeOut Then
				Call WriteToLog("Warning: Software installation on Controller" & Chr(32) & g_strServerName & Chr(32) &_
								"(" & g_strServerIPAddress & ") exceeded the" & Chr(32) & intTimeOut & Chr(32) & "minute time-out threshold.")
			End If
			Call WriteToLog("Software installation on Controller" & Chr(32) & g_strServerName & Chr(32) &_
							"(" & g_strServerIPAddress & ") evaluated as False.")
			Call UpdateCSV(g_strServerIPAddress, "True", "False")
		End If
	Else
		Call WriteToLog("Skipping Controller software installation - Register Switch Specified.")
	End If
	
	
' Function: Install software over SSH or Psexec.  Return a dictionary object with the results (T or F).
Function InstallSoftware(arrDevice, objSSH, objData)

    On Error Resume Next
  
    Dim objExec, objBatchFile, dicResult
    Dim intTimeOut, intTimer, intDone, intIndex, intResult
    Dim strExec, strBatchFile, strNow, strThen, strDevice, strAlias, strSFTP
    Dim arrExec, arrResult, arrRetry
    
    Set dicResult = CreateObject("Scripting.Dictionary")
    Set InstallSoftware = dicResult

    ' Dimension arrays.
    ReDim arrExec(arrDevice.Count - 1)
    ReDim arrResult(arrDevice.Count - 1)
    ReDim arrRetry(arrDevice.Count - 1)
    
    ' Populate status array with pending result code.
    intIndex = 0
    Do
        arrResult(intIndex) = PendingCode
        arrRetry(intIndex) = "False"
        intIndex = intIndex + 1
    Loop Until intIndex > UBound(arrResult)
 
    strBatchFile = "C:\Temp\SCCM_ADJoin\ADJoin.CMD Register"
    
    ' Install the software.
    intIndex = 0
    For Each strDevice In arrDevice
 
        If objSSH.Item(strDevice) = "True" And objData.Item(strDevice) = "True" Then
            strAlias = GetRegisterAlias(arrDevice.Item(strDevice))
            If strAlias = "" Then
                strAlias = arrDevice.Item(strDevice)
            End If
            strExec = "cmd /v:on /c (start /wait /min sshg3.exe -B cambridge@" & strAlias & Chr(32) &_
                      strBatchFile & ") & exit !errorlevel!" & Chr(32) & "> nul 2>&1"
            Set arrExec(intIndex) = g_objShell.Exec(strExec)
         ElseIf objData.Item(strDevice) = "True" Then
            strExec = "cmd /v:on /c (start /wait /min" & Chr(32) & g_strUtils & "\psexec.exe" & Chr(32) & "\\" & arrDevice.Item(strDevice) &_
                      Chr(32) & strBatchFile & ") & exit !errorlevel!" & Chr(32) & "> nul 2>&1"                      
            Set arrExec(intIndex) = g_objShell.Exec(strExec)
        Else
            arrResult(intIndex) = 888
        End If

        intIndex = intIndex + 1
        WScript.Sleep(1000)
        
    Next

    ' Wait for all Registers to finish software installation or time-out.
    intDone = 1
    intTimeOut = 15 'Time-out threshold in minutes.
    strThen = Now
    Do
        intIndex = 0
        WScript.Sleep(1000)
        For Each objExec In arrExec
                If objExec.Status = 1 And arrResult(intIndex) <> 888 Then
                    arrResult(intIndex) = objExec.ExitCode
                End If
            intIndex = intIndex + 1
        Next
        strNow = Now
        intTimer = DateDiff("n", strThen, strNow)
        intDone = ExecDone(arrResult)
    Loop Until intDone = 0 Or intTimer > intTimeOut

    ' Populate dictionary with software installation results.
    intIndex = 0
    For Each strDevice In arrDevice

        If intTimer > intTimeOut And arrResult(intIndex) = PendingCode Then
            Call WriteToLog("Warning: " & NameLookup(intIndex) & Chr(32) & "run time exceeded the" & Chr(32) &_
                            intTimeOut & Chr(32) & "minute time-out threshold.")
        End If
        
        If arrResult(intIndex) = SuccessCode Then
            Call dicResult.Add(strDevice, "True")
        Else
            Call dicResult.Add(strDevice, "False")
        End If
        intIndex = intIndex + 1
        
    Next

    ' Return the dictionary object.
    Set InstallSoftware = dicResult
 
    ' Temporary file clean-up.
    Call g_objFS.DeleteFile(g_strCurrentPath & Chr(92) & "*.tmp", True)
    Set dicResult = Nothing

    On Error GoTo 0
  
'End Function
	
    ' The main script is done. Later!
    'Main = 0
    
    'On Error GoTo 0	
	
End Function

' End :: Main Script Function :: End

' Start :: Support Functions And Subroutines :: Start

Function GetIPAddress()

    ' Function: Acquire IP address of local device.
    ' Arguments: None.
    ' Return Value: The IP address detected.
	
	On Error Resume Next
	
	GetIPAddress = "Unknown"
	
	Dim strOutput, strLine, strValue, strIPAddress
	Dim arrOutput, arrLine
	
	' Issue ARP command.
	strOutput = GetOutput("arp -a")
	arrOutput = Split(strOutput, vbCrLf)
	strIPAddress = ""
	
	' Process ARP results.
	For Each strLine In arrOutput
	    If Instr(LCase(strLine), LCase("Interface: 10")) > 0 Or Instr(LCase(strLine), LCase("Interface: 172")) > 0 Then
	        arrLine = Split(strLine, Chr(32))
	        For Each strValue In arrLine
	            If IsNumeric(Left(strValue,1)) And Not Instr(strValue, "x") > 0 Then
	                strIPAddress = RTrim(LTrim(strValue))
	                Exit For
	            End If
	        Next
	    End If
	Next

    ' Confirm IP address pings back.
    If PingStatus(strIPAddress) = 0 Then
        GetIPAddress = strIPAddress
    End If
    
    On Error GoTo 0

End Function


Function GetOutput(strCommand)

    ' Function: Capture the output from a command.
    ' Argument 1: The command to run.
    ' Return Value: Standard output of the command.
  
    On Error Resume Next

    Dim objTempFile, strTempFile, strOutput

    strTempFile = g_objFS.GetTempName
    Call g_objShell.Run("%comspec% /c """ & strCommand & " > " & strTempFile & """", MinWindow, True)

    If (Not g_objFS.FileExists(strTempFile)) Then
    GetOutput = ""
    Else
    strOutput = ""
    Set objTempFile = g_objFS.OpenTextFile(strTempFile, 1)

    If (Not Err.Number) Then
      Do While (Not objTempFile.AtEndOfStream)
        strOutput = strOutput & objTempFile.ReadAll
      Loop
      objTempFile.Close
    End If

    GetOutput = strOutput
    End If

    Call g_objFS.DeleteFile(strTempFile, True)
    
    On Error GoTo 0
  
End Function

Function PingStatus(strDeviceToPing)

    ' Function: Ping a device.
    ' Argument 1: Device to ping as IP address, hostname, or alias.
    ' Return Value: 0 = Alive Device.
    ' Return Value: 1 = No Response from Device.
	
	On Error Resume Next
	
	PingStatus = 1

	Dim objPingStatus
	Dim strLine, intCount
	
	' Issue ping.
	Set objPingStatus = g_objShell.Exec("%ComSpec% /c Ping" & Chr(32) & strDeviceToPing)
	
    ' Wait to finish.
    Do
        WScript.Sleep(500)
    Loop Until objPingStatus.Status = 1
	
	' Count the responses.
	intCount = 0
	Do
		strLine = objPingStatus.StdOut.ReadLine
		' English or French may appear in output, must consider both.
		If InStr(strLine, "Reply from") > 0 Or InStr(strLine, "ponse de") > 0 Then
			intCount = intCount + 1
		End If
	Loop Until objPingStatus.StdOut.AtEndOfStream
	
	' Two or more responses indicate a successful ping.
	If intCount >= 2 Then
		PingStatus = 0
	End If
	
	Set objPingStatus = Nothing
	
	On Error GoTo 0
	
End Function

Function ServiceLogOn(strServiceName, strLogOnName)

    ' Function: Confirm the log on properties of a service.
    ' Argument 1: Name of the service.
    ' Argument 2: Expected log on name for the service.
    ' Return Value: 0 = Service running as argument log on name.
    ' Return Value: 1 = Service NOT running as argument log on name.

    On Error Resume Next
		
	Dim objWMI, colServices, objService
	Dim strDoneFlag, strRWFlag, strFile

    strDoneFlag = "C:\Done.Flag"
    strRWFlag = "C:\RemoteWareService.Flag"
    
    ' Clear status flags.
    For Each strFile In Array(strDoneFlag, strRWFlag)
        If g_objFS.FileExists(strFile) Then
            Call g_objFS.DeleteFile(strFile, True)
        End If            
    Next
    
    ServiceLogOn = 2
		
	' Connect to WMI.
	Err.Clear
	Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
	If Err.Number <> 0 Then
	    Call g_objFS.CreateTextFile(strDoneFlag, True)        
	    Exit Function
	End If
	
	' Query RemoteWare Client service properties.
	Err.Clear
	Set colServices = objWMI.ExecQuery("Select * from Win32_Service Where Name ='" & strServiceName & "'")
    If Err.Number <> 0 Then
	    Call g_objFS.CreateTextFile(strDoneFlag, True)        
	    Exit Function
	End If
    
    ServiceLogOn = 1
    
    ' Compare service log on name and function argument name.
    For Each objService In colServices
        If Instr(LCase(objService.StartName), LCase(strLogOnName)) > 0 Then
            ServiceLogOn = 0
            Call g_objFS.CreateTextFile(strRWFlag, True)
        End If
    Next
    
    ' Indicate function is done running.
    Call g_objFS.CreateTextFile(strDoneFlag, True)
    
    On Error GoTo 0

End Function

Function CurrentTimeStamp()

    ' Function: Return current date and time in a fixed format.
    ' Arguments: None.
    ' Return Value: Current timestamp in mm-dd-yyyy hh-mm-ss fixed format.

	On Error Resume Next
	
	Dim strMonth, strDay, strYear, strNow, strHour, strMinute, strSecond
	
	CurrentTimeStamp = "Unknown"
		
	' Get current time information.
	strNow = Now()
	
	' Format the various time components.
	strMonth = TwoDigit(DatePart("m", strNow))
	strDay = TwoDigit(DatePart("d", strNow))
	strYear = DatePart("yyyy", strNow)
	strHour = TwoDigit(DatePart("h", strNow))
	strMinute = TwoDigit(DatePart("n", strNow))
	strSecond = TwoDigit(DatePart("s", strNow))
	
	' Generate the timestamp string.
	CurrentTimeStamp = strMonth & Chr(47) & strDay & Chr(47) & strYear & Chr(32) &_
	                   strHour & Chr(58) & strMinute & Chr(58) & strSecond

    On Error GoTo 0

End Function

Function TwoDigit(intNumber)

    ' Function: Ensure single-character numbers appear in two-digit format.
    ' Argument 1: The number to format.
    ' Return Value: The two-digit number.

    On Error Resume Next

	
	TwoDigit = intNumber
	
	If IsNumeric(intNumber) Then
	    If intNumber >= 0 And intNumber < 10 Then
		    TwoDigit = "0" & TwoDigit
	    End If
    End If
	
	On Error GoTo 0

End Function

Sub WriteToLog(strTextIn)

    ' Subroutine: Write information to the global log file.
    ' Argument 1: The text to write to the file.

    On Error Resume Next

    Dim objLogFile
    
    ' Open the file for append.
    Set objLogFile = g_objFS.OpenTextFile(g_strLogFile, ForAppending, True)
    
    ' Write the input.
    objLogFile.WriteLine(CurrentTimeStamp & Chr(32) & "--" & Chr(32) & strTextIn & vbCrLf)
    objLogFile.Close
    Set objLogFile = Nothing
    
    ' Show the input on screen as well.
    If TypeName(strTextIn) = "String" Then
        WScript.Echo VbCrLf & strTextIn & VbCrLf
    End If

    On Error GoTo 0

End Sub

' Class to hold information for store devices.
Class PosDevice

    Private strIP, strName, strType

    Public Sub SetName(strDeviceName)
        strName = strDeviceName
    End Sub
    
    Public Function GetName()
        GetName = strName
    End Function
    
    Public Sub SetIP(strDeviceIP)
        strIP = strDeviceIP
    End Sub
    
    Public Function GetIP()
        GetIP = strIP
    End Function
    
    Public Sub SetType(strDeviceType)
        strType = strDeviceType
    End Sub

    Public Function GetType()
        GetType = strType
    End Function

End Class

Function GenerateRegisterTable()

    ' Function: Create an array of Registers based on the current ARP table.
    ' Arguments: None.
    ' Return Value: 0 = No Registers detected.
    ' Return Value: An integer > 0 = The actual number of Registers detected.

	On Error Resume Next
	
	GenerateRegisterTable = 0
	
	Dim objARPStatus, objRegister, objWMIService, colProcess, objProcess
	Dim arrOutput, arrIPFrag
	Dim strOutput, strDivision, strCommand, strIPFrag, strNow, strThen
	Dim intCount, intDynamic, intResult, intDiff
	Dim blnPing
	
    arrIPFrag = Split(g_strServerIPAddress, ".")
    strIPFrag = arrIPFrag(0) & "." & arrIPFrag(1) & "." & arrIPFrag(2) & "."
	
	Call WriteToLog("Refreshing ARP cache by pinging all devices with ending IP of .1 to .60")
	For intCount = 1 To 60
	    strCommand = "%ComSpec% /c ping" & Chr(32) & strIPFrag & intCount
	    intResult = g_objShell.Run(strCommand, MinWindow, False)
	    WScript.Sleep(500)
	Next
	
	Call WriteToLog("Waiting for ping commands to complete.")
	strThen = Now()
	Do
	    blnPing = False
	    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2")
	    Set colProcess = objWMIService.ExecQuery("Select * from Win32_Process")
	    For Each objProcess in colProcess
            If InStr(LCase(objProcess.Name), "ping.exe") > 0 Then
                blnPing = True
            End If
        Next
        strNow = Now()
        intDiff = DateDiff("s", strThen, strNow)
        WScript.Sleep(500)
    Loop Until blnPing = False Or intDiff > 45
	
	Call WriteToLog("Ping commands complete, proceeding to scan ARP cache.")
	Set objARPStatus = g_objShell.Exec("%ComSpec% /c Arp -a")

    Do
        WScript.Sleep(500)
    Loop Until objARPStatus.Status = 1
		
	intCount = 0
	Do
		strOutput = CStr(LTrim(objARPStatus.StdOut.ReadLine))
		
		' English or French may appear in output, must consider both.
		intDynamic = InStr(strOutput, "dynamic") + InStr(strOutput, "dynamique")
		
		If intDynamic > 0 Then
	
			Dim arrCurrentIP, strCurrentIP, strCurrentHostName, intRegNum
			arrOutput = Split(strOutput, " ")
			arrCurrentIP = Split(arrOutput(0),".")
			strCurrentIP = arrOutput(0)
			strCurrentHostName = ResolveIPToHostName(strCurrentIP)
			intRegNum = RegExGetBRef(strCurrentHostName, "^([a-z]{3,4})\d{3,4}(\d{2})$", 2, True)
			If UCase(Left(g_strServerName, 7)) = UCase(Left(strCurrentHostName, 7)) Then
                If strCurrentHostName <> "Unknown" And PingStatus(strCurrentIP) = 0 And intRegNum <> "" And intRegNum <> "00" Then
                    intCount = intCount + 1
                    Set objRegister = New PosDevice
                    Call objRegister.SetIP(strCurrentIP)
                    Call objRegister.SetName(strCurrentHostName)
                    Call objRegister.SetType("Register")
                    Call g_objDevices.Add(intCount, objRegister)
                    Call WriteToLog("Device with IP address" & Chr(32) & strCurrentIP & Chr(32) & "identified as store Register" & Chr(32) & strCurrentHostName & ".")
			    Else
			        Call WriteToLog("Device with IP address" & Chr(32) & strCurrentIP & Chr(32) & "does not translate to store Register device.")
			    End If
		    End If
        
        End If
	
	Loop Until objARPStatus.StdOut.AtEndOfStream
	
	Set objARPStatus = Nothing
	
	' Confirm at least one Register detected.
	If intCount > 0 Then
	    GenerateRegisterTable = intCount
	End If
	
	On Error GoTo 0
	
End Function

Function ResolveIPToHostName(strIPAddressToResolve)

    ' Function: Resolve IP address to the NetBIOS hostname.
    ' Argument 1: Device IP address to translate.
    ' Return Value: NetBIOS hostname.

    On Error Resume Next

	ResolveIPToHostName = "Unknown"
	
	Dim objNBStatus, strOutput, strPattern, intHostName, intRegNum
	
	strPattern = "<00>  UNIQUE"
	Set objNBStatus = g_objShell.Exec("nbtstat -A" & Chr(32) & strIPAddressToResolve)

    Do
        WScript.Sleep(500)
    Loop Until objNBStatus.Status = 1
		
	Do
		strOutput = objNBStatus.StdOut.ReadLine
		intHostName = InStr(strOutput, strPattern)
		If intHostName > 0 Then
			Dim arrCurrentLine
			arrCurrentLine = Split(LTrim(strOutput), " ")
            If Instr(arrCurrentLine, "IS~") = 0 And Instr(arrCurrentLine, "..") = 0 Then
				ResolveIPToHostName = Replace(Replace(Replace(arrCurrentLine(0),"IS~",""),".",""),"<00>","")
            End If
		End If
	Loop Until objNBStatus.StdOut.AtEndOfStream
	
    Set objNBStatus = Nothing
	
	On Error GoTo 0
	
End Function

Function RegExGetBRef(strString, strPattern, intBRef, blnIgnoreCase)
'
' Provide a single-line interface to use RegExp to parse a string and return a single
' backreference.  intBRef is a Base-1 index (1 for the first capture, 2 for second, etc).
' If the pattern is not matched at all, or if an invalid value is passed for intBRef, 
' the function will return an empty string.
'
' The RegExp search is always performed with Global mode set to false.  This is for simple
' captures only.
'
' Ex:  RegExGetBRef("Hello, There!", "(.*),\s*([^,]+)$", 1, True) returns "Hello", and
'      RegExGetBRef("Hello, There!", "(.*),\s*([^,]+)$", 2, True) returns "There!"
  
    On Error Resume Next
    
    RegExGetBRef = ""

    Dim objRegExp
    Dim colMatches, objMatch

    Set objRegExp = New RegExp

    objRegExp.Pattern = strPattern
    objRegExp.IgnoreCase = blnIgnoreCase
    objRegExp.Global = False
    objRegExp.MultiLine = True

    Set colMatches = objRegExp.Execute(strString)

    For Each objMatch In colMatches
    If ((intBRef > 0) And (intBRef <= objMatch.SubMatches.Count)) Then
      RegExGetBRef = objMatch.SubMatches(intBRef - 1)
    End If
    Next

    On Error GoTo 0

End Function

Function GenerateWebPCTable()

    ' Function: Determine Web PCs on local network based on hosts file aliasing.
    ' Arguments: None.
    ' Return Value 0: No Web PCs detected on network.
    ' Return Value 1: 1 Web PCs detected on network.
    ' Return Value 2: 2 Web PCs detected on network.

    On Error Resume Next

    Dim arrWebPC, arrIP, arrWebPC1, arrWebPC2, colWebPC
    Dim strWebPC1, strWebPC2, strIP, strName, strWebPC, strType
    Dim objWebPC, objRegEx, colMatches, strMatch, arrHosts, strHosts
    Dim intCount, intResult, intIndex, intWebPC
    Dim blnWebPC1, blnWebPC2
    Dim strWebPCIP1, strWebPCIP2, strIPtoPing
    Dim colPingStatus, objPingStatus
    
    intWebPC = 0
    GenerateWebPCTable = intWebPC

    ' Interrogate local hosts file for Web PC IP address resolution.
    arrHosts = Split(g_strHosts, vbCrLf)
    Set objRegEx = CreateObject("VBScript.RegExp")
    objRegEx.Global = False
    objRegEx.Pattern = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
    
    ' Find primary Web PC IP address.
    Call WriteToLog("Extracting primary Web PC IP address from local hosts file.")
    blnWebPC1 = False
    For Each strHosts In arrHosts
        If Instr(LCase(strHosts), LCase("WebPC")) > 0 And Not Instr(LCase(strHosts), LCase("WebPC2")) > 0 Then
            Set colMatches = objRegEx.Execute(strHosts)
            If colMatches.Count > 0 Then
                For Each strMatch In colMatches
                    blnWebPC1 = True
                    strWebPCIP1 = strMatch.Value
                    Call WriteToLog("The primary Web PC IP address translated as" & Chr(32) & Chr(34) & strWebPCIP1 & Chr(34) & Chr(32) & "in hosts file.")
                Next
            End If
        End If
    Next
    
    If Not blnWebPC1 Then
        Call WriteToLog("Unable to translate primary Web PC IP address from hosts file.")
    End If
    
    ' Find secondary Web PC IP address.
    Call WriteToLog("Checking for secondary Web PC IP address in local hosts file.")
    blnWebPC2 = False
    For Each strHosts In arrHosts
        If Instr(LCase(strHosts), LCase("WebPC2")) > 0 Then
            Set colMatches = objRegEx.Execute(strHosts)
            If colMatches.Count > 0 Then
                For Each strMatch In colMatches
                    blnWebPC2 = True
                    strWebPCIP2 = strMatch.Value
                    Call WriteToLog("The secondary Web PC IP address translated as" & Chr(32) & Chr(34) & strWebPCIP2 & Chr(34) & Chr(32) & "in hosts file.")
                Next
            End If
        End If
    Next

    If Not blnWebPC2 Then
        Call WriteToLog("Unable to translate secondary Web PC IP address from hosts file.")
    End If

    ' Ping Web PCs based on hosts file alias IP resolution.
    Call WriteToLog("Pinging Web PCs by resolved IP addresses.")

    arrWebPC1 = Array(strWebPCIP1, "WebPC")
    arrWebPC2 = Array(strWebPCIP2, "WebPC2")
    
    If blnWebPC1 And blnWebPC2 And strWebPCIP1 <> strWebPCIP2 Then
        colWebPC = Array(arrWebPC1, arrWebPC2)
    ElseIf blnWebPC1 Then
        colWebPC = Array(arrWebPC1)
    ElseIf blnWebPC2 Then
        colWebPC = Array(arrWebPC2)
    End If

    ' Windows XP devices and above use this method to ping.
    If g_blnWQL And Not WScript.Arguments.Named.Exists("ARP") Then
        For Each arrWebPC In colWebPC
            strIPtoPing = arrWebPC(0)
            Set colPingStatus = GetObject("winmgmts://./root/cimv2").ExecQuery("SELECT * FROM Win32_PingStatus WHERE Address = " & Chr(39) & strIPtoPing & Chr(39))
            For Each objPingStatus In colPingStatus
                If objPingStatus.StatusCode = 0 Then
                    intIndex = g_objDevices.Count + 1
                    Call WriteToLog("Web PC IP address" & Chr(32) & Chr(34) & objPingStatus.Address & Chr(34) & Chr(32) & "responded to ping request.")
                    Set objWebPC = New PosDevice
                    Call objWebPC.SetIP(strIPtoPing)
                    strType = arrWebPC(1)
                    strName = FetchWebPCName(strType)
                    Call objWebPC.SetName(strName)
                    Call objWebPC.SetType(strType)
                    Call g_objDevices.Add(intIndex, objWebPC)
                    intWebPC = intWebPC + 1
                Else
                    Call WriteToLog("Web PC IP address" & Chr(32) & Chr(34) & objPingStatus.Address & Chr(34) & Chr(32) & "did not respond to ping request.")
                End If
            Next
        Next
    Else
    ' Windows 2000 devices use this method to ping.
        For Each arrWebPC In colWebPC
            strIPtoPing = arrWebPC(0)
            intResult = PingStatus(strIPtoPing)
            If intResult = 0 Then
                Call WriteToLog("Web PC IP address" & Chr(32) & Chr(34) & strIPtoPing & Chr(34) & Chr(32) & "responded to ping request.")
                intIndex = g_objDevices.Count + 1
                Set objWebPC = New PosDevice
                Call objWebPC.SetIP(strIPtoPing)
                strType = arrWebPC(1)
                strName = FetchWebPCName(strType)
                Call objWebPC.SetName(strName)
                Call objWebPC.SetType(strType)
                Call g_objDevices.Add(intIndex, objWebPC)
                intWebPC = intWebPC + 1
            Else
                Call WriteToLog("Web PC IP address" & Chr(32) & Chr(34) & strIPtoPing & Chr(34) & Chr(32) & "did not respond to ping request.")
            End If
        Next
    End If
    
    GenerateWebPCTable = intWebPC
    
    On Error GoTo 0

End Function

Function ConvertToIP(strDevice)

    ' Function: Resolve address Host Name to an IP address.
    ' Argument 1: The device name to translate to an IP address.
    ' Return Value: The IP address of the device.

    On Error Resume Next

	ConvertToIP = "Unknown"

	Dim objPingStatus, objShell, strLine, arrLine, strIPAddress, blnAlias
		
	' Issue ping from the command prompt.
	Set objShell = CreateObject("WScript.Shell")
	Set objPingStatus = objShell.Exec("%ComSpec% /c ping" & Chr(32) & strDevice)
	blnAlias = False
		
	' Wait for command shell to finish.
	Do
	    WScript.Sleep(1000)
    Loop Until objPingStatus.Status = 1
		
	' Test for a live device.
	Do
		strLine = objPingStatus.StdOut.ReadLine
		If InStr(strLine, "Reply from") > 0 Or InStr(strLine, "ponse de") > 0 Then
		    blnAlias = True
		    arrLine = Split(strLine,Chr(32))
		    strIPAddress = Replace(arrLine(2),":","")
		    Exit Do
		End If
	Loop Until objPingStatus.StdOut.AtEndOfStream
			
	Set objShell = Nothing
	Set objPingStatus = Nothing
	
	' Return IP address of device.
	If blnAlias = True Then
	    ConvertToIP = strIPAddress
	End If
	
	On Error GoTo 0
	
End Function

Function KillProcess(strProcessName)

    ' Function: Terminate a process.
    ' Argument 1: Name of the process to kill.
    ' Return Value 0 = Process killed.
    ' Return Value 1 = Problem killing process.

    On Error Resume Next
	
	Dim objWMIConnect, colProcess, objProcess, objLoc
	Dim intCommand, intSuccess
	Dim strCommand
	Dim blnFound
	
	KillProcess = 2
	
	Set objLoc = CreateObject("wbemscripting.swbemlocator")
	objLoc.Security_.privileges.addasstring "sedebugprivilege", True
	
	Err.Clear
	Set objWMIConnect = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
	If Err.Number <> 0 Then
	    KillProcess = 1
	    Exit Function
	End If
	
	Err.Clear
	Set colProcess = objWMIConnect.ExecQuery("Select * From Win32_Process")
	If Err.Number <> 0 Then
	    KillProcess = 1
	    Exit Function
	End If	
	
	blnFound = False
	intSuccess = 0
	For Each objProcess In colProcess
		If Instr(LCase(strProcessName), LCase(objProcess.Caption)) > 0 Or Instr(LCase(strProcessName), LCase(objProcess.Description)) > 0 Or Instr(LCase(strProcessName), LCase(objProcess.Name)) > 0 Then
		    strCommand = g_strUtils & Chr(92) & "pskill.exe" & Chr(32) & strProcessName
		    blnFound = True
		    intCommand = g_objShell.Run(strCommand, MinWindow, True)
		    If intCommand = 0 Then
		        intSuccess = intSuccess + 1
		    End If
        End If
	Next
	
	If blnFound = True And intSuccess > 0 Then
	    KillProcess = 0
    ElseIf blnFound = True And intSuccess = 0 Then
        KillProcess = 10
    Else
        KillProcess = 20
    End If
	
    Set colProcess = Nothing
    Set objWMIConnect = Nothing
    
    On Error GoTo 0

End Function

Function TestSFTP(arrDevice)

    ' Function: Confirm the SFTP connection to a device.
    ' Argument 1: Dictionary object containing a list of devices to test.
    ' Return Value: A dictionary object with the results of the SFTP test for each device.

    On Error Resume Next
  
    Dim objExec, objBatchFile, dicResult
    Dim intTimeOut, intTimer, intDone, intIndex, intResult
    Dim strExec, strBatchFile, strNow, strThen, strDevice, strAlias, strDeviceType, strAdmin, strIP
    Dim arrExec, arrResult
    Dim objDevice
    
    Set dicResult = CreateObject("Scripting.Dictionary")
    Set TestSFTP = dicResult

    ' Dimension arrays.
    ReDim arrExec(arrDevice.Count - 1)
    ReDim arrResult(arrDevice.Count - 1)
    
    ' Populate status array with pending result code.
    intIndex = 0
    Do
        arrResult(intIndex) = g_intPendingCode
        intIndex = intIndex + 1
    Loop Until intIndex > UBound(arrResult)
    
    ' Initiate the SFTP test connection.
    intIndex = 0
    For Each objDevice In arrDevice
 
        ' Get current device details.
        Set objDevice = arrDevice.Item(intIndex + 1)
        strDeviceType = objDevice.GetType()
        
        ' Define device alias and SFTP connection username.
        If strDeviceType = "Register" Then
            strAdmin = "Cambridge"
            strAlias = GetRegisterAlias(objDevice.GetIP())
            If strAlias = "" Then
                strAlias = objDevice.GetIP()
            End If
        ElseIf strDeviceType = "WebPC" Then
            strAdmin = "Cambridge"
            'strAdmin = "eService"
            strAlias = "webpc"
        ElseIf strDeviceType = "WebPC2" Then
            strAdmin = "Cambridge"
            'strAdmin = "eService"
            strAlias = "webpc2"
        End If
        
        If strDeviceType = "WebPC" And g_blnWebPC = False Then
        
            Call WriteToLog("Note: Skipping SFTP Test for unresponsive Web PC.")
            arrResult(intIndex) = 999
        
        Else
            
            ' Test batch file for SFTP connection.
            strBatchFile = g_strCurrentPath & Chr(92) & g_objFS.GetTempName()

            Err.Clear
            Set objBatchFile = g_objFS.CreateTextFile(strBatchFile, True)
            If Err.Number = 0 Then
                objBatchFile.WriteLine("open" & Chr(32) & strAdmin & "@" & strAlias)
				
                objBatchFile.WriteLine("bye")
                objBatchFile.Close
                strExec = "%ComSpec% /v:on /c (start /wait /min sftpg3.exe -B" & Chr(32) & Chr(34) & strBatchFile & Chr(34) &_
                          ") & exit !errorlevel!" & Chr(32) & "> nul 2>&1"
                Set arrExec(intIndex) = g_objShell.Exec(strExec)
            Else
                arrResult(intIndex) = 999
            End If
        
        End If

        ' Cycle through all devices.
        intIndex = intIndex + 1
        WScript.Sleep(1000)
        
    Next

    ' Wait for all Registers to finish SFTP test or time-out.
    intDone = 1
    intTimeOut = 3 'Time-out threshold in minutes for all running jobs.
    strThen = Now
    Do
        intIndex = 0
        WScript.Sleep(1000)
        For Each objExec In arrExec
            If arrResult(intIndex) <> 999 Then
                If objExec.Status = 1 Then
                    arrResult(intIndex) = objExec.ExitCode
                End If
            End If
            intIndex = intIndex + 1
        Next
        strNow = Now
        intTimer = DateDiff("n", strThen, strNow)
        intDone = ExecDone(arrResult)
    Loop Until intDone = 0 Or intTimer > intTimeOut

    ' Populate dictionary with SFTP test results.
    intIndex = 0
    For Each objDevice In arrDevice
        
        ' Get current device details.
        Set objDevice = arrDevice.Item(intIndex + 1)
        strIP = objDevice.GetIP()
        
        ' Post SFTP test result.
        If arrResult(intIndex) = g_intSuccessCode Then
            Call dicResult.Add(strIP, "True")
        Else
            Call dicResult.Add(strIP, "False")
        End If
        intIndex = intIndex + 1
    Next

    ' Return the dictionary object.
    Set TestSFTP = dicResult
 
    ' Temporary file clean-up.
    Call g_objFS.DeleteFile(g_strCurrentPath & Chr(92) & "*.tmp")
    Set dicResult = Nothing

    On Error GoTo 0
  
End Function

Function GetRegisterAlias(strIP)
  
  ' Function: Return Register alias from local hosts file based on IP address lookup.
  ' Argument 1: The IP address of the Register to look-up.
  ' Return Value: First alias defined on hosts file line for IP address.
  ' If no line found, return an empty string.
  
  GetRegisterAlias = ""
  
  Dim strLineIP
  Dim strLine
  
  For Each strLine In Split(g_strHosts, vbCrLf)
    strLineIP = RegExGetBRef(strLine, "^\s*(\S+)\s*(\S+)", 1, True)
    If (strLineIP = strIP) Then
      GetRegisterAlias = RegExGetBRef(strLine, "(reg\d{2})(?:$|\s)", 1, True)
      Exit For
    End If
  Next
End Function

Sub UpdateCSV(strDevice, strInstall)

    On Error Resume Next
    
    Dim objCurrentFile, objNewFile
    Dim strLine, strFile, strColumn, strText
    Dim arrFile, arrRow
    Dim intCount, strItem, strLookup
    
    Set objCurrentFile = g_objFS.OpenTextFile(g_strCSVFileTemp, ForReading)
    strFile = objCurrentFile.ReadAll
    objCurrentFile.Close
    Set objCurrentFile = Nothing
    
    Set objNewFile = g_objFS.CreateTextFile( g_strCSVFile & ".Update", True)
    
    strLookup = strDevice

    REM If strLookup <> g_strServerIPAddress Then
        REM For Each strItem In g_objDevices
            REM If g_objDevices.Item(strItem) = strLookup Then
                REM strLookup = strItem
                REM Exit For
            REM End If
        REM Next
    REM End If
    
    arrFile = Split(strFile, vbCrLF)
    For Each strLine In arrFile
        If Instr(strLine, strLookup) > 0 Then
            arrRow = Split(strLine, Chr(44))
            REM 'arrRow(3) = strData
            REM 'arrRow(4) = strInstall
            arrRow(3) = strInstall
            For intCount = 0 To UBound(arrRow) Step 1
                strText = Replace(arrRow(intCount), Chr(34), "")
                If intCount = UBound(arrRow) Then
                    objNewFile.WriteLine(Chr(34) & strText & Chr(34))
                Else
                    objNewFile.Write(Chr(34) & strText & Chr(34) & Chr(44))
                End If
            Next
        ElseIf Len(strLine) > 0 Then
            objNewFile.WriteLine(strLine)
        End If
    Next
    
    objNewFile.Close
    Set objNewFile = Nothing
    
    Call g_objFS.CopyFile(g_strCSVFile & ".Update", g_strCSVFileTemp, True)
    Call g_objFS.DeleteFile(g_strCSVFile & ".Update", True)
    
    On Error GoTo 0

End Sub

Function PushFolder(arrDevice, objSFTP)

    ' Function: Deliver folder, data over SFTP or UNC.
    ' Argument 1: Array of devices to deliver files.
    ' Argument 2: Array of SFTP test results for devices.
    ' Argument 3: Name of local folder to push to device.
    ' Return Value: Array containing the result of the file delivery for each device, True or False session.
    
    ' Folder is pushed to C:\Temp\ directory on the destination system.

    On Error Resume Next
 
    Dim objExec, objBatchFile, dicResult, objDevice
    Dim intTimeOut, intTimer, intDone, intIndex, intResult, intTestWMI
    Dim strExec, strBatchFile, strNow, strThen, strDevice, strAlias, strSFTP, strAdmin
    Dim arrExec, arrResult, arrRetry
    
    Dim strDeviceIP, strDeviceType
    
    Set dicResult = CreateObject("Scripting.Dictionary")
    Set PushFolder = dicResult

    ' Dimension arrays.
    ReDim arrExec(arrDevice.Count - 1)
    ReDim arrResult(arrDevice.Count - 1)
    ReDim arrRetry(arrDevice.Count - 1)
    
    ' Populate status array with pending result code.
    intIndex = 0
    Do
        arrResult(intIndex) = g_intPendingCode
        arrRetry(intIndex) = "False"
        intIndex = intIndex + 1
    Loop Until intIndex > UBound(arrResult)

    ' Temporary file clean-up.
    Call g_objFS.DeleteFile(g_strCurrentPath & Chr(92) & "*.tmp", True)
    
    ' Push the data.
    intIndex = 0
    For Each objDevice In arrDevice
 
        ' Get current device details.
        Set objDevice = arrDevice.Item(intIndex + 1)
        strDeviceType = objDevice.GetType()
        strDeviceIP = objDevice.GetIP()
        
        ' Define device alias and SFTP connection username.
        If strDeviceType = "Register" Then
            strAdmin = "Cambridge"
            strAlias = GetRegisterAlias(strDeviceIP)
            If strAlias = "" Then
                strAlias = strDeviceIP
            End If
        ElseIf strDeviceType = "WebPC" Then
            'strAdmin = "eService"
            strAdmin = "Cambridge"
            strAlias = "webpc"
        ElseIf strDeviceType = "WebPC2" Then
            'strAdmin = "eService"
            strAdmin = "Cambridge"
            strAlias = "webpc2"
        End If
		
		Dim StrCont
	
		StrCont = "C:\Temp\SCCM_ADJoin"
        
        ' SFTP delivery.
        If objSFTP.Item(strDeviceIP) = "True" Then

            strBatchFile = g_strCurrentPath & Chr(92) & g_objFS.GetTempName()
						
            Err.Clear
            Set objBatchFile = g_objFS.CreateTextFile(strBatchFile, True)
            If Err.Number = 0 Then
                objBatchFile.WriteLine("open" & Chr(32) & strAdmin & "@" & strAlias)				
				objBatchFile.WriteLine("cd" & Chr(32) & Chr(34) & "/C:/Temp" & Chr(34))
                objBatchFile.WriteLine("lcd" & Chr(32) & StrCont)
                objBatchFile.WriteLine("put -p SCCM_ADJoin")
                objBatchFile.WriteLine("bye")                
                objBatchFile.Close
                strExec = "%ComSpec% /v:on /c (Start /Wait /Min sftpg3.exe -B" & Chr(32) & Chr(34) & strBatchFile & Chr(34) &_
                          ") & Exit !ErrorLevel!" & Chr(32) & "> nul 2>&1"
               Set arrExec(intIndex) = g_objShell.Exec(strExec)
            Else
                arrResult(intIndex) = 999
            End If
        
        ' UNC delivery (xcopy).
        ElseIf strDeviceType = "Register" Then
        
            intTestWMI = TestWMI(strDeviceIP)
            If intTestWMI = 0 Then                			
				strExec = "%ComSpec% /v:on /c (xcopy /E /I /V /Y" & Chr(32) & StrCont & "\SCCM_ADJoin"
                          Chr(32) & Chr(34) & "\\" & strDeviceIP & "\C$\Temp\SCCM_ADJoin" & Chr(34) &_
                          ") & exit !errorlevel!" & Chr(32) & "> nul 2>&1"						  
                Set arrExec(intIndex) = g_objShell.Exec(strExec)
            Else
                arrResult(intIndex) = 1234
            End If
        
        Else
            
            arrResult(intIndex) = 5678
            
        End If

        intIndex = intIndex + 1
        WScript.Sleep(1000)
        
    Next

    ' Wait for all Registers to finish delivering data / retry / time-out.
    intDone = 1
    intTimeOut = 25 'Time-out threshold in minutes.
    strThen = Now()
    Do
        intIndex = 0
        WScript.Sleep(1000)
        
        For Each objExec In arrExec
            
            Set objDevice = arrDevice.Item(intIndex + 1)
            strDeviceIP = objDevice.GetIP()
            strDeviceType = objDevice.GetType()
            
            If arrResult(intIndex) = g_intPendingCode Then
                If objExec.Status = 1 Then
                    arrResult(intIndex) = objExec.ExitCode
                    If arrResult(intIndex) <> g_intSuccessCode And objSFTP.Item(strDeviceIP) = "True" And arrRetry(intIndex) = "False" Then
                        arrResult(intIndex) = g_intPendingCode
                        arrRetry(intIndex) = "True"
                    End If
                End If
            End If

            ' If SFTP fails, retry with the UNC (xcopy) method.
            If objExec.Status = 1 And arrResult(intIndex) = g_intPendingCode And objSFTP.Item(strDeviceIP) = "True" And strDeviceType = "Register" Then
                intTestWMI = TestWMI(strDeviceIP)
                If intTestWMI = 0 Then                    											  
					strExec = "%ComSpec% /v:on /c (xcopy /E /I /V /Y" & Chr(32) & StrCont & "\SCCM_ADJoin"
                          Chr(32) & Chr(34) & "\\" & strDeviceIP & "\C$\Temp\SCCM_ADJoin" & Chr(34) &_
                          ") & exit !errorlevel!" & Chr(32) & "> nul 2>&1"						  
                    Set arrExec(intIndex) = g_objShell.Exec(strExec)
                End If                   
            End If

            intIndex = intIndex + 1
            
        Next
        strNow = Now
        intTimer = DateDiff("n", strThen, strNow)
        intDone = ExecDone(arrResult)

    Loop Until intDone = 0 Or intTimer > intTimeOut

    ' Populate dictionary with file delivery results.
    intIndex = 0
    For Each objDevice In arrDevice
        
        ' Get current device details.
        Set objDevice = arrDevice.Item(intIndex + 1)
        strDeviceIP = objDevice.GetIP()
        
        ' Post file delivery result.
        If arrResult(intIndex) = g_intSuccessCode Then
            Call dicResult.Add(strDeviceIP, "True")
        Else
            Call dicResult.Add(strDeviceIP, "False")
        End If
        
        intIndex = intIndex + 1
        
    Next

    ' Return the dictionary object.
    Set PushFolder = dicResult
 
    ' Temporary file clean-up.
    Call g_objFS.DeleteFile(g_strCurrentPath & Chr(92) & "*.tmp", True)
    Set dicResult = Nothing

    On Error GoTo 0
  
End Function

Function TestWMI(strDevice)

    ' Function: Test WMI connection to a device.
    ' Argument 1: Name of device to connect (Device IP preferred.)
    ' Return Value: 0 = Success connection to device WMI.
    ' Return Value: 1 = Unable to connect to device WMI.

    On Error Resume Next
    
	Dim objWMIService, intTestWMI
    
    TestWMI = 2
        	
	' Test WMI connection.
	Err.Clear
	Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strDevice & "\root\cimv2")
	If Err.Number = 0 Then
	    intTestWMI = 0
	Else
	    intTestWMI = 1
	End If
	
	' Exit with status code.
	TestWMI = intTestWMI
	Set objWMIService = Nothing
	
	On Error GoTo 0

End Function

Function ComboWebPC()

    ' Function: Determine the secondary Web PC name in a Combo Store.
    ' Arguments: None
    ' Return Value: The host name of the secondary Web PC.
    ' Note: Function scans the back-up site.xml file from the primary Web PC to determine this information.

    On Error Resume Next
    
    ComboWebPC = "Unknown"
    
    Dim strSiteXML, strRow, strChar, strWebPC
    Dim objSiteXML
    Dim arrRow
    Dim blnFound
    
    blnFound = False
    
    ' The primary Web PC site file contains the secondary Web PC name in Combo Stores.
    If g_blnWQL = True Then
        strSiteXML = "D:\swbackups\Temp\site.xml"
    Else
        strSiteXML = "C:\swbackups\Temp\site.xml"
    End If
    
    ' Cycle through the primary site file to retrieve the secondary Web PC name.
    If g_objFS.FileExists(strSiteXML) Then
    
        Set objSiteXML = g_objFS.OpenTextFile(strSiteXML, ForReading, False)
        
        Do
        
            strRow = objSiteXML.ReadLine
            If InStr(LCase(strRow), LCase("Combo-Slave-Hostname")) Then
                strRow = Replace(strRow, "<", ".")
                strRow = Replace(strRow, ">", ".")
                arrRow = Split(strRow, ".")
                For Each strRow In arrRow
                    strChar = UCase(Right(LTrim(RTrim(strRow)), 1))
                    If strChar = "N" Then ' Look for N which signifies a Web PC name.
                        ComboWebPC = RTrim(LTrim(strRow))
                        blnFound = True
                        Exit For
                    End If
                Next
            End If
        
        Loop Until objSiteXML.AtEndOfStream Or blnFound = True
    
    End If
    
    Call objSiteXML.Close
    Set objSiteXML = Nothing
    
    On Error GoTo 0

End Function

Function GenerateRegisterTableNew(intMinIP, intMaxIP)

    ' Function: Create an array of Registers based on the LAN IP scan.
    ' Argument 1: Lowest IP (fourth) octet to scan.
    ' Argument 2: Highest IP (fourth) octet to scan.
    ' Return Value: 0 = No Registers detected.
    ' Return Value: An integer > 0 = The actual number of Registers detected.

	On Error Resume Next
	
	GenerateRegisterTableNew = 0
	
	Dim objRegister
	Dim arrOutput
	Dim strDeviceIP, strCurrentIP, strCurrentHostName
	Dim intCount, intIndex, intRegNum
	
	Dim strIPFrag
	Dim arrIPFrag
	Dim dicScanIPRange
	
	' Scan IP addresses on LAN for live devices.
	arrIPFrag = Split(g_strServerIPAddress, ".")
    strIPFrag = arrIPFrag(0) & "." & arrIPFrag(1) & "." & arrIPFrag(2) & "."
    
    Call WriteToLog("Scanning IP range ." & intMinIP & Chr(32) & "through ." & intMaxIP & Chr(32) & "on local network for live devices.")
    Set dicScanIPRange = ScanIPRange(strIPFrag, intMinIP, intMaxIP)
    Call WriteToLog("Done scanning IP address range.")
    
    ' Filter Register devices only.
    Call WriteToLog("Matching responsive IP addresses to store Register devices.")
    intIndex = 0
    For intCount = intMinIP To intMaxIP
        If dicScanIPRange.Item(intCount) = "True" Then
            strCurrentIP = strIPFrag & intCount
            strCurrentHostName = ResolveIPToHostName(strCurrentIP)
            intRegNum = RegExGetBRef(strCurrentHostName, "^([a-z]{3,4})\d{3,4}(\d{2})$", 2, True)
            If UCase(Left(g_strServerName, 7)) = UCase(Left(strCurrentHostName, 7)) Then
                If strCurrentHostName <> "Unknown" And intRegNum <> "" And intRegNum <> "00" Then
                    intIndex = intIndex + 1
                    Set objRegister = New PosDevice
                    Call objRegister.SetIP(strCurrentIP)
                    Call objRegister.SetName(strCurrentHostName)
                    Call objRegister.SetType("Register")
                    Call g_objDevices.Add(intIndex, objRegister)
                    Call WriteToLog("IP address" & Chr(32) & strCurrentIP & Chr(32) & "translated to matching store Register alias" & Chr(32) & strCurrentHostName & ".")
                Else
                    Call WriteToLog("IP address" & Chr(32) & strCurrentIP & Chr(32) & "does not translate to a matching store Register alias.")
                End If
            Else
                Call WriteToLog("IP address" & Chr(32) & strCurrentIP & Chr(32) & "does not translate to a matching store Register alias.")
            End If
        End If
    Next
    Call WriteToLog("Done matching responsive IP addresses to store Register devices.")

	' Confirm at least one Register detected.
	If intIndex > 0 Then
	    GenerateRegisterTableNew = intIndex
	End If
	
	On Error GoTo 0
	
End Function

Function ExecDone(arrResult)

    ' Function: Review status of all running Shell Exec jobs.
    ' Argument 1: A list of running Shell Exec status codes.
    ' Return Value 0 = Indicates all jobs have finished running.
    ' Return Value 1 = At least one job is still running.

    On Error Resume Next

    ExecDone = 999

    Dim intResult, intTotal, intSum
    
    intSum = 0
    intTotal = UBound(arrResult) + 1
    
    ' The pending status previously populated should change to the actual return code or a forced error code.
    For Each intResult In arrResult
        If intResult <> g_intPendingCode Then
            intSum = intSum + 1
        End If
    Next

    If intSum = intTotal Then
        ExecDone = 0
    Else
        ExecDone = 1
    End If
    
    On Error GoTo 0

End Function

Function ScanIPRange(strIP, intMin, intMax)

    ' Function: Scan IP address range for live devices.
    ' Argument 1: First/second/third IP octet combination. (e.g. 172.26.210.)
    ' Argument 2: Lowest IP (fourth) octet to scan. (e.g. 1)
    ' Argument 3: Highest IP (fourth) octet to scan. (e.g. 25)
    ' Return Value: Dictionary object containing IP address scan results formatted as (IP Fourth Octet, True/False result)

    On Error Resume Next
    
    Dim strIPtoPing
    Dim intResult, intIndex, intCount
    Dim blnPingTest
    
    Dim colPingStatus, objPingStatus, objExec
    
    Dim dicIPRange
    Set dicIPRange = CreateObject("Scripting.Dictionary")
        
    ' Cycle through IP addresses to test for live devices.
    For intCount = intMin to intMax Step 1
        strIPtoPing = strIP & intCount
        Set colPingStatus = GetObject("winmgmts://./root/cimv2").ExecQuery("SELECT * FROM Win32_PingStatus WHERE Address = " & Chr(39) & strIPtoPing & Chr(39))
        For Each objPingStatus In colPingStatus
            If objPingStatus.StatusCode = 0 Then
                Call WriteToLog("IP address" & Chr(32) & objPingStatus.Address & Chr(32) & "responded to ping request.")
                Call dicIPRange.Add(intCount, "True")
            Else
                Call WriteToLog("IP address" & Chr(32) & objPingStatus.Address & Chr(32) & "did not respond to ping request.")
                Call dicIPRange.Add(intCount, "False")
            End If
        Next
    Next

    ' Assign results.
    Set ScanIPRange = dicIPRange
    
    On Error GoTo 0

End Function

Function FetchWebPCName(strAlias)

    ' Function: Match Web PC system hosts file alias to computer name.
    ' Argument: Hosts file alias of Web PC.
    ' Return Value: Computer name of Web PC.
    ' Note: If no match is found, "Unknown" value is returned.

    On Error Resume Next
    
    Dim strNameIn, strWebPCName
    
    strNameIn = LCase(strAlias)

    Select Case strNameIn
    
        Case "webpc"
            strWebPCName = Left(g_strServerName, 7) & "N"
        Case "webpc2"
            strWebPCName = ComboWebPC()
        Case Else
            strWebPCName = "Unknown"
    End Select
    
    FetchWebPCName = strWebPCName
    
    On Error GoTo 0

End Function

' Determine environment type: Development vs. QA. vs. Production. Return value is the environment type.
Function EnvType(strEnvType)

    Dim strEnvFull

    Select Case strEnvType
    
        Case "DEV"
            strEnvFull = "Development"
            
        Case "QA"
            strEnvFull = "QA"
            
        Case "PROD"
            strEnvFull = "Production"
            
        Case Else
            strEnvFull = "Unknown"
            
    End Select
    
    EnvType = strEnvFull           

End Function

' End :: Support Functions And Subroutines :: End

Open in new window

That's not going to help...
For one, you've just pasted a bunch of text and told me to go find line 685.  I could copy and paste it somewhere and 'hope' our line 685s lined up, but then I'd be guessing. :^(

Instead, either upload a copy, or point out the line, with some surrounding context code so I know what we're looking at.  
For smaller scripts, use the Code reference above, which places it in a nice format (just don't do it again here, as that's already 7 pages of unnecessary text).

Syntax error typically means something's clearly mistyped.  The line 685 that I see from above doesn't seem to indicate any sort of error...  give me some direction on where the issue is and I'll see if I can help you.  If your code matches what you've posted, just let me know what you see as line 685.
Avatar of SDJ_1

ASKER

Hello sorry about that, see attachment.
TEST.ADJoin.vbs
Avatar of SDJ_1

ASKER

C:\Temp\SCCM_ADJoin\AD_Join.vbs(681, 1) Microsoft VBScript compilation error: Sy
ntax error

Here's the message
This may seem a bit confusing, but the syntax error stems from the fact that you 'opened' a function called "Main", but never told it where it ends...

So, this is where it becomes a guessing game, or the original coder needs to identify where Function Main should end.

If we take a stab at it, presumably it's just before your InstallSoftware function, which is what's being shown as a syntax error.
That said...you might try simply preceeding that line with

End Function

Function InstallSoftware(arrDevice, objSSH, objData)

Open in new window


Failing that, it would take a lot more digging to determine...hopefully that's all it is.  Each function must have a corresponding end function, just as each sub must have an end sub, etc...good luck!
Avatar of SDJ_1

ASKER

ok thanks.  Yes i'm digging.  Thanks for the assistance
Avatar of SDJ_1

ASKER

I've requested that this question be closed as follows:

Accepted answer: 0 points for SDJ_1's comment #a40033571

for the following reason:

Resolved
Was not your original question resolved?
I was under the impression when you stated
Thanks for the assistance.  I'm running into another issue and can't seem to locate the mis directed brackets  
that the original problem was sorted and you were just extending it because you found some other problems?
Hopefully you'll reconsider as I feel I did provide some assistance in resolving your initial problem...