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

This topic contains 5 replies, has 3 voices, and was last updated by Profile photo of John K John K 1 year, 10 months ago.

  • Author
    Posts
  • #27704
    Profile photo of John K
    John K
    Participant

    Hi,

    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 🙂

    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
    Next

    WScript.Quit(0)

    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
    Next

    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)
    Else
    GetArgValue = strDefault
    End If
    End Function

  • #27711
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    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: https://powershell.org/forums/topic/how-to-use-write-progress-in-my-function/#post-26951

    It should be as simple as:

    Get-WindowsUpdate -ComputerName (Get-Content C:\Servers.txt)
    
  • #27787
    Profile photo of John K
    John K
    Participant

    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.

    Regards,

    John.

  • #27790
    Profile photo of Max Kozlov
    Max Kozlov
    Participant

    may be you just need to test some registry key somewhere around
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate
    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

  • #27804
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    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.

  • #27876
    Profile photo of John K
    John K
    Participant

    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?

You must be logged in to reply to this topic.