Tags


Powershell

A friend caught me on Twitter and was wondering if there was a way to centrally query computers in a network for their installed applications (more particularly in his case, a SINGLE application)

That sounded like a job for Powershell!

Now we COULD just use a GET-WMIOBJECT Win32_Product but that’s only good for applications registered via the MSI (Windows Installer)

So as my mouth dropped to the ground defeated a thought dawned on me.  “That information is in the registry”

Sure sure, but Powershell doesn’t exactly have a “GET-REMOTEREGISTRY” function but it DOES have a fantastically large community of support.   One of the most brilliant Fore Fathers of Powershell is “//o//” or Marc van Orsouw who wrote a blog post explaining how to modify Remote Registry keys in Powershell.

This single post showed how leveraging [Microsoft.Win32.Registrykey] could be used to access remote registries easily!

With this in mind I sat down and played.   I knew that the Registry keeps the data for “Add/Remove Programs” under

HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsCurrentVersionUninstall

So assuming we’re just going to ask a single computer some information, we have to open the main key we’re going to work on

$computername=”localhost”

$Branch=”LocalMachine”

$SubBranch="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"

$registry=[microsoft.win32.registrykey]::OpenRemoteBaseKey($Branch,$computername)

$registrykey=$registry.OpenSubKey($Subbranch)

$SubKeys=$registrykey.GetSubKeyNames()

What have we done?

  • Opened the Registry on “local”, accessed the root key “LocalMachine” (HKEY_LOCAL_MACHINE)
  • Opened up a key to view “SoftwareMicrosoftWindowsCurrentVersionUninstall”
  • Obtained a listing of keys under the “Uninstall” key

That’s it.  So now we have a complete listing (or directory if you like) of all the keys under the Uninstall.

Now that we have the list, we need to pull out the value from the “DisplayName” under each key

To do this, we need to step through the $Subkeys and re-open each key to examine it’s value.  Since each SubKey is just a name, we can just tack on it’s name to $Subbranch and re-open it again.

Once opened, we simply pull out the Value of “DisplayName” using the available GetValule() method.

How did I figure any of this out?

One of the tricks with Powershell is using GET-MEMBER to show you what IS Available for Properties and Methods.   Another I find that really helps is within your Editor (I use The Powershell ISE since it’s convenient and I’m pretty lazy) and putting breaks in the code.

I’ll make that into a different posting later on 🙂

For now, here is a script you can use to expand or play with to list all the installed applications on a Remote Computer

Remember, the Power of Shell is in YOU

Sean
”The Energized Tech”

 

———————————————————————————————

# Original posting on how to access a remote Registry from The Powershell Guy
#
#
http://thepowershellguy.com/blogs/posh/archive/2007/06/20/remote-registry-access-and-creating-new-registry-values-with-powershell.aspx
#
# This script will Query the Uninstall Key on a computer specified in $computername and list the applications installed there
# $Branch contains the branch of the registry being accessed
#  ‘

# format of Computerlist.csv
# Line 1 – NameOfComputer
# Line 2 etcetc etc etc etc An Actual name of a computer

$COMPUTERS=IMPORT-CSV C:PowershellComputerlist.csv

FOREACH ($PC in $COMPUTERS) {
$computername=$PC.NameOfComputer

# Branch of the Registry
$Branch=’LocalMachine’

# Main Sub Branch you need to open
$SubBranch="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"

$registry=[microsoft.win32.registrykey]::OpenRemoteBaseKey(‘Localmachine’,$computername)
$registrykey=$registry.OpenSubKey($Subbranch)
$SubKeys=$registrykey.GetSubKeyNames()

# Drill through each key from the list and pull out the value of
# “DisplayName” – Write to the Host console the name of the computer
# with the application beside it

Foreach ($key in $subkeys)
{
    $exactkey=$key
    $NewSubKey=$SubBranch+"\"+$exactkey
    $ReadUninstall=$registry.OpenSubKey($NewSubKey)
    $Value=$ReadUninstall.GetValue("DisplayName")
    WRITE-HOST $computername, $Value

}

# Note – With very little modification (by killing the loop) you could modify
# this script to query a remote machine for a SPECIFIC application

Advertisements