How to get hot-fix details on multiple computers

Hi All,

I have the below script to get the hot fix details on multiple computers. For some reason i am not able to get installedby details. Any help is appreciated.

$filePath =“C:\temp\servers.txt”

$computers = Get-Content “c:\temp\Servers.txt”

foreach ($computer in $computers) {

Try {

$session = [activator]::CreateInstance([type]::GetTypeFromProgID(“Microsoft.Update.Session”,$computer))

$searcher = $session.CreateUpdateSearcher()

$historyCount = $searcher.GetTotalHistoryCount()

$hotfixes = $searcher.QueryHistory(0, $historyCount)

} catch {}

# custom output object

$objOutput = @()

“Processing hotfixes for: $($computer) …”

#Iterating and finding updates

foreach ($update in $hotfixes) {

# 1 means in progress and 2 means succeeded

if ($update.operation -eq 1 -and $update.resultcode -eq 2) {

$objOutput += New-Object -Type PSObject -Prop @{

‘ComputerName’=$computer

‘InstalledOn’=$update.date

‘KB’=[regex]::match($update.Title,‘KB(\d+)’)

‘UpdateTitle’=$update.title

‘By’=$update.InstalledBy

}

}

}

$objOutput | Export-Csv “c:\temp\Hotfixes.csv” -NoTypeInformation

}

Thank You

Bit difficult tor read… can you edit the post and use the pre tags/gist to format the code, you can follow below post for instructions…

https://powershell.org/forums/topic/read-me-before-posting-youll-be-glad-you-did/

Formatted for readability:


$filePath =“C:\temp\servers.txt”
$computers = Get-Content “c:\temp\Servers.txt”

foreach ($computer in $computers) {

Try {

    $session = [activator]::CreateInstance([type]::GetTypeFromProgID(“Microsoft.Update.Session”,$computer))
    $searcher = $session.CreateUpdateSearcher()
    $historyCount = $searcher.GetTotalHistoryCount()
    $hotfixes = $searcher.QueryHistory(0, $historyCount)

} catch {}

# custom output object
$objOutput = @()
"Processing hotfixes for: $($computer) ..."

#Iterating and finding updates
foreach ($update in $hotfixes) {

    # 1 means in progress and 2 means succeeded
    if ($update.operation -eq 1 -and $update.resultcode -eq 2) {
        $objOutput += New-Object -Type PSObject -Prop @{
            'ComputerName'=$computer
            'InstalledOn'=$update.date
            'KB'=[regex]::match($update.Title,'KB(\d+)')
            'UpdateTitle'=$update.title
            'By'=$update.InstalledBy

        } #$objOutput

    } #if $update

} #foreach $update

$objOutput | Export-Csv "c:\temp\Hotfixes.csv" -NoTypeInformation

} #foreach $computer


I think the output from QueryHistory() doesn’t contain an “InstalledBy” property, as per this technet post. You should try
$hotfixes | Get-Member
to verify what properties are available.

Just wondering why do we have to reinvent the wheel? try something like this?

$computers = Get-Content "c:\temp\Servers.txt"
$AllReport = @()
foreach ($omputer in $computers){
$Hotfix = Get-HotFix -ComputerName $computer

$AllReport += $Hotfix

} #foreach $computer

$AllReport | Export-Csv "c:\temp\Hotfixes.csv" -NoTypeInformation

There are pre-built script for this use case on the MS powershellgallery.com and many resource on the web that you can use as is or tweak as needed.

There are even whole modules you can download, install and use.

Examples:

PowerShell script to list all installed Microsoft Windows Updates https://gallery.technet.microsoft.com/scriptcenter/PowerShell-script-to-list-0955fe87

PSWindowsUpdate 2.1.1.2
https://www.powershellgallery.com/packages/PSWindowsUpdate/2.1.1.2


Or this…

# Find Missing updates
$UpdateSession = New-Object -ComObject Microsoft.Update.Session
$UpdateSearcher = $UpdateSession.CreateupdateSearcher()
$Updates = @($UpdateSearcher.Search("IsHidden=0 and IsInstalled=0").Updates)
$Updates | 
ForEach-Object {
    $pattern = 'KB\d{6,9}'
    if ($_.Title -match $pattern)
    { $kb = $matches[0] }
    else { kb = 'N/A' 
}

    [PSCustomObject]@{
        Title = $_.Title
        KB = $kb
    }
}

Or just a one-liner

$env:COMPUTERNAME | 
ForEach {
    Get-HotFix -ComputerName $PSItem | 
    Select HotfixID, Description, InstalledOn | 
    Sort-Object InstalledOn
}

# Results...
HotfixID  Description     InstalledOn           
--------  -----------     -----------           
KB4465664 Security Update 11/22/2018 12:00:00 AM
KB4470502 Update          12/13/2018 12:00:00 AM
KB4470788 Security Update 12/13/2018 12:00:00 AM

Thank you Grokitt.

Shinish, i am just looking for Computername, Description, installedon, InstalledBy, KBarticle and servicepackineffect details only.

i am finding it hard to get the below correct from my script. i am not getting who installed the particular update. Rest of the script works just fine for my requirement.

‘By’=$update.InstalledBy

You’re welcome, but I think you missed the end of my post:

[quote quote=161268]I think the output from QueryHistory() doesn’t contain an “InstalledBy” property, as per this technet post. You should try

$hotfixes | Get-Member

to verify what properties are available.[/quote]

Well, as mentioned by #grokkit installedby is not an option

PS C:\WINDOWS\system32> $update | gm


TypeName: System.__ComObject#{c2bfb780-4539-4132-ab8c-0a8772013ab6}

Name MemberType Definition 
---- ---------- ---------- 
Categories Property ICategoryCollection Categories () {get} 
ClientApplicationID Property string ClientApplicationID () {get} 
Date Property Date Date () {get} 
Description Property string Description () {get} 
HResult Property int HResult () {get} 
Operation Property UpdateOperation Operation () {get} 
ResultCode Property OperationResultCode ResultCode () {get} 
ServerSelection Property ServerSelection ServerSelection () {get} 
ServiceID Property string ServiceID () {get} 
SupportUrl Property string SupportUrl () {get} 
Title Property string Title () {get} 
UninstallationNotes Property string UninstallationNotes () {get} 
UninstallationSteps Property IStringCollection UninstallationSteps () {get} 
UnmappedResultCode Property int UnmappedResultCode () {get} 
UpdateIdentity Property IUpdateIdentity UpdateIdentity () {get}