Try something like this
$report = @()
$ErrorActionPreference = "SilentlyContinue"
If ($Error) {
$Error.Clear()
}
$updatesession=New-Object -ComObject Microsoft.update.session
$Criteria="IsInstalled=0 and Type=Software and IsHidden=0"
$searchresult=$updateSession.CreateupdateSearcher().Search("IsInstalled=0 and Type='Software' and IsHidden=0").Updates
$report = if(-not $searchresult.Count){
New-Object -TypeName PSObject -property @{
VM = $env:COMPUTERNAME
KB = ''
InstallStatus = 'There are no applicable updates for this computer.'
}
}
else{
$pendingdownloads=$searchresult | Where-Object {$_.IsDownloaded -eq $false}
if(($pendingdownloads |Select-Object IsDownloaded).count -ne '0'){
$downloadercall=$updatesession.CreateUpdateDownloader()
$downloadercall.Updates=New-Object -ComObject Microsoft.update.updatecoll
foreach($pendingdownload in $pendingdownloads){
[void]$downloadercall.Updates.add($pendingdownload)
$downloadercall.Download() |Out-Null
[void]$downloadercall.Updates.RemoveAt(0)
}
}
$updatesession=New-Object -ComObject Microsoft.update.session
$Criteria="IsInstalled=0 and Type=Software and IsHidden=0"
$searchresult=$updateSession.CreateupdateSearcher().Search("IsInstalled=0 and Type='Software' and IsHidden=0").Updates
$downloadedupdates = $searchresult | Where-Object {$_.IsDownloaded -eq $true}
$updatercall=$updatesession.CreateUpdateInstaller()
$updatercall.Updates= New-Object -ComObject Microsoft.update.updatecoll
foreach($singleupdate in $downloadedupdates){
[void]$updatercall.Updates.add($singleupdate)
$installstatus=$updatercall.install()
[void]$updatercall.Updates.RemoveAt(0)
New-Object -TypeName PSObject -property @{
VM = $env:COMPUTERNAME
KB = &{$kbnumb=$singleupdate.Title; $kbnumb.Substring($kbnumb.IndexOf("KB")).Trimend(")")}
InstallStatus = &{
if($installstatus.ResultCode -eq '2'){
'KBInstalled'
}
elseif($installstatus.ResultCode -eq '3'){
'KBInstall Succeeded with errors'
}
elseif($installstatus.ResultCode -eq '4'){
'Kb Failed to install'
}
elseif($installstatus.ResultCode -eq '5'){
'KBAborted'
}
}
}
}
}
$report | ConvertTo-Csv -NoTypeInformation
'@
$vmNames = 'TestVM01'
$tasks = @()
Get-VM -Name $vmNames -PipelineVariable vm |
ForEach-Object -Process {
$sInvoke = @{
VM = $vm
GuestUser = 'administrator'
GuestPassword = 'password'
ScriptText = $script
ScriptType = 'Powershell'
RunAsync = $true
Confirm = $false
}
$tasks += @{
VM = $vm
Task = Invoke-VMScript @sInvoke
}
}
Write-Host "Invoke Operation is performed on all the templates and waiting for results to be collected"
while($tasks.Task.State -contains 'Running'){
sleep 2
$tasks.Task.State
}
$tasks | ForEach-Object -Process {
if($_.Task.State -eq 'Success'){
$_.Task.Result.Scriptoutput | ConvertFrom-Csv |
Add-Member -MemberType NoteProperty -Name State -Value $_.Task.State -PassThru
}
else{
New-Object -TypeName PSObject -Property @{
VM = $_.VM.Name
KB = ''
InstallStatus = ''
State = $_.Task.State
}
}
} | Select VM,State,KB,InstallStatus
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference