Below I’ve built this custom script that will completely remove the SCCM Client and wait until all processes have stopped. Once it’s uninstalled it will also remove any residual files left from a previous install and then run a fresh install of the client. In order for this script to work you must place it in the same directory as the setup files for the SCCM client. Then open up a PowerShell prompt as an Administrator and type the following command:
PowerShell.exe -ExecutionPolicy ByPass ".\Invoke-SCCM-Client-Install.ps1" -Wait
The following values have to be amended to work in your environment:
"ccmsetup.exe /forceinstall /mp:[SCCM SERVER NAME] INSTALL=ALL SMSPROVISIONINGMODE=1 SMSSITECODE=[SCCM SITE CODE] FSP=[Fallback Status Point Name -- Optional Switch] /NoCRLCheck"
After the script runs you can keep track of the script process by opening another PowerShell window and typing the following command:
Get-Content $env:SystemRoot\System32\LogFiles\OSD\SCCM-Client\[Press "Tab" Key for LogFile Name] -Wait
# Script: Invoke-SCCM-Client-Install.ps1
# Description: Uninstalls current SCCM Client and Installs new Client.
# Execution: PS> PowerShell.exe -ExecutionPolicy ByPass ".\Invoke-SCCM-Client-Install.ps1" -WindowStyle Hidden -Wait
# Author: Harry Caskey // harrycaskey@gmail.com // www.harrycaskey.com
# Last Modified: 2017-04-20
#
$logPath = "$env:SystemRoot\System32\LogFiles\OSD\SCCM-Client"
New-Item -Path $logPath -Type Directory -Force | Out-Null
$timeDate = Get-Date -Format "yyyyMMdd-HHmmss"
$logFileName = $env:COMPUTERNAME + "_" + $timeDate
#
New-Item -Path $logPath -Type Directory -Force | Out-Null
#
#
$procMsiExec = Get-Process -Name msiexec -ErrorAction SilentlyContinue
$procCCMExec = Get-Process -Name ccmexec -ErrorAction SilentlyContinue
$procCCMSetup = Get-Process -Name ccmsetup -ErrorAction SilentlyContinue
#
#
if ($procMsiExec -or $procCCMExec -or $procCCMSetup) {
Stop-Service -Name CcmExec -Force | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
"Processess have been stopped. Executing ccmsetup.exe /uninstall command..." | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
Start-Process "ccmsetup.exe" -ArgumentList "/uninstall" -Wait | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
Start-Sleep 15
do {
Start-Sleep 10
"Uninstall is running..." | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
$procMsiExec = Get-Process -Name msiexec -ErrorAction SilentlyContinue
$procCCMExec = Get-Process -Name ccmexec -ErrorAction SilentlyContinue
$procCCMSetup = Get-Process -Name ccmsetup -ErrorAction SilentlyContinue
Start-Sleep 5
}
until (($procMsiExec -eq $null) -and ($procCCMExec -eq $null) -and ($procCCMSetup -eq $null))
"Uninstaller has completed..." | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
}
else {
"No processess are currently started. Executing the uninstaller now..." | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
Start-Process "ccmsetup.exe" -ArgumentList "/uninstall" -Wait | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
Start-Sleep 15
do {
Start-Sleep 10
"Uninstall is running..." | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
$procMsiExec = Get-Process -Name msiexec -ErrorAction SilentlyContinue
$procCCMExec = Get-Process -Name ccmexec -ErrorAction SilentlyContinue
$procCCMSetup = Get-Process -Name ccmsetup -ErrorAction SilentlyContinue
Start-Sleep 5
}
until (($procMsiExec -eq $null) -and ($procCCMExec -eq $null) -and ($procCCMSetup -eq $null))
Remove-Item $env:SystemRoot\CCM, $env:SystemRoot\ccmsetup, "$env:SystemDrive\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft System Center" -Recurse -Force -ErrorAction Ignore
Remove-Item HKLM:\SOFTWARE\Microsoft\CCMSetup -Force -ErrorAction Ignore
"SCCM Client removed..." | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
}
#
#
Start-Sleep -Seconds 15
$procMsiExec = Get-Process -Name msiexec -ErrorAction SilentlyContinue
$procCCMExec = Get-Process -Name ccmexec -ErrorAction SilentlyContinue
$procCCMSetup = Get-Process -Name ccmsetup -ErrorAction SilentlyContinue
#
#
"Starting SCCM Client install..." | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
Start-Process "ccmsetup.exe" -ArgumentList "ccmsetup.exe /forceinstall /mp:[SCCM SERVER NAME] INSTALL=ALL SMSPROVISIONINGMODE=1 SMSSITECODE=[SCCM SITE CODE] FSP=[Fallback Status Point Name -- Optional Switch] /NoCRLCheck" -Wait | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
do {
Start-Sleep 10
"Installing SCCM Client..." | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
$procMsiExec = Get-Process -Name msiexec -ErrorAction SilentlyContinue
$procCCMSetup = Get-Process -Name ccmsetup -ErrorAction SilentlyContinue
Start-Sleep 5
}
until (($procMsiExec -eq $null) -and ($procCCMSetup -eq $null))
Start-Sleep 120
#
Restart-Service -Name CcmExec
Start-Sleep 120
#
# Machine Policy Retrieval Cycle
Invoke-WMIMethod -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule "{00000000-0000-0000-0000-000000000021}" | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
Start-Sleep 10
# Machine Policy Evaluation Cycle
Invoke-WMIMethod -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule "{00000000-0000-0000-0000-000000000022}" | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
Start-Sleep 10
# Application Deployment Evaluation Cycle
Invoke-WMIMethod -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule "{00000000-0000-0000-0000-000000000121}" | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
Start-Sleep 10
# State Message Refresh
Invoke-WMIMethod -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule "{00000000-0000-0000-0000-000000000111}" | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
Start-Sleep 10
# Hardware Inventory Cycle
Invoke-WMIMethod -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule "{00000000-0000-0000-0000-000000000001}" | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
Start-Sleep 10
#
#
"Finished installing SCCM Client..." | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force
$procCCMExec = Get-Process -Name ccmexec
$procCCMExecStatus = $procCCMExec.ProcessName
if ($procCCMExecStatus) {"CCMExec: Enabled" | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force}
else {"CCMExec: Disabled" | Out-File -FilePath $logPath\$logFileName.log -Append -Encoding ascii -Force}
# Clean Up Process
Remove-Variable procMsiExec, procCCMExec, procCCMSetup, logPath, logFileName -Force
2 Replies to “SCCM Client Repair by Removal and Install”
Hi Harry,
I just wanted to let you know that I ran your script with the modifications you specified and it ran flawlessly. The client is on a Dell E6430 running an i5 with RAM upgraded to 8GB and a 120GB SSD as the primary drive running Windows 10 Education x64 v1803. The server is Windows Server 2016 running System Center Configuration Manager 2016 Version 5.00.8634.1000, Build number 8634. This is on a single site network with three global catalogs and one domain. The client had previously been failing to acquire a working client even after running ccmsetup.exe with /uninstall, rebooting after completion, and running ccmsetup.exe with the management point specified and /forceinstall included. Thank you so much!
I already had something pretty solid but this gave me some good ideas regarding monitoring for the closure of msiexec, etc.
Thanks!