Install-MSUpdates - .Cab file support suggestion

Topics: Archive - General
Dec 22, 2014 at 8:31 AM
Here is a modified 3.5.0 Install-MSUpdates function with .cab file support - I'm sharing as this might be useful addition for future toolkit version?

Occasionally MS updates are found in .cab format (WSUS etc) - I recently needed to implement this for an IE 11 distribution..

I also found it necessary to also add -WorkingDirectory "." to the execute-process commands in the function to get updates to work for me in 3.5.0

Thanks for the toolkit - keep up the good work!
#region Function Install-MSUpdates
Function Install-MSUpdates {
    Install all Microsoft Updates in a given directory.
    Install all Microsoft Updates of type ".exe", ".msu", or ".msp" in a given directory (recursively search directory).
.PARAMETER Directory
    Directory containing the updates.
    Install-MSUpdates -Directory "$dirFiles\MSUpdates"
    Param (
    Begin {
        ## Get the name of this function and write header
        [string]${CmdletName} = $PSCmdlet.MyInvocation.MyCommand.Name
        Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -CmdletBoundParameters $PSBoundParameters -Header
    Process {
        Write-Log -Message "Recursively install all Microsoft Updates in directory [$Directory]." -Source ${CmdletName}
        ## KB Number pattern match
        $kbPattern = '(?i)kb\d{6,8}'
        ## Get all hotfixes and install if required
        [System.IO.FileInfo[]]$files = Get-ChildItem -Path $Directory -Recurse -Include ('*.exe','*.msu','*.msp','*.cab')
        ForEach ($file in $files) {
            If ($file.Name -match 'redist') {
                [version]$redistVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($file).ProductVersion
                [string]$redistDescription = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($file).FileDescription
                Write-Log -Message "Install [$redistDescription $redistVersion]..." -Source ${CmdletName}
                #  Handle older redistributables (ie, VC++ 2005)
                If ($redistDescription -match 'Win32 Cabinet Self-Extractor') {
                    Execute-Process -Path $file -Parameters '/q' -WindowStyle Hidden -ContinueOnError $true
                Else {
                    Execute-Process -Path $file -Parameters '/quiet /norestart' -WindowStyle Hidden -ContinueOnError $true
            Else {
                #  Get the KB number of the file
                [string]$kbNumber = [regex]::Match($file, $kbPattern).ToString()
                If (-not $kbNumber) { Continue }
                #  Check to see whether the KB is already installed
                If (-not (Test-MSUpdates -KBNumber $kbNumber)) {
                    Write-Log -Message "KB Number [$KBNumber] was not detected and will be installed." -Source ${CmdletName}
                                                Switch ($file.Extension) {
                        #  Installation type for executables (i.e., Microsoft Office Updates)
                        '.exe' { Execute-Process -Path $file -Parameters '/quiet /norestart' -WindowStyle Hidden -ContinueOnError $true }
                        #  Installation type for Windows updates using Windows Update Standalone Installer
                        '.msu' { Execute-Process -Path 'wusa.exe' -WorkingDirectory "." -Parameters "`"$file`" /quiet /norestart" -WindowStyle Hidden -ContinueOnError $true }
                        #  Installation type for Windows Installer Patch
                        '.msp' { Execute-MSI -Action 'Patch' -Path $file -ContinueOnError $true }
                        #  Installation type for Windows Cab file
                        '.cab' { Execute-Process -Path 'dism.exe' -WorkingDirectory "." -Parameters "/online /add-package /packagepath:`"$file`" /quiet /norestart" -WindowStyle Hidden -ContinueOnError $true -CreateNoWindow }
                Else {
                    Write-Log -Message "KB Number [$kbNumber] is already installed. Continue..." -Source ${CmdletName}
    End {
        Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -Footer