如何在PowerShell中按名称和值过滤注册表项下的名称/值对?

Jer*_*ers 4 registry powershell powershell-3.0

我试图了解在PowerShell中使用的习语.

鉴于此脚本:

$path = 'hkcu:\Software\Microsoft\Windows\CurrentVersion\Extensions'
$key = Get-Item $path
$key
Run Code Online (Sandbox Code Playgroud)

我得到了这个问题底部的输出.

我想得到属性的输出(名称/值对下$key)我可以在名称和值上进行过滤.

例如,过滤列出所有具有以下内容的扩展:

  • 名字就像 xls*
  • 或价值 *\MSACCESS.EXE

或者排除过滤器:排除所有名称 doc*

冷杉第一个过滤器,我想要一个像这样的结果:

Name                           Value                                                                                                                                                       
----                           --------                                                                                                                                                       
xlsx                           C:\PROGRA~2\MICROS~1\Office15\EXCEL.EXE                                                                                                                 
xls                            C:\PROGRA~2\MICROS~1\Office15\EXCEL.EXE                                                                                                                 
mdb                            C:\PROGRA~2\MICROS~1\Office15\MSACCESS.EXE                                                                                                              
mda                            C:\PROGRA~2\MICROS~1\Office15\MSACCESS.EXE                                                                                                              
Run Code Online (Sandbox Code Playgroud)

这是脚本的原始输出:

Hive: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion
Name                           Property                                                                                                                                                       
----                           --------                                                                                                                                                       
Extensions                     rtf  : C:\PROGRA~2\MICROS~1\Office15\WINWORD.EXE ^.rtf                                                                                                         
                               dot  : C:\PROGRA~2\MICROS~1\Office15\WINWORD.EXE ^.dot                                                                                                         
                               dotm : C:\PROGRA~2\MICROS~1\Office15\WINWORD.EXE ^.dotm                                                                                                        
                               dotx : C:\PROGRA~2\MICROS~1\Office15\WINWORD.EXE ^.dotx                                                                                                        
                               docm : C:\PROGRA~2\MICROS~1\Office15\WINWORD.EXE ^.docm                                                                                                        
                               docx : C:\PROGRA~2\MICROS~1\Office15\WINWORD.EXE ^.docx                                                                                                        
                               doc  : C:\PROGRA~2\MICROS~1\Office15\WINWORD.EXE ^.doc                                                                                                         
                               xlsx : C:\PROGRA~2\MICROS~1\Office15\EXCEL.EXE                                                                                                                 
                               xls  : C:\PROGRA~2\MICROS~1\Office15\EXCEL.EXE                                                                                                                 
                               mdb  : C:\PROGRA~2\MICROS~1\Office15\MSACCESS.EXE                                                                                                              
                               mda  : C:\PROGRA~2\MICROS~1\Office15\MSACCESS.EXE                                                                                                              
Run Code Online (Sandbox Code Playgroud)

编辑

我解决了部分问题:获取名称/值对列表.它使用PSCustomObject:

$namevalues = $key.GetValueNames() | ForEach-Object { [pscustomobject]@{ Name=$_; Value=$key.GetValue($_) } }
$namevalues
Run Code Online (Sandbox Code Playgroud)

(我应该如何包装该代码?)

任何有关过滤的帮助将非常感激

Jer*_*ers 6

两部分答案.

我们$key从注册表开始:

$path = 'hkcu:\Software\Microsoft\Windows\CurrentVersion\Extensions'
$key = Get-Item $path
$key
$key | Get-Member
Run Code Online (Sandbox Code Playgroud)

由于$key是Microsoft.Win32.RegistryKey,因此无法直接获取名称值对.

第一步是使用/ pairs 创建PSCustomObjects列表.在来自GetValueNames通过管道输送的foreach对象.对于每个名称,我们通过GetValue得到:NameValueNameValue

$namevalues = $key.GetValueNames() | 
  ForEach-Object { 
    [PSCustomObject] @{ 
      Name = $_; 
      Value = $key.GetValue($_) 
    } 
  }
$namevalues | Format-Table
Run Code Online (Sandbox Code Playgroud)

第一步的替代方法是使用-Spad Saad解释的使用-ExpandProperty的Select-Object:

$namevalues = $key | Select-Object -ExpandProperty Property | 
  ForEach-Object { 
    [PSCustomObject] @{ 
      Name = $_; 
      Value = $key.GetValue($_) 
    } 
  }
$namevalues | Format-Table
Run Code Online (Sandbox Code Playgroud)

第二步是过滤$namevalues通过任一Name或通过Value.

该位置对象有一些很酷的比较操作符接受正则表达式一样match,notMatch等等.

为了使代码更具可读性,你可以换行(感谢Joey!)要么使用反引号(`),要么利用PowerShell语法中的地方接受换行符,比如在管道(|)或左括号之后({):

$matches = $namevalues | 
  Where-Object { 
    $_.Name -match '^xls' `
    -or $_.Value -match 'msaccess.exe$' 
  }
$matches | Format-Table
Run Code Online (Sandbox Code Playgroud)

结果如所需:

Name    Value                                                                                         
----    -----                                                                                         
xlsx    C:\PROGRA~2\MICROS~1\Office15\EXCEL.EXE                                                       
xls     C:\PROGRA~2\MICROS~1\Office15\EXCEL.EXE                                                       
mdb     C:\PROGRA~2\MICROS~1\Office15\MSACCESS.EXE                                                    
mda     C:\PROGRA~2\MICROS~1\Office15\MSACCESS.EXE
Run Code Online (Sandbox Code Playgroud)


mon*_*ero 5

有一个更聪明的方法来枚举注册表值(在这里找到)。而且它更像是 IMO 的 powershell 方式。

我把它变成了单行:

(Get-ItemProperty $path).psobject.properties | 
   where {$_.name -like "xls*" -or $_.value -like "*\MSACCESS.EXE"} | 
      select name,value
Run Code Online (Sandbox Code Playgroud)

更新:正如@ mklement0在评论中指出,你应该小心性质PSPath,PSParentPath,PSChildName,PSDrive,和PSProvider中psobject.properties。

  • 尽管这个解决方案既方便又简洁,也有一个陷阱:PowerShell 的注册表提供程序会自动将自己的属性添加到 `.psobject.properties` 中报告的属性集合中,即 `PSPath`、`PSParentPath`、`PSChildName`、` PSDrive` 和 `PSProvider`,这意味着按名称过滤的通配符表达式可能会意外包含它们,或者更糟糕的是,如果键上碰巧存在同名的值(即使不太可能),提供程序属性会覆盖它们. (2认同)