使用Powershell掃描軟體版本

最近對於Powershell又有新發現了!

原由:

因為公司某個內部網站需要安裝元件,而且常常會更新,有時候會因為元件版本過於老舊或是未安裝元件而無法使用。

當然比較先進的方式是用Agent的方式做檢查並且派送,但是很無奈的在外商公司很多東西都不是Local IT可以觸碰的。

而且很詭異的是總部的派送常常會失敗,大概因為距離很遙遠吧(Cyberjaya or Pargue???)…

科技始終來自於惰性,我又不想一個一個打電話去問去檢查,這很不科學。

所以我一開始本來想用WMI的方式

1
<b>Get-WmiObject -Class Win32_Product</b>.

但是這會碰到兩個問題:

1.這效率非常不好,因為它會全部掃過一遍,他相對於資料庫查詢很像是 Select * from Win32_Product where (name like ‘XXXXX%’)。

2.根據我查到的資料,他會一併檢查軟體安裝的一致性,如果檢查到有問題還會一併觸發Windows Installer去做修復與重新設定。

原文說明:On Windows Server 2003, Windows Vista, and newer operating systems, querying Win32_Product will trigger Windows Installer to perform a consistency check to verify the health of the application. This consistency check could cause a repair installation to occur. You can confirm this by checking the Windows Application Event log.

參考1(新分頁):https://blogs.technet.microsoft.com/heyscriptingguy/2011/11/13/use-powershell-to-quickly-find-installed-software/

這樣的Script給User自己點選跑起來可能很久,還要擔心萬一發生其他想不到的問題。

後來發現了可以用掃描機碼的方式,

32位元:HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

64位元還要加上:HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

然後搭配Out-GridView這樣是不是淺顯易懂!

附上Powershell裡面的XXXXX請自由變化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
function Search-RegistryUninstallKey {
param($SearchFor,[switch]$Wow6432Node)
$results = @()
$keys = Get-ChildItem HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall |
foreach {
$obj = New-Object psobject
Add-Member -InputObject $obj -MemberType NoteProperty -Name GUID -Value $_.pschildname
Add-Member -InputObject $obj -MemberType NoteProperty -Name DisplayName -Value $_.GetValue("DisplayName")
Add-Member -InputObject $obj -MemberType NoteProperty -Name DisplayVersion -Value $_.GetValue("DisplayVersion")
if ($Wow6432Node)
{Add-Member -InputObject $obj -MemberType NoteProperty -Name Wow6432Node? -Value "No"}
$results += $obj
}

if ($Wow6432Node) {
$keys = Get-ChildItem HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall |
foreach {
$obj = New-Object psobject
Add-Member -InputObject $obj -MemberType NoteProperty -Name GUID -Value $_.pschildname
Add-Member -InputObject $obj -MemberType NoteProperty -Name DisplayName -Value $_.GetValue("DisplayName")
Add-Member -InputObject $obj -MemberType NoteProperty -Name DisplayVersion -Value $_.GetValue("DisplayVersion")
Add-Member -InputObject $obj -MemberType NoteProperty -Name Wow6432Node? -Value "Yes"
$results += $obj
}
}
$results | sort DisplayName | where {$_.DisplayName -match $SearchFor}
}
[String]$OS = ((Get-CimInstance win32_OperatingSystem).version).split(".",2)[-2]
Switch($OS)
{
10
{
Search-RegistryUninstallkey -Wow6432Node -SearchFor "XXXXX" | Out-GridView -Wait
}
6
{
Search-RegistryUninstallkey -SearchFor "XXXXX" | Out-GridView -Wait
}
}

 

Please follow and like us: