Windows Updates Pending - using PS and VB - Help required.


I’ve been trying to find a script that can check a number of servers for pending updates. Some of these servers don’t have PS installed so I figured I could try and use vbs a long side PS. The problem is I have no vbs knowledge :slight_smile:

A lot of the PS scripts and vbs I found were doing a lot more than I actually require. I managed to find a script that contained a part which was exactly what I need and with help from a colleague we extracted the part I require.

The problem I have is it’s not always working and when it fails on one server it doesn’t continue. When it works it’s perfect.

Here’s what I’m using PS for:

Variable listing servers

$servers = Get-Content c:\servers.txt

Calling up the .vbs to run against the servers contained in the variable,and outputting to .txt.

CSCRIPT.exe C:\Update_pending.vbs $servers > C:\pending_updates.txt

Here’s the vbs, and as mentioned it’s butchered from another bigger script.
'# ServerPendingUpdates.vbs
'# Usage: cscript ServerPendingUpdates.vbs {servername} {servername} {servername} {servername}
'# If no {servername} specified then ‘localhost’ assumed
'# To do: Error handling
Option Explicit
Dim strServer : strServer = GetArgValue(0,“localhost”)

'# Loop through the input parameters for each server
Dim i
For i = 0 To WScript.Arguments.Count - 1
CheckServerUpdateStatus GetArgValue(i,“localhost”) 'strServer


Function CheckServerUpdateStatus( ByVal strServer )

WScript.Echo vbCRLF & "Connecting to " & strServer & " to check software update status..."

Dim blnRebootRequired    : blnRebootRequired     = False
Dim blnRebootPending    : blnRebootPending     = False
Dim objSession        : Set objSession    = CreateObject("Microsoft.Update.Session", strServer)
Dim objUpdateSearcher     : Set objUpdateSearcher    = objSession.CreateUpdateSearcher
Dim objSearchResult    : Set objSearchResult     = objUpdateSearcher.Search(" IsAssigned=1 and IsHidden=0 and Type='Software'")

Dim i, objUpdate
Dim intPendingInstalls    : intPendingInstalls     = 0

For i = 0 To objSearchResult.Updates.Count-1
    Set objUpdate = objSearchResult.Updates.Item(I) 

    If not (objUpdate.IsInstalled) Then
        intPendingInstalls    = intPendingInstalls + 1
    End If

WScript.Echo strServer & " has " & intPendingInstalls & " updates pending installation"

End Function

Function GetArgValue( intArgItem, strDefault )
If WScript.Arguments.Count > intArgItem Then
GetArgValue = WScript.Arguments.Item(intArgItem)
GetArgValue = strDefault
End If
End Function

The work that’s being done is not Powershell dependent. You actually are using the Windows Update COM object to get Windows Update information. Take a look at this post:

It should be as simple as:

Get-WindowsUpdate -ComputerName (Get-Content C:\Servers.txt)

Hi Rob,

thanks for your reply.

What you provided in the link isn’t what I need. I don’t require lists of updates. All I need is to check a list of servers for pending updates. The servers don’t all have PowerShell installed.

The VBS I pasted above, when it works, give me exactly what I need.

To give you a little back ground on this. I’ve got some PS scripts that I use with WSUS and Active Directory to automate our patching. This is working well and I need it to run until our new SCCM 2012 is configured. The only problem I’m seeing is the odd the server, that for what ever reason, fails to start updating. If I could get this script to run properly against my daily list of servers, this would save me checking them all and I would only need to check the servers that show up with updates pending.



may be you just need to test some registry key somewhere around
I thinks you need
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\UAS\UpdateCount

It’s a hack, but can satisfy your needs and can be coded in a few lines

You don’t need Powershell on every server, you actually only need Powershell on the system that you are running this script from. The VBScript is doing a foreach loop on every server and connecting with DCOM using RPC. Here you are connecting to the server using the Microsoft.Update.Session COM object using strServer:

Dim objSession : Set objSession = CreateObject("Microsoft.Update.Session", strServer)

You only need Powershell installed if you wanted to use Invoke-Command and run Powershell code on each device, but your posted information does not indicate that’s how you are using the script. Here is a Scripting Guys article that uses the .Search method:

#Scripting Guys code...
$Result = $Searcher.Search("UpdateID='$updateID'")

Here you are using the same .Search method, but passing a different query. You just need to update the “UpdateID=’$updateID’” with the below query and you are using a Powershell solution to do the same thing:

#Your posted code
Dim objSearchResult : Set objSearchResult = objUpdateSearcher.Search(" IsAssigned=1 and IsHidden=0 and Type='Software'")

You can use these examples do return exactly what you want, using all Powershell and with Powershell not installed on the end-point system.

Hi Rob,

thanks for taking the time to help, it’s appreciated. As you may have worked out my PoSh skills are not at an advance level.

I tested the function that was provided in your first link. I don’t fully understand the working of it, but from what I could see it doesn’t look like it does what I need. I run it on a test VM and the output was just a lot of details about patches. However, this detail looks like it’s about patches that are installed, not pending. I only need to know how many patches are pending installation. In the vbs I initially pasted it would provide the output below.

Connecting to server1 to check software update status…
server1 has 6 updates pending installation

This is all need, but I need to get it work with a list of servers. For some reason it sometimes fails.

Any suggestions?