This script was hastily/sloppily written to address a major problem we had migrating from SMS 2003 to SCCM 2007 where the clients didn't like being reassinged to a new site. The fix action ended up being a myraid of things:
- Hung 'ccmexec' service due to the process not terminating
- The uninstall didn't fully complete
- Duplicate GUID problems
- ...etc
You may have to change some parts around:
On Error Resume Next Set objShell = CreateObject("WScript.Shell") Set objFSO = CreateObject("Scripting.FileSystemObject") strOutputFile = "CCMOutputFile.txt" strComputerFile = "computers.txt" strSMSCfgFile = "c$\Windows\smscfg.ini" strSMSDelCertString = "c:\temp\ccmdelcert.exe" strSMSUninstallString = "c:\windows\system32\ccmsetup\ccmsetup.exe /uninstall" strSMSCleanString = "c:\temp\ccmclean.exe /all /q" strSCCMServer = "SCCMSERVERNAME" strSMSServiceName = "ccmexec" iComputersSuccess = 0 iComputersOffline = 0 iComputersTotal = 0 arrComputers = Split(getTextFile(strComputerFile), vbCrLf) If IsArray(arrComputers) Then For Each strComputer In arrComputers strComputer = Trim(strComputer) If strComputer <> "" Then WScript.Echo "Pinging " & strComputer & " to see if it is online." If Ping(strComputer) Then WScript.Echo "Binding to " & strComputer & " via WMI." Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") If Err.Number <> 0 Then displayError("Binding error to WMI on: " & strComputer) Err.Clear End If If Not objWMI Is Nothing Then WScript.Echo "Copying pertinent files to c:\temp" If Not objFSO.FileExists("\\" & strComputer & "\c$\" & strSMSUninstallString) Then objFSO.CopyFile "\\" & strSCCMServer & "\SCCM Client Tools\*", "\\" & strComputer & "\c$\temp\", true End If killProcess strComputer, "ccmexec.exe" Set objWMIProcess = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process") WScript.Echo "Running delcert process on remote host." If objFSO.FileExists("\\" & strComputer & "\c$\temp\ccmdelcert.exe") Then spawnProcess strComputer, strSMSDelCertString Else WScript.Echo "Unable to locate delcert executable for execution." End If WScript.Echo "Running ccmsetup /uninstall process on remote host." If objFSO.FileExists("\\" & strComputer & "\c$\windows\system32\ccmsetup\ccmsetup.exe") Then spawnProcess strComputer, strSMSUninstallString Else WScript.Echo "Unable to locate ccmsetup executable for execution." End If WScript.Echo "Running ccmclean process on remote host." If objFSO.FileExists("\\" & strComputer & "\c$\temp\ccmclean.exe") Then spawnProcess strComputer, strSMSCleanString Else WScript.Echo "Unable to locate ccmclean executable for execution." End If iComputersSuccess = iComputersSuccess + 1 Else WScript.Echo "Error binding to WMI using the syntax: winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" End If Else iComputersOffline = iComputersOffline + 1 End If iComputersTotal = iComputersTotal + 1 End If If iComputersTotal Mod 5 = 0 Then WScript.Echo "" WScript.Echo "STATUS UPDATE:" WScript.Echo vbTab & "Hosts Successfully Uninstalled: " & iComputersSuccess WScript.Echo vbTab & "Hosts Offline: " & iComputersOffline WScript.Echo vbTab & "Total Hosts Evaluated: " & iComputersTotal WScript.Echo "" Else WScript.Echo "" End If Next End If ' *********************************************************************************** Sub displayError(strMessage) 'Display custom message and information from VBScript Err object. strError = VbCrLf & "ERROR: " & strMessage & VbCrLf & _ "Number (dec) : " & Err.Number & VbCrLf & _ "Number (hex) : &H" & Hex(Err.Number) & VbCrLf & _ "Description : " & Err.Description & VbCrLf & _ "Source : " & Err.Source Err.Clear WScript.Echo strError End Sub Function Ping(strComputer) Dim objPing, strPing Set objPing = objShell.Exec("ping -n 1 -w 2000 " & strComputer & "") strPing = objPing.StdOut.ReadAll() If Instr(strPing, "Reply") <> 0 Then Ping = True Else Ping = False End If End Function Function getTextFile(strFilePath) If Not objFSO.FileExists(strFilePath) Then WScript.Echo "Could not locate text file: " & strFilePath WScript.Quit End If Set objTextFile = objFSO.OpenTextFile(strFilePath, 1) strTemp = objTextFile.ReadAll objTextFile.Close getTextFile = strTemp End Function Sub killProcess(strComputer, strProcess) Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") objSWbemLocator.Security_.privileges.addasstring "sedebugprivilege", true Set objWMIService = objSWbemLocator.ConnectServer(strComputer, "root\CIMV2") Set colProcesses = objWMIService.ExecQuery("Select * From Win32_Process Where Name = '" & strProcess & "'") If colProcesses.Count = 0 Then log("Process not found to be running: " & strProcess & vbCrLf) ElseIf colProcesses.Count > 0 Then For Each objProcess in colProcesses intReturn = objProcess.Terminate() log("Attempting to kill process (" & strProcess & ") returned error code: " & intReturn & vbCrLf) Next Else log(".Count method returned an unexpected value while attempting to kill: " & strProcess & vbCrLf) End If End Sub Sub spawnProcess(strComputer, strExec) intReturn = objWMIProcess.Create(strExec) Select Case intReturn Case 0 WScript.Echo "Process creation was a success" Case 2 WScript.Echo "Process creation returned Access Denied" Case 3 WScript.Echo "There were insufficient priviledges to complete the process" Case 8 WScript.Echo "Unknown failure" Case 9 WScript.Echo "Path not found" Case 21 WScript.Echo "Invalid Parameter" Case Else WScript.Echo "Process creation returned an unrecognized parameter" End Select End Sub
No comments:
Post a Comment