In this post, we’ll run a Powershell script that will perform the client checks we discussed in the last post, against multiple machines that failed to install the ConfigMgr client. Note, all the scripts in these posts are designed to run in Powershell ISE.
Create a Collection for Computers without the SCCM Client
The first thing we need to do is to put all the machines that don’t have the SCCM 2012 client installed into one collection, so we can work with them all at once.
- In the SCCM Console, navigate to Assets and Compliance > Device Collections
- Create a new collection, for example ‘All Computers with no SCCM client installed’
- Give it a query-based rule, and use a query like the following to identify all workstations and servers for that site that have no SCCM 2012 client installed:
- select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where (SMS_R_System.Client is null or SMS_R_System.Client = “0”) order by SMS_R_System.Name
- View the members of the collection and you should see that they all have ‘Client Type’ = ‘None’ and ‘Client’ = ‘No’
Run the Powershell Script
Now that you have the collection, you can run the Powershell script below against that collection.
- You must have local administrator rights to the client computers and you must have read-access to SCCM collections to run this script
- Powershell remoting must be open on the ConfigMgr Site server.
- Open the script in a Powershell ISE. It can be run on your local computer, it will contact the SCCM server remotely so it doesn’t need to be run there
- In the ‘$Collection’ variable, change the name to the name of the collection you created earlier
- Enter your Site server name and Site Code in the variables
- Run the script and view the output in the ISE window
What Does the Script Do?
- First we connect to the ConfigMgr Site server will Powershell remoting and get the members of the collection we created earlier
- We export this into a csv file on the Site server, at C:\Scripts\Staging\ClientCSVs\computernames.csv (change the path as needed)
- We create some local directories to store stuff, then create a second csv file and put some headers in it
- Then we import the members of the first csv, and run checks against all those machines, adding the data to the second csv file. We also copy client logs from the remote machines to the local machine where these are available, so they can be easily viewed from one place
Reviewing the Results
While the script is running it will inform you if a machine is offline, or if it cannot connect to the admin$ share. When the script has completed, it will open the directory containing the files it created, something like this:
The subfolders with the computer names contain the ccmsetup log files from the client machine. You can review these using the CMTrace utility to find any errors.
The report.csv contains the results of the checks against the client machine. Open it in Excel, and filter the ‘Machine is Online’ column to show only those machines that are online.
These results, together with the client log files and the CCM.log on the site server, will help you identify where the problem is occurring with each client.
Since the ConfigMgr Client Push method will attempt to push the SSCM client to the machine every hour for 7 days, if the machine is still not online or the problem is not remediated with the 7 days, you will need to push the client again. This can be done to the entire collection at once using the SCCM Console.
In the next post, we’ll look at some common reasons for client upgrade/installation failure, and how to remediate them.
The Powershell Script
<# This script performs inital client checks on a collection of remote hosts where the SCCM client failed to upgrade/install. #> $Collection = "All Computers with NO SCCM Client Installed" $SiteServer = "PS1sccm-01" $SiteCode = "PS1" ##################################### # Get the members of the collection # ##################################### cls write-host "###########################################" write-host "# ConfigMgr Client Upgrade Failure Script #" Write-Host "###########################################" Write-Host "" write-host "Getting members of '$collection' collection" $s = New-PSSession -ComputerName $SiteServer Invoke-Command -Session $s -Argu $Collection -ScriptBlock ` { param ($Collection) Import-Module 'C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1' $Drive = $SiteCode + ':' cd $Drive $Computernames = @(Get-CMDevice -CollectionName $Collection | Select Name | Sort Name) foreach ($ComputerName in $Computernames) {$ComputerName = $ComputerName.Name $ComputerName | out-file -filepath C:\Scripts\Staging\ClientCSVs\computernames.csv -Append } $Countremote = (Get-CMDevice -CollectionName $Collection | Select Name).Count } $countlocal = Invoke-Command -Session $s -ScriptBlock { $countremote } Remove-PSSession $s write-host "Collection contains $countlocal members" ################################################################ # Create local directories to store files, and create CSV file # ################################################################ # Create Directory for files if doesn't exist if (Test-Path $env:USERPROFILE\ClientLogFiles) {} else { New-Item -Path "$env:USERPROFILE\ClientLogFiles" -ItemType Directory | Out-Null } New-Item -Path "$env:USERPROFILE\ClientLogFiles\$(Get-Date -Format yyyy-MM-dd-HH-mm)" -ItemType Directory | Out-Null $location = "$env:USERPROFILE\ClientLogFiles\$(Get-Date -Format yyyy-MM-dd-HH-mm)" # Create CSV file with headers $headers = "Computer Name,Machine is online?,Can connect to admin$ share?,C:\Windows\CCM folder exists?,C:\Windows\ccmsetup exists?,C:\Windows\ccmsetup\scepinstall.exe,C:\Windows\ccmsetup\Logs exists?" $headers | Out-File -FilePath $location\report.csv -Encoding UTF8 ######################################## # Check each machine in the collection # ######################################## Write-Host 'Getting data for:' $csv = Get-Content \\$SiteServer\c$\Scripts\Staging\ClientCSVs\computernames.csv # Get data for each computer Foreach ($ComputerName in $csv) { $online = $null,$admin = $null,$ccm = $null,$ccmsetup = $null,$scep = $null,$logs = $null $ComputerName # Test connectivity to the computer if (Test-Connection -Quiet -Count 2 -ComputerName $ComputerName -ErrorAction SilentlyContinue) { $Online = "Yes" } else { $Online = "No" Write-host " Offline" -ForegroundColor Gray } # Test admin$ path if ($Online -ne "No") { if (Test-Path \\$ComputerName\admin$) { $admin = "Yes" } else { $admin = "No" Write-host " Cannot connect to admin$ share" -ForegroundColor Red } } # Test CCM folder if ($admin -ne "No") { if (Test-Path \\$ComputerName\C$\Windows\CCM) { $ccm = "Yes" } else { $ccm = "No" } # Test ccmsetup folder if (Test-Path \\$ComputerName\C$\Windows\ccmsetup) { $ccmsetup = "Yes" } else { $ccmsetup = "No" } # Test if scepinstall.exe is present if ($ccmsetup -ne "No") { if (Test-Path \\$ComputerName\C$\Windows\ccmsetup\scepinstall.exe) { $scep = "Yes" } else { $scep = "No" } # Copy ccmsetup logs if (Test-path \\$ComputerName\C$\Windows\ccmsetup\Logs) { $logs = "Yes" } else { $logs = "No" } if ($logs -eq "Yes") { Copy-Item \\$ComputerName\C$\Windows\ccmsetup\Logs $location\$ComputerName\Logs -Recurse } } } ########################### # Output data to CSV file # ########################### $list = "$ComputerName,$online,$admin,$ccm,$ccmsetup,$scep,$logs" $list | Out-File -FilePath $location\report.csv -Encoding UTF8 -Append $online = $null,$admin = $null,$ccm = $null,$ccmsetup = $null,$scep = $null,$logs = $null } # Delete temp csv Remove-Item \\$SiteServer\c$\Scripts\Staging\ClientCSVs\computernames.csv # Open the directory Invoke-Item $location