Back to Basics: Use PowerShell to Search Servers for Specific Software
An old acquaintance, Mr. Rupert Torquil-Smythe Esq. (yes, it is he), recently wanted to know whether a certain piece of software was installed on a particular list of servers in his test lab.
I asked him for the list of servers (servers.txt) and the name of the software (Python). I then wrote and ran this:
$Servers = Get-Content -Path .\servers.txt
foreach ($Server in $Servers) {
$Found = (Get-WmiObject -ComputerName $Server -Query {select name from win32_product where name like '%Python%'} -ErrorAction SilentlyContinue).Name
if ($Found) {
Add-Content -Path .\output.txt -Value "================"
Add-Content -Path .\output.txt -Value "$Server"
Add-Content -Path .\output.txt -Value "================"
foreach ($Entry in $Found) {
Add-Content -Path .\output.txt -Value $Entry
}
Add-Content -Path .\output.txt -Value " "
}
}
We end up with a text file (output.txt) containing details of each server that has Python installed.
Things to note:
- servers.txt is read and stored as a variable ( $Servers)
- we use WMI to query each of the remote servers, from $Servers, in a foreach loop
- the query string is WQL
- we only ask for the name property to be returned (select name is more efficient than select * )
- % allows for a wildcard search, e.g. any number of characters before and after Python
- Win32reg_AddRemovePrograms rather than Win32_Product should be used in production environments
Comments
- Anonymous
March 25, 2016
has ms changed its opinion on win32_product, previously they'd mention to not use it in production. Don't really remember the issue. - Anonymous
March 25, 2016
cool stuff
thanks - Anonymous
March 26, 2016
@tony - Thank you... and I believe you are referring to this: https://support.microsoft.com/en-gb/kb/974524
The work-around (Win32reg_AddRemovePrograms) involves having an SCCM agent installed, so won't be an option for everyone. Even on Windows Server 2012 R2, Win32_Product will produce the described behaviour (re-evaluation and potential repair), so use with caution!
My esteemed friend, of course, only has servers in a test lab :) - Anonymous
March 26, 2016
a - Anonymous
August 05, 2016
A very handy script for a windows system administrator, thanks for sharing. - Anonymous
September 06, 2017
The Win32reg_AddRemovePrograms class does not have a 'Name" property. It only has a "DisplayName' so you would have to edit the query like so:$Found = (Get-WmiObject -Query {select DisplayName from win32reg_AddRemovePrograms where DisplayName like '%Microsoft%'} -ErrorAction SilentlyContinue).DisplayName