Reputation: 63
I am using PS V3.0 to check Google chrome version:
get-content -Path C:\Support\assets.txt | ForEach-Object ({get-wmiobject win32_product -ComputerName $_ | where-Object {$_.name -eq "google chrome"} |FT version})
{write-host "$_"}
Inside the txt file are the IP addresses of remote devices.
The command is working fine and gives me Chrome version, but I cannot include IP address inside the loop.
It gives me only chrome version without information to which remote device it's from. I would like to get something like this :
IP address - Chrome version IP address - Chrome version
As far as I understand this it should be Foreach (action){do something}
?
Also is there any chance to remove word "version" from the input?
Upvotes: 3
Views: 6152
Reputation: 36297
Ok, you've made some very innocent beginner type mistakes, but that's fairly easily remedied.
Let's start with ft
. ft
is short for Format-Table
. Generally speaking, you only use a Format-
command when you are trying to output something. You are trying to use the results of that, not output it, so we need to drop the ft
. Instead use the Select-Object
cmdlet (or more commonly used is the shorter select
).
get-content -Path C:\Support\assets.txt | ForEach-Object ({get-wmiobject win32_product -ComputerName $_ | where-Object {$_.name -eq "google chrome"} |Select version})
Ok, that gets you an array of objects that only have the Version
property. Not super useful, especially when you wanted to know what computer each is associated with! So, that's a good lesson in general, but not very practical here. Let's move on with actually making things better!
You are making things harder than need be by piping things to a ForEach
loop like that. You are making separate Get-WMIObject
calls against each IP address. If we look at get-help get-wmiobject -parameter computername
we can see that it accepts an array of strings. So we can make 1 call against multiple targets, which should help speed things up a bit.
$IPList = get-content -Path C:\Support\assets.txt
Get-WMIObject win32_product -ComputerName $IPList | Where{$_.Name -eq 'Google Chrome'}
That should speed up your results a bit, but what will make things a whole lot faster is to use Get-WMIObject
's -Filter
parameter instead of Where
. The reason is that the provider is more efficient at filtering its own objects, and returning just what you want, than PowerShell is as filtering things. Also, this reduces the data sent back from the remote machines, so you are only getting the data you want from them rather than potentially hundreds of results per machine, and then parsing down to just the ones you want. Essentially you have all of the computers' processors working on your problem, instead of just yours. So let's use the -Filter
parameter:
$IPList = get-content -Path C:\Support\assets.txt
Get-WMIObject win32_product -ComputerName $IPList -Filter "Name='Google Chrome'"
Ok, things should come back a whole lot faster now. So down to the last item, you want the computer name for what each version was found on. Good news, you already have it! Well, we have the actual name of the computer, not the IP address that you specified. It is not displayed by default, but each one of those results has a PSComputerName
property that you can refer to. We can simply pipe to Select
and specify the properties that we want:
$IPList = get-content -Path C:\Support\assets.txt
Get-WMIObject win32_product -ComputerName $IPList -Filter "Name='Google Chrome'" | Select PSComputerName,Version
That's probably going to get you results that you're happy with. If not, you can run it through a ForEach
loop similarly to how you were, and format it like you specified:
$IPList = get-content -Path C:\Support\assets.txt
ForEach($IP in $IPList){
$Version = Get-WMIObject win32_product -ComputerName $IP -Filter "Name='Google Chrome'" | Select -Expand Version
"$IP - $Version"
}
Upvotes: 2