我试图让这个ForEach循环使用注册表搜索在计算机上搜索特定的软件安装。由于某些原因,它只找到一个,而不是另外两个,即使我知道和可以看到他们是安装。错过了什么。
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也被安装在我正在寻找的地方。我已经看了这段代码一段时间了,但我不明白为什么。
我知道我已将计算机设置为主机名,我将更改为包含计算机列表的文件。这只是暂时的测试。
谢谢,请提前。
发布于 2015-04-23 05:05:11
我认为可以用一个更快更好的Switch语句代替所有的Switch语句(一个调用从远程注册表获得值,而不是3),另外它还可以正则匹配。考虑删除所有3条If语句,并将它们替换为:
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}
}
}https://stackoverflow.com/questions/29813325
复制相似问题