安装PowerShell搜索软件

问题描述:

我试图让这个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语句。到目前为止,它工作我认为,我会继续测试假软件,看看是否应该报告回来。感谢您的答复。 –

我认为你所有的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