Pulling Windows Update Information Remotely

by Lahru at 2013-03-19 12:50:56

I am trying to run the following bit of code from a windows 7 workstation against multiple servers. Some of these do NOT have powershell installed on them.

$Computers = Import-csv "c:\servers.csv"

foreach ($server in $computers)
$server = $computers.server
Get-WmiObject -Class Win32_QuickFixEngineering -computername $server | select-object hotfixID, installedon, description | export-csv "c:\updated$server.csv"

What I end up getting is a csv file labeled "Server01 Server02.csv" with the "select-object" information in it, but no indication as to which server each update belongs to.

What I WANT (if not readily understood by the above code) is to feed the -computername parameter its value from a csv file.
I want to create a CSV file for EACH server with the attendant output.

So what am I doing wrong please OR How do I correct/replace my code?
by MasterOfTheHat at 2013-03-19 13:37:36
You’re overwriting the $server object with a string that represents the server names in the csv file. When you use the foreach construct, you are creating an object called $server that represents a single element in the $computers array. That $server object is automatically replaced with the next element in the array on each iteration of the loop. Because of that, there is no reason to try and assign an element of the $computers array to the $server object, which I’m guessing is what you thought you were doing on 5.

The catch, though, is that you can’t just remove line 5 and run the script. Remember that $server is an object, which means it has properties and methods. The -ComputerName parameter of Get-WmiObject and the -Path parameter of Export-Csv both want strings, though, so you have to figure out which property of the $server object holds the string you want to use. Do that by piping the array created from Import-Csv to Get-Member:
> Import-Csv -Path C:\temp\servers.csv | Get-Member

TypeName: System.Management.Automation.PSCustomObject

Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Server NoteProperty System.String Server=jxtools01

Since the only column I have in that servers.csv file is the "Server" column, it’s pretty easy to see which property we need to use. So, using that property, here’s what your loop would look like:
$Computers = Import-csv "c:\temp\servers.csv"

foreach ($server in $computers)
Get-WmiObject -Class Win32_QuickFixEngineering -computername $server.server | select-object hotfixID, installedon, description | export-csv "c:\temp$($server.server).csv"

And, just because it’s posh and we can shove all of this to one line and get rid of that foreach programming construct:
Import-Csv -Path "c:\temp\servers.csv" | ForEach-Object { Get-WmiObject -Class Win32_QuickFixEngineering -ComputerName $.Server | Select-Object hotfixID, installedon, description | Export-Csv -Path "c:\temp$($.Server).csv" -NoTypeInformation }
by Lahru at 2013-03-19 14:35:54
Thank you so much, this is just what I needed. I am still trying to decipher your explanations, but it’s beginning to make more sense as I continue to reread them.