rss logo

Install KB files from a directory with PowerShell

Intro

I had to install a lot of KB files in order to update a very slow workstation. As there were a lot to install and in order to avoid to do it one by one I created a powershell script which install only KB that are not already installed. It is specially usefull for Windows 7 Workstations.

PowerShell Script

###########################
# author : shebangthedolphins.net
# version : 1.0
# date : 2018.10
# role : install kb updates file only if not already installed
# other : http://www.danielclasson.com/2015/04/21/powershell-install-hotfixes-only-if-they-are-not-installed/ helped me.
# updates :
#       - 1.X (x/x/xxxx) :  

param (
    [string]$source = "F:\MAJ" #We can use the -source argument to precise the directory where the kb are. Default directory is F:\MAJ
    )

#################################
#DELETE KAV LOGS (NOT USED HERE)#
#################################
#$date_D=[dateTime]$(get-date)
#$date_B=$date_D.AddMonths(-12)
#
#Remove-Item -path 'C:\ProgramData\Kaspersky Lab' -Recurse -Filter *KES* -Include *.dmp | Where-Object { 
##    $_.LastWriteTime -le $(Get-Date $date_B) # we delete dmp files which have been modified more than a year ago
#}

###########################
########KBs UPDATES########
###########################

$KBArrayList = New-Object -TypeName System.Collections.ArrayList #KBs list

$KBs = Get-ChildItem -Recurse -Filter *x64*msu* "$source" | Select-Object Directory, Name #We only get the files with "x64" and "msu"

#foreach ($KB in $KBs.Name) { # $KBs.Name doesn't work with PowerShell 2. Ok with PowerShell 5.
foreach ($KB in $($KBs | select -ExpandProperty "Name")) { #In order to have PowerShell 2 compatibility
    $splitUp = $KB -split "kb" #Cut the name file with "kb" as separator
    $KB = "KB" + $splitUp[1].ToUpper() #We get the element n°1 (KB name). The element 0 is the path. ToUpper() convert the name in uppercase.
    $splitUp = $KB -split "-" #Cut the name file with "-" as separator
    $KB = $splitUp[0].ToUpper() #We get the element n°1 (KB name). The element 0 is the path. ToUpper() convert the name in uppercase.
    $KBArrayList.AddRange(@("$KB")) #We add the KN name to our KBArrayList list
}
Write-Host $KBArrayList #show all the KBs

foreach ($KB in $($KBArrayList | Where-Object { $_ -match ".*KB.*" } | select -Unique)) { #we remove duplicate KBs from the list and we only get elements where the word KB is present.
    if (-not(Get-HotFix -Id $KB)) {
        Write-Host "$KB update is going to be installed"
        $KB_dir = $KBs | Where-Object { $_.Name -match ".*$($KB.ToLower()).*" } | select -First 1 -expand Directory #get the directory where the KB is. First 1 allows to only get the first occurence. Expand allows to convert current objet in string format.
        $KB_name = $KBs | Where-Object { $_.Name -match ".*$($KB.ToLower()).*" } | select -First 1 -expand Name #get the KB name. First 1 allows to only get the first occurence. Expand allows to convert current objet in string format.
        Write-Host "Start-Process -FilePath wusa.exe -ArgumentList `"$KB_dir\$KB_name`" /quiet /norestart -Wait" #Show the command
        Start-Process -FilePath wusa.exe -ArgumentList "`"$KB_dir\$KB_name`" /quiet /norestart" -Wait #KB installation

    } else {
        Write-Host "$KB is already installed"
    }
}
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Contact :

contact mail address