问题描述
在尝试查询 Win32_Product
以查找软件版本后,我不明白为什么结果如此之慢.比查询 Win32_service
或 Win32_process
慢 15 倍.所以来这里看看我是否遗漏了什么,我发现其他人报告了同样的问题,而这个 文章 解释了原因.
After playing around with querying Win32_Product
to find a software version, I couldn't understand why the results were so dog-slow. As much as 15 times slower than querying Win32_service
or Win32_process
. So coming here to see if I'm missing something, I find that others have reported the same issue, and this article explains why.
最常建议的替代查找已安装软件的方法是查询一个或三个注册表项.这将是我的第一个解决方案,但我的公司还没有开始配置服务器以接受 PSRemoting
.任何 reg 查询只会返回 Kerberos 身份验证错误.我可以在单个服务器上启用 PSRemoting
,但我的团队支持 30K 系统.这样解决方案就出来了.
The most-often suggested alternative to finding installed software is querying a registry entry or three. That was going to be my first solution, except my company hasn't moved to configure servers to accept PSRemoting
yet. Any reg queries just return Kerberos authentication errors. I can enable PSRemoting
on individual servers, but my team supports 30K systems. So that solution is out.
最重要的是,我们正在将 Symantec Endpoint Protection 从 v. 11 升级到 v. 12,我想简单检查一下服务器上安装的版本.除了 Win32_Product
和注册表查询之外,还有其他方法可以找到版本吗?
Bottom line, we're upgrading Symantec Endpoint Protection from v. 11 to v. 12, and I want a simple check to find what version is installed on a server. Are there any alternatives to find the version other than Win32_Product
and registry queries?
推荐答案
我远程使用注册表,没有 PSRemoting.下面是我自己写的,每天用来查询软件的函数.
I use the registry remotely, without PSRemoting. Here's the function I wrote and use daily to query software.
Function Get-RemoteSoftware{
<#
.SYNOPSIS
Displays all software listed in the registry on a given computer.
.DESCRIPTION
Uses the SOFTWARE registry keys (both 32 and 64bit) to list the name, version, vendor, and uninstall string for each software entry on a given computer.
.EXAMPLE
C:\PS> Get-RemoteSoftware -ComputerName SERVER1
This shows the software installed on SERVER1.
#>
param (
[Parameter(mandatory=$true,ValueFromPipelineByPropertyName=$true)][string[]]
# Specifies the computer name to connect to
$ComputerName
)
Process {
foreach ($Computer in $ComputerName)
{
#Open Remote Base
$reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$Computer)
#Check if it's got 64bit regkeys
$keyRootSoftware = $reg.OpenSubKey("SOFTWARE")
[bool]$is64 = ($keyRootSoftware.GetSubKeyNames() | ? {$_ -eq 'WOW6432Node'} | Measure-Object).Count
$keyRootSoftware.Close()
#Get all of they keys into a list
$softwareKeys = @()
if ($is64){
$pathUninstall64 = "SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
$keyUninstall64 = $reg.OpenSubKey($pathUninstall64)
$keyUninstall64.GetSubKeyNames() | % {
$softwareKeys += $pathUninstall64 + "\\" + $_
}
$keyUninstall64.Close()
}
$pathUninstall32 = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
$keyUninstall32 = $reg.OpenSubKey($pathUninstall32)
$keyUninstall32.GetSubKeyNames() | % {
$softwareKeys += $pathUninstall32 + "\\" + $_
}
$keyUninstall32.Close()
#Get information from all the keys
$softwareKeys | % {
$subkey=$reg.OpenSubKey($_)
if ($subkey.GetValue("DisplayName")){
$installDate = $null
if ($subkey.GetValue("InstallDate") -match "/"){
$installDate = Get-Date $subkey.GetValue("InstallDate")
}
elseif ($subkey.GetValue("InstallDate").length -eq 8){
$installDate = Get-Date $subkey.GetValue("InstallDate").Insert(6,".").Insert(4,".")
}
New-Object PSObject -Property @{
ComputerName = $Computer
Name = $subkey.GetValue("DisplayName")
Version = $subKey.GetValue("DisplayVersion")
Vendor = $subkey.GetValue("Publisher")
UninstallString = $subkey.GetValue("UninstallString")
InstallDate = $installDate
}
}
$subkey.Close()
}
$reg.Close()
}
}
}
这篇关于Win32_Product 的替代品?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!