Torgeir Bakken
' Script that installs WMI Core 1.5 remotely and unattended ' on NT 4.0 servers and workstations ' Author Torgeir Bakken ' Using wmicore.exe from ' http://www.microsoft.com/downloads/release.asp?ReleaseID=18490 ' as well as PsExec.exe from the free PsTools suite at ' http://www.sysinternals.com ' Flow of the script: ' It loops through an array of the computer names. ' First will the script use ping to see if the computer is connectible. ' If it is, it will test on the file ' "\\\c$\winnt\system32\WBEM\Wbemcore.dll" to see If ' an update is needed. If the file does not exist, or the version Is ' less then 1.5, WMI will be installed. ' Reboot is supressed and is not handled by this script. ' Use e.g. PsShutdown from SysInternals for this. ' Create an array of servers to be updated ' This can be done from a domain lookup, a text file, a spreadsheet, ' or by doing as below, using | as delimiter. aServers = Split("Y32444|ntieakpc", "|") ' Install parameters to PsExec from SysInternals ' The file "behind" -c must exist on the local computer running ' the script. Spaces in the path are *not* allowed. ' PsExec will copy the specified program to the remote system For ' execution (with additional switches) ' Run with domain user sInstCmd = "-c c:\wmi_install\wmicore.exe /s" ' If not domain, username and password can be supplied 'sInstCmd = "-u user -p pwd -c c:\wmi_install\wmicore.exe /s" ' Install status will be written here sLogStatusFile = "c:\wmi_install\InstallStatus.txt" 'Will only be created if some error occurs ' The errors will be written to sLogStatusFile as well sLogErrorFile = "c:\wmi_install\InstallErrors.txt" Const OpenAsASCII = 0 Const OpenAsUnicode = -1 ' FileSystemObject.CreateTextFile Const OverwriteIfExist = -1 Const FailIfExist = 0 ' FileSystemObject.OpenTextFile Const OpenAsDefault = -2 Const CreateIfNotExist = -1 Const FailIfNotExist = 0 Const ForReading = 1 Const ForWriting = 2 Const ForAppending = 8 Set oShell = CreateObject("WScript.Shell") Set oFSO = CreateObject("Scripting.FileSystemObject") If oFSO.FileExists(sLogErrorFile) Then oFSO.DeleteFile sLogErrorFile, True End If Set fLogStatusFile = oFSO.CreateTextFile(sLogStatusFile, _ OverwriteIfExist, OpenAsASCII) LogStatus(vbTab & "**** Update started " & Now & " ****" & vbCrLf) For Each sServer In aServers LogStatus Now & " ---- Starting " & sServer & " ----" ' test with ping If IsConnectible(sServer,"","") Then ' test on Wbemcore.dll If WmiMissing(sServer) Then ' run Psexec and test on return code from it If InstallWmi(sServer, sInstCmd) Then ' test on Wbemcore.dll again If WmiMissing(sServer) Then sErr = "PsExec successfull, but Wbemcore.dll could " _ & "not be found, possible error" LogStatus vbTab & sErr LogError sErr, sServer Else LogStatus vbTab & "Install successfull, reboot needed" End If Else sErr = "PsExec failed" LogStatus vbTab & sErr LogError sErr, sServer End If Else 'WMI is already up to date LogStatus(vbTab & "WMI is already up to date") End If Else sErr = "Could not connect (ping failed)" LogStatus vbTab & sErr LogError sErr, sServer End If LogStatus Now & " ---- Finished " & sServer & " ----" & vbCrLf Next LogStatus(vbTab & "**** Update finished " & Now & " ****") fLogStatusFile.Close ' ********* Functions *********** Function LogStatus(sMsg) fLogStatusFile.WriteLine sMsg End Function Function LogError(sMsg, sNode) Set fLogErrorFile = oFSO.OpenTextFile(sLogErrorFile, _ ForAppending, CreateIfNotExist, OpenAsASCII) fLogErrorFile.WriteLine Now & " Error: " & sMsg & vbTab _ & "Server: " & sNode fLogErrorFile.Close End Function Function WmiMissing(sNode) ' Returns True if WMI is missing or version is < 1.5 sFile = "\\" & sNode & "\c$\winnt\system32\WBEM\Wbemcore.dll" SetLocale "en-us" If (oFSO.FileExists(sFile)) Then iVersion = CDbl(Left(oFSO.GetFileVersion(sFile), 3)) If iVersion < 1.5 Then WmiMissing = True Else WmiMissing = False End If Else WmiMissing = True End If End Function Function InstallWmi(sNode, sCmd) iRC = oShell.Run("""C:\sysinternals\psexec.exe"" \\" & sNode _ & " " & sCmd, 1, True) If iRC = 0 Then InstallWmi = True Else ' -1 Something went wrong ' (e.g the remote computer is not available by some reason) InstallWmi = False End If End Function Function IsConnectible(sHost, iPings, iTO) ' Returns True or False based on the output from ping.exe ' ' Author: Alex Angelopoulos/Torgeir Bakken ' Works an "all" WSH versions ' sHost is a hostname or IP ' iPings is number of ping attempts ' iTO is timeout in milliseconds ' if values are set to "", then defaults below used If iPings = "" Then iPings = 2 If iTO = "" Then iTO = 750 Const OpenAsDefault = -2 Const FailIfNotExist = 0 Const ForReading = 1 Set oShell = CreateObject("WScript.Shell") Set oFSO = CreateObject("Scripting.FileSystemObject") sTemp = oShell.ExpandEnvironmentStrings("%TEMP%") sTempFile = sTemp & "\runresult.tmp" oShell.Run "%comspec% /c ping -n " & iPings & " -w " & iTO _ & " " & sHost & ">" & sTempFile, 0 , True Set fFile = oFSO.OpenTextFile(sTempFile, ForReading, _ FailIfNotExist, OpenAsDefault) sResults = fFile.ReadAll fFile.Close oFSO.DeleteFile(sTempFile) Select Case InStr(sResults,"TTL=") Case 0 IsConnectible = False Case Else IsConnectible = True End Select End Function