Powershell – Get SCCM Client info from WMI
Last week I was busy with a deployment and this week the question came up “does every server have a SCCM client installed”. My first reaction was “yes” but after a close look at our SCCM sites I wasn’t sure. The problem I had was that there are multiple AD domains linked to multiple SCCM sites, so if one site showed ‘Client=No’ that didn’t mean the server didn’t have a client. It only meant that the server didn’t have a client in that particular site. So only looking at SCCM wouldn’t give me the answer.
What if I would use AD as a source for my search? Dump every computer object into a list and run through that list to obtain information about the client. The challenge with that approach was that AD contains computer objects that are not really computer objects… For instance, if you build a Failover Cluster the cluster itself creates a computer object and also the cluster resources use computer objects. So using AD as a starting point was of the table.
Another possible source was vCenter. As vCenter contains all the (virtual) servers I could use that as a source. A small problem was that in the DTA (Development, Test, and Acceptance) domains a lot of servers were turned off. So I had to use a filter to get the correct list of servers. And I had to filter on the OS of the VM…
The script I finally put together looked like this:
<# .SYNOPSIS Get SCCM client information from WMI(based on vSphere VM's) .DESCRIPTION Use this script if you need to retrieve SCCM client information .PARAMETER vCenterServer Name of the vCenter Server .EXAMPLE .\Get-CMClientInfo.ps1 -vCenterServer 'vcserver.domain.local' Retrieve SCCM client info from all VM's under the vCenter Server vcserver.domain.local .NOTES Script name: Get-CMClientInfo.ps1 Author: Jeroen Buren DateCreated: 06-06-2017 #> [CmdletBinding(SupportsShouldProcess=$true)] param( [parameter(Mandatory=$true,HelpMessage="Name of the vCenter Server")] [ValidateScript({Test-Connection -ComputerName $_ -Count 1 -Quiet})] [string]$vCenterServer ) #---------------------------------------------------------- # STATIC VARIABLES #---------------------------------------------------------- $ProgressCount = 0 $Results = @() #---------------------------------------------------------- # FUNCTIONS #---------------------------------------------------------- function Get-VMFolderPath { Begin {} Process { foreach ($vm in $Input) { $DataCenter = $vm | Get-Datacenter $DataCenterName = $DataCenter.Name $VMname = $vm.Name $VMParentName = $vm.Folder if ($VMParentName.Name -eq "vm") { $FolderStructure = "{0}\{1}" -f $DataCenterName, $VMname $FolderStructure Continue } else { $FolderStructure = "{0}\{1}" -f $VMParentName.Name, $VMname $VMParentID = Get-Folder -Id $VMParentName.ParentId do { $ParentFolderName = $VMParentID.Name if ($ParentFolderName -eq "vm") { $FolderStructure = "$DataCenterName\$FolderStructure" $FolderStructure break } $FolderStructure = "$ParentFolderName\$FolderStructure" $VMParentID = Get-Folder -Id $VMParentID.ParentId } until ($VMParentName.ParentId -eq $DataCenter.Id) } } } End {} } #---------------------------------------------------------- # SCRIPTBODY #---------------------------------------------------------- # Connect to vCenter Server Connect-VIServer -Server $vCenterServer | Out-Null # Select the VMs.. $VMs = Get-VM | Where {($_.PowerState -eq 'PoweredOn') -and ($_.Guest -match 'Microsoft Windows Server')} | Sort-Object -Property Name # ..and count them $ComputerCount = $VMs.Count Foreach ($VM in $VMs) { $ProgressCount++ $Computer = $VM.Name $Folder = $VM | Get-VMFolderPath Write-Progress -Activity "Getting SCCM client information..." -Id 1 -Status "$($ProgressCount) / $($ComputerCount)" -CurrentOperation "$Computer" -PercentComplete (($ProgressCount / $ComputerCount) * 100) #If (Test-Connection -ComputerName $Computer -Count 1 -Quiet) { Try { $ClientVersion = $(Get-WMIObject -Query "SELECT ClientVersion FROM SMS_Client" -Namespace "root/ccm" -Computername $Computer -ErrorAction Stop | Select ClientVersion).ClientVersion $SiteCode = $($([WMIClass]"\\$Computer\root\ccm:SMS_Client").GetAssignedSite() | Select sSiteCode).sSiteCode $Object = [pscustomobject]@{ Computername = $Computer Folder = $Folder SiteCode = $SiteCode ClientVersion = $ClientVersion } $Results += $Object } Catch { $Object = [pscustomobject]@{ Computername = $Computer Folder = $Folder SiteCode = "Unknown" ClientVersion = "Unknown" } $Results += $Object } #} } $Results #| Export-Csv -Path <path to CSV file> -NoTypeInformation # Disconnect from the vCenter Server Disconnect-VIServer -Server $vCenterServer -Confirm:$false