使用WMIC查询远程主机已安装产品时如何关联主机名?
Yes, you absolutely can modify your WMIC command to include hostnames in the results, or use a simple batch script to segment output by host. Here are two straightforward approaches:
Option 1: Include Hostname Directly in Query Results
WMI exposes a system property called __SERVER that returns the name of the remote host you're querying. You can add this to your get clause to tie each result line to its host:
wmic:root\cli>/node:@HOSTNAMES.txt /output:INSTALLS.txt product where "name like 'APPNAME'" get __SERVER,name,version
This will add a __SERVER column to your output, making it immediately clear which host each product entry belongs to.
Option 2: Batch Script for Per-Host Segmented Output
If you prefer cleaner, separated sections for each host (instead of a flat table), use a Windows batch script to loop through your host list and append results with a clear host header:
@echo off setlocal enabledelayedexpansion set "OUTPUT_FILE=INSTALLS.txt" :: Clear the output file first echo. > "%OUTPUT_FILE%" :: Loop through each hostname in the text file for /f %%h in (HOSTNAMES.txt) do ( echo === Results for Host: %%h === >> "%OUTPUT_FILE%" :: Run WMIC query for the current host and append results wmic /node:%%h product where "name like 'APPNAME'" get name,version /format:table >> "%OUTPUT_FILE%" echo. >> "%OUTPUT_FILE%" :: Add a blank line to separate hosts )
This script adds a distinct header for each host before its product results, making the output easy to scan. Note: If a host is unreachable, WMIC will write an error message to the file—you can add a ping check before the WMIC command to skip unresponsive hosts if needed.
Microsoft has deprecated WMIC in favor of PowerShell's CIM cmdlets, which are more powerful, flexible, and less error-prone. Here are two better modern alternatives:
PowerShell with Get-CimInstance
PowerShell's Get-CimInstance replaces WMIC, and it automatically includes the PSComputerName property (the remote host name) in results. You can export to CSV for easy sorting and filtering:
# Read host list from file $hosts = Get-Content -Path "HOSTNAMES.txt" # Loop through each host and query foreach ($host in $hosts) { try { Get-CimInstance -ClassName Win32_Product -ComputerName $host -Filter "Name like 'APPNAME'" | Select-Object PSComputerName, Name, Version | Export-Csv -Path "INSTALLS.csv" -Append -NoTypeInformation } catch { Write-Warning "Failed to query $host : $_" } }
CSV output is far easier to work with in spreadsheets or other tools compared to WMIC's plain text.
PowerShell Registry Query (Faster & Safer)
A critical note: The Win32_Product class (used by both WMIC and Get-CimInstance) triggers a Windows Installer consistency check every time it's queried. This can slow down remote hosts, trigger unexpected repair operations, or cause errors.
For a faster, safer approach, query the Windows Registry directly (where installed programs are normally registered):
$hosts = Get-Content -Path "HOSTNAMES.txt" foreach ($host in $hosts) { try { # Query 64-bit programs registry path $regPath64 = "\\$host\HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" Get-ItemProperty -Path $regPath64 -ErrorAction Stop | Where-Object { $_.DisplayName -like "*APPNAME*" } | Select-Object @{Name='PSComputerName'; Expression={$host}}, DisplayName, DisplayVersion | Export-Csv -Path "INSTALLS.csv" -Append -NoTypeInformation # Query 32-bit programs registry path (for 64-bit systems) $regPath32 = "\\$host\HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" Get-ItemProperty -Path $regPath32 -ErrorAction Stop | Where-Object { $_.DisplayName -like "*APPNAME*" } | Select-Object @{Name='PSComputerName'; Expression={$host}}, DisplayName, DisplayVersion | Export-Csv -Path "INSTALLS.csv" -Append -NoTypeInformation } catch { Write-Warning "Failed to query $host : $_" } }
This method avoids the Windows Installer overhead and works for both 32-bit and 64-bit applications.
内容的提问来源于stack exchange,提问作者Thomas Owen

