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?
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.
0
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

1

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

1
Top Threats of Q1 & How to Defend Against Them

WEBINAR: Join WatchGuard CTO and our Threat Research Team on Aug. 2nd to hear the findings from our Q1 Internet Security Report! Learn more about the top threats detected in the first quarter and how you can defend your business against them!

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
0
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

1
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
1
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.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.