I'm currently writing a type of automated program that among other things searches for windows updates. It can search for and retrieve updates just fine, but I am having trouble drilling down for what priority an update is. I would like to have an output similar to:
Total Updates: 25
Important: 12
Optional: 13
The .IsMandatory field is only used when the update is specifically for WUA itself, so important updates are not necessary labeled with .IsMandatory.
Code snippet for searching the WUA is below:
Dim updateSession ' Object to hold our MS Update Session
Dim updateSearcher ' Object to perform our MS Win Update Search
Dim results ' Object to hold our MS Win Update Search Results
Dim stopWatch As New Stopwatch()
stopWatch.Start()
outputWriter.WriteLine("----WINDOWS UPDATES-----@ " & Now, False)
outputWriter.WriteLine(" -We are beginning our update search. Please note, this may take a few minutes." & _
" On Windows Server 2003 this may take 800 years.", False)
' We cannot guarantee the update check will succeed, so use a try catch in case of error.
Try
updateSession = CreateObject("Microsoft.Update.Session")
updateSearcher = updateSession.CreateUpdateSearcher()
results = updateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")
Catch ex As Exception
outputWriter.WriteLine(" ERROR: Something went wrong in our update search. Details below...", False)
outputWriter.WriteLine(" Error Msg: " & ex.Message, False)
Return 1
End Try
Dim imp_updates = 0
Dim opt_updates = 0
For i = 0 To results.Updates.Count - 1
Dim update = results.Updates.Item(i)
If update.IsMandatory = False Then
opt_updates = opt_updates + 1
Else
imp_updates = imp_updates + 1
End If
Next
outputWriter.WriteLine("Important Updates: " & imp_updates, True)
outputWriter.WriteLine("Optional Updates: " & opt_updates, True)
It turns out that I did not have a reference to WUApi.DLL in my code. Once I put that reference in, I was successfully able to cast my result as an IUpdate3. IUpdate3 is an interface which contains a property named BrowseOnly. What BrowseOnly does, is specify if an update is optional or not. Using BrowseOnly, I can determine if an update is important or optional.
See below (IUpdate3 used around the middle of the code chunk)...
''' <summary>
''' Performs a windows update check for any updates that are...
''' A: Not installed
''' B: Not hidden
''' C: Software updates (OS and software, no hardware updates)
''' </summary>
''' <returns>0 on success, 1 on failure</returns>
''' <remarks></remarks>
Function checkForUpdates() As Integer
Dim updateSession ' Object to hold our MS Update Session
Dim updateSearcher ' Object to perform our MS Win Update Search
Dim results ' Object to hold our MS Win Update Search Results
Dim stopWatch As New Stopwatch()
stopWatch.Start()
outputWriter.WriteLine("----WINDOWS UPDATES-----@ " & Now, False)
outputWriter.WriteLine(" -We are beginning our update search. Please note, this may take a few minutes." & _
" On Windows Server 2003 this may take 800 years.", False)
' We cannot guarantee the update check will succeed, so use a try catch in case of error.
Try
updateSession = CreateObject("Microsoft.Update.Session")
updateSearcher = updateSession.CreateUpdateSearcher()
results = updateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")
Catch ex As Exception
outputWriter.WriteLine(" ERROR: Something went wrong in our update search. Details below...", False)
outputWriter.WriteLine(" Error Msg: " & ex.Message, False)
Return 1
End Try
outputWriter.WriteLine(" -Windows update search has successfully completed. Beginning iteration of result set...", False)
' Similar to above, we cannot guarantee iterating through our result set will succeed. Use a try catch.
Try
Dim totalUpdates = results.Updates.Count
outputWriter.WriteLine("-----Windows Updates-----@ " & Now, True)
If results.Updates.Count = 0 Then
outputWriter.WriteLine("Total Updates: 0", True)
outputWriter.WriteLine("Important: 0", True)
outputWriter.WriteLine("Optional: 0", True)
Else
Dim imp_updates = 0
Dim opt_updates = 0
For i = 0 To totalUpdates - 1
Dim update = results.Updates.Item(i)
If CType(update, WUApiLib.IUpdate3).BrowseOnly = True Then ' BrowseOnly is specifically used for whether an update is deemed optional or not (True for optional)
opt_updates = opt_updates + 1
Else
imp_updates = imp_updates + 1
End If
Next
outputWriter.WriteLine("Total Updates: " & totalUpdates, True)
outputWriter.WriteLine("Important: " & imp_updates, True)
outputWriter.WriteLine("Optional : " & opt_updates, True)
End If
stopWatch.Stop()
If stopWatch.ElapsedMilliseconds >= 1000 Then
outputWriter.WriteLine("--------Total Time: " & Math.Round((CDbl(stopWatch.ElapsedMilliseconds) / 1000), 2) & " Sec----------------" & vbCrLf, True)
Else
outputWriter.WriteLine("--------Total Time: " & stopWatch.ElapsedMilliseconds & " MS-------------------" & vbCrLf, True)
End If
Catch ex As Exception
outputWriter.WriteLine(" ERROR: We encountered an issue while iterating through Windows Update Search Results. Details below...", False)
outputWriter.WriteLine(" Error Msg: " & ex.Message, False)
Return 1
End Try
outputWriter.WriteLine(" -Iteration of Windows Update Search Results has successfully completed.", False)
outputWriter.WriteLine("-------------------------" & vbCrLf, False)
' Clean up our objects.
updateSession = Nothing
updateSearcher = Nothing
results = Nothing
' Success!
Return 0
End Function
You should be able to check the MsrcSeverity of the update:
Select Case update.MsrcSeverity
Case "Important"
Case "Critical"
Case "Moderate"
Case "Low"
Case "Unspecified"
End Select
Loop over results.Updates.Count and then check for each Update.Item its Categories item names.
For i As Integer = 0 To results.Updates.Count - 1
updateCategories = results.Updates.Item(i).Categories
For j As Integer = 0 To updateCategories.Count - 1
updateCategorie = updateCategories.Item(j).Name
Select Case updateCategorie
Case "Updates"
'do something
Case "Critical Updates"
'do something
Case "Security Updates"
'do something
Case "Service Packs"
'do something
Case "Update Rollups"
'do something
Case "Feature Packs"
'do something
Case Else
'do something
End Select
Next
Next