Skip to content

Instantly share code, notes, and snippets.

@adamchilcott
Created October 14, 2018 11:31
Show Gist options
  • Save adamchilcott/f19b8cdb0bcf39a7b637ed0fe436c6a6 to your computer and use it in GitHub Desktop.
Save adamchilcott/f19b8cdb0bcf39a7b637ed0fe436c6a6 to your computer and use it in GitHub Desktop.

Revisions

  1. adamchilcott created this gist Oct 14, 2018.
    222 changes: 222 additions & 0 deletions checkUpdates.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,222 @@
    ###########################################################
    # Check For Windows Updates, Then Install
    # Aimed At Remote Monitoring And Management Solutions (RMM)
    # LogMeIn Central, AVG Managed Workplace Et. al
    ###########################################################

    ######################################################
    # Provide The Literal Path To Required System Binaries
    ######################################################
    $cscriptBinary = "C:\Windows\System32\cscript.exe"
    $scBinary = "C:\Windows\System32\sc.exe"
    $netBinary = "C:\Windows\System32\net.exe"

    #########################
    # Supply checkUpdates.vbs
    #########################
    $vbsCheckUpdates = @"
    'ServerSelection values
    ssDefault = 0
    ssManagedServer = 1
    ssWindowsUpdate = 2
    ssOthers = 3
    'InStr values
    intSearchStartChar = 1
    dim strTitle
    Set updateSession = CreateObject("Microsoft.Update.Session")
    Set updateSearcher = updateSession.CreateupdateSearcher()
    updateSearcher.ServerSelection = ssWindowsUpdate
    Set searchResult = updateSearcher.Search("IsInstalled=0 and Type='Software'")
    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
    strInput = "Y"
    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 vbCRLF & "Would you like to install updates now? (Y/N)"
    ''strInput = WScript.StdIn.ReadLine
    strInput = "Y"
    WScript.Echo
    If (strInput = "Y" or strInput = "y") Then
    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
    End If
    'ServerSelection values
    ' START NOTES
    ' Reference:
    ' <https://gallery.technet.microsoft.com/scriptcenter/VB-Script-to-Check-and-620579cd>
    ' END NOTES
    "@

    ###########################
    # Supply enableOptional.vbs
    ###########################
    $vbsEnableOptional = @"
    Set ServiceManager = CreateObject("Microsoft.Update.ServiceManager")
    ServiceManager.ClientApplicationID = "My App"
    'add the Microsoft Update Service, GUID
    Set NewUpdateService = ServiceManager.AddService2("7971f918-a847-4430-9279-4a52d1efe18d",7,"")
    ' START NOTES
    ' Reference:
    ' <https://docs.microsoft.com/en-gb/windows/desktop/Wua_Sdk/opt-in-to-microsoft-update>
    ' <https://blogs.technet.microsoft.com/danbuche/2010/01/06/enabling-and-disabling-microsoft-update-in-windows-7-via-script/>
    ' END NOTES
    "@

    #######################
    # Write Out *.vbs Files
    #######################
    $vbsCheckUpdates | Out-File checkUpdates.vbs -Force
    $vbsEnableOptional | Out-File enableOptional.vbs -Force

    ###########################
    # Enable 'wuauserv' Service
    ###########################
    & $scBinary config wuauserv start= auto
    & $netBinary start wuauserv

    ###############################
    # Interpret Written *.vbs Files
    ###############################
    & $cscriptBinary enableOptional.vbs
    & $cscriptBinary checkUpdates.vbs

    ######################
    # Clean-Up *.vbs Files
    ######################
    Remove-Item .\enableOptional.vbs -Force
    Remove-Item .\checkUpdates.vbs -Force

    #############
    # START NOTES
    #############

    ## You Must Run This PowerShell Script As An Administrator.
    ## Leverages 'Here-Strings' To Output The Self-Contained VBScript(s).
    ## In Future, Instead Of Writing Out To A File, Perhaps VBScript(s) Can Be Piped Directly To The Interpreter.

    ## Use 'C:\Windows\System32\where.exe' To Find Literal Binary Paths.
    ##
    ## OR
    ##
    ## 'Get-Command'.

    ###########
    # END NOTES
    ###########