安装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也安装在我正在寻找的地方。我有一段时间看了这段代码,看不出为什么。
我知道我已经将电脑设置为主机名,我将更改为带有计算机列表的文件。这只是为了目前的测试。
谢谢你,并提前。
我认为你所有的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}
}
}
甜美,看起来不错。我会给它一个尝试和更多的软件。这基本上是在构建结束时SCCM中的一个任务序列,让我知道是否已安装所有软件。 –
也只是想,我可以得到它来检查Wow6432Node –
好吧,我转贴了一个完整的脚本,修改后检查两个键。我做了一些其他的修改,你可以拿走或者离开。 – TheMadTechnician
64位操作系统?你可能有一个32位的应用程序,他们位于WoW6432Node。你的CCLeaner'''''语句没有通配符。我会建议使用'-match'而不是''like',并删除星号。这可能很好地解决你的问题。由于7-Zip的显示名称以7-Zip开头,因此如果在文本前面加星号,我不记得'-like'是否会找到它。如果可以使用,匹配比我认为的更好。 – TheMadTechnician
它是64位操作系统,我可能不得不迎合这两种情况,我已经为通配符添加了通配符并删除了else语句。到目前为止,它工作我认为,我会继续测试假软件,看看是否应该报告回来。感谢您的答复。 –