Differentiation Between Multiple Windows Updates

I wrote a script that produces a report that will indicate the update status of each server on my domain.  When I review the report produced, I see that there are multiple entries in the report for a single server.  They are distinguished by the following descriptions:

Update or Security Update.  I understand the difference between the two descriptions.  

What I am trying to achieve is a method to extract the latest updates without getting all updates applied for the most recent patch release per server.

Does anyone have a script that meet the above requirements or suggestions on what modification(s) I should make to the attached script.
lipotechSys EngAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

lipotechSys EngAuthor Commented:
I wanted a bit more to description above.  is there a way to get the latest update per server and not multiple update items per server. For example, I would like the output file to appear as follows:

 Name                   Update             Security Update   Installed Date
 DBServer01         KB979687         KB2726236          7/26/2015
 RADServer01       KB979997         KB2726555          7/26/2015
 TXServer01          KB879767         KB2726535          7/26/2015

 Is there a way to use -Class "Win32_QuickFixEngineering" to achieve this format.  One Update and one Security Update per server.  See attached file.  This is the latest output file from the latest version of the script.  Is there a simple way to create the output file as an excel file format?

Lipotech
oBdACommented:
Try this then:
$servers = (Get-Content .\WinUpVer\Updates.txt)
$servers | ForEach-Object {
	$Server = $_
	"Processing $Server ... " | Write-Host -NoNewline -ForegroundColor White
	Try {
		$QFEGroups = Get-WmiObject -Class "Win32_QuickFixEngineering" -ComputerName $Server -ErrorAction Stop |
			Select-Object -Property `
				"Description",
				"HotfixID",
				@{Name="InstalledOn"; Expression={([DateTime]($_.InstalledOn)).ToLocalTime()}} |
			Group-Object -Property Description
		$LastHotfix = ($QFEGroups | ? {$_.Name -eq "Hotfix"}).Group | Sort-Object -Property InstalledOn | Select-Object -Last 1
		$LastUpdate = ($QFEGroups | ? {$_.Name -eq "Update"}).Group | Sort-Object -Property InstalledOn | Select-Object -Last 1
		$LastSecurityUpdate = ($QFEGroups | ? {$_.Name -eq "Security Update"}).Group | Sort-Object -Property InstalledOn | Select-Object -Last 1
		"" | Select-Object -Property `
			@{Name="ComputerName"; Expression={$Server}},
			@{Name="Hotfix"; Expression={$LastHotfix.HotfixID}},
			@{Name="HF_InstalledOn"; Expression={$LastHotfix.InstalledOn}},
			@{Name="Update"; Expression={$LastUpdate.HotfixID}},
			@{Name="UP_InstalledOn"; Expression={$LastUpdate.InstalledOn}},
			@{Name="Security Update"; Expression={$LastSecurityUpdate.HotfixID}},
			@{Name="SU_InstalledOn"; Expression={$LastSecurityUpdate.InstalledOn}},
			"Error"
		"OK." | Write-Host -ForegroundColor Green
	} Catch {
		$_.Exception.Message | Select-Object -Property `
			@{Name="ComputerName"; Expression={$Server}},
			"Hotfix",
			"HF_InstalledOn",
			"Update",
			"UP_InstalledOn",
			"Security Update",
			"SU_InstalledOn",
			@{Name="Error"; Expression={$_}}
		$_.Exception.Message | Write-Host -ForegroundColor Red
	}
} | Export-Csv -NoTypeInformation -Path "C:\WinUpVer\WinUpdateVerify.csv"

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
lipotechSys EngAuthor Commented:
oBdA,

That modification worked! Thank you.  One final question.  The script is currently reading the input from the Updates.txt file to the machine name.  How would I read another column in the text that held a string that represents a name. For example "John Doe" would be the person responsible for the machine.

Example file:

Column#1           Column#2
DCRADUIS           John Doe

The string in Column#2 will be on the same row as Column#1

Would I add a variable $Respon and add or modify @{Name in some way?

Lipotech
SD-WAN: Making It Work for You

As bandwidth requirements and Internet costs grow, businesses naturally want to manage budgets by reducing reliance on their most expensive connection types. Learn more about how to make SD-WAN work for your business in our on-demand webinar!

oBdACommented:
Prepare the text file as csv with a header line::
ComputerName,Responsible
DCRADUIS,John Doe

Open in new window

Then use this:
$servers = Import-Csv -Path .\WinUpVer\Updates.csv
$servers | ForEach-Object {
	$Server = $_
	"Processing $($Server.ComputerName) ... " | Write-Host -NoNewline -ForegroundColor White
	Try {
		$QFEGroups = Get-WmiObject -Class "Win32_QuickFixEngineering" -ComputerName $Server.ComputerName -ErrorAction Stop |
			Select-Object -Property `
				"Description",
				"HotfixID",
				@{Name="InstalledOn"; Expression={([DateTime]($_.InstalledOn)).ToLocalTime()}} |
			Group-Object -Property Description
		$LastHotfix = ($QFEGroups | ? {$_.Name -eq "Hotfix"}).Group | Sort-Object -Property InstalledOn | Select-Object -Last 1
		$LastUpdate = ($QFEGroups | ? {$_.Name -eq "Update"}).Group | Sort-Object -Property InstalledOn | Select-Object -Last 1
		$LastSecurityUpdate = ($QFEGroups | ? {$_.Name -eq "Security Update"}).Group | Sort-Object -Property InstalledOn | Select-Object -Last 1
		"" | Select-Object -Property `
			@{Name="ComputerName"; Expression={$Server.ComputerName}},
			@{Name="Responsible"; Expression={$Server.Responsible}},
			@{Name="Hotfix"; Expression={$LastHotfix.HotfixID}},
			@{Name="HF_InstalledOn"; Expression={$LastHotfix.InstalledOn}},
			@{Name="Update"; Expression={$LastUpdate.HotfixID}},
			@{Name="UP_InstalledOn"; Expression={$LastUpdate.InstalledOn}},
			@{Name="Security Update"; Expression={$LastSecurityUpdate.HotfixID}},
			@{Name="SU_InstalledOn"; Expression={$LastSecurityUpdate.InstalledOn}},
			"Error"
		"OK." | Write-Host -ForegroundColor Green
	} Catch {
		$_.Exception.Message | Select-Object -Property `
			@{Name="ComputerName"; Expression={$Server.ComputerName}},
			@{Name="Responsible"; Expression={$Server.Responsible}},
			"Hotfix",
			"HF_InstalledOn",
			"Update",
			"UP_InstalledOn",
			"Security Update",
			"SU_InstalledOn",
			@{Name="Error"; Expression={$_}}
		$_.Exception.Message | Write-Host -ForegroundColor Red
	}
} | Export-Csv -NoTypeInformation -Path "C:\WinUpVer\WinUpdateVerify.csv"

Open in new window

lipotechSys EngAuthor Commented:
oBdA,,

It worked like a charm. Thank you.

Excellent support.

Lipotech
lipotechSys EngAuthor Commented:
Excellent support.  Bravo!!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Windows Server 2008

From novice to tech pro — start learning today.