' Const Const ForAppending = 8 Const TristateMixed = -2 Const TristateTrue = -1 Const TristateFalse = 0 Const ForReading = 1 Const ForWriting = 2 ' EndConst ' Region Description ' ' License: GPL ' Copyright: (c) 2008 - 2020 Thomas Borger ESG ' Name: NSClientUpdate ' Author: Thomas Borger ' Version: 0.1.5 ' Description: deploy new Versions of NSClient to all Windows Servers ' ' - check if exists and running a prior version of NSClient on the system ' - stop the service ' - rename the folder which hostes the old version ' - get alle files and folder of new version from network share ' - install the new version ' - copy nsclient.ini from prior version folder to new version folder ' - start the new version service ' - print all actions and results to a logfile on server share ' REQUIREMENTS: ' The script needs on the remote server share which stored the new NSClient++ Versions the following ' structure: ' ..\NSClient++ ' ..\NSClient++\32 --> Win32 Version from NSClient++ (unpacked ZIP archive) ' ..\NSClient++\64 --> X64 Versiob from NSClient++ (unpacked ZIP archive) ' ..\NSClient++\log --> folder where the installation logfiles from each server is stored. ' SYNTAX: NSClientCheck /S:[ServerShare] /c:[config file] ' NSClientCheck /S:\\server6\download\Nagios /c:\\server6\download\Nagios\servers.txt ' WHERE OPTION: ' /S: server share wich stores the new NSClient version unpacked zip archiv ' /c: full path and name of configuration file which is used to handle client requirements ' ' The Options are case sensitive ' EndRegion 'Initialize Set wshshell = CreateObject("WScript.Shell") Set WshNetwork = WScript.CreateObject("WScript.Network") Set fso = CreateObject("Scripting.FileSystemObject") ' Variable Dim strProgramFiles, strServerLogFile, strHostName, strServerShare, strToDo Dim hostNameMatch, zline hostNameMatch = False Dim cfLINES(), cfHOST(), cfINI(), cfSCRIPT() strToDo = "new" On Error Resume Next '############# PRE Checking ################ 'check all Arguments Set argsNamed = WScript.Arguments.Named If Err.number <> 0 Then WScript.Echo "* ERROR: could not get arguments " & Err.Description wshshell.LogEvent 2, "ERROR: could not get arguments" & vbNewLine & Err.Description WScript.Quit 1 End If If argsNamed.Count <= 1 Then WScript.Echo "* ERROR: insufficient arguments" wshshell.LogEvent 2, "insufficient arguments!" WScript.Quit 2 End If For i = 0 To argsNamed.Count - 1 If argsNamed.Exists ("c") = vbFalse Then WScript.Echo "* ERROR: argument /c: is missing - ConfigFile" wshshell.LogEvent 2, "ERROR: argument /c: is missing - ConfigFile" WScript.Quit 3 Else configFile = argsNamed.Item("c") End If If argsNamed.Exists ("S") = vbFalse Then WScript.Echo "* ERROR: argument /S: is missing - Server share where can find the new NSClient++ version" wshshell.LogEvent 2, "ERROR: argument /S: is missing - Server share where can find the new NSClient++ version" WScript.Quit 4 Else strServerShare = argsNamed.Item("S") End If Next 'check if NSClient folder and config file are valid If fso.FolderExists(strServerShare) = vbFalse Then WScript.Echo "* ERROR: " & strServerShare & " is not a valid folder" & vbNewLine & Err.Description wshshell.LogEvent 2, "ERROR: " & strServerShare & " is not a valid folder" & vbNewLine & Err.Description WScript.Quit 5 End If If fso.FileExists(configFile) = vbFalse Then WScript.Echo "* ERROR: " & configFile & " is not a valid file" & vbNewLine & Err.Description wshshell.LogEvent 2, "ERROR: " & configFile & " is not a valid file" & vbNewLine & Err.Description WScript.Quit 6 End If 'get hostname strHostName = UCase(WshNetwork.ComputerName) If Len(strHostName) = 0 Then WScript.Quit "* ERROR: could not get hostname " & Err.Description wshshell.LogEvent 1, "could not get HostName" & Err.Description WScript.Quit 7 Else WScript.Echo "* hostname is: " & strHostName End If Err.Clear 'initialize the service state within windows wmi Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strHostName & "\root\cimv2") If Err.number <> 0 Then WScript.Echo "* ERROR: could not initialize WMIObject " & Err.Description wshshell.LogEvent 2, "ERROR: could not initialize WMIObject " & Err.Description WScript.Quit 8 End If 'define TEMP folder and file for writing version information and create the still empty file Err.Clear Set objPROCESS = wshshell.Environment ("PROCESS") myTEMP = objPROCESS("TEMP") If Err.number <> 0 Then WScript.Echo "* ERROR: couldn't get TEMP environment for this system" WScript.Quit 9 Else myTEMPVersion = myTEMP & "\NSClientVersionen.txt" End If myCPUType = objPROCESS("PROCESSOR_ARCHITECTURE") If InStr(1, myCPUType, "x86") > 0 Then myCPUSubFolder = "32" WScript.Echo "* CPU-Type: " & myCPUType ElseIf InStr(1, myCPUType, "64") > 0 Then myCPUSubFolder = "64" WScript.Echo "* CPU-Type: " & myCPUType Else WScript.Echo "* ERROR: unknown CPU Type: " & myCPUType WScript.Quit 10 End If 'get the folder name from %ProgramFiles% strProgramFiles = wshshell.RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir") If Len(strProgramFiles) = 0 Or Err.number <> 0 Then WScript.Echo "* ERROR: could not get current ProgramFiles " & Err.Description LogFile.WriteLine Now & " - ERROR: could not get current ProgramFiles " & Err.Description LogFile.Close WScript.Quit 11 End If ' Date for Logfile Name y = CStr(Year(Now())) mo = CStr(Month(Now())) if len(mo) = 1 then mo = "0" + mo d = CStr(Day(Now())) if len(d) = 1 then d = "0" + d h = CStr(Hour(Now())) if len(h) = 1 then h = "0" + h m = CStr(Minute(Now())) if len(m) = 1 then m = "0" + m 'get Registry Keys for a installed NSClient++ Err.Clear ImagePath = wshshell.RegRead ("HKLM\SYSTEM\CurrentControlSet\Services\NSClientpp\ImagePath") If Err.number <> 0 Then WScript.Echo "* " & Err.Description WScript.Echo "* perhaps a new installation?" Else Set objInstalledDir = fso.GetFile(ImagePath) InstalledDir = objInstalledDir.ParentFolder WScript.Echo "* NSClient++ is installed on: " & InstalledDir Err.Clear DisplayName = wshshell.RegRead ("HKLM\SYSTEM\CurrentControlSet\Services\NSClientpp\DisplayName") If Err.number <> 0 Then If Len(DisplayName) = 0 Then WScript.Echo "* HKLM\SYSTEM\CurrentControlSet\Services\NSClientpp\DisplayName is empty" End If Else oldVersions = Split(DisplayName, " ") oldVersion = oldVersions(2) oldReleaseDate = oldVersions(3) oldPlattform = oldVersions(4) End If End If 'folder definition strServerRepo = strServerShare & "\log" strServerInstDir = strServerShare & "\" & myCPUSubFolder 'get the version string from NSClient++ version which to be installed. Err.Clear fso.CopyFile strServerInstDir & "\NSClient++.exe", myTEMP & "\" If Err.number <> 0 Then WScript.Echo "* ERROR: couldn't copy remote NSClient++.exe to " & myTEMP & " " & Err.Description WScript.Quit 12 Else rcCMD = wshshell.Run("cmd /c " & myTEMP & "\nsclient++.exe -version > " & myTEMPVersion, 0, 1) If rcCMD <> 0 Then WScript.Echo "* ERROR: could not get version information from: " & strServerInstDir & "\nsclient++.exe" wshshell.LogEvent 2, "ERROR: " & "could not get version information from: " & strServerInstDir & "\nsclient++.exe" WScript.Quit 13 Else 'open version file and read one line Set vFile = fso.OpenTextFile (myTEMPVersion, ForReading , vbFalse , TristateMixed ) If Err.number <> 0 Then WScript.Echo "* ERROR: could not open: " & myTEMPVersion & " for reading " & Err.Description wshshell.LogEvent 2, "ERROR: could not open: " & myTEMPVersion & " for reading " & Err.Description WScript.Quit 14 Else newVersions = Split(vFile.ReadLine, " ") newVersion = newVersions(4) newReleaseDate = Mid(newVersions(5),1,Len(newVersions(5)) - 1) newPlattform = newVersions(7) End If vFile.Close 'delete tmp file fso.DeleteFile myTEMPVersion, vbTrue If Err.number <> 0 Then WScript.Echo "* ERROR: could not delete file: " & myTEMPVersion & " " & Err.Description End If Set vFile = Nothing 'delete tmp nsclient file Err.Clear fso.DeleteFile myTEMP & "\NSClient++.exe", vbTrue If Err.number <> 0 Then WScript.Echo "* ERROR: couldn't delete " & myTEMP & "\NSClient++.exe" End If End If End If 'open the Logfile for each client on the server strServerLogFile = strServerRepo & "\" & y & "_" & mo & "_" & d & "_" & h & m & "-" & strHostName & ".log" Set LogFile = fso.CreateTextFile(strServerLogFile, vbTrue, vbTrue) If Err.number <> 0 Then WScript.Echo "* ERROR: could not write to server logfile: " & strServerLogFile & vbNewLine & Err.Description wshshell.LogEvent 1, "ERROR: could not write to server logfile: " & strServerLogFile & vbNewLine & Err.Description WScript.Quit 15 End If 'start writing the client logfile on server LogFile.WriteLine String(20, "*") & " START NSClient Update Version " & version & " " & String(20, "*") & vbNewLine 'parse the configFile for independent settings Err.Clear Set cF = fso.OpenTextFile(configFile, ForReading, vbFalse, TristateMixed) If Err.number <> 0 Then WScript.Echo "* ERROR: could not open config file: " & configFile LogFile.WriteLine Now & " - ERROR: could not open config file: " & configFile LogFile.Close WScript.Quit 16 Else 'skip the first 15 lines in config file For i = 0 To 14 cF.SkipLine Next zline = 0 Do Until cF.AtEndOfStream ReDim cfLINES(zline) ReDim cfHOST(zline) ReDim cfSCRIPT(zline) ReDim cfINI(zline) line = cF.ReadLine if len(line) = 0 then Exit Do line = UCase(line) cfParams = Split(line,":") cfHOST(zline) = cfParams(0) cfINI(zline) = cfParams(1) cfSCRIPT(zline) = cfParams(2) 'check if hostname in config file matches this host? If strHostName = cfParams(0) then hostNameMatch = True zline = zline + 1 Loop cF.Close Set cF = Nothing End If 'if client hostname does not match one of config file --> cancel installation If hostNameMatch = False Then WScript.Echo "* ERROR: hostname does not match any line in config file" LogFile.WriteLine Now & " - ERROR: hostname does not match any line in config file" LogFile.Close WScript.Quit 17 End If 'set the client specific values for NSC.ini and script folder For i = LBound(cfHOST) To UBound(cfHOST) If cfHOST(i) = strHostName Then myINI = cfINI(i) mySCRIPT = cfSCRIPT(i) myPlattform = cfPlattform(i) End If Next ' check if NSClient in prior version is installed If fso.FileExists(ImagePath) = vbTrue Then strToDo = "update" 'plattform check If oldPlattform <> newPlattform Then WScript.Echo "* ERROR: " & oldPlattform & " is not equal " & newPlattform LogFile.WriteLine Now & " - ERROR: " & oldPlattform & " Is Not equal " & newPlattform WScript.Quit 18 End If 'Version check If newVersion = oldVersion And oldReleaseDate = newReleaseDate Then strToDo = "up2date" Else strToDo = "update" End If End If ' ################################################# ' ############# Install/Remove/Rename/Copy SECTION ######## Select Case strToDo Case "update" 'stop Service Set svc_nsclientpp = objWMIService.Get("Win32_Service.Name='NSClientpp'") svc_state = svc_nsclientpp.State If Err.number <> 0 Then svc_error_nr = Err.number WScript.Echo "* ERROR: couldn't get WMI service state from NSClient++ " & Err.Description LogFile.WriteLine Now & " - ERROR: could not get WMI service state from NSClient++ " & Err.Description 'try to stop service with "net stop" rcCMD = 0 rcCMD = wshshell.Run("cmd /c net stop nsclientpp", 0, 1) If rcCMD = 0 Then WScript.Echo "* service state from NSClientpp is UNKNOWN, but stopped successfully with 'net stop'" LogFile.WriteLine Now & "- service state from NSClientpp is UNKNOWN, but stopped successfully with 'net stop'" Else WScript.Echo "* couldn't stop nsclientpp through 'net stop'" LogFile.WriteLine Now & "* couldn't stop nsclientpp through 'net stop'" WScript.Quit 19 End If Else WScript.Echo "* service NSClientpp is in state: " & svc_state LogFile.WriteLine Now & " - service: NSClientpp is in state: " & svc_state End If If svc_state = "Running" Then svc_nsclientpp.Stopservice() WScript.Sleep 3000 Set svc_nsclientpp = objWMIService.Get("Win32_Service.Name='NSClientpp'") svc_state = svc_nsclientpp.State If svc_state = "Stopped" Then WScript.Echo "* service: NSClientpp successfully stopped" LogFile.WriteLine Now & " - Service nsclientpp successfully stoped" Else WScript.Echo "* ERROR: service NSClientpp couldn't stop" LogFile.WriteLine Now & " - ERROR: Service nsclientpp could not stopped" WScript.Quit 20 End If End If 'uninstall old version rcCMD = wshshell.Run(ImagePath & " /uninstall", 0, 1) If rcCMD = 0 Then WScript.Echo "* NSClient++ successfully uninstalled" LogFile.WriteLine Now & " - NSClient++ successfully uninstalled" Else WScript.Echo "* ERROR: couldn't uninstall NSClient++" LogFile.WriteLine Now & " - ERROR: could not uninstall NSClient++" If svc_error_nr = -2147217406 Then WScript.Echo "* ERROR: NSClient++ isn't installed here" LogFile.WriteLine Now & " - ERROR: service NSClientpp is not installed here" End If End If 'rename the current folder where NSClient++ was installed Err.Clear fso.MoveFolder InstalledDir, InstalledDir & "_" & oldVersion If Err.number <> 0 Then WScript.Echo "* ERROR: couldn't rename folder: " & InstalledDir & " " & Err.Description LogFile.WriteLine Now & " - ERROR: could not rename folder: " & InstalledDir & " " & Err.Description LogFile.Close WScript.Quit 21 Else WScript.Echo "* folder: " & InstalledDir & " renamed to: " & InstalledDir & "_" & oldVersion LogFile.WriteLine Now & " - folder: " & InstalledDir & " successfully renamend to " & InstalledDir & "_" & oldVersion End If 'copy the new version to lokal ProgramFiles WScript.Echo "* copy new NSClient++ Version from remote share . . . - " & Now Err.Clear fso.CopyFolder strServerInstDir, strProgramFiles & "\NSClient++" If Err.number = 0 Then WScript.Echo "* copying files from " & strServerInstDir & " to " & strProgramFiles & " \NSClient++ was successfully " & Now LogFile.WriteLine Now & " - copy new NSClient++ version was successfully" Else WScript.Echo "* ERROR: couldn't copy files from server share to local disk" LogFile.WriteLine Now & " - ERROR: could not copy the new version " & Err.Description LogFile.Close WScript.Quit 22 End If 'install the new version rcCMD = wshshell.Run(strProgramFiles & "\NSClient++\nsclient++.exe /install", 0, 1) If rcCMD = 0 Then WScript.Echo "* new NSClient++ version was successfully installed" LogFile.WriteLine Now & " - new NSClient++ version was successfully installed" Else WScript.Echo "* ERROR: could not install new NSClient++ version" LogFile.WriteLine Now & " - ERROR: could not install new NSClient++ version" LogFile.Close WScript.Quit 23 End If 'use independent settings if specified in config file If myINI = "Y" Then Err.clear fso.CopyFile InstalledDir & "\NSC.ini", strProgramFiles & "\NSClient++\NSC.ini", vbTrue If Err.number <> 0 Then WScript.Echo "* ERROR: could not copy NSC.ini from prior version! " & Err.Description LogFile.WriteLine Now & " - ERROR: could not copy NSC.ini from prior version! " & Err.Description Else WScript.Echo "* restore NSC.ini from prior version was successfully" LogFile.WriteLine Now & " - restore NSC.ini from prior version" End If End If If mySCRIPT = "Y" Then Err.Clear fso.CopyFolder InstalledDir & "_" & oldVersion & "\scripts", strProgramFiles & "\NSClient++\scripts", vbTrue If Err.number <> 0 Then WScript.Echo "* ERROR: could not copy script folder in new version script folder! " & Err.Description LogFile.WriteLine Now & " - ERROR: could not copy script folder in new version script folder! " & Err.Description Else WScript.Echo "* restore script folder from prior version was successfully" LogFile.WriteLine Now & " - restore script folder from prior version" End If End If 'start the NSClient daemon rcCMD = wshshell.Run("cmd /c net start nsclientpp", 0, 1) If rcCMD = 0 Then WScript.Echo "* NSClient++ daemon was successfully started" LogFile.WriteLine Now & " - NSClient daemon was successfully started" Else WScript.Echo "* ERROR: couldn't start NSClient++ daemon!" LogFile.WriteLine Now & " - ERROR: couldn't start NSClient++ daemon!" LogFile.Close WScript.Quit 24 End If 'finish WScript.Echo vbNewLine LogFile.WriteBlankLines(1) LogFile.WriteLine String(20, "*") & " F I N I S H " & String(20,"*") LogFile.Close WScript.Quit 'NSClient++ is not installed yet Case "new" Err.clear fso.CopyFolder strServerInstDir, strProgramFiles & "\NSClient++" If Err.number = 0 Then WScript.Echo "* copying files from " & strServerInstDir & " to " & strProgramFiles & " \NSClient++ was successfully" LogFile.WriteLine Now & " - copying files from " & strServerInstDir & " to " & strProgramFiles & "\NSClient++ was successfully" Else WScript.Quit "* ERROR: couldn't copy the new version " & Err.Description LogFile.WriteLine Now & " - ERROR: could not copy the new version " & Err.Description LogFile.Close WScript.Quit 25 End If 'install the new version rcCMD = wshshell.Run(strProgramFiles & "\NSClient++\nsclient++.exe /install", 0, 1) If rcCMD = 0 Then WScript.Echo "* new NSClient++ version was successfully installed" LogFile.WriteLine Now & " - new NSClient++ version was successfully installed" Else WScript.Echo "* ERROR: could not install new NSClient++ version" LogFile.WriteLine Now & " - ERROR: could not install new NSClient++ version" LogFile.Close WScript.Quit 26 End If 'start the NSClient daemon rcCMD = wshshell.Run("cmd /c net start nsclientpp", 0, 1) If rcCMD = 0 Then WScript.Echo "* NSClientpp daemon was successfully started" LogFile.WriteLine Now & " - NSClientpp daemon was successfully started" Else WScript.Echo "* ERROR: could not start NSClientpp daemon!" LogFile.WriteLine Now & " - ERROR: could not start NSClientpp daemon!" LogFile.Close WScript.Quit 27 End If 'finish WScript.Echo vbNewLine LogFile.WriteBlankLines(1) LogFile.WriteLine String(20, "*") & " F I N I S H " & String(20,"*") WScript.Quit 0 'NSClient++ is already up to date Case "up2date" WScript.Echo "* NSClient++ is up to date: Version " & oldVersion LogFile.WriteLine Now & " - NSClient++ is up to date: Version " & oldVersion 'finish WScript.Echo vbNewLine LogFile.WriteBlankLines(1) LogFile.WriteLine String(20, "*") & " F I N I S H " & String(20,"*") LogFile.Close Set LogFile = Nothing WScript.Quit 0 End Select