<#
.Synopsis
Script to automatically keep SCVMM Baselines in sync with WSUS
.DESCRIPTION
Script that synchronizes WSUS Updates with SCVMM, both adding new updates and removes old inactive updates.
.EXAMPLE
Update-BaseLineUpdates $Baselinename
# Author
Current Author, Markus Lassfolk @Truesec
Original Author, Mikael Nyström @Truesec
# Version 1.2
Markus Lassfolk
- Added section to remove inactive updates
# Version 1.0
Markus Lassfolk
- Initial Release
# Version 0.5
Mikael Nyström
#>
Function Update-BaseLineUpdates{
Param
(
[Parameter(Mandatory=$false,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
ValueFromRemainingArguments=$false,
Position=0)]
[String]
$BaseLineName
)
$baseline = Get-SCBaseline -Name $BaseLineName
# Set-SCBaseline -Baseline $baseline -Name $BaseLineName -Description $BaseLineName -RemoveUpdates $baseline.Updates
write-host $baseline.UpdateCount : Current number of Updates in Baseline $BaseLineName
$addedUpdateList = ""
$addedUpdateList = @()
if ($baseline.UpdateCount -eq 0) {
write-host "No previous updates in" $BaselineName", adding all existing updates for" $BaseLineName "from WSUS"
$addedUpdateList += Get-SCUpdate | Where-Object -Property UpdateClassification -EQ -Value $BaseLineName | Where-Object -Property IsApproved -Like -Value "True" | Where-Object -Property IsDeclined -Like -Value "False"| Where-Object -Property IsExpired -Like -Value "False" | Where-Object -Property IsSuperseded -Like -Value "False" | Where-Object -Property Products -like "*Windows Server 2012*"
write-host $addedUpdateList.Count ": New updates to add in" $Baseline
Set-SCBaseline -Baseline $baseline -Name $BaseLineName -Description $BaseLineName -AddUpdates $addedUpdateList -RunAsynchronously
}
if ($baseline.UpdateCount -gt 0 ) {
write-host "Scanning Newest 500 WSUS Updates for matching updates for $BaselineName"
$LatestUpdates = Get-SCUpdate -Newest 500 | Where-Object -Property UpdateClassification -EQ -Value $BaseLineName | Where-Object -Property IsApproved -Like -Value "True" | Where-Object -Property IsDeclined -Like -Value "False"| Where-Object -Property IsExpired -Like -Value "False" | Where-Object -Property IsSuperseded -Like -Value "False" | Where-Object -Property Products -like "*Windows Server 2012*"
write-host $LatestUpdates.Count ": Updates found, verifying if update(s) already exist in" $BaseLineName
Compare-Object -ReferenceObject $baseline.Updates -DifferenceObject $LatestUpdates -IncludeEqual | % {
if($_.SideIndicator -eq '=>') { $addedUpdateList += Get-SCUpdate -ID $_.inputobject.id }
}
write-host $addedUpdateList.Count : New updates to be added to SCVMM for $BaseLineName
write-host $addedUpdateList | ft
Set-SCBaseline -Baseline $baseline -Name $BaseLineName -Description $BaseLineName -AddUpdate $addedupdateList -RunAsynchronously
}
write-host "Scan WSUS for Updates that should not be Checked anymore"
$remove = ""
$remove = @()
$removeUpdateList = ""
$removeUpdateList = @()
$remove += Get-SCUpdate | Where-Object -Property UpdateClassification -EQ -Value $BaseLineName | Where-Object -Property IsApproved -Like -Value "False" | Where-Object -Property Products -like "*Windows Server 2012*"
$remove += Get-SCUpdate | Where-Object -Property UpdateClassification -EQ -Value $BaseLineName | Where-Object -Property IsDeclined -Like -Value "True"| Where-Object -Property Products -like "*Windows Server 2012*"
$remove += Get-SCUpdate | Where-Object -Property UpdateClassification -EQ -Value $BaseLineName | Where-Object -Property IsExpired -Like -Value "True" | Where-Object -Property Products -like "*Windows Server 2012*"
$remove += Get-SCUpdate | Where-Object -Property UpdateClassification -EQ -Value $BaseLineName | Where-Object -Property IsSuperseded -Like -Value "True" | Where-Object -Property Products -like "*Windows Server 2012*"
write-host $remove.count "Remove Unapproved/Superseded/Expired/Declined updates"
Compare-Object -ReferenceObject $baseline.Updates -DifferenceObject $remove -IncludeEqual | % {
if($_.SideIndicator -eq '==') { $removeUpdateList += Get-SCUpdate -ID $_.inputobject.id }
}
Set-SCBaseline -Baseline $baseline -Name $BaseLineName -Description $BaseLineName -RemoveUpdates $RemoveupdateList
}
Function Add-BaseLine{
Param
(
[Parameter(Mandatory=$false,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
ValueFromRemainingArguments=$false,
Position=0)]
[String]
$BaseLineName
)
$baseline = New-SCBaseline -Name $BaseLineName -Description $BaseLineName
$scope = Get-SCVMHostGroup -Name "All Hosts"
Set-SCBaseline -Baseline $baseline -AddAssignmentScope $scope
$scope2 = Get-SCVMMManagedComputer
ForEach($Server in $scope2){
Set-SCBaseline -Baseline $baseline -Name $baseLine -AddAssignmentScope $Server
}
}
Write-Host "Synchronizing with WSUS Server"
Get-SCUpdateServer | Start-SCUpdateServerSynchronization
. Update-BaseLineUpdates "Security Updates"
. Update-BaseLineUpdates "Critical Updates"
. Update-BaseLineUpdates "Updates"
. Update-BaseLineUpdates "Update Rollups"
#. Update-BaseLineUpdates "Definition Updates"
#. Update-BaseLineUpdates "Service Packs"
#. Update-BaseLineUpdates "Feature Packs"
write-host "Start Compliance Scan for all Servers"
Get-SCVMMManagedComputer | Start-SCComplianceScan