WMI Registry Syntax

When I’m required to enumerate a registry key and return values in the subkeys, I’ll use a combination of get-childitem and pipe that to get-itemproperty. Â When I need to do this on a remote computer I use the invoke-command cmdlet. Â Unfortunately, I’m faced with a challenge that has most of the computers not having psremoting enabled. Â Enabling this will not be ideal. Â So that leaves me with WMI. Â My WMI registry query skills are lack luster at best.

What I’m looking to do is to enumerate through a registry key and return some specific values from whatever subkeys are found. Â Here is the query I use when I do not need to use WMI.

Get-ChildItem -Path 'HKLM:\SOFTWARE\obiwan\kenobi\Plugin Objects\Agents' | Get-ItemProperty | select 'agent name',hidden,'Product Version','Install Path' | Where-Object {$_.'agent name' -and $_.hidden -eq '0'}	}| select 'agent name','Product Version','Install Path' | ft -AutoSize

That works great. Â It also works great when put into an invoke-command.

For WMI this is what I have so far:

$hklm=2147483650
$rootkey="SOFTWARE\obiwan\kenobi\Plugin Objects\Agents"
$wmi = [wmiclass]"root\default:stdRegProv"

$rootkeys = $wmi.EnumKey($hklm,$rootkey).snames
$rootkeys

The above works perfectly to enumerate through the rootkey value and returns the .snames values.

Now I need to go into each of those subkeys and pull out specifics. Â Does anyone have the syntax I could use to accomplish this? Â If you use the sample I posted above for the get-childitem, get-itemproperty syntax, you can see exactly what I’m trying to pull out.

An easy starting point would be http://www.activexperts.com/activmonitor/windowsmanagement/adminscripts/registry/, which shows how to do most of these tasks in VBScript. Simialr syntax and easy to adapt.

If I were a VB scripter, yes that would probably be easy. Â I’ll read through them and see if I cannot figure it out. Â I learned PowerShell as my first scripting language. Â So VB is foreign to me.

I’ve spent a few hours trying to understand the VBScript examples Don provided. Â Unfortunately, I’m not getting far. Â As I mentioned I’ve been learning PowerShell. Â VBScript is completely foreign to me.

So, if anyone has an example on how to accomplish what I mentioned in my first post, I would greatly appreciate it.

Hope this helps you…

#Registry Hives
[long]$HIVE_HKROOT = 2147483648
[long]$HIVE_HKCU = 2147483649
[long]$HIVE_HKLM = 2147483650
[long]$HIVE_HKU = 2147483651
[long]$HIVE_HKCC = 2147483653
[long]$HIVE_HKDD = 2147483654

# Value Data Types
[int]$REG_SZ = 1
[int]$REG_EXPAND_SZ = 2
[int]$REG_BINARY = 3
[int]$REG_DWORD = 4
[int]$REG_MULTI_SZ = 7
[int]$REG_QWORD = 11

# Get Regeirty Provider
if ($Computer) {
  # Remote Computer
  $RegProv = [WMIClass]$("\\$Computer\root\Default:StdRegProv")
} else {
  # Local Computer
  $RegProv = [WMIClass]"root\Default:StdRegProv"
}

# Enumerate Keys
$ReturnedInfo = $RegProv.EnumKey($Hive, $RegKey)

# Enumerate Values
$ReturnedInfo = $RegProv.EnumValues($Hive, $RegKey)

# Create a Key
$ReturnedInfo = $RegProv.CreateKey($Hive, $RegKey)

# Delete a Key
$ReturnedInfo = $RegProv.DeleteKey($Hive, $RegKey)

# Write a Values
$ReturnedInfo = $RegProv.SetBinaryValue($Hive, $RegKey, $ValueName, $Value)
$ReturnedInfo = $RegProv.SetDWORDValue($Hive, $RegKey, $ValueName, $Value)
$ReturnedInfo = $RegProv.SetQWORDValue($Hive, $RegKey, $ValueName, $Value)
$ReturnedInfo = $RegProv.SetExpandedStringValue($Hive, $RegKey, $ValueName, $Value)
$ReturnedInfo = $RegProv.SetMultiStringValue($Hive, $RegKey, $ValueName, $Value)
$ReturnedInfo = $RegProv.SetStringValue($Hive, $RegKey, $ValueName, $Value)

# Read Values
$ReturnedInfo = $RegProv.GetBinaryValue($Hive, $RegKey, $ValueName)
$ReturnedInfo = $RegProv.GetDWORDValue($Hive, $RegKey, $ValueName)
$ReturnedInfo = $RegProv.GetQWORDValue($Hive, $RegKey, $ValueName)
$ReturnedInfo = $RegProv.GetExpandedStringValue($Hive, $RegKey, $ValueName)
$ReturnedInfo = $RegProv.GetMultiStringValue($Hive, $RegKey, $ValueName)
$ReturnedInfo = $RegProv.GetStringValue($Hive, $RegKey, $ValueName)

# Delete values
$ReturnedInfo = $RegProv.DeleteValue($Hive, $RegKey, $ValueName)

 

[quote=4517]Hope this helps you…

PowerShell

#Registry Hives
[long]$HIVE_HKROOT = 2147483648
[long]$HIVE_HKCU = 2147483649
[long]$HIVE_HKLM = 2147483650
[long]$HIVE_HKU = 2147483651
[long]$HIVE_HKCC = 2147483653
[long]$HIVE_HKDD = 2147483654

Value Data Types

[int]$REG_SZ = 1
[int]$REG_EXPAND_SZ = 2
[int]$REG_BINARY = 3
[int]$REG_DWORD = 4
[int]$REG_MULTI_SZ = 7
[int]$REG_QWORD = 11

Get Regeirty Provider

if ($Computer) {

Remote Computer

$RegProv = [WMIClass]$("\$Computer\root\Default:StdRegProv")
} else {

Local Computer

$RegProv = [WMIClass]“root\Default:StdRegProv”
}

Enumerate Keys

$ReturnedInfo = $RegProv.EnumKey($Hive, $RegKey)

Enumerate Values

$ReturnedInfo = $RegProv.EnumValues($Hive, $RegKey)

Create a Key

$ReturnedInfo = $RegProv.CreateKey($Hive, $RegKey)

Delete a Key

$ReturnedInfo = $RegProv.DeleteKey($Hive, $RegKey)

Write a Values

$ReturnedInfo = $RegProv.SetBinaryValue($Hive, $RegKey, $ValueName, $Value)
$ReturnedInfo = $RegProv.SetDWORDValue($Hive, $RegKey, $ValueName, $Value)
$ReturnedInfo = $RegProv.SetQWORDValue($Hive, $RegKey, $ValueName, $Value)
$ReturnedInfo = $RegProv.SetExpandedStringValue($Hive, $RegKey, $ValueName, $Value)
$ReturnedInfo = $RegProv.SetMultiStringValue($Hive, $RegKey, $ValueName, $Value)
$ReturnedInfo = $RegProv.SetStringValue($Hive, $RegKey, $ValueName, $Value)

Read Values

$ReturnedInfo = $RegProv.GetBinaryValue($Hive, $RegKey, $ValueName)
$ReturnedInfo = $RegProv.GetDWORDValue($Hive, $RegKey, $ValueName)
$ReturnedInfo = $RegProv.GetQWORDValue($Hive, $RegKey, $ValueName)
$ReturnedInfo = $RegProv.GetExpandedStringValue($Hive, $RegKey, $ValueName)
$ReturnedInfo = $RegProv.GetMultiStringValue($Hive, $RegKey, $ValueName)
$ReturnedInfo = $RegProv.GetStringValue($Hive, $RegKey, $ValueName)

Delete values

$ReturnedInfo = $RegProv.DeleteValue($Hive, $RegKey, $ValueName)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

#Registry Hives
[long]$HIVE_HKROOT=2147483648
[long]$HIVE_HKCU=2147483649
[long]$HIVE_HKLM=2147483650
[long]$HIVE_HKU=2147483651
[long]$HIVE_HKCC=2147483653
[long]$HIVE_HKDD=2147483654

Value Data Types

[int]$REG_SZ=1
[int]$REG_EXPAND_SZ=2
[int]$REG_BINARY=3
[int]$REG_DWORD=4
[int]$REG_MULTI_SZ=7
[int]$REG_QWORD=11

Get Regeirty Provider

if($Computer){

Remote Computer

$RegProv=[WMIClass]$("\$Computer\root\Default:StdRegProv")
}else{

Local Computer

$RegProv=[WMIClass]“root\Default:StdRegProv”
}

Enumerate Keys

$ReturnedInfo=$RegProv.EnumKey($Hive,$RegKey)

Enumerate Values

$ReturnedInfo=$RegProv.EnumValues($Hive,$RegKey)

Create a Key

$ReturnedInfo=$RegProv.CreateKey($Hive,$RegKey)

Delete a Key

$ReturnedInfo=$RegProv.DeleteKey($Hive,$RegKey)

Write a Values

$ReturnedInfo=$RegProv.SetBinaryValue($Hive,$RegKey,$ValueName,$Value)
$ReturnedInfo=$RegProv.SetDWORDValue($Hive,$RegKey,$ValueName,$Value)
$ReturnedInfo=$RegProv.SetQWORDValue($Hive,$RegKey,$ValueName,$Value)
$ReturnedInfo=$RegProv.SetExpandedStringValue($Hive,$RegKey,$ValueName,$Value)
$ReturnedInfo=$RegProv.SetMultiStringValue($Hive,$RegKey,$ValueName,$Value)
$ReturnedInfo=$RegProv.SetStringValue($Hive,$RegKey,$ValueName,$Value)

Read Values

$ReturnedInfo=$RegProv.GetBinaryValue($Hive,$RegKey,$ValueName)
$ReturnedInfo=$RegProv.GetDWORDValue($Hive,$RegKey,$ValueName)
$ReturnedInfo=$RegProv.GetQWORDValue($Hive,$RegKey,$ValueName)
$ReturnedInfo=$RegProv.GetExpandedStringValue($Hive,$RegKey,$ValueName)
$ReturnedInfo=$RegProv.GetMultiStringValue($Hive,$RegKey,$ValueName)
$ReturnedInfo=$RegProv.GetStringValue($Hive,$RegKey,$ValueName)

Delete values

$ReturnedInfo=$RegProv.DeleteValue($Hive,$RegKey,$ValueName)

[/quote]

 

That was incredibly helpful.  Thank you.  I’m still having a little trouble.

My registry looks like this:

 

Obiwan

Kenobi

Plugin Objects

Agents

Luke

Vader

So, HKLM\Software\Obiwan\Kenobi\Plugin Objects\Agents will always be there. Â Â I need to go into every sub-key under Agents and retrieve one or two string values. Â I then need to only include, as done in a where-object command, specific string values that were retrieved.

Using your very helpful post, I’m able to enumerate the keys under Agents. Â They’re in the sNames property. Â I just am unable to figure out how to go further.

Any help, or example using my keys, would be a tremendous help.

 

From the PowerShell Window try piping your returned object to “Get-Member” it gives you all the methods and how to call them…

Is this what you mean?

if ($Computer) {
  # Remote Computer
  $RegProv = [WMIClass]$("\\$Computer\root\Default:StdRegProv")
} else {
  # Local Computer
  $RegProv = [WMIClass]"root\Default:StdRegProv"
}

$hive = 2147483650
$regkey="SOFTWARE\obiwan\kenobi\Plugin Objects\Agents\"
$ReturnedInfo = $RegProv.EnumKey($Hive, $RegKey)
$ReturnedInfo | get-member

If so, this all I get back:

Name MemberType Definition


PSComputerName AliasProperty PSComputerName = __SERVER
ReturnValue Property uint32 ReturnValue {get;set;}
sNames Property string[] sNames {get;set;}
__CLASS Property string __CLASS {get;set;}
__DERIVATION Property string[] __DERIVATION {get;set;}
__DYNASTY Property string __DYNASTY {get;set;}
__GENUS Property int __GENUS {get;set;}
__NAMESPACE Property string __NAMESPACE {get;set;}
__PATH Property string __PATH {get;set;}
__PROPERTY_COUNT Property int __PROPERTY_COUNT {get;set;}
__RELPATH Property string __RELPATH {get;set;}
__SERVER Property string __SERVER {get;set;}
__SUPERCLASS Property string __SUPERCLASS {get;set;}

With what you’ve already provided, if you could provide me with an example using my registry keys that I’ve listed I think it would get me going. Â The part that is tripping me is up is having to enumerate through sub-keys and return values. Â I can easily go into a single registry key to retrieve the value of one string.

#Registry Hives
[long]$HIVE_HKROOT = 2147483648
[long]$HIVE_HKCU = 2147483649
[long]$HIVE_HKLM = 2147483650
[long]$HIVE_HKU = 2147483651
[long]$HIVE_HKCC = 2147483653
[long]$HIVE_HKDD = 2147483654

# Value Data Types
[int]$REG_SZ = 1
[int]$REG_EXPAND_SZ = 2
[int]$REG_BINARY = 3
[int]$REG_DWORD = 4
[int]$REG_MULTI_SZ = 7
[int]$REG_QWORD = 11

$RegProv = [WMIClass]"root\Default:StdRegProv"

$Hive = $HIVE_HKLM
$RegKey = "SOFTWARE\MyTestKey"

# Get SubKey names
$SubKeys = $RegProv.EnumKey($Hive, $RegKey)
# Make Sure No Error when Reading Registry
if ($SubKeys.ReturnValue -eq 0)
{
  # Loop Trhough All Returned SubKEys
  ForEach ($Name in $SubKeys.sNames)
  {
    $SubKey = "$RegKey\$Name"
    # Get Values under SubKey
    $Values = $RegProv.EnumValues($Hive, $SubKey)
    # Make Sure No Error when Reading Registry
    if ($Values.ReturnValue -eq 0)
    {
      $Total = $Values.sNames.Count
      # Lopp Throught All found Values
      For ($Count=0; $Count -lt $Total; $Count++)
      {
        $ValueName = $Values.sNames[$Count]
        $ValueType = $Values.Types[$Count]
        # Get Value Based on Returned Data Type
        Switch($ValueType)
        {
          $REG_SZ
          {
            $RegValue = $RegProv.GetStringValue($Hive, $SubKey, $ValueName)
            Break
          }
          $REG_EXPAND_SZ
          {
            $RegValue = $RegProv.GetExpandedStringValue($Hive, $SubKey, $ValueName)
            Break
          }
          $REG_BINARY
          {
            $RegValue = $RegProv.GetBinaryValue($Hive, $SubKey, $ValueName)
            Break
          }
          $REG_DWORD
          {
            $RegValue = $RegProv.GetDWORDValue($Hive, $SubKey, $ValueName)
            Break
          }
          $REG_MULTI_SZ
          {
            $RegValue = $RegProv.GetMultiStringValue($Hive, $SubKey, $ValueName)
            Break
          }
          $REG_QWORD
          {
            $RegValue = $RegProv.GetQWORDValue($Hive, $SubKey, $ValueName)
            Break
          }
        }
        # Make Sure No Error when Reading Registry
        if ($RegValue.ReturnValue -eq 0)
        {
          if (@($RegValue.Properties | Select-Object -ExpandProperty Name) -contains "sValue")
          {
            # String, Multi-String, and Expanded String Values
            New-Object -TypeName PSObject -Property @{"Hive"=$Hive; "Key"=$SubKey; "Value"=$ValueName; "DataType"=$ValueType; "Data"=$RegValue.sValue} 
          }
          Else
          {
            # DWord, QWord, and Binary Values
            New-Object -TypeName PSObject -Property @{"Hive"=$Hive; "Key"=$SubKey; "Value"=$ValueName; "DataType"=$ValueType; "Data"=$RegValue.uValue} 
          }
        }
      }
    }
  }
}

 

TeewsNek,

When I run that I get an error stating:

Property ‘ReturnValue’ cannot be found on this object. Make sure that it exists.
At line:25 char:5

  • if ($SubKeys.ReturnValue -eq 0)
  • CategoryInfo : NotSpecified: (:slight_smile: [], PropertyNotFoundException
  • FullyQualifiedErrorId : PropertyNotFoundStrict

When I run $subkeys it says: Â System.Management.ManagementBaseObject

All I did was change your code $RegKey = “SOFTWARE\MyTestKey” to $RegKey = “SOFTWARE\Obiwan\Kenobi\plugin objects\agents”  Under the agents key is all the subkeys with values inside them that I’m looking to retrieve.

TeewsNek,

It seems PowerShell did not like the variable named $subkeys. Â I simply replaced $subkeys with $keys and it worked.

The results look great! Â Thank you so much. Â Now I will take what you originally posted, along with the updated code and I should be able to absorb all this information.

Thanks again!