Public/Get-SoftwareDetectionMethod2.ps1
<#
.SYNOPSIS Alternative method for generating software detection rules. .COMPONENT QuickSoft .DESCRIPTION Provides an alternative approach to generating software detection methods, focusing on GUID-based detection and additional registry paths. This function is particularly useful for MSI-based installations. .PARAMETER DisplayName The name of the software to analyze. Supports wildcards (*). .EXAMPLE Get-SoftwareDetectionMethod2 -DisplayName "Adobe Reader" Returns alternative detection methods for Adobe Reader installation. .EXAMPLE Get-SoftwareDetectionMethod2 -DisplayName "Microsoft*" Returns alternative detection methods for all Microsoft software. .OUTPUTS System.Management.Automation.PSCustomObject Returns objects containing detection information including GUIDs and registry paths. .NOTES Name: Get-SoftwareDetectionMethod2 Author: AutomateSilent Version: 1.0.0 Last Updated: 2025-01-31 #> function Get-SoftwareDetectionMethod2 { [CmdletBinding()] param ( [Parameter( Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "Name of the software to analyze (supports wildcards)" )] [SupportsWildcards()] [string]$DisplayName = "*" ) $uninstallKeys = @( "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" ) $commonRegPaths = @( "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall", "HKLM:\SOFTWARE", "HKLM:\SOFTWARE\Wow6432Node" ) $results = @() foreach ($key in $uninstallKeys) { $items = Get-ItemProperty -Path $key -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -like $DisplayName -and $_.UninstallString } foreach ($item in $items) { $GUID = $null $registryPath = $null $registryValue = $null $version = $item.DisplayVersion if ($item.UninstallString -match "({[A-Z0-9-]+})") { $GUID = $matches[1] } if (-not $GUID) { $itemPath = $item.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" $registryPath = $itemPath $properties = Get-ItemProperty -Path $itemPath -ErrorAction SilentlyContinue $potentialValues = @( @{ Name = "DisplayName"; Value = $properties.DisplayName }, @{ Name = "InstallLocation"; Value = $properties.InstallLocation }, @{ Name = "DisplayVersion"; Value = $properties.DisplayVersion }, @{ Name = "Publisher"; Value = $properties.Publisher } ) foreach ($prop in $potentialValues) { if ($prop.Value) { $registryValue = @{ Name = $prop.Name Value = $prop.Value } break } } } $additionalPaths = @() foreach ($basePath in $commonRegPaths) { $searchPath = Join-Path $basePath "*$($item.DisplayName)*" $additionalKeys = Get-Item -Path $searchPath -ErrorAction SilentlyContinue if ($additionalKeys) { $additionalPaths += $additionalKeys.PSPath -replace "Microsoft.PowerShell.Core\\Registry::", "" } } $results += [PSCustomObject]@{ DisplayName = $item.DisplayName Version = $version Architecture = if($key -like "*WOW6432Node*") {"32-bit"} else {"64-bit"} GUID = $GUID RegistryPath = $registryPath RegistryValue = if ($registryValue) { "$($registryValue.Name)=$($registryValue.Value)" } else { $null } AdditionalPaths = $additionalPaths } } } if ($results.Count -gt 0) { foreach ($result in $results) { Write-Host "`n====== Detection Information for: $($result.DisplayName) ======" -ForegroundColor Green Write-Host "Version: $($result.Version)" -ForegroundColor Yellow Write-Host "Architecture: $($result.Architecture)" -ForegroundColor Yellow if ($result.GUID) { Write-Host "`nRecommended Detection Method (GUID):" -ForegroundColor Cyan Write-Host "Registry detection rule:" Write-Host "Path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$($result.GUID)" Write-Host "Value: DisplayName" Write-Host "Check existence: Yes" } else { Write-Host "`nAlternative Registry Detection Method:" -ForegroundColor Cyan Write-Host "Path: $($result.RegistryPath -replace 'HKLM:\\', 'HKEY_LOCAL_MACHINE\')" Write-Host "Value: $($result.RegistryValue)" Write-Host "Check existence: Yes" if ($result.AdditionalPaths) { Write-Host "`nAdditional Potential Registry Paths:" -ForegroundColor Magenta foreach ($path in $result.AdditionalPaths) { Write-Host $path } } } } } else { Write-Host "No software matching '$DisplayName' found." -ForegroundColor Red } return $results } |