patches not installing because they are not downloaded

Jan 15, 2014 at 1:32 PM
Hi. First off, thank you for this incredible utility.

I have had trouble getting this to work in my environment and I have finally figured out why. The settings in Windows Update (set by GPO) are to notify me of updates and allow me to download and install them. PoshPAIG will only install the patches that have already been downloaded. There is no error indicating this. The behavior of the script is that the first patch indicates that it is installed and the script exits with code 0.

I made some modifications to PoshPAIG_2_1_5\Scripts\Install-Patches.ps1 to download the patches if they are not already downloaded.

First, where the other variables were set at the top of the VB code:
Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")
Then, after the Else statement for If searchresult.updates.count = 0 (and before the existing For loop):
For I = 0 To searchResult.Updates.Count-1
    set update = searchResult.Updates.Item(I)
        If update.IsDownloaded = false Then
            updatesToDownload.Add(update)   
        End If
Next
Set downloader = updateSession.CreateUpdateDownloader() 
downloader.Updates = updatesToDownload
downloader.Download()
Now, this will download the patches that are missing prior to setting them up for installation. I hope this helps and that you might add this to future versions. Thanks again for the utility!!
Coordinator
Mar 13, 2014 at 6:52 PM
Thanks for the code snippet! I will look at this and see about adding it into a future release of PoshPAIG.
Feb 20, 2015 at 4:41 PM
Hi - Thanks for this great project. I have validated the above code and found it fixed an issue where I was seeing the error
"COMAPI FATAL: Unable to perform synchronous installation successfully. (hr=80240024)"
In the windowsupdate.log

This turns out to be the issue where the updates are not downloaded.

This was especially annoying after an installation installed say 30 patches as part of a scheduled install, then audit reported say 6 more updates. This is where this tool really has helped me, and I needed this fix.

I also added the following which I think also fixes an issue with prompts on a system where a user may be logged on.
installer.AllowSourcePrompts = False
installer.ForceQuiet = True
from a discussion at:
force-wu-install-remotely-via-vbs

so the whole vbs script now reads:
ON ERROR RESUME NEXT
CONST ForAppending = 8
CONST ForWriting = 2
CONST ForReading = 1
strlocalhost = "."
Set oShell = CreateObject("WScript.Shell") 
Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")
set ofso = createobject("scripting.filesystemobject")
Set updateSession = CreateObject("Microsoft.Update.Session")
Set updateSearcher = updateSession.CreateupdateSearcher()
Set updatesToInstall = CreateObject("Microsoft.Update.UpdateColl")
Set searchResult = updateSearcher.Search("IsInstalled=0 and Type='Software'")
Set objWMI = GetObject("winmgmts:\\" & strlocalhost & "\root\CIMV2")
set colitems = objWMI.ExecQuery("SELECT Name FROM Win32_ComputerSystem")
    For Each objcol in colitems
        strcomputer = objcol.Name
    Next
set objtextfile = ofso.createtextfile("C:\" & strcomputer & "_patchlog.csv", True)
objtextfile.writeline "Computer" & vbTab & "Title" & vbTab & "KB" & vbTab & "IsDownloaded" & vbTab & "Notes"
If searchresult.updates.count = 0 Then
    Wscript.echo "No updates to install."
    objtextfile.writeline strcomputer & vbTab & "NA" & vbTab & "NA" & vbTab & "NA" & vbTab & "NA"
    Wscript.Quit
Else
For I = 0 To searchResult.Updates.Count-1
    set update = searchResult.Updates.Item(I)
        If update.IsDownloaded = false Then
            updatesToDownload.Add(update)   
        End If
Next
Set downloader = updateSession.CreateUpdateDownloader() 
downloader.Updates = updatesToDownload
downloader.Download()

For I = 0 To searchResult.Updates.Count-1
    set update = searchResult.Updates.Item(I)
        If update.IsDownloaded = true Then
            updatesToInstall.Add(update)    
        End If
Next
End If
err.clear
Wscript.Echo "Installing Updates"
Set installer = updateSession.CreateUpdateInstaller()
installer.Updates = updatesToInstall
installer.AllowSourcePrompts = False
installer.ForceQuiet = True
Set installationResult = installer.Install()
    If err.number <> 0 Then
        objtextfile.writeline strcomputer & "," & update.Title & "," & err.number
    Else        
        For I = 0 to updatesToInstall.Count - 1
        objtextfile.writeline strcomputer & vbTab & updatesToInstall.Item(i).Title & vbTab & "NA" & vbTab & "NA" & vbTab & installationResult.GetUpdateResult(i).ResultCode 
        Next
    End If
Wscript.Quit