Link to home
Start Free TrialLog in
Avatar of chad
chad

asked on

Powershell - Read registry to determine installed apps

I have tried using Win32_Product and it takes about three minutes when ran locally and doesn't run at all for remote systems.  

I would like to read the registry to determine what s/w are installed. I need to be able to have a filter so that it only shows apps that have a display name of "adobe *".

hklm:\software\microsoft\windows\currentversion\uninstall

contains everything I need but I only want some select info for select applications.

Any help would be greatly appreciated.

Thanks,
K
Avatar of rockiroads
rockiroads
Flag of United States of America image

looks like you need to read the registry as a drive then use something like

examples here
http://tfl09.blogspot.com/2007/01/using-registry-with-powershell.html
helper functions http://powershell.com/cs/blogs/tips/archive/2009/11/25/reading-registry-values.aspx
Avatar of chad
chad

ASKER

The first link refers to code that only works on a local machine.  It doesn't do what I need for remote systems
The second link refers to gaining access to exact keys.  That is not what I am trying to do.  I am looking to gain access to an array of keys based on search filter for many computers on a network.

I have attached code snip that does what I want when run from a local box.  I want to do the same for many others from one system

thanks,
C


Clear-Host

clear-variable strcomputer
$colComputers = get-content "c:\powershell\outputFiles\Clients.txt" 

foreach ($strComputer in $colComputer)
    {
    write-host $strcomputer -foreground "green"

    $Programs = $RegLoc | foreach-object {Get-ItemProperty $_.PsPath}
    $RegLoc = Get-ChildItem HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall #-computername $strComputer
    Foreach ($name in $Programs | sort-Object DisplayName) `
        {
        if ($name.displayname -match "adobe")
        {
        Write-Host $name.Displayname -nonewline 
        Write-Host $name.DisplayVersion        
        }

}

}

Open in new window

This provides you with a rough list of installed programs:


Dir hklm:\software\microsoft\windows\currentversion\uninstall |   ForEach-Object { Write-Host -ForegroundColor Yellow "Installed Products:" 
}
{
    $values = Get-ItemProperty $_.PSPath;     "{0:-30} {1:20}" -f $values.DisplayName, $values.MoreInfoURL  
}
{
Write-Host -ForegroundColor Yellow "Finished!"
}

Open in new window

SOLUTION
Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of chad

ASKER

Thanks Chris and R3nder,

I have to step out of office for a few days so my testing and access will be limited but I will do what I can to ensure this question doesn't stay open too long.

The scripts I, including this one, will be done by a user or users that are local admins on all boxes so passing specific credentials would not be required.

Thanks,
C
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

Upgraded the snippet a little bit.

Chris
Function Get-InstalledSoftware {
  <#
    .Synopsis
      Enumerates the Uninstall registry key to display installed software
    .Description
      Enumerates the Uninstall registry key to display installed software. This function assumes the caller is authenticated.
    .Parameter ComputerName
      The computer to execute against. Defaults to local machine.
  #>
  
  [CmdLetBinding()]
  Param(
    $ComputerName = $Env:ComputerName
  )

  Try {
    $BaseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", $ComputerName)
  } Catch { }
  If ($?) {
    $UninstallKey = $BaseKey.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Uninstall")

    $UninstallKey.GetSubKeyNames() | ForEach-Object { 
      $UninstallKey.OpenSubKey($_) | 
        Where-Object { $_.GetValue("DisplayName") } |
        Select-Object `
          @{n='Name';e={ $_.GetValue("DisplayName") }},
          @{n='DisplayVersion';e={ $_.GetValue("DisplayVersion") }},
          @{n='InstallDate';e={
            $DateString = $_.GetValue("InstallDate")
            If ($DateString) {
              [DateTime]$DateTime = "01/01/1601"
               If ([DateTime]::TryParse($DateString, [Ref]$DateTime)) {
                $DateTime
              } Else {
                [DateTime]::ParseExact($DateString, "yyyyMMdd", $Null)
              }
            } }},
          @{n='Publisher';e={ $_.GetValue("Publisher") }}
    }
  }
}

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of chad

ASKER

Thanks again Chris.  I do not have much time to work with this but I did a quick test.  The first version works great and I can work with it.  The second runs without error but yields empty.  no Results (on Win7).
I will try to get more time with it later.

Thanks again.

The second is only the function, it still needs calling, or did you do that? :)

e.g.

Get-InstalledSoftware "SomeComputer"

If you don't specify a computer it will default to the local machine.

Chris
Avatar of chad

ASKER

Ahh that makes sense.  Thanks,

for what I need these are both outstanding options.   I am upping the points because you had more work to do on this one.

Thanks again,
K
Overtime solution with PowerShell remoting:
Clear-Host  
  
$colComputers = get-content "c:\powershell\outputFiles\Clients.txt"   

$script = {
    $regloc = get-item hklm:\software\microsoft\windows\currentversion\uninstall
    write-host $env:computername -foreground "green"  
  
    $RegLoc | get-childitem | 
        Get-ItemProperty | sort-Object DisplayName | 
            Where-Object {$_.pschildname -match "adobe"} | 
                ft displayname, displayversion -HideTableHeaders
}

Invoke-Command -ComputerName $colComputers -ScriptBlock $script

Open in new window