Inside the Microsoft IT Datacenter environment SCCM is the main tool used for automated patch management. Some servers are still manually patched by their server owners using many different tools (scripts, WSUS, AutomaticUpdates, download/install the exe’s manually, etc.). Since our primary focus is on the security of the environment it doesn’t really matter how servers get secured each month for the required updates.
However, in order to measure the usage of our automated patching service we wanted to see how many of these servers are actually getting updates installed by SCCM versus those being manually patched.
You would think this data would exist in the SCCM database…
SCCM does have a column that looks like it contains the install source information; the column is EnforcementSource in the view v_UpdateComplianceStatus (and a few other views too).
The column is an integer type and the WMI class definition shows the possible values as follows:
After comparing the data for machines I manually updated and machines where I let SCCM install the updates I found that this view did not provide the results I was expecting; both sets of machines showed EnforcementSource = 2 == USER. After more research, testing and chats with colleagues, it appears these values are tied to the mandatory enforcement messages and not necessarily the mechanism that installed the update; else it’s bad data being returned to SCCM…
I talked with another Microsoft colleague, Satish Petwe, who works on the SCCM team managing a large population of desktop clients, and he had found that update install source data does exist on the machine in the local Windows Update agent repository.
Executing the QueryHistory method inside the Microsoft.Update.Searcher object will return a list of updates applicable to the machine. The list can be filtered to show only the installed updates and most importantly the result object contains a property called ClientApplicationID which stores the application that processed the update.
As you can see in the output generated by the vbscript (code at the bottom of the page) this is exactly the information I was looking for:
You could also use this data to see the different non-SCCM applications that are being used to install updates in your environment, but as I stated earlier true install counts by SCCM was our main goal.
There are a number of options on how to get this data back to a central location; I decided on funneling the relevant information into a local WMI class and then extending SCCM inventory to bring it back to the central site database. I haven’t done further investigation to see if this information is available in WSUS natively; I assume we would have to enable WSUS reporting events on our Software Update Points.
Here’s some quick vbscript code just to give you an idea how to find the data.
Set loc = CreateObject("WbemScripting.SWbemLocator")
Set WbemServices = loc.ConnectServer(, "root\cimv2")
On Error Resume Next
Set oWU = CreateObject("Microsoft.Update.Searcher")
iTHCount = oWU.GetTotalHistoryCount
'make sure there is something returned from the WU searcher
If iTHCount > 0 Then
'query the WU history to get all the updates on this machine
Set colUpdate = oWU.QueryHistory(0, iTHCount)
For Each oUpdate In colUpdate
'only look for successfully installed updates ResultCode=2
If oUpdate.ResultCode = 2 then
wscript.echo " UpdateGUID: [" & UpdateID & "]"
wscript.echo " Installed by: " & InstallAgent
wscript.echo " Installed on: [" & DateGMT & "]"