Verify Windows Update PowellShell Script

I executed the following script to determine the patch level for a  specified list of servers.  

$servers = (Get-Content .\WinUpVer\Updates.txt)

 foreach ($server in $servers){

 Get-WmiObject -Class "win32_quickfixengineering" |
  Select-Object -Property "Description", "HotfixID",
  @{Name="InstalledOn"; Expression={([DateTime]($_.InstalledOn)).ToLocalTime()}} | Export-Csv -path "C:\WinUpVer\WinUpdateVerify.csv"
 }

Their 14 servers listed in my input file.  If you open the attached Excel file you will see there are more than a 168 line items returned after the script is executed.  I was hoping the script would give a one for one line item report.  Where is this other data coming from? How can I modify this script to get a one for one line item report. I also need to write the server name to the output.  How do I modify the to able to write the server name with the associated line item.  Any help with theses two issues will be appreciated.

See attached files.

Thank you,
Lipotech
Updates.txt
WinUpdateVerify.csv
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.

Toni UranjekConsultant/TrainerCommented:
First add another propetry to select-object cmdlet.

Select-Object -Property "PSComputername","Description", "HotfixID",
   @{Name="InstalledOn"; Expression={([DateTime]($_.InstalledOn)).ToLocalTime()}}

And run script again.
oBdACommented:
You're constantly overwriting the csv file, so what you're seeing is just the result for the last server in the list.
Try it like this:
$servers = (Get-Content .\WinUpVer\Updates.txt)
$servers | ForEach-Object {
	"Processing $_ ..." | Write-Host
	Get-WmiObject -Class "Win32_QuickFixEngineering" |
		Select-Object -Property `
			@{Name="ComputerName"; Expression={$_.PSComputerName}},
			"Description",
			"HotfixID",
			@{Name="InstalledOn"; Expression={([DateTime]($_.InstalledOn)).ToLocalTime()}}
} | 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
David Johnson, CD, MVPOwnerCommented:
everyone forgot get-wmiobject -computername parameter
Remove-Item "c:\test\Winupver\WinUpdateVerify.csv" -ErrorAction SilentlyContinue
[System.Collections.ArrayList]$results = New-Object System.Collections.ArrayList($null)
$servers = (Get-Content "c:\test\WinUpVer\Updates.txt")
foreach ($server in $servers) {	
    $updates = Get-WmiObject -Class "Win32_QuickFixEngineering" -ComputerName $server
    foreach ($update in $updates){
    $serverupdate = @{}
        $serverupdate = @{"ComputerName"=$server;
    			        "Description"=$update.Description;
			            "HotfixID"=$update.HotFixID;
                        "InstalledOn"= $update.InstalledON }
                        $results.add((New-Object -TypeName psobject -Property $serverupdate));
                        }
  
    }	
    $results | Export-Csv -nti -Encoding UTF8 -path "c:\test\Winupver\WinUpdateVerify.csv"
    

Open in new window

Defend Against the Q2 Top Security Threats

Were you aware that overall malware worldwide was down a surprising 42% from Q1'18? Every quarter, the WatchGuard Threat Lab releases an Internet Security Report that analyzes the top threat trends impacting companies worldwide. Learn more by viewing our on-demand webinar today!

lipotechSys EngAuthor Commented:
David,

When I run your version of the script it executes with no error, but the Excel spreadsheet is rewritten blank.

 Any further suggestions?

 $servers = (Get-Content .\WinUpVer\Updates.txt)
 $servers | ForEach-Object {
       "Processing $_ ..." | Write-Host
       Get-WmiObject -Class "Win32_QuickFixEngineering" |
             Select-Object -Property `
                   @{Name="ComputerName"; Expression={$_.PSComputerName}},
                   "Description",
                   "HotfixID",
                   @{Name="InstalledOn"; Expression={([DateTime]($_.InstalledOn)).ToLocalTime()}}
 } | Export-Csv -NoTypeInformation -Path "C:\WinUpVer\WinUpdateVerify.csv"

 Thank you,

 Lipotech
oBdACommented:
Corrected version, including proper error handling:
$servers = (Get-Content .\WinUpVer\Updates.txt)
$servers | ForEach-Object {
	$Server = $_
	"Processing $Server ... " | Write-Host -NoNewline
	Try {
		Get-WmiObject -Class "Win32_QuickFixEngineering" -ComputerName $Server -ErrorAction Stop |
			Select-Object -Property `
				@{Name="ComputerName"; Expression={$Server}},
				"Description",
				"HotfixID",
				@{Name="InstalledOn"; Expression={([DateTime]($_.InstalledOn)).ToLocalTime()}},
				"Error"
		"OK." | Write-Host -ForegroundColor Green
	} Catch {
		$_.Exception.Message | Select-Object -Property `
			@{Name="ComputerName"; Expression={$Server}},
			"Description",
			"HotfixID",
			"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:
David,

The script executed properly and the output content is presence.  As I asked in a previous reply, 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?

Thank you for the error handling construct.

 Lipotech
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
Powershell

From novice to tech pro — start learning today.