Private/Get-InstalledSoftware.ps1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
function Get-InstalledSoftware { <# .SYNOPSIS Pull software details from registry on one or more computers .DESCRIPTION Pull software details from registry on one or more computers. Details: -This avoids the performance impact and potential danger of using the WMI Win32_Product class -The computer name, display name, publisher, version, uninstall string and install date are included in the results -Remote registry must be enabled on the computer(s) you query -This command must run with privileges to query the registry of the remote system(s) -Running this in a 32 bit PowerShell session on a 64 bit computer will limit your results to 32 bit software and result in double entries in the results .PARAMETER ComputerName One or more computers to pull software list from. .PARAMETER DisplayName If specified, return only software with DisplayNames that match this parameter (uses -match operator) .PARAMETER Publisher If specified, return only software with Publishers that match this parameter (uses -match operator) .EXAMPLE #Pull all software from c-is-ts-91, c-is-ts-92, format in a table Get-InstalledSoftware c-is-ts-91, c-is-ts-92 | Format-Table -AutoSize .EXAMPLE #pull software with publisher matching microsoft and displayname matching lync from c-is-ts-91 "c-is-ts-91" | Get-InstalledSoftware -DisplayName lync -Publisher microsoft | Format-Table -AutoSize .LINK http://gallery.technet.microsoft.com/scriptcenter/Get-InstalledSoftware-Get-5607a465 .FUNCTIONALITY Computers #> param ( [Parameter( Position = 0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ValueFromRemainingArguments=$false )] [ValidateNotNullOrEmpty()] [Alias('CN','__SERVER','Server','Computer')] [string[]]$ComputerName = $env:computername, [string]$DisplayName = $null, [string]$Publisher = $null ) Begin { #define uninstall keys to cover 32 and 64 bit operating systems. #This will yeild only 32 bit software and double entries on 64 bit systems running 32 bit PowerShell $UninstallKeys = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall" function Get-SoftwareKey { [cmdletbinding()] param( $Reg, $UninstallKey, $Hive ) Try { if($UninstallKey -like 'SOFTWARE\\Wow6432Node*') { $Arch = '32' } else { $Arch = '64' } $regkey = $null $regkey = $reg.OpenSubKey($UninstallKey) #If the reg key exists... if($regkey) { #Retrieve an array of strings containing 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) { #Build the full path to the key for this software $thisKey = $UninstallKey+"\\"+$key #Open the subkey for this software $thisSubKey = $null $thisSubKey=$reg.OpenSubKey($thisKey) #If the subkey exists if($thisSubKey){ try { #Get the display name. If this is not empty we know there is information to show $dispName = $thisSubKey.GetValue("DisplayName") #Get the publisher name ahead of time to allow filtering using Publisher parameter $pubName = $thisSubKey.GetValue("Publisher") #Collect subset of values from the key if there is a displayname #Filter by displayname and publisher if specified if( $dispName -and (-not $DisplayName -or $dispName -match $DisplayName ) -and (-not $Publisher -or $pubName -match $Publisher ) ) { #Display the output object, compatible with PowerShell 2 New-Object PSObject -Property @{ ComputerName = $computer DisplayName = $dispname Publisher = $pubName Version = $thisSubKey.GetValue("DisplayVersion") UninstallString = $thisSubKey.GetValue("UninstallString") InstallDate = $thisSubKey.GetValue("InstallDate") Hive = $Hive Arch = $Arch } | Select-Object ComputerName, DisplayName, Publisher, Version, Hive, Arch, UninstallString, InstallDate } } Catch { #Error with one specific subkey, continue to the next Write-Error "Unknown error: $_" Continue } } } } } Catch { #Write verbose output if we couldn't open the uninstall key Write-Verbose "Could not open key '$uninstallkey' on computer '$computer': $_" #If we see an access denied message, let the user know and provide details, continue to the next computer if($_ -match "Requested registry access is not allowed"){ Write-Error "Registry access to $computer denied. Check your permissions. Details: $_" continue computerLoop } } } } Process { #Loop through each provided computer. Provide a label for error handling to continue with the next computer. :computerLoop foreach($computer in $computername) { Try { #Attempt to connect to the localmachine hive of the specified computer $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$computer) } Catch { #Skip to the next computer if we can't talk to this one Write-Error "Error: Could not open LocalMachine hive on $computer`: $_" Write-Verbose "Check Connectivity, permissions, and Remote Registry service for '$computer'" Continue } #Loop through the 32 bit and 64 bit registry keys foreach($uninstallKey in $UninstallKeys) { Write-Verbose "Checking [LocalMachine] [$uninstallKey] on [$computer]" Get-SoftwareKey -Reg $Reg -UninstallKey $uninstallKey -Hive 'HKLM' } Try { #Attempt to connect to the localmachine hive of the specified computer $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('CurrentUser',$computer) } Catch { #Skip to the next computer if we can't talk to this one Write-Error "Error: Could not open LocalMachine hive on $computer`: $_" Write-Verbose "Check Connectivity, permissions, and Remote Registry service for '$computer'" Continue } #Loop through the 32 bit and 64 bit registry keys foreach($uninstallKey in $UninstallKeys) { Write-Verbose "Checking [CurrentUser] [$uninstallKey] on [$computer]" Get-SoftwareKey -Reg $Reg -UninstallKey $uninstallKey -Hive HKCU } } } } |