Get-InstalledSoftware PowerShell Commandlet

This cmdlet will get the installed software that is contain in the HKLM set of keys from a local, remote or list of computers, and will return various information about the programs. It will return the name, current version and uninstall string . It pulls from the same locations that Add/Remove Programs pulls from. This cmdlet was taken from the URL listed below, but I added the uninstall member to it to aid for use in application installation scripts.

Updated 1/15/18. GIS 2.0. Supports pipeline data for software names. Supports get-help capabilities. Added cmdlet binding support, including verbose, debug, whatif and confirm support. Contains line by line commenting for explanation.

Function Get-InstalledSoftware{ 

Gets installed software on local or remote computers. 

This Script will query the registry to get programs that are registered as installed on the machine
It will query both the 32bit registry and the 64bit registry. 
It queries HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
and HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
This script could be used to query for a piece of software and uninstall it using the Uninstall String property that is returned.
It also returns a version number, so it can be used to check if a piece of software is a certain version or not

.PARAMETER SoftwareName
Specify the name of the software that you wish to search for. The function uses wilcards so you do not need to have the exact name. Use quotation marks if there are multiple words in the software

.PARAMETER Computers
Specify the name of a computer, or a series of computers, to get software remotely from. This parameter is optional and if it is not specified, the local machine will be queried

Get-InstalledSoftware -SoftwareName Office
Gets any software like the name Office on your local machine

Get-InstalledSoftware -SoftwareName "Adobe Acrobat" -Computers COMPUTER1
Gets any software like the name Adobe Acrobat on a remote computer with the name COMPUTER1

Get-InstalledSoftware -SoftwareName "Engagement" -Computers COMPUTER1,COMPUTER2
Gets any software like the name Engagement on two remote computers with the names COMPUTER1 and COMPUTER2


    Returns a custom PSPbject or series of objects with the following properties: ComputerName, Software Name, Publisher, InstallDate, Estimated Size, Uninstall String, Version and if it is in the 64 bit registry location

String, series of strings. You can pipe name of softwares to search for using this commandlet.

    Author:  Curtis Wright
    Email:   curtis (at) 
    Date:    14JAN2018 
    PSVer:   2.0/3.0/4.0/5.0 

#Allowing Cmdlet Bindings
#Defining Parameters   
    [String[]]$Computers = $ENV:ComputerName
#If the computer name is not supplied, use the local machine 
If (!$Computers) 
    Write-Verbose "Using $ENV:ComputerName as the computer to search"
    $Computers = $ENV:ComputerName
    #Build a PSObject to store the values that are obtained from the registry 
    Write-Debug "Builing PSObject as a template store individual software results in"
    $Base = New-Object PSObject; 
    $Base | Add-Member Noteproperty ComputerName -Value $Null; 
    $Base | Add-Member Noteproperty Name -Value $Null; 
    $Base | Add-Member Noteproperty Publisher -Value $Null; 
    $Base | Add-Member Noteproperty InstallDate -Value $Null; 
    $Base | Add-Member Noteproperty EstimatedSize -Value $Null;
    $Base | Add-Member Noteproperty UninstallString -Value $Null; 
    $Base | Add-Member Noteproperty Version -Value $Null; 
    $Base | Add-Member Noteproperty Wow6432Node -Value $Null;
    #Results is a generic list to store all results in 
    $Results =  New-Object System.Collections.Generic.List[System.Object]; 
    $NumberofComps = $Computers.Count
    Write-Verbose "Getting software for $NumberofComps computers, $Computers"
    ForEach ($ComputerName in $Computers){
    if ($PSCmdlet.ShouldProcess($ComputerName,"Getting software like $SoftwareName"))
        Write-Verbose "Getting Software for $ComputerName"
        #Setting Remote Registry so that required information can be read
        Set-Service RemoteRegistry -ComputerName $ComputerName -StartupType Automatic | Out-Null 
        Set-Service RemoteRegistry -ComputerName $ComputerName -Status Running | Out-Null 
        #Resetting the resgitry value in case this being run for multiple computers
        $Registry = $Null; 
        #Trying to get the remote registry
        Write-Debug "Trying registry for $ComputerName"
        $Registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$ComputerName);
        Catch{Write-Error "$($_.Exception.Message)";} 
        #If the registry exists, get information 
        If ($Registry){
            #Resetting previous values 
            $UninstallKeys = $Null; 
            $SubKey = $Null;
            #Getting the subkeys values 
            $UninstallKeys = $Registry.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Uninstall",$False);
            #Foreach loop to get the values for each subkey in the subkey name arrary 
                $SubKey = $UninstallKeys.OpenSubKey($_,$False); 
                $DisplayName = $SubKey.GetValue("DisplayName");
                #Filtering out for display names less than 0 
                If ($DisplayName.Length -gt 0){ 
                    $Entry = $Base | Select-Object *
                    #Getting ComputerName 
                    $Entry.ComputerName = $ComputerName; 
                    #Getting DisplayName
                    $Entry.Name = $DisplayName.Trim();  
                    #Getting Publisher
                    $Entry.Publisher = $SubKey.GetValue("Publisher");
                    #Getting the the installed date  
                    [ref]$ParsedInstallDate = Get-Date 
                    If ([DateTime]::TryParseExact($SubKey.GetValue("InstallDate"),"yyyyMMdd",$Null,[System.Globalization.DateTimeStyles]::None,$ParsedInstallDate)){                     
                    $Entry.InstallDate = $ParsedInstallDate.Value 
                    #Getting the estimated size 
                    $Entry.EstimatedSize = [Math]::Round($SubKey.GetValue("EstimatedSize")/1KB,1);
                    #Getting Uninstall string
                    $Entry.UninstallString = $Subkey.GetValue("UninstallString");
                    #Getting the display version
                    $Entry.Version = $SubKey.GetValue("DisplayVersion");
                    #Adding software info to results list 
                If ([IntPtr]::Size -eq 8){ 
                $UninstallKeysWow6432Node = $Null; 
                $SubKeyWow6432Node = $Null; 
                $UninstallKeysWow6432Node = $Registry.OpenSubKey("Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall",$False); 
                    If ($UninstallKeysWow6432Node) { 
                        $SubKeyWow6432Node = $UninstallKeysWow6432Node.OpenSubKey($_,$False); 
                        $DisplayName = $SubKeyWow6432Node.GetValue("DisplayName"); 
                        If ($DisplayName.Length -gt 0){ 
                            $Entry = $Base | Select-Object * 
                            $Entry.ComputerName = $ComputerName; 
                            $Entry.Name = $DisplayName.Trim();  
                            $Entry.Publisher = $SubKeyWow6432Node.GetValue("Publisher");  
                            [ref]$ParsedInstallDate = Get-Date 
                            If ([DateTime]::TryParseExact($SubKeyWow6432Node.GetValue("InstallDate"),"yyyyMMdd",$Null,[System.Globalization.DateTimeStyles]::None,$ParsedInstallDate)){                      
                            $Entry.InstallDate = $ParsedInstallDate.Value 
                            $Entry.EstimatedSize = [Math]::Round($SubKeyWow6432Node.GetValue("EstimatedSize")/1KB,1);
                            $Entry.UninstallString = $Subkeywow6432Node.GetValue("UninstallString"); 
                            $Entry.Version = $SubKeyWow6432Node.GetValue("DisplayVersion"); 
                            $Entry.Wow6432Node = $True; 
    #If no software name is supplied, return all results
    if (!$SoftwareName)
    Write-Verbose "No Software detected as being searched for, returning all" 
        #Return the results of the software names based on a wildcard 
        foreach ($name in $SoftwareName)
            Write-Verbose "Returning Results for $name"
            $Results | ?{$ -like "*$Name*"}   
Set-Alias GIS Get-InstalledSoftware


  1. Throughout the history of authorized on-line casinos within the US, many fortunate gamblers have hit it massive on mobile units, winning jackpots of several of} hundreds of hundreds of dollars merely taking part in} on their cell telephones. The mobile numbers in quantity of} states have been 1xbet notably much less robust than in some of their friends. In Nevada’s case, this might be be} end result of} magnetism of The Las Vegas Strip, however all three states require gamblers to register in-person at casinos to set up a mobile gaming account.


Post a Comment

Popular posts from this blog

Checklist for PowerShell Commandlets/Functions

How To Fix Miracast for a Specific Device when the Firewall blocks All Public Connections