Posts RSS Comments RSS 253 Posts and 408 Comments till now

Archive for the 'Registry' Category

Get-InstalledSoftware (what software is installed?)

nishant left a comment on my “Powershell, Remote Registry and You! Part 1 (Overview)” post.

Nishant asked “I want a complete list of software installed on a remote machine using Powershell.”

I decided to post on this because it is brought up a lot. Unfortunately, getting a complete list of install applications is not that straightforward. Some applications do not store information in the Registry so the best we can do is list software that provides Uninstall regkey info. That is what the script below does. While this is not perfect it does a pretty good job getting the info.

Param($srv=$env:ComputerName)
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$Srv)
$key = $regKey.OpenSubkey("Software\Microsoft\Windows\CurrentVersion\Uninstall",$false)
$key.GetSubKeyNames()

It is common to see people use Win32_Product to list installed apps, but it is important to point out this only list applications installed by an MSI installer.

Perhaps the best options is to combine both of these options.

# Get-InstalledSoftware
Param($srv=$env:ComputerName)
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$Srv)
$key = $regKey.OpenSubkey("Software\Microsoft\Windows\CurrentVersion\Uninstall",$false)
Write-Host
Write-Host "Getting Software in Uninstall Key" -Fore Green
Write-Host ("-"*60) -Fore Gray
$key.GetSubKeyNames()
Write-Host
Write-Host "Getting Software From Win32_Product" -Fore Green
Write-Host ("-"*60) -Fore Gray
get-wmiobject Win32_Product -comp $srv | foreach{$_.Name}
Write-Host

Powershell, Remote Registry and You! Part 1 (Overview)

I was reading the news groups (as I do all the time) and I have notice numerous request/questions regarding remote registry access in powershell. I thought I would try to see if I could shed some light on the subject. So without further delay… on with the show!

Overview:
———-
Registry access in Posh is realatively simple and extremely powerful.
From a local stand point its as simple as:
PS> Set-Location HKLM:System
From a remote standpoint… you have to utilize the powers of .NET.
$ServerKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, ServerName)

For the purpose of this post… I am going to focus on the remote aspect. Local is cover in tons of documentation. So, cause of time, I am only going to address the .NET method.

I will start by giving you the Remote Registry Object useful Properties/Methods

Object
——-
[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,MachineName)

Properties
————-
Name
SubKeyCount
ValueCount

Methods (Not all.. just the ones I use often)
—————————————————
CreateSubKey
DeleteSubKey
DeleteSubKeyTree
DeleteValue
GetAccessControl
GetLifetimeService
GetSubKeyNames
GetType
GetValue
GetValueKind
GetValueNames
OpenSubKey
SetAccessControl
SetValue

As you can see… You can do basically everything you could ever want.

Now that you have a basic idea of what the .NET provider can give you… let put it to practical use.

Examples:
———-
Purpose: Get a list of Subkeys and Values of Specific Registry Key.

[code]$key = "SOFTWARE\Microsoft\Windows\CurrentVersion"
$type = [Microsoft.Win32.RegistryHive]::LocalMachine
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $Srv)
$regKey = $regKey.OpenSubKey($key)
Write-Host "Sub Keys"
Write-Host "--------"
Foreach($sub in $regKey.GetSubKeyNames()){$sub}
Write-Host
Write-Host "Values"
Write-Host "------"
Foreach($val in $regKey.GetValueNames()){$val}[/code]

Result (only showing first 10 of each:)

Sub Keys
——–
App Management
App Paths
Applets
BITS
Control Panel
Controls Folder
CSCSettings
DateTimeDynamic
DirectoryExplorer

Values
——
DevicePath
MediaPath
Unexpanded
SM_GamesName
SM_Configure
ProgramsName
ProgramFilesDir
CommonFilesDir
ProductId
WallPaperDir
MediaPath
ProgramFilesPath

——————————————-
Purpose: Get the Value of each of the Values.

[code]$key = "SOFTWARE\Microsoft\Windows\CurrentVersion"
$type = [Microsoft.Win32.RegistryHive]::LocalMachine
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $Srv)
$regKey = $regKey.OpenSubKey($key)
Write-Host "Values"
Write-Host "------"
Foreach($val in $regKey.GetValueNames()){
   Write-Host $val.PadRight(30) -nonewline
   Write-Host $regKey.GetValue("$val")
}[/code]

Result (only showing first 10:)

Values
——
DevicePath = [C:\WINDOWS\inf;C:\Drivers\Broadcom\Win2003]
MediaPathUnexpanded = [C:\WINDOWS\Media]
SM_GamesName = [Games]
SM_ConfigureProgramsName = [Set Program Access and Defaults]
ProgramFilesDir = [C:\Program Files]
CommonFilesDir = [C:\Program Files\Common Files]
ProductId = [69713-640-4031427-45876]
WallPaperDir = [C:\WINDOWS\Web\Wallpaper]
MediaPath = [C:\WINDOWS\Media]
ProgramFilesPath = [C:\Program Files]

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

Summary:
———–
As you now can see. POSH is really powerful given its .NET access to the registry. Honestly… there is virtually nothing you can’t do and its easy to boot. You have complete access to Registry keys/subkeys/values. You can even Create, Delete, and evaluate Values and keys. In the future I will be sharing a function I wrote to compare Registry Subkeys between machines. That has proven to be super valuable.

Well… That about does it (at least for today :) ) I think this is a pretty good start to your POSH .NET registry adventure. I will be expanding this as I have time.

As always… PLEASE PROVIDE FEEDBACK!!! :)