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