A Holistic Approach to ConfigMgr Client Health

For ConfigMgr admins and operation teams the struggle for better ConfigMgr client health is very real. The harsh truth is that unless you are managing a small lab with like 50 clients, you are very likely to never reach 100 percent client health (sorry). There will always be machines that simply will not fully cooperate for one reason or another.

In this post you learn about techniques and solutions to improve the number of health clients in your environment. From building your own custom health check solution, to info about community and commercial health check solutions.

The ConfigMgr Client Health Dashboard

What is ConfigMgr Client Health anyway?

Depending on who you ask the answer to this question may vary, but for me it boils down to a few main pillars/questions. In these examples I'm purposely excluding Network Health, as well as generic ConfigMgr Site System Role Health. While they certainly affect the ConfigMgr Client Health, improving those are topics on their own. In these examples I'm simply assuming that the network and server side of ConfigMgr is somewhat working. So here the questions goes:

  • Does all machines that are supposed to have ConfigMgr client installed, actually have it installed?
  • For the machines that do have the ConfigMgr client installed:
    • Is it on the right version? (in general you want the client version to match the production version in your ConfigMgr site)
    • Does it work? (can you send out deployments, receive inventory, run configuration baselines, when online – does it show up as green in the ConfigMgr admin console etc. )
    • Are the clients in the right boundary group? (For example, are they getting content from the right DPs or Peer?)
  • What about generic Windows health:
    • Are you running out of disk space on your clients?
    • Are depending services running and/or configured correctly? (Good example here is the BranchCache service, which has to be configured, and running, for the ConfigMgr client to be able to use BranchCache).

Getting the Real-World numbers

While the ConfigMgr client itself has some built-in health controls that runs on daily schedule (via a scheduled task), they certainly won't help you find problems on machines not having the client installed in the first place. Plus that they typically doesn't gather enough data to get the whole picture of issues in your environments.

To get more and better data points you simply have to gather information outside of the ConfigMgr client, and this is usually done with a bit of PowerShell. In it's simplest approach, it works as follows:

  • On each client and server in the domain that is supposed to have a ConfigMgr agent, you run a script via a GPO or scheduled task.
  • That script gathers data point and store the results in a file share or database.
  • You compile the results in to some sorts of report, spreadsheet, dashboard. Somehow visualizing the information.

Building a Simple Health Check Solution

To give you some inspiration, here is a guide on how you can create your own simple health check solution. In this example I've decided to gather some related data points, and then compile them to a report (Excel). Here is the list of the data points I decided to collect:

  • Computer name
  • Date the data was collected
  • IP address
  • Operating System version
  • Free disk space
  • ConfigMgr client version
  • BranchCache service running
  • Number of files in C:\Windows\Temp (the ConfigMgr client won't install if you have more than 75K files in that folder)
  • Get Microsoft .NET Framework version

Note: The preceding list are just some sample, but valid, data points. We usually capture at least 20-30 more depending on the ConfigMgr environment.

Step 1 – Create a share for the data

On a server in your environment, create a share to store the data reported by the clients, and allow domain computers to write data to it. In this example I created the E:\HealthCheck folder on my site server and shared it as HealthCheck$. In the E:\HealthCheck folder I then created the Clients, Results and Scripts sub folders.

Note: You typically don't need to worry about disk space, each client only stores 1-2 KB of data. So if you have 40K clients, it will only use about 160 MB on disk (assuming a 4 KB cluster size on the NTFS disk volume).

The E:\HealthCheck folder.

Step 2 – Run the data collection script on each client

Find a way to run the data collection script on each client, for example via a daily scheduled task created via Group Policies Preferences. Don't forget to modify the $ExportPath variable in the script to match your folder.

Scheduled task on each client, created by a group policy.

Below you find a script that collects the previously listed data points.

# Where to store the collected data points
$ExportPath = "\\cm01.corp.viamonstra.com\HealthCheck$\Clients"

# Begin data points area

# Get the computer name
$ComputerName = $env:computername

# Get the date
$CollectedDate = Get-Date -Format "dd/MM/yyyy"

# Get the IP address
$IPAddress=((Get-wmiObject Win32_networkAdapterConfiguration | Where-Object{$_.IPEnabled}).IPAddress)

# Get the operating system version
$OSVersion = (Get-WmiObject win32_operatingsystem).version

# Get free disk space on C: in GB
$FreeDiskspaceGB = [math]::Round(((Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='C:'").freespace/1GB),2)

# Get ConfigMgr Client Version
$CMVersion = (Get-WmiObject -NameSpace Root\CCM -Class Sms_Client).clientversion

# Get status of BranchCache service
$BranchCacheServiceStatus = (Get-BCStatus).BranchCacheServiceStatus

# Check C:\Windows\Temp folder
$TempFolder = "C:\Windows\Temp"
$TempFilesCount = ( Get-ChildItem $TempFolder | Measure-Object ).Count

# Get full .NET Framework version
$Version = Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse |
Get-ItemProperty -name Release -EA 0 |
Where { $_.PSChildName -eq "Full"} |
Select PSChildName, Version, Release, @{
      switch -regex ($_.Release) {
        "378389" { [Version]"4.5" }
        "378675|378758" { [Version]"4.5.1" }
        "379893" { [Version]"4.5.2" }
        "393295|393297" { [Version]"4.6" }
        "394254|394271" { [Version]"4.6.1" }
        "394802|394806" { [Version]"4.6.2" }
        "460798|460805" { [Version]"4.7" }
        "461308|461310" { [Version]"4.7.1" }
        "461808|461814" { [Version]"4.7.2" }
        "528040|528049" { [Version]"4.8" }
        {$_ -gt 528049} { [Version]"Undocumented version (> 4.8), please update script" }
$NETFrameworkVersion = $Version.Product.ToString() 

# End data points area

# Export the result to a CSV file
$ExportPath = "$($ExportPath)\$($computername).CSV"
if(test-path -Path $EXPORTPATH) {
    remove-item -path $EXPORTPATH

$Hash = New-Object System.Collections.Specialized.OrderedDictionary
$Hash.Add("IPAddress", $IPAddress[0]) # Only get the first one
$Hash.Add("OSVersion", $OSVersion)
$Hash.Add("FreeDiskspaceGB", $FreeDiskspaceGB)
$Hash.Add("BranchCacheServiceStatus", $BranchCacheServiceStatus)
$Hash.Add("TempFilesCount", $TempFilesCount)
$Hash.Add("NETFrameworkVersion", $FrameworkVersion)

$CSVObject = New-Object -TypeName psobject -Property $Hash
$CSVObject | Export-Csv -Path $ExportPath -NoTypeInformation

After a day or so, you will see clients starting to report in data to the E:\HealthCheck\Clients folder.

Sample CSV file from one client.
Clients reporting in data.

Step 3 – Create the report

Once you see clients reporting in data into the Clients folder, you can run the below script to summarize them into a larger CSV file. Then simply open Excel, and start to look into your data using filters, pivots or other visualization options.

# Where to store the collected data points
$HealthCheckPath = "\\cm01.corp.viamonstra.com\HealthCheck$"
$ts = $(get-date -f MMddyyyy)+$(get-date -f HHmmss)
$ReportFileName = "ConfigMgrClientHealthSummary_$ts.csv"

# Get the CSV files
$CSVFiles = Get-ChildItem -Path "$HealthCheckPath\Clients" -Filter "*.CSV"
Write-Output "Importing $($CSVFiles.count) CSV files. Sit tight, may take a while..."
Write-Output ""

# Export to a report
foreach ($CSVFile in $CSVFiles){
    (Import-CSV -Path $CSVFile.FullName) | Export-CSV -Path "$HealthCheckPath\Results\$ReportFileName" -NoTypeInformation -Append 

After running the above script you get a larger CSV file that you can open in Notepad, Excel, import into Power BI etc.

Five CSV files imported into a larger CSV file (the report)
CSV Report opened in Excel, and filter applied.

More ConfigMgr Client Health Check Solutions

As mentioned in the introduction there are bigger/better solutions out there. With the script sample provided here, I was just giving ideas on how data points can be collected fairly quickly.

Anders Rodland – ConfigMgr Client Health

Anders Rodland is known for his ConfigMgr Client Health solution. Read more on Anders site:

Microsoft PFE Client Health Tool

A team of Microsoft PFE's is also maintaining a solution called the PFE Client Health Tool. This is not a free tool, and is delivered as part of an engagement with Microsoft.

About the author

Johan Arwidmark

0 0 vote
Article Rating
Notify of
Oldest Most Voted
Inline Feedbacks
View all comments
1 year ago

Thanks Johan, great post.

I feel like this is an area Microsoft could offer more help with. In particular I don't think they should really be charging people with software assurance for the privilege of using the client health tool. I get that many of the issues admins face are environmental, even self-inflicted, but I don't think they should be paying again to access a troubleshooting tool. I believe they should charge for the implementation but not for access to the tool itself. I mean, we get lots of cool new features through current branch, why not this?