从注册表一次查询多个条目(使用reg查询)

时间:2019-08-21 18:08:06

标签: powershell cmd registry regedit

我运行后续的reg查询,这需要相当长的时间:

reg query HKLM\SOFTWARE\Classes /s /f "foo"
reg query HKLM\SOFTWARE\Classes /s /f "bar"

是否可以使用reg query一次按多个值搜索?

1 个答案:

答案 0 :(得分:5)

不,很遗憾, reg query /s /f仅接受单个过滤器表达式

过滤器表达式:帽子aschipfl的提示。

    默认情况下,
  • 与所有 注册表实体匹配:键名称,值名称和数据。

    • ({或}组合的选项/k(键),/v(值)和/d(数据)可用于缩小范围。

    • >
      • /v也可以 /f使用,在这种情况下,它需要一个值名称搜索词(例如{{1 }})完全匹配 (请参见下文); /v foo仅返回默认值(名称为空字符串的值)(如果它们包含数据)
      • /ve/f/v <valueNameSearchTerm> 组合时,仅组合 key 搜索({支持通过/ve的{​​1}}来缩小匹配范围;也就是说,唯一有意义的组合是
        • /k
        • /f
        • 这样,/f <keySearchTerm> /k /v <valueNameSearchTerm> / /f <keySearchTerm> /k /ve匹配被限制为与/v <valueNameSearchTerm>匹配的那些键,等于AND逻辑。
        • 任何其他组合-省略/ve,添加/f <keySearchTerm>,仅使用/k-有效地导致/d搜索词被忽略
    • /d可用于将匹配范围缩小到指定的值类型,例如/f

  • 默认执行不区分大小写的 substring 匹配。

    • 支持通配符/t REG_*(任意数量的字符,包括无字符)和REG_SZ(恰好1个字符)-尽管请注意,*之类的字符仍只执行 substring 匹配;似乎没有办法子字符串。

      • 如前所述,当您将?直接与值名称搜索词(例如foo*)一起使用时,它必须与完全匹配;例如,要找到一个值包含子字符串/v的名称,则必须使用/v foo
    • foo执行整个字符串匹配,而没有通配符支持。

    • *foo*使用区分大小写的 匹配。

  • 诸如/e之类的
  • 数字数据以其十进制字符串表示形式匹配

  • binary 数据(/c)作为“字节字符串”进行匹配:一个不带分隔符的2进制数字字节值列表。

运行REG_DWORD以查看所有选项或咨询documentation


您可以使用以下PowerShell命令提供多个过滤器:

注意:

  • 该命令仅限于以下搜索逻辑-尽管该命令可以进行调整以支持所有REG_BINARY选项,此时将创建函数包装器

    • 使用正则表达式(带有reg query /?)而不是通配符匹配(带有reg query),这既简化了命令,又使其更加灵活(调整解决方案以使用通配符匹配就不难了。

    • 仅搜索注册表数据 ,而不搜索键名和值名。

      • 例如,仅搜索键名,该命令将非常简单:
        -match
    • -like不同,二进制数据根据其十进制字符串表示形式逐字节匹配。

    • 仅检查目标键的 sub 键,而不检查目标键本身。

  • 使用单个过滤器,该命令比Get-ChildItem HKLM:\SOFTWARE\Classes -Recurse | Where-Object { $_.PSChildName -match 'foo|bar' } ,但是使用多个过滤器,最终可能比多个reg.exe通话要快;对于OP,花了4-5-YMMV。

    • 直接使用.NET框架进行递归密钥枚举替换reg.exe调用可能会带来速度改进,尽管我不知道有多少。专门构建的本机二进制文件(例如reg.exe)总是比自定义PowerShell代码更快。

    • 通常,PowerShell解决方案的主要优点是:

      • Objects 将被返回,这极大地方便了后续处理(无需解析 text 输出)。
      • 使用正则表达式可以进行更复杂的匹配。
Get-ChildItem

输出类似于以下内容,其中reg.exe列包含匹配项(向右滚动;或者,将以上内容通过管道传递到# The two filters to use, combined into a single regex. $regex = 'foo|bar' Get-ChildItem HKLM:\SOFTWARE\Classes -Recurse | ForEach-Object { foreach ($value in $_.GetValueNames()) { if (($data = $_.GetValue($value)) -match $regex) { [PSCustomObject]@{ Key = $_.Name Value = if ($value) { $value } else { '(default)' } Data = $data } } } } 以获取每行一个属性的视图) :

Data