Automate MBSA scan and download missing patches

Posted by

Many of you are using MBSA, Microsoft Baseline Security Analyzer, to get a list of missing patches for Windows and Microsoft applications. If you want to learn more about automate the scan and automatically download the patches here are some tips and a script that will help you to save time!

MBSA Web Site, http://go.microsoft.com/fwlink/?linkid=20567
Download MBSA 2.3, http://www.microsoft.com/en-us/download/details.aspx?id=7558

So go download the tool and browse to the installed folder and you will find mbsacli.exe. This is the command you want to use for automate your scans! If you want just information about the missing patches, add the parameter /xmlout.

image

Example: MBSACLI /xmlout /catalog c:\temp\wsusscn2.cab /unicode >updates.xml

If you take a closer look at the XML file in Internet Explorer you will notice it is easy to read and browse the content, you can even copy the Download URL and paste into Internet Explorer to download the patch.

image

But hold on, that is just too time consuming.. If you use PowerShell you can perform all these steps automatically.

Following PowerShell example script will browse the XML content, download all the missing patches, and even create a batch file for you to install all the patches in one click! I hope this will help you to save time and do some fun stuff instead!

(Added 2015-03-27) Copy the script below, paste it into Notepad or PowerShell ISE and save it as GetUpdates.ps1 in the same folder as the Updates.xml file. To run the script, open a command prompt or a PowerShell prompt and type “Powershell .\GetUpdates.ps1” when you are located in the same directory as the script.

$UpdateXML = “updates.xml”
$toFolder = “c:\temp\”
$installFile = $toFolder +”\_Install.bat”

#Initialize webclient for downloading files
$webclient = New-Object Net.Webclient
$webClient.UseDefaultCredentials = $true

# Get the content of the XML file
$Updates = [xml](Get-Content $UpdateXML)

“@Echo Off” | Out-File $installFile
“REM This will install all patches” | Out-File $installFile -Append

foreach ($Check in $Updates.XMLOut.Check)
{
Write-Host “Checking for”, $Check.Name
Write-Host $Check.Advice.ToString()

#Checking for files to download
foreach ($UpdateData in $Check.Detail.UpdateData)
{
if ($UpdateData.IsInstalled -eq $false)
{
Write-Host “Download the file for KB”, $UpdateData.KBID
Write-Host “Starting download “, $UpdateData.Title, “.”
$url = [URI]$UpdateData.References.DownloadURL
$fileName = $url.Segments[$url.Segments.Count – 1]
$toFile = $toFolder +”\”+ $fileName
#$webClient.DownloadFile($url, $toFile)
Write-Host “Done downloading”

“@ECHO Starting installing “+ $fileName | Out-File $installFile -Append
if ($fileName.EndsWith(“.msu”))
{
“wusa.exe “+ $fileName + ” /quiet /norestart /log:%SystemRoot%\Temp\KB”+$UpdateData.KBID+”.log” | Out-File $installFile -Append
}
elseif ($fileName.EndsWith(“.cab”))
{
“start /wait pkgmgr.exe /ip /m:”+ $fileName + ” /quiet /nostart /l:%SystemRoot%\Temp\KB”+$UpdateData.KBID+”.log” | Out-File $installFile -Append
}
else
{
$fileName + ” /passive /norestart /log %SystemRoot%\Temp\KB”+$UpdateData.KBID+”.log” | Out-File $installFile -Append
}
“@ECHO Installation returned %ERRORLEVEL%” | Out-File $installFile -Append
“@ECHO.” | Out-File $installFile -Append
Write-Host
}
}

Write-Host
}

10 comments

  1. Hi,

    Just got into MBSA, and like it a lot more than using OfflineWUS. Rather than having to install MBSA onto a new build computer everytime I do one (Frequenetly), what would be required for me to run this all from a USB Key?

    I am assuming I will need as a minimum MBSACli, wusscan.dll and then would be a case of downloading the latest “wusscn2.cab” each time, then copying your script to the same location and running it in PS (Admin)….. OR can you think of a better way, maybe easier way?

    Like

  2. First, I love the concept of what you have written here. It will be even better if I can get it to work! My first error happens at this command in your script: # Get the content of the XML file
    $Updates = [xml](Get-Content $UpdateXML)

    My Error
    Get-Content : Cannot find path ‘C:\temp\updates.xml’ because it does not exist.
    At line:1 char:29
    + $Updates = [xml](Get-Content <<<< $UpdateXML)
    + CategoryInfo : ObjectNotFound: (C:\temp\updates.xml:String) [Get-Content], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

    This seems right as I don't have a file called updates.xml in that directory. I do have the results.xml in this directory as I piped it there instead of the MBSA install directory. Should I rename results.xml to updaters.xml? I have tried that to no avail.

    Can you point me in the right direction to get this to work?

    Thanks in advance!

    David

    Like

    1. Mattias, thanks for the quick reply! I’m not sure what you meant by a type as I don’t see anything “fixed”. I would like to share what I’ve done and the results to see if we can get this to work as it’s the only script out there that fits what I’m doing perfectly!

      First I renamed the results.xml file to updates.xml. This got rid of the missing file error.

      The script seems to run from there, but I emphasize “seems” to run. Here is a copy of where I’m at after executing your script:

      PS C:\temp> $UpdateXML = “updates.xml”
      PS C:\temp> $toFolder = “c:\temp\”
      PS C:\temp> $installFile = $toFolder +”\_Install.bat”
      PS C:\temp>
      PS C:\temp> #Initialize webclient for downloading files
      PS C:\temp> $webclient = New-Object Net.Webclient
      PS C:\temp> $webClient.UseDefaultCredentials = $true
      PS C:\temp>
      PS C:\temp> # Get the content of the XML file
      PS C:\temp> $Updates = [xml](Get-Content $UpdateXML)
      PS C:\temp>
      PS C:\temp> “@Echo Off” | Out-File $installFile
      PS C:\temp> “REM This will install all patches” | Out-File $installFile -Append
      PS C:\temp>
      PS C:\temp> foreach ($Check in $Updates.XMLOut.Check)
      >> {
      >> Write-Host “Checking for”, $Check.Name
      >> Write-Host $Check.Advice.ToString()
      >>
      >> #Checking for files to download
      >> foreach ($UpdateData in $Check.Detail.UpdateData)
      >> {
      >> if ($UpdateData.IsInstalled -eq $false)
      >> {
      >> Write-Host “Download the file for KB”, $UpdateData.KBID
      >> Write-Host “Starting download “, $UpdateData.Title, “.”
      >> $url = [URI]$UpdateData.References.DownloadURL
      >> $fileName = $url.Segments[$url.Segments.Count – 1]
      >> $toFile = $toFolder +”\”+ $fileName
      >> #$webClient.DownloadFile($url, $toFile)
      >> Write-Host “Done downloading”
      >>
      >> “@ECHO Starting installing “+ $fileName | Out-File $installFile -Append
      >> if ($fileName.EndsWith(“.msu”))
      >> {
      >> “wusa.exe “+ $fileName + ” /quiet /norestart /log:%SystemRoot%\Temp\KB”+$UpdateData.KBID+”.log” | Out-File $installFi
      le -Append
      >> }
      >> elseif ($fileName.EndsWith(“.cab”))
      >> {
      >> “start /wait pkgmgr.exe /ip /m:”+ $fileName + ” /quiet /nostart /l:%SystemRoot%\Temp\KB”+$UpdateData.KBID+”.log” | Ou
      t-File $installFile -Append
      >> }
      >> else
      >> {
      >> $fileName + ” /passive /norestart /log %SystemRoot%\Temp\KB”+$UpdateData.KBID+”.log” | Out-File $installFile -Append
      >> }
      >> “@ECHO Installation returned %ERRORLEVEL%” | Out-File $installFile -Append
      >> “@ECHO.” | Out-File $installFile -Append
      >> Write-Host
      >> }
      >> }
      >>
      >> Write-Host
      >> }

      The batch file has almost nothing in it and certainly nothing to call and execute. Here is the contents of _Install.bat:

      @Echo Off
      REM This will install all patches

      Nothing looks quite right here… I’m hoping you can help.

      David

      Like

    2. Sorry for the delay, first make sure the update.xml is not empty. Second thing I recommend is to paste the script into notepad and save the file as exportupdates.ps1 and run from the command prompt powershell .\exportupdates.ps1

      Like

  3. This is very interesting, You are an excessively skilled
    blogger. I have joined your rss feed and look forward to in quest of
    more of your excellent post. Additionally, I have shared your web site in my social networks

    Like

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.