Reputation: 68862
In PowerShell 2.0 on Win2008R2, if I want to get the same output from a registry key that "REG QUERY" would give me, in as readable a format, with the values from a particular registry key, like this:
reg query hkcu\Software\Microsoft\CharMap
HKEY_CURRENT_USER\Software\Microsoft\CharMap
Advanced REG_DWORD 0x0
CodePage REG_SZ Unicode
Font REG_SZ Arial
How would I do that with PowerShell? The behaviour of PowerShell mystifies me, once again.
Get-ItemProperty example:
Get-ItemProperty HKCU:\Software\Microsoft\CharMap
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\CharMap
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft
PSChildName : CharMap
PSDrive : HKCU
PSProvider : Microsoft.PowerShell.Core\Registry
Advanced : 0
CodePage : Unicode
Font : Arial
In my contrived example above, I want to see "Advanced", "CodePage" and "Font", but not any of the PowerShell metadata (names starting in PS). Sadly filtering on the name "PS" would not work for me, because I am not REALLY trying to read the MS Windows Character Map settings, I simply chose them as a registry key that probably everyone with Windows has, so everyone can see how utterly different the experience of using PowerShell is to look at the registry, compared to say the REG.EXE
program. There are reasons why anybody might want to get just the registry values from a registry key without getting any of the metadata, and anybody writing tools in PowerShell may want to do this simple task.
I would like output similar to REG QUERY
but still in native PowerShell format, not just flattened to text. I've googled and searched all over and can't seem to figure this out.
I'd like to be able to for example do this:
$all = GetRealRegistryKeysFrom( HKCU:\Software\Microsoft\CharMap )
for ($item in $all) { ... }
Update Using the function below, works great....
Example Get-RegistryKeyPropertiesAndValues -path HKCU:\Software\.....
Upvotes: 6
Views: 19033
Reputation: 217
Here's a version which returns the output as objects, so they can be looped through programmatically.
gp "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" | get-member | ? {$_.memberType -eq 'NoteProperty'} | ? {$_.name -notmatch '^PS'}
In a nutshell, what this is doing is:
get-itemProperty
): Show me the values within this Registry keygetType
, toString
etc) – those aren't useful to usThe result will be just the Registry values within that key.
Combine this with similar code just to enumerate subkeys and you have some pretty powerful PS.
Upvotes: 0
Reputation: 27418
Here's my substitute script for get-itemproperty I call get-itemproperty2.ps1:
# get-childitem skips top level key, use get-item
param([parameter(ValueFromPipeline)]$key)
process {
$valuenames = $key.getvaluenames()
if ($valuenames) {
$valuenames | foreach {
$value = $_
[pscustomobject] @{
Path = $key -replace 'HKEY_CURRENT_USER',
'HKCU:' -replace 'HKEY_LOCAL_MACHINE','HKLM:'
Name = $Value
Value = $Key.GetValue($Value)
Type = $Key.GetValueKind($Value)
}
}
} else {
[pscustomobject] @{
Path = $key -replace 'HKEY_CURRENT_USER',
'HKCU:' -replace 'HKEY_LOCAL_MACHINE','HKLM:'
Name = ''
Value = ''
Type = ''
}
}
}
Example:
get-item hkcu:\key1 | get-itemproperty2
Path Name Value Type
---- ---- ----- ----
HKCU:\key1 name1 1 DWord
Upvotes: 1
Reputation: 137
Following code will enumerate all values for a certain Registry key, will sort them and will return value name : value pairs separated by colon (:):
$path = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework';
Get-Item -Path $path | Select-Object -ExpandProperty Property | Sort | % {
$command = [String]::Format('(Get-ItemProperty -Path "{0}" -Name "{1}")."{1}"', $path, $_);
$value = Invoke-Expression -Command $command;
$_ + ' : ' + $value; };
Like this:
DbgJITDebugLaunchSetting : 16
DbgManagedDebugger : "C:\Windows\system32\vsjitdebugger.exe" PID %d APPDOM %d EXTEXT "%s" EVTHDL %d
InstallRoot : C:\Windows\Microsoft.NET\Framework\
Upvotes: 1
Reputation: 60910
This is a trick:
Get-ItemProperty HKCU:\Software\Microsoft\CharMap | out-string -stream | ? { $_ -NOTMATCH '^ps.+' }
The problem is when a property start with PS
. Working on this code you can elaborate to exclude these:
PSPath
PSParentPath
PSChildName
PSDrive
PSProvider
... One by one inside the where clause. Or just try using
get-item hkcu\Software\Microsoft\CharMap
There a script that do what you need.
update reproduced script here:
Function Get-RegistryKeyPropertiesAndValues
{
<#
Get-RegistryKeyPropertiesAndValues -path 'HKCU:\Volatile Environment'
Http://www.ScriptingGuys.com/blog
#>
Param(
[Parameter(Mandatory=$true)]
[string]$path)
Push-Location
Set-Location -Path $path
Get-Item . |
Select-Object -ExpandProperty property |
ForEach-Object {
New-Object psobject -Property @{"property"=$_;
"Value" = (Get-ItemProperty -Path . -Name $_).$_}}
Pop-Location
} #end function Get-RegistryKeyPropertiesAndValues
Upvotes: 7