SCCM Client Repair Script

I’m periodically tasked to identify and attempt to repair computers with SCCM client issues. How I identity problem computers is a subject for another post, but for now I’d just like to share the method I use to repair those clients that need attention.

In my experience, probably about 80% of SCCM client-related issues (maybe higher) are resolved by performing one or all of the following:

  1. A full uninstall and reinstall of the SCCM client
  2. Repairing or rebuilding the WMI Repository
  3. Repairing or re-registering the Windows Update Agent components

Rather than do these manually, I decided to write a script that will perform some basic checks to evaluate the client’s health and then take appropriate actions to attempt any necessary repairs. The script allows me to then leverage other tools like PsExec to run repairs remotely and on multiple computers simultaneously.

If you’d like to skip the details and get right to the code, the script is named SCCM_Client_Repair.vbs and can be found over in my script repository on GitHub


Now for some more details about the script and what it’s doing.

There are plenty of good SCCM client repair scripts out there, but I decided to write my own mainly for two reasons:

  1. Practice
  2. I wanted precise control over what actions are taken and under what circumstances

For reference, I used the following blog posts from Microsoft to determine what specific actions to take to perform each task:


There are a couple of variables that need to be changed to match your environment before the script can be executed.

strClientSharePath – Set this to the full UNC path to ccmsetup.exe on your SCCM client share (e.g. \\SiteServer\client\ccmsetup.exe)
strSMSSiteCode – Set this to your SCCM site code. Will be used for the “SMSSITECODE=” argument when reinstalling the SCCM client.
strSMSInstallArgs – Change this to customize the parameters passed to ccmsetup to reinstall the SCCM client. Default value is “/BITSPriority:LOW SMSSITECODE=MySiteCode”.
strLogFilePath = Change this if you want the log file to be written to a different location. Default value is “C:\Windows\Temp\SCCMClientRepair.log”.

The script accepts several arguments to help control the aggressiveness of the repair operations and it’s verbosity.

There are three execution modes: reinstall, lite, and full. I’ll get into more details about what each mode does below, but you can pass the name of the mode you want to use as an argument when calling the script. For example:

C:\Windows\System32\cscript.exe SCCM_Client_Repair.vbs full

If you do not specify a mode and just run the vbs with no arguments, it will default to “lite” mode.

By default, when the script is complete it will create and present a dialog box stating that the execution has finished and the error code returned, if any. If you wish to run the script silently and with no prompt at the end, use the “quiet” parameter. For example:

C:\Windows\System32\cscript.exe SCCM_Client_Repair.vbs quiet

You can also combine the two. So if you want to run the script in reinstall mode with no prompt at the end, simply run:

C:\Windows\System32\cscript.exe SCCM_Client_Repair.vbs reinstall quiet

Execution Modes

As stated above, the script has three modes that perform increasingly aggressive repair operations.


The reinstall mode will perform a full uninstall of the SCCM client per the referenced documentation, then simply reinstalls the client when finished.


After uninstalling the SCCM client, will perform the following:

  1. Attempt to verify the health of the WMI Repository by connecting to common namespaces and running a few simple queries.
  2. If any of the WMI health checks fail, will attempt a repair by running “winmgmt /salvagerepository
  3. Rename the C:\Windows\SoftwareDistribution folder to reset Windows Update components.
  4. Reinstall the SCCM client

After uninstalling the SCCM client, will perform the following:

  1. Skip the health analysis and perform a rebuild of the WMI Repository, per the referenced documentation
  2. Perform a full reset of Windows Update components, per the referenced documentation.
  3. Reinstall the SCCM client.

Note that I added safeguards so that FULL mode cannot be executed on server OSes. If you attempt to run the script in FULL mode on a server, the argument will be overwritten and the script will run in “lite” mode instead.

Troubleshooting and additional notes

  • If the script is unable to locate ccmsetup.exe at the UNC path specified in variable strClientSharePath, it will search for it in the script’s execution directory. This allows the script to be bundled in with the SCCM client’s setup files for offline/remote execution.
  • If ccmsetup.exe cannot be located in any of the expected locations, the script will exit with error code 3202.
  • After running ccmsetup.exe to reinstall the SCCM client, the script will attempt to verify the installation was able to complete successfully. If these checks timeout or if ccmexec is not found in the list of running processes after setup has completed, the script will exit with error code 3201.
  • While the script is running, I recommend monitoring the log file with CMTrace to see a detailed status of the execution.

Once again, the script is named SCCM_Client_Repair.vbs and can be founder over in my script repository on GitHub.


Announcing the MacGyverIT Script Repository

I’ve been searching for quite a while for the best way to share some of the scripts that I’ve written over the years, and today I’d like to finally announce the MacGyverIT Script Repository on GitHub!

For now there isn’t a ton of content but I’ll be continuing to add more, and more complex, scripts as time goes on so please check back often. I’ll also be creating dedicated posts for some of the more complex scripts once they’re available to provide more details.

Obligatory Disclaimer: Please note that I’m sharing these scripts for reference only, and I am not offering any guarantees or support. All scripts were developed, tested, and executed in the specific computing environments for which they were intended. If you’d like to copy and reuse any of the code in the Script Repository, please test it thoroughly in an isolated environment and make changes as necessary. I’ve tried to include links to all the sources and references I used where applicable, so I just ask that you please do the same if you choose to use any of my original code.

Windows 10 Build Numbers

I find myself needing to look up the Windows 10 build numbers more often than I care to admit, so I figured I might as well post them here. Very useful for SCCM queries or scripts that take action depending upon the OS build.

Windows 10 release information

  • Windows 10 1709 (OS build 16299)
  • Windows 10 1703 (OS build 15063)
  • Windows 10 1607 (OS build 14393)
  • Windows 10 1511 (OS build 10586)
  • Windows 10 1507 (OS build 10240)

In SCCM, the build number can be queried via the Operating System.Build Number attribute. For example, to get all computers running Windows 10 1703:


select SMS_R_System.Name from SMS_R_System inner join SMS_G_System_OPERATING_SYSTEM on SMS_G_System_OPERATING_SYSTEM.ResourceID = SMS_R_System.ResourceId where SMS_G_System_OPERATING_SYSTEM.BuildNumber = "15063"

The build number can also be retrieved locally by querying WMI or the system Registry.


Select BuildNumber from Win32_OperatingSystem

wmic os get buildnumber


REG QUERY "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentBuild

REG QUERY "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentBuildNumber

BitLocker – Determining Non-Compliance Reasons for MBAM Clients

Here’s a useful article from Microsoft on determining non-compliance reasons for MBAM 2.5 clients.

Determining why a Device Receives a Noncompliance Message

Basically, it describes how to query the non-compliance code and provides reference for what each code means. You can then use this data to troubleshoot and take corrective action as needed.


gwmi -class mbam_volume -Namespace root\microsoft\mbam


wmic /namespace:\\root\microsoft\mbam path MBAM_Volume where "VolumeName like 'C:%'" get ReasonsForNoncompliance


Namespace: root\Microsoft\MBAM

Select ReasonsForNoncompliance from MBAM_Volume where VolumeName like 'C:%'


Non-compliance Codes

0 – Cipher strength not AES 256.

1 – MBAM Policy requires this volume to be encrypted but it is not.

2 – MBAM Policy requires this volume to NOT be encrypted, but it is.

3 – MBAM Policy requires this volume use a TPM protector, but it does not.

4 – MBAM Policy requires this volume use a TPM+PIN protector, but it does not

5 – MBAM Policy does not allow non TPM machines to report as compliant.

6 – Volume has a TPM protector but the TPM is not visible (booted with recover key after disabling TPM in BIOS?).

7 – MBAM Policy requires this volume use a password protector, but it does not have one.

8 – MBAM Policy requires this volume NOT use a password protector, but it has one.

9 – MBAM Policy requires this volume use an auto-unlock protector, but it does not have one.

10 – MBAM Policy requires this volume NOT use an auto-unlock protector, but it has one.

11 – Policy conflict detected preventing MBAM from reporting this volume as compliant.

12 – A system volume is needed to encrypt the OS volume but it is not present.

13 – Protection is suspended for the volume.

14 – AutoUnlock unsafe unless the OS volume is encrypted.

15 – Policy requires minimum cypher strength is XTS-AES-128 bit, actual cypher strength is weaker than that.

16 – Policy requires minimum cypher strength is XTS-AES-256 bit, actual cypher strength is weaker than that.


VMware Horizon – Preparing a Gold Master VM for Cloning

As a follow up to an older post,  Prepare Windows 7 Gold Master Virtual Machine for Cloning, below is a quick batch script that I use to prepare my Windows gold VMs just before creating a snapshot and recomposing my pools.

I’ve added a few commands for my environment, but credit to this blog for the framework:

This script has been tested on the following platforms:

  • Windows 10 Enterprise 1511
  • Windows 10 Enterprise 1607
  • Windows 10 Enterprise 1607 LTSB
  • Windows 10 Enterprise 1703

I have not tested it on Windows 7/8/8.1, but I imagine it will work fine on those platforms as well.

In summary, when executed the script will:

  1. Execute all queued .NET framework items
  2. Disable the Windows Update Service
  3. Configures the AppVolumes Service for automatic start, if applicable
  4. Delete all shadow copies
  5. Delete cached Windows Update downloads
  6. Delete hidden install files
  7. Delete prefetch files
  8. Run Disk Cleanup
  9. Defragment the disk
  10. Rearm Office 2016 activation, if applicable
  11. Clear the Windows Event Logs
  12. Release the currently assigned IP address
  13. Flush the local DNS cache
  14. Shut down the VM

Script code:

REM Copy this code into a blank txt file and then rename the file to VMCleanup.bat
REM Copy VMCleanup.bat to your Gold Master VM and run as an admin just before creating a snapshot
REM *****************************************************
REM Execute queued .NET Framework items
C:\Windows\Microsoft.NET\Framework\v2.0.50727\ngen.exe executeQueuedItems
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\ngen.exe executeQueuedItems
REM *****************************************************
REM Stop and Disable the Windows Update Service
sc stop wuauserv
sc config wuauserv start= disabled
REM *****************************************************
REM Set AppVolumes Service to automatic start
sc config svservice start= auto
REM *****************************************************
REM Delete shadow copies
vssadmin delete shadows /All /Quiet
REM *****************************************************
REM Delete all cached Windows Update downloads
del c:\Windows\SoftwareDistribution\Download\*.* /f /s /q
REM *****************************************************
REM Delete hidden install files
del %windir%\$NT* /f /s /q /a:h
REM *****************************************************
REM Delete prefetch files
del c:\Windows\Prefetch\*.* /f /s /q
REM *****************************************************
REM Run Disk Cleanup. Runc:\windows\system32\cleanmgr /sageset:1 and check
REM desired options before running
c:\windows\system32\cleanmgr /sagerun:1
REM *****************************************************
REM Defragment the disk
sc config defragsvc start= auto
net start defragsvc
defrag c: /U /V
net stop defragsvc
sc config defragsvc start = disabled
REM *****************************************************
REM Rearm Microsoft Office 2016 activation
"C:\Program Files (x86)\Microsoft Office\Office16\OSPPREARM.exe"
REM *****************************************************
REM Clear Windows Event Logs
wevtutil el 1>a.txt
for /f %%x in (a.txt) do wevtutil cl %%x
del a.txt
REM *****************************************************
REM Release IP address
ipconfig /release
REM *****************************************************
REM Flush DNS cache
ipconfig /flushdns
REM *****************************************************
REM Shutdown the VM
shutdown -s -f -t 15


Disclaimer: Scripts on this blog are provided as-is and I offer not support for them. All scripts were written for and tested in the specific environment for which they were intended for use, and are in no way guaranteed. Always test scripts in an isolated environment and please feel free to make modifications as needed. I also acknowledge that there may be alternate and/or more efficient ways to write these scripts and accomplish the same tasks, and I welcome suggestions and feedback.

Using Group Policy Preferences with Older Versions of Windows was doing some testing with a newly created GPO that used Group Policy Preferences (GPP) to add a user account to the local administrators group, and I noticed that the policy seemed to apply properly to all of my Server 2012 and 2008 systems but not on any Server 2003 machines.

I did some research and came across an article on Microsoft’s Group Policy blog that shined some light on my issue:

Group Policy Preferences Not Applying on Some Clients: Client-Side Extension, XMLLite

The gist of it is that I needed to install the proper Client-Side  Extensions (CSEs) for Server 2003. All of the links for the individual OSes and versions are in the MS blog post, but the specific one I needed is below.

CSEs for Windows Server 2003 with SP1 or later (32-bit)

You may also need to install XMLLite in addition to the CSEs, but to quote the post:

“XMLLite is not needed if:

· Your clients run Windows Server 2008 or Windows Vista.

· Your clients Windows XP and Windows Server 2003 clients run Internet Explorer 7 and/or the latest service packs.”

After installing the CSEs on my machines, they started processing the GPPs normally.

Drop Down

As a side-note for anyone interested; The GPP to add user accounts to local groups is located under Computer Configuration -> Preferences -> Control Panel Settings -> Local Users and Groups.

To modify a local group, right-click and select New – > Local Group, choose Update as the action, pick a group from the Group Name drop down menu, in my case Administrators (built-in) (make sure to use the drop down and not the ellipses button; see image), and then use the Add button at the bottom of the window to add either local or domain accounts to that group.

Most of the guides I’ve found suggest using Computer Configuration\Policies\Windows Settings\Security Settings\Restricted Groups to add users to the local administrators group, but this policy acts to replace any existing memberships rather than merge with them, so keep this in mind if you have Group Policy Objects linked at higher OUs which add users to the same groups. If you want to preserve the existing memberships, consider using GPPs to make the modifications instead.


Alt Methods to Fix: “The Trust Relationship Between This Workstation and the Primary Domain Failed”


For any Windows admin, this error is a familiar sight.

The typical fix, and Microsoft’s recommended resolution, is to log in with a local admin account, join the system to a workgroup, and then rejoin it to the domain.

However, I ran into this blog post a while back which details some cool alternative methods and saved the link in case it should come in handy some day, which it has on several occasions.

DON’T REJOIN TO FIX: The trust relationship between this workstation and the primary domain failed

Basically, he lists two distinct methods for resetting the computer password:

  1. use netdom.exe

netdom.exe resetpwd /s:<server> /ud:<user> /pd:*

<server> = a domain controller in the joined domain

< user> = DOMAIN\User format with rights to change the computer password

“Where you get netdom.exe depends on what version of Windows you’re running.”

“On Windows Vista and Windows 7 you can get it from the Remote Server Administration Tools (RSAT).”

Download RSAT for Windows 7 SP1 here

Download RSAT for Windows 8.1 here

You can read some additional notes about this method in the blog post. (link here)

  1. via Powershell

Reset-ComputerMachinePassword [-Credential <PSCredential>] [-Server <String>]

“You can use the Get-Credential cmdlet for a secure way to generate a PSCredential, which can be stored in a variable and used in a script.  You will want to generate a credential for an Active Directory user with sufficient rights to change the computer’s password.  The Server parameter is the domain controller to use when setting the machine account password.”

Here’s a TechNet article on the Reset-ComputerMachinePassword command for additional reference.


SCCM 2012 R2 Client Installation Fails on Windows Server 2003

If your environment is like mine, you may be forced to manage some legacy systems with Configuration Manager, some of which may be running older operating systems like Windows Server 2003.

You may also find that the SCCM client refuses to install on Server 2003.

Luckily, the fix is easy enough. The SCCM client requires BITS 2.5 to be installed as a prerequisite. You can download BITS 2.5 for Windows Server 2003 here.

After downloading and installing BITS 2.5 on your Windows Server 2003 systems, you should be able to deploy the SCCM client without a problem.


SCCM Not installing 2012 SP1 client on Server 2003 clients

SCCM 2012 and Server 2003×64\XPx64


SCCM 2012 R2 – Error When Running Reports – UserTokenSIDS: A Specified logon session does not exist



After installing my SCCM 2012 R2 Primary Site, I attempted to test out the reporting feature and kept running into the following error when trying to run any of the built-in reports:

The DefaultValue expression for the report parameter ‘UserTokenSIDs’ contains an error: a specified login session does not exist. It may already have been terminated.

I did some research and eventually tied it back to my SQL Server Reporting Services (SSRS) configuration.

I have SSRS installed on my primary site server with the reporting database sitting on a remote system running SQL Server 2012,  and when I initially set up SSRS I had it using the Local System built-in account as the service account.



After going back and reviewing the documentation and reading over various blog posts, I realized using Local System as the service account wasn’t going to work and I needed to specify a domain resource account to use with the proper permissions set.

Configuring Reporting in Configuration Manager

Configure a Service Account for Reporting Services

Reporting Services Configuration Manager (SSRS)

So I created a new resource account specifically for SCCM and SSRS, named SMSRS, and made sure to add it to the local SMS Admins group on the site server and grant it sysadmin and remote access permissions to the reporting databases on my SQL server. I then reconfigured the SSRS Service Account and Current Report Server Database Credential settings to use this new SMSRS account.

After restarting the service, I was able to run reports in SCCM without any further trouble.

A few quick additional notes:

  • Before changing the service account for SSRS, be sure to back up the encryption key for the original account so you don’t lose the ability to talk to the existing reporting database.
  • After changing the service account, perform a restore of the backed-up encryption key.

Instructions for backing up and restoring SSRS encryption keys for SQL Server 2012 are here:

Back Up and Restore Reporting Services Encryption Keys


  • The service account used for SSRS must be a member of the domain local security group Windows Authorization Access Group and have Allow Read tokenGroupsGlobalAndUniversal permissions in Active Directory.

SCCM 2012 R2 Upgrade Breaks SSRS with UserTokenSIDs contains an error


SCCM 2012 R2 – Configure Software Inventory


Shortly after installing SCCM 2012 R2 and getting the client installed on a few test systems, I noticed that the Inventoried Software section under Assets and Compliance\Asset Intelligence was empty and there was no application information showing up in Resource Explorer. I double checked that I had enabled Software Inventory in my client settings, which I had, so I started doing some research.

Turns out that I was missing two key settings to get what I wanted.

First, I neglected to specify any file types for the SCCM client to include in its software inventory.

Configuration Manager 2012 Software Inventory Missing

I had initially made the assumption that there was a built-in process for discovering installed software and that the “Inventory these file types” setting was only to specify additional file types as needed. As the blog post above suggests, in SCCM 2012 this isn’t the case.  If you don’t explicitly tell the client what to look for, it won’t return any results.

To correct this, I added two wild card entries to the client settings for file types:

  1. *.exe in %ProgramFiles%
  2. *.exe in %ProgramFiles(x86)%


After adding these rules and giving my clients time to get the new settings and run another software inventory cycle, I started seeing results in Asset Intelligence.

However, when I opened up Resource Explorer I found that the only information available under Software was simple file names, paths, and the modified date, among a few other minor file details. Useful, but not quite what I was looking for.

I can’t find the article that I came across now (I’ll try to add it later), but after doing some more research I found  out that you can also add software inventory functionality to the Hardware Inventory pass to get more details about installed applications. Luckily, enabling this was easy enough and just required adding a few additional classes to the hardware inventory client settings.

With Hardware Inventory selected click the Set Classes…. button, which brings up a list of the available items to be included in the hardware inventory. To enable additional software inventory functionality, just check the Installed Applications, Installed Executable, and Installed Software classes from the list.


After doing this, Resource Explorer now has these new classes available and I’m able to see product GUIDs, version numbers, install dates, file hashes, uninstall strings, and more. Much more useful.