Prof. Powershell

Romancing the Registry

The Windows registry is full of wonder. Get at that information with this PowerShell awesomeness: Registry PSDrive.

Whenever I teach PowerShell and show off the Registry PSDrive, it inevitably draws a few oohs and occasionally mild applause. Using the same cmdlets you use with the file system you can easily navigate the local registry. But sometimes it takes a little extra coddling that isn't always readily apparent or intuitive. Let's look at this key:

HKLM:\software\microsoft\windows nt\CurrentVersion

I'll save it to a variable to make it easier and save on typing:

PS C:\> $regpath="HKLM:\software\microsoft\windows nt\CurrentVersion"
PS C:\> Get-Item $regpath

Hive: HKEY_LOCAL_MACHINE\software\microsoft\windows nt

SKC  VC  Name            Property
---  --  ----            --------
 76  20  CurrentVersion  {CurrentVersion, CurrentBuild,
                          SoftwareType, CurrentType...}

I could also get a listing of all sub keys using Get-Childitem or its alias, dir:

PS C:\> dir $regpath

But I can tell that this path itself has 20 property values itself like CurrentVersion and RegisteredOwner. How do I see those? Well, the registry key is like a folder and some of these "folders" have a number of attributes or properties. We use the Get-ItemProperty cmdlet. It requires a positional parameter for the item path:

PS C:\> Get-ItemProperty $regpath

If you've defined $regpath you should see a list of registry values. You can pipe this to any other PowerShell cmdlet:

PS C:\> Get-ItemProperty $regpath | Select Registered*,ProductName,Current*

RegisteredOrganization : JDH IT
RegisteredOwner        : Jeff
ProductName            : Windows 7 Professional
CurrentVersion         : 6.1
CurrentBuild           : 7600
CurrentType            : Multiprocessor Free
CurrentBuildNumber     : 7600

If you simply want to see values, this is perfectly acceptable. But if you need to figure out if something is a string or DWORD you can't tell because the cmdlet turns everything into a string.

However I can give you a little .NET trick to coax this information from the registry. First I'll save the registry key to a variable using Get-Item:

PS C:\> $reg=get-item $regpath

The Property property (confusing I admit) contains all the registry key properties:

PS C:\> $reg.property
CurrentVersion
CurrentBuild
SoftwareType
CurrentType
InstallDate
RegisteredOrganization
RegisteredOwner
SystemRoot
InstallationType
EditionID
ProductName
ProductId
DigitalProductId
DigitalProductId4
CurrentBuildNumber
BuildLab
BuildLabEx
BuildGUID
CSDBuildNumber
PathName

Using a direct .NET method I can even retrieve values with the GetValue() method:

PS C:\> $reg.GetValue("installdate")
1276354060

PS C:\> $reg.GetValue("currentversion")
6.1

Now for the real magic: use the GetValueKind() method to retrieve the registry type:

PS C:\> $reg.GetValueKind("installdate")
DWord

PS C:\> $reg.GetValueKind("currentversion")
String

I'll wrap up this lesson by leaving you with a code snippet you might use as the basis for a function to return this type of information:

$reg.property | foreach {
  New-Object PSObject -Property @{
    Name=$_
    Type=$reg.GetValueKind($_)
    Value=$reg.GetValue($_)
  }
}

Or, take a look at my blog for more PowerShell registry examples, including a registry export function.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular