=====================Get_Missing_Updates.ps1=================
[CmdletBinding()]
param (
[Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string]$HostName=$Env:COMPUTERNAME,
[Parameter(Mandatory=$true)]
[string]$wsusscnPath,
[Parameter(Mandatory=$false)]
[string]$wuredistPath,
[Parameter(Mandatory=$false)]
[string]$MBSAPath
)
begin
{
$PipelineInput = (-not $PSBOUNDPARAMETERS.ContainsKey("HostName")) -and (-not $HostName)
If (!$MBSAPath) {$MBSAPath=$env:ProgramFiles}
$ExeFilePath = "$MBSAPath\Microsoft Baseline Security Analyzer 2\mbsacli.exe"
if (!(Test-Path $ExeFilePath)) {
Write-Host "$ExeFilePath not found" -ForegroundColor Red
Exit
}
If (!(Test-path $wsusscnPath)) {
Write-Host "$wsusscnPath not found" -ForegroundColor Red
Exit
}
[string]$MBSAVersion=$(Get-Item $ExeFilePath).versioninfo.productVersion
$CachePath=(join-path $env:LOCALAPPDATA "Microsoft\MBSA\$MBSAVersion\Cache")
If (!(Test-Path $CachePath))
{
Write-host "Creating cache folder: $CachePath"
New-Item -ItemType directory -Force $CachePath
}
If (!$wuredistPath){$wuredistPath=$(Join-Path $CachePath "wuredist.cab")}
If (!(Test-path $wuredistPath)) {
Write-Host "$wuredistPath not found" -ForegroundColor Red
Exit
}
if ($wuredistPath -ieq $(Join-Path $CachePath "wuredist.cab"))
{
Write-host "wuredist cab is: $wuredistPath"
}
Else
{
Write-host "Copying wuredist cab from $wuredistPath to $(Join-Path $CachePath "wuredist.cab")"
Copy-Item $wuredistPath $(Join-Path $CachePath "wuredist.cab") -Force
Write-host "wuredist cab is: $(Join-Path $CachePath "wuredist.cab")"
}
function New-Project
{
New-Object PSObject -Property @{
ComputerName=‘NoNeed‘
id = ‘NoNeed‘
KBID = ‘NoNeed‘
Title = ‘NoNeed‘
GUID = ‘NoNeed‘
IsInstalled = ‘NoNeed‘
Severity =‘NoNeed‘
BulletinID = ‘NoNeed‘
RestartRequired = ‘NoNeed‘
Type = ‘NoNeed‘
InformationURL=‘NoNeed‘
DownloadLink=‘NoNeed‘
}
} #End Function
function Get-MissingUpdates
{
Param([Parameter(Mandatory=$true)]
[string]$ComputerName)
try {
$ComputerName=$ComputerName.ToUpper()
[string]$LogDate=$(get-date -Format _yyyyMMdd_HHmmss)
Write-Host "=================================="
Write-Host "Start scanning $ComputerName"
Write-Host "=================================="
## Remove any previous reports
Get-Item "$($Env:USERPROFILE)\SecurityScans\$($Computername.Split(‘.‘)[0])$LogDate.mbsa" -ErrorAction ‘SilentlyContinue‘ | Remove-Item -Force -Recurse
## Run the report to create the output XML
& $ExeFilePath /target $ComputerName /n IIS+OS+Password+SQL /wi /nvc /mu /nd /qr /catalog $wsusscnPath /o %C%$LogDate
## Convert the report to XML so I can use it
[xml]$ScanResults = Get-Content "$($Env:USERPROFILE)\SecurityScans\$($Computername.Split(‘.‘)[0])$LogDate.mbsa"
$UpdateSeverityLabels = @{
‘0‘ = ‘Other‘
‘1‘ = ‘Low‘
‘2‘ = ‘Moderate‘
‘3‘ = ‘Important‘
‘4‘ = ‘Critical‘
}
$MissingUpdates = $ScanResults.SelectNodes("//Check/Detail/UpdateData[@IsInstalled=‘false‘]")
$ResultObjects = @()
foreach ($Update in $MissingUpdates) {
$UpdateTitle=$($Update | select -ExpandProperty Title)
$UpdateBulletinID=$($Update | select -ExpandProperty BulletinID)
If (!((($UpdateTitle -imatch ‘^Cumulative Security Update for Internet Explorer‘) -or ($UpdateTitle -imatch ‘^Security Update‘)) -and ($UpdateBulletinID -imatch ‘MS\d{2}\-\d{2,3}‘)))
{Continue}
$UpdateGUID=$($Update |select -expandproperty GUID)
$UpdateRef = $ScanResults.SelectNodes("//Check/Detail/UpdateData[@GUID=‘$UpdateGUID‘]/References")
$project = New-Project
$project.ComputerName = $Computername
$project.ID = $($Update |select -expandproperty ID)
$project.KBID = $($Update |select -expandproperty KBID)
$project.Title = $($Update |select -expandproperty Title)
$project.GUID = $($Update |select -expandproperty GUID)
$project.IsInstalled = $($Update |select -expandproperty IsInstalled)
$project.Severity = $UpdateSeverityLabels.[string]$($Update |select -expandproperty Severity)
$project.BulletinID = $($Update |select -expandproperty BulletinID)
$project.RestartRequired = $($Update |select -expandproperty RestartRequired)
$project.Type = $($Update |select -expandproperty Type)
$project.InformationURL = $UpdateRef | select -ExpandProperty InformationURL
$project.DownloadLink = $UpdateRef | select -ExpandProperty DownloadURL
$ResultObjects += $project
<#
$Properties = $Update | Get-Member -Type Property
foreach ($Prop in $Properties) {
$Value = ($Update | select -expandproperty $Prop.Name)
if ($Prop.Name -eq ‘Severity‘) {
$Value = $UpdateSeverityLabels[$Value]
}
$Ht[$Prop.Name] = $Value
}
#>
}
Write-Host "Scan finished for $ComputerName"
Write-Host ""
If(!$ResultObjects)
{
$ResultObjects = New-Project
$ResultObjects.ComputerName = $Computername
}
Return $ResultObjects | select ComputerName,BulletinID,KBID,Title,RestartRequired,Severity,IsInstalled,InformationURL,DownloadLink
} catch {
Write-Error "Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)"
Write-Host "Scan failed for $ComputerName"
$ErrResultObjects = New-Project
$ErrResultObjects.ComputerName = $Computername
$ErrResultObjects.ID = "ERROR"
$ErrResultObjects.KBID = "ERROR"
$ErrResultObjects.Title = "ERROR"
$ErrResultObjects.GUID = "ERROR"
$ErrResultObjects.IsInstalled = "ERROR"
$ErrResultObjects.Severity = "ERROR"
$ErrResultObjects.BulletinID = "ERROR"
$ErrResultObjects.RestartRequired = "ERROR"
$ErrResultObjects.Type = "ERROR"
$ErrResultObjects.InformationURL = "ERROR"
$ErrResultObjects.DownloadLink = "ERROR"
Return $ErrResultObjects | select ComputerName,BulletinID,KBID,Title,RestartRequired,Severity,IsInstalled,InformationURL,DownloadLink
}
}
}
process {
if ( $PipelineInput ) {
Get-MissingUpdates -ComputerName $_
}
else {
$HostName | foreach-object {
Get-MissingUpdates -ComputerName $_
}
}
}
#Get-MissingUpdates -ComputerName HKFIL7402WIN -wsusscnPath d:\wsusscn2.cab -MBSAPath "D:\Program Files"
====================MBSA_Export.ps1===========================
$location = (Get-Item ($MyInvocation.MyCommand.Definition)).DirectoryName
Set-Location $location
$list=cat .\MBSAList.txt -ErrorAction SilentlyContinue
if (!$list) {Write-Host "Cannot find MBSAList.txt or it‘s Null!" -ForegroundColor Red;exit}
$mbsa=$list | .\Get_Missing_Updates.ps1 -wsusscnPath .\wsusscn2.cab -wuredistPath .\wuredist.cab
$OutputFileDate=$(get-date)
$year=‘{0:d4}‘ -f $OutputFileDate.Year
$month=‘{0:d2}‘ -f $OutputFileDate.Month
$day=‘{0:d2}‘ -f $OutputFileDate.Day
$hour=‘{0:d2}‘ -f $OutputFileDate.Hour
$minute=‘{0:d2}‘ -f $OutputFileDate.Minute
$second=‘{0:d2}‘ -f $OutputFileDate.second
$OutputFileName = ‘MBSA_‘+[string]$year + [string]$month + [string]$day+ ‘_‘ + [string]$hour+ [string]$minute+ [string]$second + ".csv"
$mbsa | Export-Csv -NoTypeInformation $OutputFileName
=====================Run.ps1=========================
$location = (Get-Item ($MyInvocation.MyCommand.Definition)).DirectoryName
Set-Location $location
Start-Process powershell.exe -ArgumentList "-noprofile -file $location\MBSA_Export.ps1" -verb RunAs
=======================Run.bat==========================
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -file Run.ps1
=======================How to use===========================
How to use:
Install Version 2.1 MBSA on particular server, recommendif want to scan JP servers then install MBSA on a JP server, If want to scanHK then install on a HK server…otherpoles, and so on….BTW, please keep default setting during installation, it’s recommendation.
https://www.microsoft.com/en-us/download/details.aspx?id=19892
Download Offline catalog (Wsusscn2.cab). This isthe offline catalog file, and Microsoft willing upgrade it regularly (usually 1month, release around patching day) .
http://download.windowsupdate.com/microsoftupdate/v6/wsusscan/wsusscn2.cab
Download Authentication file (wuredist.cab).This authentication file allows the remote WUA client to respond to MBSA. Thisfile doesn’t update very often, but it’s very small.
http://update.microsoft.com/v8/microsoftupdate/redir/MUAuth.cab
Copy above 2 downloaded files to script directory.The files in script directory
Input all the servers’ name you want to scaninto MBSAList.txt.
Run “Run.bat” with your privileged account(almost are SA account), if popup UAC as below, please click Yes.
A powershell window will show you which serveris being scanned.
After all, once the scanning job is finished,you can see a MBSA_%Date%_%Time%.csv under script directory, use excel open it.
“no need”, this server isn’t missing criticalpatches.
“Error”, this server couldn’t be scanned, likeno access right or it is offline.
Other normal data, which patch is missing forthe server.
本文出自 “向神竖起中指” 博客,请务必保留此出处http://xrbenbeba.blog.51cto.com/492648/1726734
原文:http://xrbenbeba.blog.51cto.com/492648/1726734