WUSA vbs Progress bar

1.4k views Asked by At

I am using the following code for Windows Update:

Set updateSession = CreateObject("Microsoft.Update.Session")
updateSession.ClientApplicationID = "MSDN Sample Script"

Set updateSearcher = updateSession.CreateUpdateSearcher()

WScript.Echo "Searching for updates..." & vbCRLF

Set searchResult = _
updateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")

WScript.Echo "List of applicable items on the machine:"

For I = 0 To searchResult.Updates.Count-1
    Set update = searchResult.Updates.Item(I)
    WScript.Echo I + 1 & "> " & update.Title
Next

If searchResult.Updates.Count = 0 Then
    WScript.Echo "There are no applicable updates."
    WScript.Quit
End If

WScript.Echo vbCRLF & "Creating collection of updates to download:"

Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")

For I = 0 to searchResult.Updates.Count-1
    Set update = searchResult.Updates.Item(I)
    addThisUpdate = false
    If update.InstallationBehavior.CanRequestUserInput = true Then
        WScript.Echo I + 1 & "> skipping: " & update.Title & _
        " because it requires user input"
    Else
        If update.EulaAccepted = false Then
            WScript.Echo I + 1 & "> note: " & update.Title & _
            " has a license agreement that must be accepted:"
            WScript.Echo update.EulaText
            WScript.Echo "Do you accept this license agreement? (Y/N)"
            strInput = WScript.StdIn.Readline
            WScript.Echo 
            If (strInput = "Y" or strInput = "y") Then
                update.AcceptEula()
                addThisUpdate = true
            Else
                WScript.Echo I + 1 & "> skipping: " & update.Title & _
                " because the license agreement was declined"
            End If
        Else
            addThisUpdate = true
        End If
    End If
    If addThisUpdate = true Then
        WScript.Echo I + 1 & "> adding: " & update.Title 
        updatesToDownload.Add(update)
    End If
Next

If updatesToDownload.Count = 0 Then
    WScript.Echo "All applicable updates were skipped."
    WScript.Quit
End If

WScript.Echo vbCRLF & "Downloading updates..."

Set downloader = updateSession.CreateUpdateDownloader() 
downloader.Updates = updatesToDownload
downloader.Download()

Set updatesToInstall = CreateObject("Microsoft.Update.UpdateColl")

rebootMayBeRequired = false

WScript.Echo vbCRLF & "Successfully downloaded updates:"

For I = 0 To searchResult.Updates.Count-1
    set update = searchResult.Updates.Item(I)
    If update.IsDownloaded = true Then
        WScript.Echo I + 1 & "> " & update.Title 
        updatesToInstall.Add(update) 
        If update.InstallationBehavior.RebootBehavior > 0 Then
            rebootMayBeRequired = true
        End If
    End If
Next

If updatesToInstall.Count = 0 Then
    WScript.Echo "No updates were successfully downloaded."
    WScript.Quit
End If

If rebootMayBeRequired = true Then
    WScript.Echo vbCRLF & "These updates may require a reboot."
End If

WScript.Echo "Installing updates..."
Set installer = updateSession.CreateUpdateInstaller()
installer.Updates = updatesToInstall
Set installationResult = installer.Install()

'Output results of install
WScript.Echo "Installation Result: " & _
installationResult.ResultCode 
WScript.Echo "Reboot Required: " & _ 
installationResult.RebootRequired & vbCRLF 
WScript.Echo "Listing of updates installed " & _
"and individual installation results:" 

   For I = 0 to updatesToInstall.Count - 1
        WScript.Echo I + 1 & "> " & _
        updatesToInstall.Item(i).Title & _
        ": " & installationResult.GetUpdateResult(i).ResultCode         
    Next

Works like a charm, taken from a Microsoft website, so im not 100% on the buildup.

I am having issues finding a way to add a progress bar, or just have it say: "Update 1/65 installed" etc.

Can anyone point me in the right direction? Not sure which part of the code actually does the installation one by one.

1

There are 1 answers

0
Air2 On

I found the solution here:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa385820(v=vs.85).aspx In de comment of "RM de Jong"

So this is my script. It also reboots the system at then and everything is automatic answered with Yes. Its not beautifull scripting, just quick and dirty. So you should change it to your needs. I guess the downloading and searching can be scripted the same way as the install. But not tested that.

Set updateSession = CreateObject("Microsoft.Update.Session")
updateSession.ClientApplicationID = "MSDN Sample Script"

Set updateSearcher = updateSession.CreateUpdateSearcher()

WScript.Echo "Searching for updates..." & vbCRLF

Function AddBackspace(ByVal Text)
  AddBackspace = String(18, Chr(08)) & Text
End Function

WScript.StdOut.Write AddBackspace("Please wait...")
WScript.StdOut.Write AddBackspace("Please wait...")


Set searchResult = _
updateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")

WScript.Echo "List of applicable items on the machine:"

For I = 0 To searchResult.Updates.Count-1
    Set update = searchResult.Updates.Item(I)
    WScript.Echo I + 1 & "> " & update.Title
Next

If searchResult.Updates.Count = 0 Then
    WScript.Echo "There are no applicable updates."
    WScript.Quit
End If

WScript.Echo vbCRLF & "Creating collection of updates to download:"

Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")

For I = 0 to searchResult.Updates.Count-1
    Set update = searchResult.Updates.Item(I)
    addThisUpdate = false
    If update.InstallationBehavior.CanRequestUserInput = true Then
        WScript.Echo I + 1 & "> skipping: " & update.Title & _
        " because it requires user input"
    Else
        If update.EulaAccepted = false Then
            WScript.Echo I + 1 & "> note: " & update.Title & _
            " has a license agreement that must be accepted:"
            WScript.Echo update.EulaText
            WScript.Echo "Do you accept this license agreement? (Y/N)"
            WScript.Echo 
            WScript.Echo "Y"
            update.AcceptEula()
            addThisUpdate = true
        Else
            addThisUpdate = true
        End If
    End If
    If addThisUpdate = true Then
        WScript.Echo I + 1 & "> adding: " & update.Title 
        updatesToDownload.Add(update)
    End If
Next

If updatesToDownload.Count = 0 Then
    WScript.Echo "All applicable updates were skipped."
    WScript.Quit
End If

WScript.Echo vbCRLF & "Downloading updates..."

Set downloader = updateSession.CreateUpdateDownloader() 
downloader.Updates = updatesToDownload
downloader.Download()

Set updatesToInstall = CreateObject("Microsoft.Update.UpdateColl")

rebootMayBeRequired = false

WScript.Echo vbCRLF & "Successfully downloaded updates:"

For I = 0 To searchResult.Updates.Count-1
    set update = searchResult.Updates.Item(I)
    If update.IsDownloaded = true Then
        WScript.Echo I + 1 & "> " & update.Title 
        updatesToInstall.Add(update) 
        If update.InstallationBehavior.RebootBehavior > 0 Then
            rebootMayBeRequired = true
        End If
    End If
Next

If updatesToInstall.Count = 0 Then
    WScript.Echo "No updates were successfully downloaded."
    WScript.Quit
End If

If rebootMayBeRequired = true Then
    WScript.Echo vbCRLF & "These updates may require a reboot."
End If

WScript.Echo  vbCRLF & "Would you like to install updates now? (Y/N)"
WScript.Echo 
WScript.Echo "Y"



Function Install(Byval hCollection)
 Dim Result

 If Not Verbose Then
  WScript.StdOut.Write AddBackspace("Please wait...")
 End If
 Set Installer = updateSession.CreateUpdateInstaller

 Installer.Updates = hCollection

 Set InstallJob = Installer.BeginInstall(GetRef("Install_OnProgressChanged"), GetRef("Install_OnComplete"), "")
 If Not Err.Number = 0 Then
  WScript.StdOut.WriteLine "Error " & Err.Number & ": " & Err.Description
 End If

 Do Until InstallJob.IsCompleted Or Now >= EndRuntime
  WScript.Sleep 100
 Loop

On Error Resume Next 
 Set Result = Installer.EndInstall(InstallJob)
On Error Goto 0
 If Err.Number = 0 Then
  'WScript.StdOut.WriteLine TranslateResultCode(Result.ResultCode)
 End If

 Set Install = Result
End Function

Sub Install_OnProgressChanged(ByVal hInstallJob, ByVal hArguments)
 If Verbose Then
  WScript.StdOut.Write AddBackspace(hArguments.Progress.CurrentUpdateIndex + 1 & " " & hArguments.Progress.CurrentUpdatePercentComplete & "%  ")
 Else
  WScript.StdOut.Write AddBackspace(hArguments.Progress.PercentComplete & "% Please wait...")
 End If
End Sub

Sub Install_OnComplete(ByVal hInstallJob, ByVal hArguments)
 If Verbose Then
  WScript.StdOut.WriteLine "Installation completed"
 End If
End Sub


WScript.Echo "Installing updates..."
Set installationResult = Install(updatesToInstall)
'Set installationResult = installer.Install()

'Output results of install
WScript.Echo "Installation Result: " & _
installationResult.ResultCode 
WScript.Echo "Reboot Required: " & _ 
installationResult.RebootRequired & vbCRLF 
WScript.Echo "Listing of updates installed " & _
"and individual installation results:" 

If installationResult.RebootRequired = true Then
    For I = 0 to updatesToInstall.Count - 1
        WScript.Echo I + 1 & "> " & _
        updatesToInstall.Item(i).Title & _
        ": " & installationResult.GetUpdateResult(i).ResultCode   
    Next

    Set objWMIService = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate,(Shutdown)}!\\localhost\root\cimv2")
    Set colOperatingSystems = objWMIService.ExecQuery _
        ("Select * from Win32_OperatingSystem")

    For Each objOperatingSystem in colOperatingSystems
        ObjOperatingSystem.Win32Shutdown(2)

    If Err.Number <> 0 Then
      WScript.Echo Err.Description
    Else
      WScript.Echo "Computer is performing a reboot."
    End If
    Err.Clear

    Next
End If