2015-04-23 101 views
0

我試圖讓這個ForEach循環搜索特定的軟件安裝在計算機上使用註冊表搜索。出於某種原因,它只能找到一個,而不是其他兩個,即使我知道並可以看到它們已安裝。 錯過了什麼。安裝PowerShell搜索軟件

Clear-Host 
$Computers = hostname 

$array = @() 

foreach($pc in $computers){ 

    $computername=$pc.computername 

    #Define the variable to hold the location of Currently Installed Programs 

    $UninstallKey="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" 

    #Create an instance of the Registry Object and open the HKLM base key 

    $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$computername) 

    #Drill down into the Uninstall key using the OpenSubKey Method 

    $regkey=$reg.OpenSubKey($UninstallKey) 

    #Retrieve an array of string that contain all the subkey names 

    $subkeys=$regkey.GetSubKeyNames() 

    #Open each Subkey and use GetValue Method to return the required values for each 


    ForEach($Key in $subkeys) { 
     $thisKey=$UninstallKey+"\\"+$key 

     $thisSubKey=$reg.OpenSubKey($thisKey) 
     #If found set variable to True for used in report 

      if (($thisSubKey.GetValue("DisplayName") -like "CCleaner")) {Write-Host "CCleaner = True"} 
      Else {Write-Host = " False"} 

     if (($thisSubKey.GetValue("DisplayName") -like "*7-Zip*")) {Write-Host "7Zip = True"} 
      Else {Write-Host = " False"} 

     if (($thisSubKey.GetValue("DisplayName") -like "*.NET Framework*")) {Write-Host ".NET = True"} 
      Else {Write-Host = " False"} 


    } 

} 

它發現DotNet和它的等於True,但7-Zip和CCleaner也安裝在我正在尋找的地方。我有一段時間看了這段代碼,看不出爲什麼。

我知道我已經將電腦設置爲主機名,我將更改爲帶有計算機列表的文件。這只是爲了目前的測試。

謝謝你,並提前。

+0

64位操作系統?你可能有一個32位的應用程序,他們位於WoW6432Node。你的CCLeaner'''''語句沒有通配符。我會建議使用'-match'而不是''like',並刪除星號。這可能很好地解決你的問題。由於7-Zip的顯示名稱以7-Zip開頭,因此如果在文本前面加星號,我不記得'-like'是否會找到它。如果可以使用,匹配比我認爲的更好。 – TheMadTechnician

+0

它是64位操作系統,我可能不得不迎合這兩種情況,我已經爲通配符添加了通配符並刪除了else語句。到目前爲止,它工作我認爲,我會繼續測試假軟件,看看是否應該報告回來。感謝您的答覆。 –

回答

3

我認爲你所有的If語句都可以用Switch語句代替,它會更快更好地工作(一次調用從遠程註冊表中獲取值而不是3次),再加上它可以與正則表達式匹配。考慮刪除您If語句的所有3與替換它們:

Switch -Regex ($thisSubKey.GetValue("DisplayName")){ 
    "CCleaner" {Write-Host "CCleaner = True";continue} 
    "7-Zip" {Write-Host "7-Zip = True";continue} 
    "\.Net Framework" {Write-Host ".Net Framework = True"} 
} 

這應該有效地做同樣的事情,因爲所有你If陳述

編輯的:如何獲取32個的密鑰。 ..好吧,你已經有了從註冊表中獲取東西的代碼,只需在切換後的第二部分基本上使用修改後的路徑即可。更好的是,讓我們根據DisplayName值創建所有安裝的應用程序的單個列表,將Wow6432Node部分中的所有應用程序添加到該列表中,然後通過Switch運行整個列表。現在我假設,由於您在代碼中引用computername屬性,因此您正在導入CSV並循環執行該操作?我希望如此,我基於這種情況。因此,這將循環通過CSV中計算機的名稱存儲在computername屬性中的計算機。它將爲每臺計算機添加3個新屬性:CClean,7-Zip.Net Framework。它默認將它們全部設置爲$false。然後它會提取軟件列表,如果發現其中的任何一個,它會將該屬性更改爲$true

Clear-Host 
$Computers = @($(new-object PSObject -prop @{'ComputerName' = $env:COMPUTERNAME})) 
##Computers = Import-CSV 'C:\Path\To\SCCMVerify.csv' 

$array = @() 

for($i = 0; $i -lt $computers.count;$i++){ 

    $computername=$computers[$i].computername 
    Add-Member -InputObject $computers[$i] -NotePropertyName 'CCleaner' -NotePropertyValue $false 
    Add-Member -InputObject $computers[$i] -NotePropertyName '7-Zip' -NotePropertyValue $false 
    Add-Member -InputObject $computers[$i] -NotePropertyName '.Net Framework' -NotePropertyValue $false 



    #Define the variable to hold the location of Currently Installed Programs 

    $UninstallKey="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" 
    $Uninstall32Key="SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall" 

    #Create an instance of the Registry Object and open the HKLM base key 

    $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$computername) 

    #Drill down into the Uninstall key using the OpenSubKey Method 

    $regkey=$reg.OpenSubKey($UninstallKey) 
    $reg32key=$reg.OpenSubKey($Uninstall32Key) 

    #Retrieve an array of string that contain all the subkey names 

    $subkeys=$regkey.GetSubKeyNames() 
    $sub32keys=$reg32key.GetSubKeyNames() 

    #Open each Subkey and use GetValue Method to return the required values for each, compile that in a list 

    $applications = $subkeys|ForEach{$reg.OpenSubKey("$UninstallKey\\$_").GetValue('DisplayName')} 
    $applications += $sub32keys|ForEach{$reg.OpenSubKey("$Uninstall32Key\\$_").GetValue('DisplayName')} 

    #Search all applications for matching software 
    Switch -Regex ($applications) { 
     "CCleaner" {Write-Host "CCleaner = True";$Computers[$i].CCleaner = $true ;continue} 
     "7-Zip" {Write-Host "7-Zip = True";$computers[$i].'7-Zip' = $true;continue} 
     "\.Net Framework" {Write-Host ".Net Framework = True";$Computers[$i].'.Net Framework' = $true}   
    } 

} 
+0

甜美,看起來不錯。我會給它一個嘗試和更多的軟件。這基本上是在構建結束時SCCM中的一個任務序列,讓我知道是否已安裝所有軟件。 –

+0

也只是想,我可以得到它來檢查Wow6432Node –

+0

好吧,我轉貼了一個完整的腳本,修改後檢查兩個鍵。我做了一些其他的修改,你可以拿走或者離開。 – TheMadTechnician