There are a lot of ways to install the SCCM client: automatic client push, push via the console, GPOs and many more. I will be sharing here a simple PowerShell script meant to be run interactively. The script will install the SCCM client using a batch file stored on a file share accessible to all machines.
PSExec is part of Microsoft Windows Sysinternals PsTools and can be obtained here. For those who are not familiar with it, it is a powerful tool used to remotely execute commands on remote machines. It should be placed in an Execution subfolder compared to where the PowerShell script is placed, otherwise, modify the code to point to where PSExec is actually located.
The full script is below. Many lines have comments in them to make the script easy to read. I will further explain some code as well. Watch out for the & sign being converted to & by WordPress:
Do { $ListOrManual = Read-Host "Would you like to run the script using an input list or manual entry? (L)ist/(M)anual" if ($ListOrManual -eq 'L') #If user chooses to use an input list { $TestList = Test-Path .\Machines.txt #Tests if the input list is present if ($TestList) { $Date = Get-Date -Format yyyy.MM.dd-HH.mm.ss #Formats the date at script runtime to rename and move pre-existing files in order to avoid deleting potentially needed lists from previous runs Rename-Item -Path .\Output\Success.txt -NewName Success-$Date.txt -ErrorAction SilentlyContinue Rename-Item -Path .\Output\Failure.txt -NewName Failure-$Date.txt -ErrorAction SilentlyContinue Move-Item .\Output\*.txt .\Output\Archive $PSExec = ".\Execution\PSExec.exe" $ComputersList = Get-Content .\Machines.txt #Parse the input list and populate it in ComputersList $ComputersCount = $ComputersList.Count Write-Host "You are attempting to install the CM 2012 client on " -NoNewLine; Write-Host "$ComputersCount devices." -ForegroundColor Yellow $Confirm = Read-Host "Are you sure you want to proceed? Y/N" #Confirmation required to proceed if ($Confirm -eq 'Y') { $FailureCount = 0 $SuccessCount = 0 foreach ($Computer in $ComputersList) #Loop for each item in the input list { Write-Host "Running CM installation on $Computer" Remove-Item "\\$Computer\Admin$\System32\Tasks\Microsoft\Microsoft\Configuration Manager\Configuration Manager Client Retry Task" -ErrorAction SilentlyContinue #Removes the CM 2012 Client Retry Task that may be present due to a bug in CM2012 R2 Pre-SP1 &$PSExec -s \\$Computer cmd /c \\$ServerHostingClientFiles\CMClient_Install\Inst_CM.cmd 2>$Var | Out-Null #PSExec will target the current machine in the list and run the CM manual client install script in SYSTEM context, PSExec output redirected to lala land if ($LastExitCode -Eq 0) { $Computer | Out-File -Encoding ascii -Append .\Output\Success.txt #PSExec succeeded in copying the files and launching setup on the target machine Write-Host "CM installation " -NoNewLine; Write-Host "was successfully launched" -ForegroundColor Green -NoNewLine; Write-Host " on $Computer" Write-Host "--------------------------------------------------" $SuccessCount++ } else { $Computer | Out-File -Encoding ascii -Append .\Output\Failure.txt #PSExec failed in copying the files and launching setup on the target machine Write-Host "CM installation " -NoNewLine; Write-Host "could not be launched" -ForegroundColor Red -NoNewLine; Write-Host " on $Computer" Write-Host "--------------------------------------------------" $FailureCount++ } } Write-Host "Finished executing on " -NoNewLine; Write-Host "$ComputersCount devices:" -ForegroundColor Yellow -NoNewLine; Write-Host " $SuccessCount installation(s) succeeded, " -ForegroundColor Green -NoNewLine; Write-Host "$FailureCount installation(s) failed." -ForegroundColor Red Pause } else { Write-Host "CM2012 client installation aborted by user!" Pause } } else { Write-Host "The Machines.txt list is missing. Make sure the file exists and is populated." #If Machines.txt list is missing, inform the user running the script accordingly Pause } } if ($ListOrManual -eq 'M') #If user chooses to use manual target entry { $Target = Read-Host "Please input target machine name" #Takes from the user the target device to deploy to $PSExec = ".\Execution\PSExec.exe" Remove-Item "\\$Target\Admin$\System32\Tasks\Microsoft\Microsoft\Configuration Manager\Configuration Manager Client Retry Task" -ErrorAction SilentlyContinue #Removes the CM 2012 Client Retry Task that may be present due to a bug in CM2012 R2 Pre-SP1 &$PSExec -s \\$Target cmd /c \\$ServerHostingClientFiles\CMClient_Install\Inst_CM.cmd 2>$Var | Out-Null #PSExec will target the current machine in the list and run the CM manual client install script in SYSTEM context, PSExec output redirected to lala land if ($LastExitCode -Eq 0) { Write-Host "CM installation " -NoNewLine; Write-Host "was successfully launched" -ForegroundColor Green -NoNewLine; Write-Host " on $Target" Write-Host "--------------------------------------------------" } else { Write-Host "CM installation " -NoNewLine; Write-Host "could not be launched" -ForegroundColor Red -NoNewLine; Write-Host " on $Target" Write-Host "--------------------------------------------------" } Pause } if ($ListOrManual -ne "L" -and $ListOrManual -ne "M") #If user made a wrong selection { Write-Host "Incorrect selection made. Please input either 'L' to use a list or 'M' for manual entry ..." } $Retry = Read-Host "Would you like to run the script again? Y/N" #Rerun script if desired } While ($Retry -eq 'Y') Write-Host "Have a good day!" Pause
The script first asks the user(s) running it if they would like to use a list of machines as input or specify a single manual entry to install the SCCM client on.
If the user chooses to use a list input, the script checks for the presence of a file named Machines.txt that should be located in the same folder as the PowerShell script. The script then renames output log files from previous runs to avoid overwriting them, retrieves all the machine names from the Machines.txt file and asks the user for confirmation before proceeding since the number of machines could be large.
If the user confirms, the script will perform two actions. The first is to attempt to remove a scheduled task which is present due to a bug in SCCM 2012 R2 for versions prior to SP1.
Remove-Item "\\$Computer\Admin$\System32\Tasks\Microsoft\Microsoft\Configuration Manager\Configuration Manager Client Retry Task" -ErrorAction SilentlyContinue
The scheduled task is named Configuration Manager Client Retry Task and the bug probably exists due to an oversight that places this scheduled task in the scheduled tasks folder Microsoft\Microsoft\Configuration Manager instead of Microsoft\Configuration Manager where all the other SCCM client related tasks are.
Microsoft confirmed that this behavior has been fixed in SCCM 2012 R2 SP1. Unfortunately, they also confirmed that no hotfix exists for pre-SP1 version, you either have to fix it manually as the script does, or upgrade to SP1 to squash the bug. As Windows 10 becomes more relevant, you would want to upgrade to SP1 (and CU2) soon in all cases.
In the next step, the PowerShell script uses PSExec to remotely execute the batch file responsible for installing the SCCM client. The batch file consists of ccmsetup.exe with any additional parameters that are needed in your environment. We used the batch file as well to copy all the client setup content locally before launching ccmsetup in our environment. The script will monitor the return from PSExec to determine if the setup was successfully launched on the target machine.
if ($LastExitCode -Eq 0)
If the exit code was ‘0’, PSExec remote execution was successful, if not, it failed in launching the SCCM client setup. The script will track the number of successes and failures and will report at the end of the execution the total numbers.
Manual entry is similar in behavior, it will ask the user to input a machine’s name and will proceed to perform the same two actions and monitor PSExec remote execution attempt. In the end, the user running the script is asked if they would like to run the script again or exit the session.
As you can see, the script is simple in nature and there is a lot of room for improvements if desired. For example, parallel execution can be implemented to speed up the process of installing numerous SCCM clients or log files for SCCM client setup can be monitored. Feel free to improve the script as you wish.
9 responses to “SCCM Client Installation using PowerShell and PSExec”
$LastExitCode -Eq 0
This only mean client installation was started successfully.
How to find if the installation was completed successfully?
How to check and bypass machines which already have SCCM installed?
How to uninstall SCCM before installing? (For troubleshooting issues)
Any help will be appreciated!
Correct, this only indicates that it was launched successfully, nothing more. To check whether it finished successfully, you can for example modify the script to wait for the installation to finish and check ccmsetup’s last line, or you can create another script that parses the list of machines that successfully launched the setup (in success.txt) and check ccmsetup.log on them.
For checking if the client is already installed, there are several ways, you can query remotely to check if SMS Agent Host service is running or check ccmsetup or check the presence of core file or check the registry for CCM, and many others. You can even combine some of those methods if you wish. For uninstalling, integrate your modifications to detect if the client is already installed and remotely launch via PSExec ccmsetup.exe /uninstall.
Let me know if you need further help or some code snippets for this.
Great script, thank you so much. However, where is the batch file? Did you post it here or we have to create one. Again, thank you.
You’re welcome. The batch file contents are nothing specific really, they can be anything you want, for example it contain a command to copy all client installation files locally and launch ccmsetup.exe while specifying the local source along with whatever other parameters you want. The only thing that actually needs to be in that batch is ccmsetup.exe along with whatever parameters you want.
need PowerShell command(Instead of below) to run sccm client installation for local host
this is bash command: ccmsetup.exe SMSMP=CONTOSO.COM SMSSiteCode=SVR DISABLESITEOPT=TRUE
What do you mean you need the PowerShell command for that?
This is the CM Client installer, you can execute that command in any script.
Hello, I am not expert on PowerShell and learning lot, script looks great but I am getting following errors messages. Any idea or why ? Help will be appreciated.
C:\Users\AnantBhagat\Documents\CMInstall\PSExec.exe : The handle is invalid.
At C:\Users\AnantBhagat\Documents\CMInstall\Untitled1.ps1:33 char:1
+ C:\Users\AnantBhagat\Documents\CMInstall\PSExec.exe -s \\$Computer cm …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (The handle is invalid.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Connecting to Desktop-0o441nm…Couldn’t access Desktop-0o441nm:
Connecting to Desktop-0o441nm…
New message:
At C:\Users\AnantBhagat\Documents\CMInstall\Untitled1.ps1:33 char:14
+ &$PSExec -s \\$Computer cmd /c \\$Computer cmd /c C:\Users\AnantB …
+ ~~
Unexpected token ‘-s’ in expression or statement.
At C:\Users\AnantBhagat\Documents\CMInstall\Untitled1.ps1:33 char:17
+ &$PSExec -s \\$Computer cmd /c \\$Computer cmd /c C:\Users\AnantB …
+ ~~~~~~~~~~~
Unexpected token ‘\\$Computer’ in expression or statement.
At C:\Users\AnantBhagat\Documents\CMInstall\Untitled1.ps1:33 char:109
+ … md /c C:\Users\AnantBhagat\Documents\CMInstall\Inst_CM.cmd 2>$Var …
+ ~
The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double quotation marks
(“&”) to pass it as part of a string.
At C:\Users\AnantBhagat\Documents\CMInstall\Untitled1.ps1:72 char:14
+ &$PSExec -s \\$Target cmd /c \\$Target cmd /c C:\Users\AnantBhaga …
+ ~~
Unexpected token ‘-s’ in expression or statement.
At C:\Users\AnantBhagat\Documents\CMInstall\Untitled1.ps1:72 char:17
+ &$PSExec -s \\$Target cmd /c \\$Target cmd /c C:\Users\AnantBhaga …
+ ~~~~~~~~~
Unexpected token ‘\\$Target’ in expression or statement.
At C:\Users\AnantBhagat\Documents\CMInstall\Untitled1.ps1:72 char:105
+ … md /c C:\Users\AnantBhagat\Documents\CMInstall\Inst_CM.cmd 2>$Var …
+ ~
The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double quotation marks
(“&”) to pass it as part of a string.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken
It’s running fine on my end. Double check the copied code, it was probably auto-formatted incorrectly in the post, & should be & and > should be >