使用 PowerShell 使用升级代码查找产品版本
Finding product version using upgrade code using PowerShell
我必须使用 upgrade codes 更新一些产品 (MSI),我有所有此类产品的升级代码列表。现在要推送更新,我需要比较每个产品的版本。
在这种情况下如何查找产品版本?
喜欢:
gwmi win32_product | Where-Object {$_.Name -like "name"}
但是这个用了名字,我想找只用升级码的版本
在 PowerShell 中完成您要查找的内容的最简单方法是使用以下 WMI 查询来获取属于 UpgradeCode 系列的程序包。
$UpgradeCode = '{AA783A14-A7A3-3D33-95F0-9A351D530011}'
$ProductGUIDs = @(Get-WmiObject -Class Win32_Property | Where-Object {$_.Property -eq 'UpgradeCode' -and $_.value -eq $UpgradeCode}).ProductCode
Get-WmiObject -Class Win32_Product | Where-Object {$ProductGUIDs -Contains $_.IdentifyingNumber}
唯一的缺点是 Win32_Property 和 Win32_Product 类 都很慢,如果时间不是一个重要因素,您可以使用它。如果您需要更快的性能,您可以像这样从注册表中获取类似的信息
function Decode-GUID {
param( [string]$GUID )
$GUIDSections = @( 8, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2 )
$Position = 0
$result = @()
ForEach($GUIDSection In $GUIDSections)
{ $arr = $GUID.SubString($Position, $GUIDSection) -split "";
[array]::Reverse($arr);
$result = $result +($arr -join '').replace(' ','');
$Position += $GUIDSection }
return "{$(($result -join '').Insert(8,'-').Insert(13, '-').Insert(18, '-').Insert(23, '-'))}"
}
function Encode-GUID {
param( [string]$GUID )
$GUID = $GUID -creplace '[^0-F]'
$GUIDSections = @( 8, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2 )
$Position = 0
$result = ""
ForEach($GUIDSection In $GUIDSections)
{ $arr = $GUID.substring($Position, $GUIDSection) -split "";
[array]::Reverse($arr);
$result = $result + ($arr -join '').replace(' ','');
$Position += $GUIDSection }
return $result
}
function Get-Bitness {
param( [string]$Location )
if([Environment]::Is64BitOperatingSystem){
if($_.PSPath -match '\SOFTWARE\Wow6432Node'){
return '32'
}else{
return '64'
}
} else {
Return '32'
}
}
#Enter the UpgradeCode here
$UpgradeCode = Encode-GUID "{AA783A14-A7A3-3D33-95F0-9A351D530011}"
$ProductGUIDs = (Get-Item HKLM:"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UpgradeCodes$UpgradeCode", HKLM:"SOFTWARE\Classes\Installer\UpgradeCodes$UpgradeCode").Property |
Select-Object -Unique |
ForEach-Object {Decode-GUID $_}
Get-ChildItem HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall |
Where-Object {$ProductGUIDs -contains $_.PSChildName} |
Get-ItemProperty |
Select-Object -Property @{Name='PackageCode';Expression={$_.PSChildName}}, DisplayName, Publisher, DisplayVersion, InstallDate, PSParentPath, @{Name='Bitness';Expression={Get-Bitness $_.PSPath}}
在注册表中,"Installer" 部分中使用的 GUID 被编码以匹配 C++ 本机使用它们的方式。上例中的 Decode 和 Encode 函数基于此 Roger Zander blog post 中使用的技术。请原谅某些代码的混乱,如果您需要解释其中的任何部分,请告诉我。希望对你有帮助。
我必须使用 upgrade codes 更新一些产品 (MSI),我有所有此类产品的升级代码列表。现在要推送更新,我需要比较每个产品的版本。
在这种情况下如何查找产品版本?
喜欢:
gwmi win32_product | Where-Object {$_.Name -like "name"}
但是这个用了名字,我想找只用升级码的版本
在 PowerShell 中完成您要查找的内容的最简单方法是使用以下 WMI 查询来获取属于 UpgradeCode 系列的程序包。
$UpgradeCode = '{AA783A14-A7A3-3D33-95F0-9A351D530011}'
$ProductGUIDs = @(Get-WmiObject -Class Win32_Property | Where-Object {$_.Property -eq 'UpgradeCode' -and $_.value -eq $UpgradeCode}).ProductCode
Get-WmiObject -Class Win32_Product | Where-Object {$ProductGUIDs -Contains $_.IdentifyingNumber}
唯一的缺点是 Win32_Property 和 Win32_Product 类 都很慢,如果时间不是一个重要因素,您可以使用它。如果您需要更快的性能,您可以像这样从注册表中获取类似的信息
function Decode-GUID {
param( [string]$GUID )
$GUIDSections = @( 8, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2 )
$Position = 0
$result = @()
ForEach($GUIDSection In $GUIDSections)
{ $arr = $GUID.SubString($Position, $GUIDSection) -split "";
[array]::Reverse($arr);
$result = $result +($arr -join '').replace(' ','');
$Position += $GUIDSection }
return "{$(($result -join '').Insert(8,'-').Insert(13, '-').Insert(18, '-').Insert(23, '-'))}"
}
function Encode-GUID {
param( [string]$GUID )
$GUID = $GUID -creplace '[^0-F]'
$GUIDSections = @( 8, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2 )
$Position = 0
$result = ""
ForEach($GUIDSection In $GUIDSections)
{ $arr = $GUID.substring($Position, $GUIDSection) -split "";
[array]::Reverse($arr);
$result = $result + ($arr -join '').replace(' ','');
$Position += $GUIDSection }
return $result
}
function Get-Bitness {
param( [string]$Location )
if([Environment]::Is64BitOperatingSystem){
if($_.PSPath -match '\SOFTWARE\Wow6432Node'){
return '32'
}else{
return '64'
}
} else {
Return '32'
}
}
#Enter the UpgradeCode here
$UpgradeCode = Encode-GUID "{AA783A14-A7A3-3D33-95F0-9A351D530011}"
$ProductGUIDs = (Get-Item HKLM:"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UpgradeCodes$UpgradeCode", HKLM:"SOFTWARE\Classes\Installer\UpgradeCodes$UpgradeCode").Property |
Select-Object -Unique |
ForEach-Object {Decode-GUID $_}
Get-ChildItem HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall |
Where-Object {$ProductGUIDs -contains $_.PSChildName} |
Get-ItemProperty |
Select-Object -Property @{Name='PackageCode';Expression={$_.PSChildName}}, DisplayName, Publisher, DisplayVersion, InstallDate, PSParentPath, @{Name='Bitness';Expression={Get-Bitness $_.PSPath}}
在注册表中,"Installer" 部分中使用的 GUID 被编码以匹配 C++ 本机使用它们的方式。上例中的 Decode 和 Encode 函数基于此 Roger Zander blog post 中使用的技术。请原谅某些代码的混乱,如果您需要解释其中的任何部分,请告诉我。希望对你有帮助。