I am attempting to get this ForEach loop to search for specific software install on a computer using a registry search. For some reason it is only find one and not the other two
I think all of your If
statements could be replaced with a Switch
statement that would work faster and better (one call to get the value from the remote registry instead of 3), plus it can regex match. Consider removing all 3 of your If
statements and replacing them with:
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"}
}
That should effectively do the same thing as all of your If
statements
Edit: How to get the 32 bit keys... Well, you already have the code to get things from the registry, just tack on a second part after the switch basically with a modified path. Better yet, let's make a single list of all the applications installed from the DisplayName values, add all the ones from the Wow6432Node section to that list, and then run the whole list through the Switch
. Now I assume that, since you are referencing a computername
property in your code, you are importing a CSV and looping through that? I hope so, I kind of based this off that. So this will loop through computers in a CSV where the computer name is stored in a computername
property. It will add 3 new properties to each computer: CClean
, 7-Zip
, and .Net Framework
. It sets them all as $false
by default. Then it pulls the software listings, and if it finds any of those it changes that property to $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}
}
}