Windows Updates Status

This is basically for users with large environments. One of the main issues with 1000’s of Physical servers and Virtual machine in environment is not only the repair/s or bugs in the software but “Windows Updates”. Dealing with over 1500 + Windows Devices the updates are always an issue. We have tackled this by “deferring Update” and completely turning updates off. Now we have created a policy to only download security updates, which mean no auto-reboot in the middle of the night. Alerts going off and customers wondering what is happening. To keep track of what machines will and do need updates like the priority of the updates, etc… I have a visual basic script that gathers the information and displays it. I’m quite sure there is other software out there that would be easier, but this is free and a little time consuming but with Ansible it can be implemented quickly.
I have two visual basic scripts one that gets the status on the updates and the other script that shows the setting of how the update s are configured

Set args = WScript.Arguments
IF (WScript.Arguments.Count > 0) Then
	IF (WScript.Arguments.Item(0) = "last") Then
		Set objSession = CreateObject("Microsoft.Update.Session")
		Set objSearcher = objSession.CreateUpdateSearcher
		Set colHistory = objSearcher.QueryHistory(0,1)
		For Each objEntry in colHistory
			WScript.Echo  date2epoch(objEntry.Date)
		Wscript.Echo getUpdates(WScript.Arguments.Item(0))
	End IF	
	Wscript.Echo "ERROR in CheckWinUpdate parameter"
End IF
Function getUpdates(updateType)
	Set objSearcher = CreateObject("Microsoft.Update.Searcher")
	Set objResults = objSearcher.Search("IsInstalled=0")
	Set colUpdates = objResults.Updates
	updatesHigh = 0
	updatesOptional = 0
	priorityUpdateList = "Priority Updates:" & vbCrLf
	optionalUpdateList = "Optional Updates:" & vbCrLf
	For i = 0 to colUpdates.Count - 1
		If (colUpdates.Item(i).IsInstalled = False AND colUpdates.Item(i).AutoSelectOnWebSites = False) Then
			updatesOptional = updatesOptional + 1
			title = "Optional Update"
			optionalUpdateList = optionalUpdateList & colUpdates.Item(i).Title & vbCrLf
		ElseIf (colUpdates.Item(i).IsInstalled = False AND colUpdates.Item(i).AutoSelectOnWebSites = True) Then
			updatesHigh = updatesHigh + 1
			title = "High Priority Update"
			priorityUpdateList = priorityUpdateList & colUpdates.Item(i).Title & vbCrLf
		End IF
	IF (updateType = "priority") Then
		getUpdates = updatesHigh
	ElseIf (updateType = "optional") Then
		getUpdates = updatesOptional
	ElseIf (updateType = "total") Then
		getUpdates = (updatesHigh + updatesOptional)
	ElseIf (updateType = "full") Then
		getUpdates = priorityUpdateList & vbCrLf & optionalUpdateList
		getUpdates = "ERROR in CheckWinUpdate parameter"
	End IF
End function
Function getmydat(wmitime) 
  dtmInstallDate.Value = wmitime 
  getmydat = dtmInstallDate.GetVarDate
End function
function date2epoch(myDate)
date2epoch = DateDiff("s", "01/01/1970 00:00:00", myDate)
end function

That script will show the following

  • Windows Updates (All Available Updates)
  • Windows Updates (Last Run)
  • Windows Updates (Optional Updates)
  • Windows Updates (Priority Updates)
  • Windows Updates (Total Count)

Next Script will show the Settings of Windows Update

Set objAutoUpdate = CreateObject("Microsoft.Update.AutoUpdate")
Set objSettings = objAutoUpdate.Settings

Select Case objSettings.NotificationLevel
Case 0
Wscript.Echo "Notification level: Automatic Updates is not configured by the user " & _
"or by a Group Policy administrator."
Case 1
Wscript.Echo "Notification level: never check for updates(not recommended)."
Case 2
Wscript.Echo "Notification level: Check for updates " & _
"But let me choose wheather to download and install them."
Case 3
Wscript.Echo "Notification level: Download updates but let me choose whether to install them."
Case 4
Wscript.Echo "Notification level: Install updates automatically (recommended)"
Case Else
Wscript.Echo "Notification level could not be determined."
End Select

I found this from the “Script Guy’s” 7-8 years ago @tmacgbay and they still work today on Windows server 2019 Datacenter addition.

Create a Task Scheduler on windows to execute visual basic scripts once a day then write it to a log file.

Example: Data received.

One Problem with VBS, MS Task scheduler has a hard time executing it, so what I had to do is the following:

Created task Scheduler with new action under the Program/script section using cmd

It does two things

  1. executes the VBS
  2. Creates log file

Log shipper picks it up and sends it to Graylog :smiley:

<Input updates>
    Module       im_file
    FILE         "C:\Users\greg.smith\Desktop\log.txt"
    SavePos       TRUE
    ReadFromLast  TRUE
    PollInterval  1
    Exec  $Message = $raw_event;


Log/s need some adjusting mainly because I’m sending those logs GELF type and its sending them one line at a time.
Task scheduler will do this once a day.

Pretty cool - a lot of setup work but runs smooth once you get there - You could deploy the Windows Tasks automatically via old school group policy so that machines would automatically run their update scripts.

Thx @tmacgbay

We now are using Ansible to run updates all machines or individual ones at the same time. Some cluster servers have to be update one at a time since … well there cluster servers :laughing:. When I first started working with MS Hyper-V servers and this one day I decided to updated them at the same time. They rebooted and took down the whole environment and both AD DNS servers. OMG that was really, really bad. Took about 4 hours t bring DNS server back up :frowning:

Just knowing which server needs Priority update, I can configure Ansible synchronize updates so that all of the servers don’t reboot once when applying MS updates.

EDIT: Sorry still waking up , Yes…noted having a GPO for executing the scripts :laughing: Need more coffee

1 Like

Think I have it figured out :+1: It will it install VBS script on a new node (i.e. First time connected to the domain on LOGON) but also configure the Task scheduler to run that script per day. Any node already connected to the domain I have to use Ansible first but after that its a piece of :cake:

1 Like