如何查询跳过 PS* 的注册表值

Jer*_*ers 5 registry powershell

像这样查询注册表值名称时:

Get-ItemProperty HKCU:\Software\Microsoft\Osk
Run Code Online (Sandbox Code Playgroud)

你会得到一大堆额外的价值。

PSPath            : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Osk
PSParentPath      : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft
PSChildName       : Osk
PSDrive           : HKCU
PSProvider        : Microsoft.PowerShell.Core\Registry
WindowLeft        : 100
WindowTop         : 100
WindowWidth       : 828
WindowHeight      : 236
ClickSound        : 1
Mode              : 1
HoverPeriod       : 1000
ScanInterval      : 1000
UseDevice         : 1
UseMouse          : 0
UseKB             : 1
ScanKey           : 32
UseTextPrediction : 1
InsertSpace       : 1
ShowNumPad        : 0
Run Code Online (Sandbox Code Playgroud)

我想要的只是值名称 ( WindowLeft, ...)

我怎样才能做到这一点?

编辑:字符串匹配不会削减它。我确实希望包含合法的注册表值名称。

示例(可以用reg query hklm /v PS* /s或做类似的事情reg query hkcu /v PS* /s

reg add "HKCU\Software\BeSharp.net\Test" /v "Foo" /t REG_SZ /d "Bar" /f
reg add "HKCU\Software\BeSharp.net\Test" /v "Bar" /t REG_SZ /d "Foo" /f

reg add "HKCU\Software\BeSharp.net\Test" /v "PSPath" /t REG_SZ /d "Foo" /f
reg add "HKCU\Software\BeSharp.net\Test" /v "PSParentPath" /t REG_SZ /d "Foo" /f
reg add "HKCU\Software\BeSharp.net\Test" /v "PSChildName" /t REG_SZ /d "Foo" /f
reg add "HKCU\Software\BeSharp.net\Test" /v "PSDrive" /t REG_SZ /d "Foo" /f
reg add "HKCU\Software\BeSharp.net\Test" /v "PSProvider" /t REG_SZ /d "Foo" /f

reg add "HKCU\Software\BeSharp.net\Test" /v "1" /t REG_SZ /d "PSPath" /f
reg add "HKCU\Software\BeSharp.net\Test" /v "2" /t REG_SZ /d "PSParentPath" /f
reg add "HKCU\Software\BeSharp.net\Test" /v "3" /t REG_SZ /d "PSChildName" /f
reg add "HKCU\Software\BeSharp.net\Test" /v "4" /t REG_SZ /d "PSDrive" /f
reg add "HKCU\Software\BeSharp.net\Test" /v "5" /t REG_SZ /d "PSProvider" /f

reg query "HKCU\Software\BeSharp.net\Test"
Run Code Online (Sandbox Code Playgroud)

您可以使用以下命令删除上述演示数据:

reg delete "HKCU\Software\BeSharp.net\Test"
Run Code Online (Sandbox Code Playgroud)

reg query "HKCU\Software\BeSharp.net\Test"返回此:

HKEY_CURRENT_USER\Software\BeSharp.net\Test
    Foo    REG_SZ    Bar
    Bar    REG_SZ    Foo
    PSPath    REG_SZ    Foo
    PSParentPath    REG_SZ    Foo
    PSChildName    REG_SZ    Foo
    PSDrive    REG_SZ    Foo
    PSProvider    REG_SZ    Foo
    1    REG_SZ    PSPath
    2    REG_SZ    PSParentPath
    3    REG_SZ    PSChildName
    4    REG_SZ    PSDrive
    5    REG_SZ    PSProvider
Run Code Online (Sandbox Code Playgroud)

但是PowerShell Get-ItemProperty "HKCU:\Software\BeSharp.net\Test"返回这个,覆盖PS*注册表中的值:

PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\BeSharp.net\Test
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\BeSharp.net
PSChildName  : Test
PSDrive      : HKCU
PSProvider   : Microsoft.PowerShell.Core\Registry
Foo          : Bar
Bar          : Foo
1            : PSPath
2            : PSParentPath
3            : PSChildName
4            : PSDrive
5            : PSProvider
Run Code Online (Sandbox Code Playgroud)

添加Select子句会跳过所有PS*值,即使它们来自注册表PowerShell Get-ItemProperty "HKCU:\Software\BeSharp.net\Test" ^| Select * -Exclude PS*::

Foo : Bar
Bar : Foo
1   : PSPath
2   : PSParentPath
3   : PSChildName
4   : PSDrive
5   : PSProvider
Run Code Online (Sandbox Code Playgroud)

所以:跳过 PS* 值,如PSPath, PSParentPath, PSChildName,PSDrivePSProvider(还有更多?)当它们不在注册表中时,但当它们在注册表中时包含它们。

奖励:只列出名称(而不是值)。

Roh*_*rds 5

您可以在注册表项对象上使用 GetValueNames() 方法:

$RegPath = "HKCU:\Software\Microsoft\Osk"

# Get just value names:
(Get-Item $RegPath).GetValueNames() -replace "^$", "(default)"

# Get PSObject excluding PS properties (this won't work when value names collide 
# with reserved PS properties, e.g., PSPath, PSParentPath, PSChildName):
Get-Item $RegPath | ForEach-Object {
    $_ | Get-ItemProperty | select ($_.GetValueNames() -replace "^$", "(default)")
}

# Get PSObject excluding PS properties (this works when the value names collide)
Get-Item $RegPath | ForEach-Object {
    $RegKey = $_
    $PropertyHash = @{}
    $_.GetValueNames() -replace "^$", "(default)" | ForEach-Object {
        $PropertyHash.$_ = $RegKey.GetValue($_)
    }
    New-Object PSObject -Property $PropertyHash
}
Run Code Online (Sandbox Code Playgroud)


The*_*ian 4

这很简单,您只需使用 Select,并告诉它排除 PS*:

Get-ItemProperty HKCU:\Software\Microsoft\Osk|Select * -Exclude PS*
Run Code Online (Sandbox Code Playgroud)

编辑:我真的应该阅读整个问题。好的,要仅获取名称,您可以通过管道传输到 Get-Member -MemberType Properties,然后选择 -Expand Name,然后过滤以 PS 开头的项目

Get-ItemProperty HKCU:\Software\Microsoft\Osk|GM -MemberType Properties|Select -Expand Name| ?{!($_ -Match "^PS")}
Run Code Online (Sandbox Code Playgroud)

编辑:好的,如果您想要值名称,并且想要避免 PowerShell 生成的值,那么我们将解决内置提供程序并执行 WMI 查询...

$HKEY_CLASSES_ROOT = 2147483648
$HKEY_CURRENT_USER = 2147483649
$HKEY_LOCAL_MACHINE = 2147483650
$HKEY_USERS = 2147483651
$HKEY_CURRENT_CONFIG = 2147483653
$reg = [WMIClass]"ROOT\DEFAULT:StdRegProv"
$reg.EnumValues($HKEY_CURRENT_USER,"Software\Microsoft\Osk")|Select -Expand sNames
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我很好奇 2147483652 是什么,因为它似乎跳过了它。

编辑:意义2147483652通过搜索2147483652 HKEY_CLASSES_ROOT 2147483648 HKEY_CURRENT_USER 2147483649 HKEY_LOCAL_MACHINE 2147483650 HKEY_USERS 2147483651 HKEY_CURRENT_CONFIG 21474836找到53 HKEY_DYN_DATA 2147483654

许多链接都回答了这个问题,包括DLLBinder 示例 - 注册表访问,表明它位于winreg.h中(毫不奇怪,它包含十六进制值)。

因此,为了完整性:

  $HKEY_CLASSES_ROOT       = 2147483648 # 0x80000000   
  $HKEY_CURRENT_USER       = 2147483649 # 0x80000001   
  $HKEY_LOCAL_MACHINE      = 2147483650 # 0x80000002   
  $HKEY_USERS              = 2147483651 # 0x80000003   
  $HKEY_PERFORMANCE_DATA   = 2147483652 # 0x80000004   
  $HKEY_CURRENT_CONFIG     = 2147483653 # 0x80000005   
  $HKEY_DYN_DATA           = 2147483654 # 0x80000006 
Run Code Online (Sandbox Code Playgroud)