Powershell 中的快速注册表搜索器 [英] Fast Registry Searcher in Powershell

查看:85
本文介绍了Powershell 中的快速注册表搜索器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将我在 Github 上找到的这个搜索注册表脚本合并到我的一个脚本中.

https://github.com/KurtDeGreeff/PlayPowershell/blob/master/Search-Registry.ps1

为了测试它,我使用了它提供的示例之一:

Search-Registry -StartKey HKLM -Pattern $ENV:USERNAME -MatchData

执行后,仍然提示我在控制台中输入一个StartKey和一个Pattern.再次提供该信息后,该命令失败.

cmdlet Search-Registry.ps1 在命令管道位置 1提供以下参数的值:开始密钥:HKLM模式:$ENV:USERNAME -MatchData您必须至少指定以下之一: -MatchKey -MatchValue -MatchData在 C:\Users\Cole\Desktop\Powershell\Search-Registry.ps1:93 字符:5+ throw "您必须至少指定以下一项:-MatchKey -MatchValue -M ...+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ CategoryInfo : OperationStopped: (你必须指定...alue -MatchData:String) [], RuntimeException+ FullQualifiedErrorId :您必须至少指定以下之一:-MatchKey -MatchValue -MatchData

是不是我做错了什么?

解决方案

我已经在 GitHub 也遇到了错误,所以我决定自己完全重写.

下面的函数可以使用正则表达式匹配或使用 -like 运算符的通配符比较.
要搜索无名的默认属性,或者根本不指定 PatternRegexPattern 参数,或者使用其中之一和空字符串.

该函数还有一个 Recurse 开关,因此是否要递归搜索所有子键取决于您.

请注意,虽然该函数执行速度很快,但搜索注册表可能需要很长时间才能完成..

# 如果你想在 PowerShell 上运行它 <3.0 使用# New-Object -TypeName PSObject -Property @{ ... } 无论在哪里说 [PSCustomObject]@{ ... }# 并将requires"的 -version 值更改为 2#requires - 版本 3功能搜索注册表{<#.概要在一台或多台计算机上的注册表中搜索指定的文本模式..描述在一台或多台计算机上的注册表中搜索指定的文本模式.支持搜索键名、值名和/或值数据的任意组合.搜索模式是正则表达式或使用like"运算符的通配符模式.(两者都不区分大小写).PARAMETER 计算机名(必需)搜索指定计算机上的注册表.此参数支持管道输入..PARAMETER 模式(可选)使用通配符模式和 -like 运算符进行搜索.与参数RegexPattern"互斥.PARAMETER 正则表达式模式(可选)使用正则表达式模式进行搜索.与参数Pattern"互斥.PARAMETER 蜂巢(可选)注册表配置单元根名称.可以是'HKEY_CLASSES_ROOT'、'HKEY_CURRENT_CONFIG'、'HKEY_CURRENT_USER'、'HKEY_DYN_DATA'、'HKEY_LOCAL_MACHINE'中的任何一个,'HKEY_PERFORMANCE_DATA','HKEY_USERS','HKCR','HKCC','HKCU','HKDD','HKLM','HKPD','HKU'如果未指定,则配置单元必须是KeyPath"参数的一部分..PARAMETER 键路径(可选)在指定的注册表项处开始搜索.键名只包含子键.此参数可以使用配置单元名称作为前缀.在这种情况下,参数 'Hive' 将被忽略,因为它是从给定的路径中获取的.例子:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\UninstallHKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall软件\Microsoft\Windows\CurrentVersion\Uninstall.PARAMETER 最大结果(可选)指定每台计算机搜索的最大结果数.值 <= 0 表示将返回可能匹配的最大数量 (2147483647)..PARAMETER 搜索键名(可选)搜索注册表项名称.您必须至少指定 -SearchKeyName、-SearchPropertyName 或 -SearchPropertyValue 之一..PARAMETER 搜索属性名称(可选)搜索注册表值名称.您必须至少指定 -SearchKeyName、-SearchPropertyName 或 -SearchPropertyValue 之一..PARAMETER 搜索属性值(可选)搜索注册表值数据.您必须至少指定 -SearchKeyName、-SearchPropertyName 或 -SearchPropertyValue 之一..PARAMETER 递归(可选)如果设置,该函数将通过找到的所有子项递归搜索..输出PSCustomObjects 具有以下属性:ComputerName 执行搜索的计算机名称Hive Win32 格式中使用的配置单元名称(CurrentUser"、LocalMachine"等)HiveName 使用的配置单元名称(HKEY_CURRENT_USER"、HKEY_LOCAL_MACHINE"等)HiveShortName 使用的缩写配置单元名称(HKCU"、HKLM"等)路径 完整的注册表路径(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall")SubKey 不带 hive 的子项(Software\Microsoft\Windows\CurrentVersion\Uninstall")ItemType 信息:描述类型RegistryKey"或RegistryProperty"DataType .REG 格式的数据类型(REG_SZ"、REG_EXPAND_SZ"、REG_DWORD"等).ItemType 'RegistryKey' 的 $nullValueKind Win32 数据类型(String"、ExpandString"、DWord"等).ItemType 'RegistryKey' 的 $nullPropertyName 属性的名称.ItemType 'RegistryKey' 的 $nullPropertyValue 注册表属性的值.ItemType 'RegistryKey' 的 $nullPropertyValueRaw 注册表属性的原始未扩展值.ItemType 'RegistryKey' 的 $null'PropertyValue' 和 'PropertyValueRaw' 的区别在于,在 'PropertyValue' 中扩展了环境名称(数据中的%SystemRoot%"被扩展为C:\Windows"),而在PropertyValueRaw"中,数据按原样返回.(环境名称返回为%SystemRoot%").例子Search-Registry -Hive HKLM -KeyPath SOFTWARE -Pattern $env:USERNAME -SearchPropertyValue -Recurse -Verbose在本地计算机上的 HKEY_LOCAL_MACHINE 中搜索其数据包含当前用户名的注册表值.像这样的搜索可能需要很长时间,您可能会在不允许输入的注册表项上看到警告消息..例子Search-Registry -KeyPath 'HKEY_CURRENT_USER\Printers\Settings' -Pattern * -SearchPropertyName |导出-Csv -Path 'D:\printers.csv' -NoTypeInformation或者Search-Registry -Hive HKEY_CURRENT_USER -KeyPath 'Printers\Settings' -Pattern * -SearchPropertyName |导出-Csv -Path 'D:\printers.csv' -NoTypeInformation在本地计算机上搜索 HKEY_CURRENT_USER (HKCU) 以查找打印机名称并将其输出为 CSV 文件..例子Search-Registry -KeyPath 'HKLM:\SOFTWARE\Classes\Installer' -Pattern LastUsedSource -SearchPropertyName -Recurse或者Search-Registry -Hive HKLM -KeyPath 'SOFTWARE\Classes\Installer' -Pattern LastUsedSource -SearchPropertyName -Recurse输出当前计算机上的 LastUsedSource 注册表项..例子Search-Registry -KeyPath 'HKCR\.odt' -RegexPattern '.*' -SearchKeyName -MaximumResults 10 -Verbose或者Search-Registry -Hive HKCR -KeyPath '.odt' -RegexPattern '.*' -SearchKeyName -MaximumResults 10 -Verbose如果指定的键存在,则最多输出十个匹配项.如果当前计算机已注册程序以打开扩展名为 .odt 的文件,则此命令将返回结果.模式 '.*' 表示匹配所有内容..例子获取内容 Computers.txt |Search-Registry -KeyPath "HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine" -Pattern '*' -SearchPropertyName |导出-CSV -Path 'D:\powershell.csv' -NoTypeInformation从指定的子项开始,在文件 Computers.txt 中列出的每台计算机的注册表中搜索任何属性名称.输出被发送到指定的 CSV 文件..例子搜索注册表 -KeyPath 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace' -SearchPropertyName -Recurse -Verbose在指定的注册表项中搜索默认(无名)属性.#>[CmdletBinding(DefaultParameterSetName = 'ByWildCard')]参数([参数(ValueFromPipeline = $true,Mandatory = $false,Position = 0)][string[]]$ComputerName = $env:COMPUTERNAME,[Parameter(Mandatory = $false, ParameterSetName = 'ByRegex')][字符串]$RegexPattern,[Parameter(Mandatory = $false, ParameterSetName = 'ByWildCard')][字符串]$模式,[参数(强制= $false)][ValidateSet('HKEY_CLASSES_ROOT','HKEY_CURRENT_CONFIG','HKEY_CURRENT_USER','HKEY_DYN_DATA','HKEY_LOCAL_MACHINE','HKEY_PERFORMANCE_DATA','HKEY_USERS','HKCR','HKCC','HKCU','HKDD','HKLM','HKPD','HKU')][字符串]$Hive,[字符串]$KeyPath,[int32] $MaximumResults = [int32]::MaxValue,[开关]$SearchKeyName,[开关]$SearchPropertyName,[开关]$SearchPropertyValue,[开关]$递归)开始 {# 检测函数是否被管道调用# 见:https://communary.net/2015/01/12/quick-tip-determine-if-input-comes-from-the-pipeline-or-not/# 和:https://www.petri.com/unraveling-mystery-myinvocation[bool]$isPipeLine = $MyInvocation.ExpectingInput# 清理给定的参数if ([string]::IsNullOrWhiteSpace($ComputerName) -or $ComputerName -eq '.') { $ComputerName = $env:COMPUTERNAME }# 解析给定的 KeyPathif ($KeyPath -match '^(HK(?:CR|CU|LM|U|PD|CC|DD)|HKEY_[A-Z_]+)[:\\]?') {$Hive = $matches[1]# 从路径中删除 HKLM、HKEY_CURRENT_USER 等$KeyPath = $KeyPath.Split("\", 2)[1]}开关($蜂巢){{ @('HKCC', 'HKEY_CURRENT_CONFIG') -包含 $_ } { $objHive = [Microsoft.Win32.RegistryHive]::CurrentConfig;休息 }{ @('HKCR', 'HKEY_CLASSES_ROOT') -包含 $_ } { $objHive = [Microsoft.Win32.RegistryHive]::ClassesRoot;休息 }{ @('HKCU', 'HKEY_CURRENT_USER') - 包含 $_ } { $objHive = [Microsoft.Win32.RegistryHive]::CurrentUser;休息 }{ @('HKDD', 'HKEY_DYN_DATA') - 包含 $_ } { $objHive = [Microsoft.Win32.RegistryHive]::DynData;休息 }{ @('HKLM', 'HKEY_LOCAL_MACHINE') - 包含 $_ } { $objHive = [Microsoft.Win32.RegistryHive]::LocalMachine;休息 }{ @('HKPD', 'HKEY_PERFORMANCE_DATA') -包含 $_ } { $objHive = [Microsoft.Win32.RegistryHive]::PerformanceData;休息 }{ @('HKU', 'HKEY_USERS') - 包含 $_ } { $objHive = [Microsoft.Win32.RegistryHive]::Users;休息 }}#critical:无法确定Hive如果(!$objHive){抛出未指定参数 'Hive' 或无法从 'KeyPath' 参数解析."}# 关键:没有给出搜索条件if (-not ($SearchKeyName -or $SearchPropertyName -or $SearchPropertyValue)) {抛出您必须至少指定以下参数之一:'SearchKeyName'、'SearchPropertyName' 或 'SearchPropertyValue'"}# 没有给出的模式只适用于 SearchPropertyName 和 SearchPropertyValueif ([string]::IsNullOrEmpty($RegexPattern) -and [string]::IsNullOrEmpty($Pattern)) {如果 ($SearchKeyName) {写警告参数 'RegexPattern' 和 'Pattern' 都是空字符串.搜索 KeyNames 不会产生结果."}}# 为输出目的创建两个变量开关 ($objHive.ToString()) {'CurrentConfig' { $hiveShort = 'HKCC';$hiveName = 'HKEY_CURRENT_CONFIG' }'ClassesRoot' { $hiveShort = 'HKCR';$hiveName = 'HKEY_CLASSES_ROOT' }'CurrentUser' { $hiveShort = 'HKCU';$hiveName = 'HKEY_CURRENT_USER' }'动态数据' { $hiveShort = 'HKDD';$hiveName = 'HKEY_DYN_DATA' }'LocalMachine' { $hiveShort = 'HKLM';$hiveName = 'HKEY_LOCAL_MACHINE' }'性能数据' { $hiveShort = 'HKPD';$hiveName = 'HKEY_PERFORMANCE_DATA' }'用户' { $hiveShort = 'HKU' ;$hiveName = 'HKEY_USERS' }}if ($MaximumResults -le 0) { $MaximumResults = [int32]::MaxValue }$script:resultCount = 0[bool]$useRegEx = ($PSCmdlet.ParameterSetName -eq 'ByRegex')# ----------------------------------------------------------------------# 嵌套的辅助函数来(递归地)搜索注册表# ----------------------------------------------------------------------function _RegSearch([Microsoft.Win32.RegistryKey]$objRootKey, [string]$regPath, [string]$computer) {尝试 {if ([string]::IsNullOrWhiteSpace($regPath)) {$objSubKey = $objRootKey}别的 {$regPath = $regPath.TrimStart("\")$objSubKey = $objRootKey.OpenSubKey($regPath, $false) # $false -->只读}}抓住 {写警告(打开错误 $($objRootKey.Name)\$regPath" + "`r`n " + $_.Exception.Message)返回}$subKeys = $objSubKey.GetSubKeyNames()# 搜索键名如果 ($SearchKeyName) {foreach ($subKeys 中的 $keyName) {如果 ($script:resultCount -lt $MaximumResults) {if ($useRegEx) { $isMatch = ($keyName -match $RegexPattern) }else { $isMatch = ($keyName -like $Pattern) }如果($isMatch){# 对于 PowerShell <3.0 使用:New-Object -TypeName PSObject -Property @{ ... }[PSCustomObject]@{'计算机名' = $计算机'蜂巢' = $objHive.ToString()'蜂巢名称' = $蜂巢名称'HiveShortName' = $hiveShort'路径' = $objSubKey.Name'SubKey' = "$regPath\$keyName".TrimStart("\")'项目类型' = '注册表键''数据类型' = $null'ValueKind' = $null'属性名称' = $null'属性值' = $null'PropertyValueRaw' = $null}$script:resultCount++}}}}# 搜索 PropertyName 和/或 PropertyValue如果($SearchPropertyName - 或 $SearchPropertyValue){foreach ($objSubKey.GetValueNames() 中的 $name) {如果 ($script:resultCount -lt $MaximumResults) {$data = $objSubKey.GetValue($name)$raw = $objSubKey.GetValue($name, '', [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)如果($SearchPropertyName){if ($useRegEx) { $isMatch = ($name -match $RegexPattern) }else { $isMatch = ($name -like $Pattern) }}别的 {if ($useRegEx) { $isMatch = ($data -match $RegexPattern -or $raw -match $RegexPattern) }else { $isMatch = ($data -like $Pattern -or $raw -like $Pattern) }}如果($isMatch){$kind = $objSubKey.GetValueKind($name).ToString()开关($kind){'二进制' { $dataType = 'REG_BINARY';休息 }'DWord' { $dataType = 'REG_DWORD';休息 }'ExpandString' { $dataType = 'REG_EXPAND_SZ';休息 }'MultiString' { $dataType = 'REG_MULTI_SZ';休息 }'QWord' { $dataType = 'REG_QWORD';休息 }'String' { $dataType = 'REG_SZ';休息 }默认{ $dataType = 'REG_NONE';休息 }}# 对于 PowerShell <3.0 使用:New-Object -TypeName PSObject -Property @{ ... }[PSCustomObject]@{'计算机名' = $计算机'蜂巢' = $objHive.ToString()'蜂巢名称' = $蜂巢名称'HiveShortName' = $hiveShort'路径' = $objSubKey.Name'SubKey' = $regPath.TrimStart("\")'ItemType' = 'RegistryProperty''数据类型' = $数据类型'ValueKind' = $kind'PropertyName' = if ([string]::IsNullOrEmpty($name)) { '(Default)' } else { $name }'PropertyValue' = $data'PropertyValueRaw' = $raw}$script:resultCount++}}}}# 递归遍历所有子键如果($递归){foreach ($subKeys 中的 $keyName) {如果 ($script:resultCount -lt $MaximumResults) {$newPath = "$regPath\$keyName"_RegSearch $objRootKey $newPath $computer}}}# 关闭打开的子项if (($objSubKey) -and $objSubKey.Name -ne $objRootKey.Name) { $objSubKey.Close() }}}过程{if ($isPipeLine) { $ComputerName = @($_) }$计算机名 |ForEach-Object {写详细正在计算机 '$ComputerName' 上搜索注册表.."尝试 {$rootKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($objHive, $_)_RegSearch $rootKey $KeyPath $_}抓住 {写错误$($_.Exception.Message)"}最后 {if ($rootKey) { $rootKey.Close() }}}Write-Verbose 所有完成注册表搜索.找到 $($script:resultCount) 结果."}}

它返回具有以下属性的对象集合:

<块引用>

计算机名:MYMACHINE蜂巢:本地机器蜂巢名称:HKEY_LOCAL_MACHINEHiveShortName : HKLM路径:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\{F3F5824C-AD58-4728-AF59-A1EBE3392799}子键:SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\{F3F5824C-AD58-4728-AF59-A1EBE3392799}项目类型:注册表属性数据类型:REG_SZ值种类:字符串属性名称:(默认)PropertyValue:Windows 桌面搜索的便签命名空间扩展PropertyValueRaw:Windows 桌面搜索的便签命名空间扩展

PropertyValuePropertyValueRaw 的区别在于在 PropertyValue 中扩展了环境名称(数据中的 '%SystemRoot%' 被扩展为 'C:\Windows'),而在 PropertyValueRaw 中,数据按原样返回.(环境名称返回为%SystemRoot%")

I'm trying to incorporate this search-registry script that I found on Github into one of my scripts.

https://github.com/KurtDeGreeff/PlayPowershell/blob/master/Search-Registry.ps1

To test it, I used one of the examples that it provided:

Search-Registry -StartKey HKLM -Pattern $ENV:USERNAME -MatchData

After executing, I was still prompted to enter a StartKey and a Pattern into the console. After providing that information once again, the command fails.

cmdlet Search-Registry.ps1 at command pipeline position 1
Supply values for the following parameters:
StartKey: HKLM
Pattern: $ENV:USERNAME -MatchData
You must specify at least one of: -MatchKey -MatchValue -MatchData
At C:\Users\Cole\Desktop\Powershell\Search-Registry.ps1:93 char:5
+     throw "You must specify at least one of: -MatchKey -MatchValue -M ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (You must specif...alue -MatchData:String) [], RuntimeException
    + FullyQualifiedErrorId : You must specify at least one of: -MatchKey -MatchValue -MatchData

Is there something that I'm doing incorrectly?

解决方案

I have tested that same function on GitHub too and also came across errors with it, so I decided to do a complete rewrite myself.

The function below can use either Regular Expression matches or Wildcard comparisons using the -like operator.
To search for nameless default properties, either don't specify the Pattern or RegexPattern parameters at all, or use one of them with an empty string.

The function also has a Recurse switch, so it is up to you if you want to recursively search through all subkeys or not.

Note that although the function performs fast, searching the registry can take a long time to finish..

# If you want to run this on PowerShell < 3.0 use
# New-Object -TypeName PSObject -Property @{ ... } wherever it says [PSCustomObject]@{ ... }
# and change the -version value for 'requires' to 2

#requires -version 3

function Search-Registry {
    <#
        .SYNOPSIS
            Searches the registry on one or more computers for a specified text pattern.
        .DESCRIPTION
            Searches the registry on one or more computers for a specified text pattern. 
            Supports searching for any combination of key names, value names, and/or value data. 
            The search pattern is either a regular expression or a wildcard pattern using the 'like' operator.
            (both are case-insensitive)
        .PARAMETER ComputerName
            (Required) Searches the registry on the specified computer(s). This parameter supports piped input.
        .PARAMETER Pattern
            (Optional) Searches using a wildcard pattern and the -like operator.
            Mutually exclusive with parameter 'RegexPattern'
        .PARAMETER RegexPattern
            (Optional) Searches using a regular expression pattern.
            Mutually exclusive with parameter 'Pattern'
        .PARAMETER Hive
            (Optional) The registry hive rootname.
            Can be any of 'HKEY_CLASSES_ROOT','HKEY_CURRENT_CONFIG','HKEY_CURRENT_USER','HKEY_DYN_DATA','HKEY_LOCAL_MACHINE',
                          'HKEY_PERFORMANCE_DATA','HKEY_USERS','HKCR','HKCC','HKCU','HKDD','HKLM','HKPD','HKU'
            If not specified, the hive must be part of the 'KeyPath' parameter.
        .PARAMETER KeyPath
            (Optional) Starts the search at the specified registry key. The key name contains only the subkey.
            This parameter can be prefixed with the hive name. 
            In that case, parameter 'Hive' is ignored as it is then taken from the given path.
            Examples: 
              HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall
              HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall
              Software\Microsoft\Windows\CurrentVersion\Uninstall
        .PARAMETER MaximumResults
            (Optional) Specifies the maximum number of results per computer searched. 
            A value <= 0 means will return the maximum number of possible matches (2147483647).
        .PARAMETER SearchKeyName
            (Optional) Searches for registry key names. You must specify at least one of -SearchKeyName, -SearchPropertyName, or -SearchPropertyValue.
        .PARAMETER SearchPropertyName
            (Optional) Searches for registry value names. You must specify at least one of -SearchKeyName, -SearchPropertyName, or -SearchPropertyValue.
        .PARAMETER SearchPropertyValue
            (Optional) Searches for registry value data. You must specify at least one of -SearchKeyName, -SearchPropertyName, or -SearchPropertyValue.
        .PARAMETER Recurse
            (Optional) If set, the function will recurse the search through all subkeys found.
        .OUTPUTS
            PSCustomObjects with the following properties:

              ComputerName     The computer name where the search was executed
              Hive             The hive name used in Win32 format ("CurrentUser", "LocalMachine" etc)
              HiveName         The hive name used ("HKEY_CURRENT_USER", "HKEY_LOCAL_MACHINE" etc.)
              HiveShortName    The abbreviated hive name used ("HKCU", "HKLM" etc.)
              Path             The full registry path ("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall")
              SubKey           The subkey without the hive ("Software\Microsoft\Windows\CurrentVersion\Uninstall")
              ItemType         Informational: describes the type 'RegistryKey' or 'RegistryProperty'
              DataType         The .REG formatted datatype ("REG_SZ", "REG_EXPAND_SZ", "REG_DWORD" etc.). $null for ItemType 'RegistryKey'
              ValueKind        The Win32 datatype ("String", "ExpandString", "DWord" etc.). $null for ItemType 'RegistryKey'
              PropertyName     The name of the property. $null for ItemType 'RegistryKey'
              PropertyValue    The value of the registry property. $null for ItemType 'RegistryKey'
              PropertyValueRaw The raw, unexpanded value of the registry property. $null for ItemType 'RegistryKey'

              The difference between 'PropertyValue' and 'PropertyValueRaw' is that in 'PropertyValue' Environment names are expanded
              ('%SystemRoot%' in the data gets expanded to 'C:\Windows'), whereas in 'PropertyValueRaw' the data is returned as-is.
              (Environment names return as '%SystemRoot%')

        .EXAMPLE
            Search-Registry -Hive HKLM -KeyPath SOFTWARE -Pattern $env:USERNAME -SearchPropertyValue -Recurse -Verbose

            Searches HKEY_LOCAL_MACHINE on the local computer for registry values whose data contains the current user's name.
            Searches like this can take a long time and you may see warning messages on registry keys you are not allowed to enter.
        .EXAMPLE
            Search-Registry -KeyPath 'HKEY_CURRENT_USER\Printers\Settings' -Pattern * -SearchPropertyName | Export-Csv -Path 'D:\printers.csv' -NoTypeInformation

            or

            Search-Registry -Hive HKEY_CURRENT_USER -KeyPath 'Printers\Settings' -Pattern * -SearchPropertyName | Export-Csv -Path 'D:\printers.csv' -NoTypeInformation

            Searches HKEY_CURRENT_USER (HKCU) on the local computer for printer names and outputs it as a CSV file.
        .EXAMPLE
            Search-Registry -KeyPath 'HKLM:\SOFTWARE\Classes\Installer' -Pattern LastUsedSource -SearchPropertyName -Recurse

            or

            Search-Registry -Hive HKLM -KeyPath 'SOFTWARE\Classes\Installer' -Pattern LastUsedSource -SearchPropertyName -Recurse

            Outputs the LastUsedSource registry entries on the current computer.
        .EXAMPLE
            Search-Registry -KeyPath 'HKCR\.odt' -RegexPattern '.*' -SearchKeyName -MaximumResults 10 -Verbose

            or 

            Search-Registry -Hive HKCR -KeyPath '.odt' -RegexPattern '.*' -SearchKeyName -MaximumResults 10 -Verbose

            Outputs at most ten matches if the specified key exists. 
            This command returns a result if the current computer has a program registered to open files with the .odt extension. 
            The pattern '.*' means match everything.
        .EXAMPLE
            Get-Content Computers.txt | Search-Registry -KeyPath "HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine" -Pattern '*' -SearchPropertyName | Export-Csv -Path 'D:\powershell.csv' -NoTypeInformation

            Searches for any property name in the registry on each computer listed in the file Computers.txt starting at the specified subkey. 
            Output is sent to the specified CSV file.
        .EXAMPLE
            Search-Registry -KeyPath 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace' -SearchPropertyName -Recurse -Verbose

            Searches for the default (nameless) properties in the specified registry key.
    #>
    [CmdletBinding(DefaultParameterSetName = 'ByWildCard')]
    Param(
        [Parameter(ValueFromPipeline = $true, Mandatory = $false, Position = 0)]
        [string[]]$ComputerName = $env:COMPUTERNAME,

        [Parameter(Mandatory = $false, ParameterSetName = 'ByRegex')]
        [string]$RegexPattern,

        [Parameter(Mandatory = $false, ParameterSetName = 'ByWildCard')]
        [string]$Pattern,

        [Parameter(Mandatory = $false)]
        [ValidateSet('HKEY_CLASSES_ROOT','HKEY_CURRENT_CONFIG','HKEY_CURRENT_USER','HKEY_DYN_DATA','HKEY_LOCAL_MACHINE',
                     'HKEY_PERFORMANCE_DATA','HKEY_USERS','HKCR','HKCC','HKCU','HKDD','HKLM','HKPD','HKU')]
        [string]$Hive,

        [string]$KeyPath,
        [int32] $MaximumResults = [int32]::MaxValue,
        [switch]$SearchKeyName,
        [switch]$SearchPropertyName,
        [switch]$SearchPropertyValue,
        [switch]$Recurse
    )
    Begin {
        # detect if the function is called using the pipeline or not
        # see: https://communary.net/2015/01/12/quick-tip-determine-if-input-comes-from-the-pipeline-or-not/
        # and: https://www.petri.com/unraveling-mystery-myinvocation
        [bool]$isPipeLine = $MyInvocation.ExpectingInput

        # sanitize given parameters
        if ([string]::IsNullOrWhiteSpace($ComputerName) -or $ComputerName -eq '.') { $ComputerName = $env:COMPUTERNAME }

        # parse the give KeyPath
        if ($KeyPath -match '^(HK(?:CR|CU|LM|U|PD|CC|DD)|HKEY_[A-Z_]+)[:\\]?') {
            $Hive = $matches[1]
            # remove HKLM, HKEY_CURRENT_USER etc. from the path
            $KeyPath = $KeyPath.Split("\", 2)[1]
        }
        switch($Hive) {
            { @('HKCC', 'HKEY_CURRENT_CONFIG') -contains $_ }   { $objHive = [Microsoft.Win32.RegistryHive]::CurrentConfig;   break }
            { @('HKCR', 'HKEY_CLASSES_ROOT') -contains $_ }     { $objHive = [Microsoft.Win32.RegistryHive]::ClassesRoot;     break }
            { @('HKCU', 'HKEY_CURRENT_USER') -contains $_ }     { $objHive = [Microsoft.Win32.RegistryHive]::CurrentUser;     break }
            { @('HKDD', 'HKEY_DYN_DATA') -contains $_ }         { $objHive = [Microsoft.Win32.RegistryHive]::DynData;         break }
            { @('HKLM', 'HKEY_LOCAL_MACHINE') -contains $_ }    { $objHive = [Microsoft.Win32.RegistryHive]::LocalMachine;    break }
            { @('HKPD', 'HKEY_PERFORMANCE_DATA') -contains $_ } { $objHive = [Microsoft.Win32.RegistryHive]::PerformanceData; break }
            { @('HKU',  'HKEY_USERS') -contains $_ }            { $objHive = [Microsoft.Win32.RegistryHive]::Users;           break }
        }

        # critical: Hive could not be determined
        if (!$objHive) {
            Throw "Parameter 'Hive' not specified or could not be parsed from the 'KeyPath' parameter."
        }

        # critical: no search criteria given
        if (-not ($SearchKeyName -or $SearchPropertyName -or $SearchPropertyValue)) {
            Throw "You must specify at least one of these parameters: 'SearchKeyName', 'SearchPropertyName' or 'SearchPropertyValue'"
        }

        # no patterns given will only work for SearchPropertyName and SearchPropertyValue
        if ([string]::IsNullOrEmpty($RegexPattern) -and [string]::IsNullOrEmpty($Pattern)) {
            if ($SearchKeyName) {
                Write-Warning "Both parameters 'RegexPattern' and 'Pattern' are emtpy strings. Searching for KeyNames will not yield results."
            }
        }

        # create two variables for output purposes
        switch ($objHive.ToString()) {
            'CurrentConfig'   { $hiveShort = 'HKCC'; $hiveName = 'HKEY_CURRENT_CONFIG' }
            'ClassesRoot'     { $hiveShort = 'HKCR'; $hiveName = 'HKEY_CLASSES_ROOT' }
            'CurrentUser'     { $hiveShort = 'HKCU'; $hiveName = 'HKEY_CURRENT_USER' }
            'DynData'         { $hiveShort = 'HKDD'; $hiveName = 'HKEY_DYN_DATA' }
            'LocalMachine'    { $hiveShort = 'HKLM'; $hiveName = 'HKEY_LOCAL_MACHINE' }
            'PerformanceData' { $hiveShort = 'HKPD'; $hiveName = 'HKEY_PERFORMANCE_DATA' }
            'Users'           { $hiveShort = 'HKU' ; $hiveName = 'HKEY_USERS' }
        }

        if ($MaximumResults -le 0) { $MaximumResults = [int32]::MaxValue }
        $script:resultCount = 0
        [bool]$useRegEx = ($PSCmdlet.ParameterSetName -eq 'ByRegex')

        # -------------------------------------------------------------------------------------
        # Nested helper function to (recursively) search the registry
        # -------------------------------------------------------------------------------------
        function _RegSearch([Microsoft.Win32.RegistryKey]$objRootKey, [string]$regPath, [string]$computer) {
            try {
                if ([string]::IsNullOrWhiteSpace($regPath)) {
                    $objSubKey = $objRootKey
                }
                else {
                    $regPath = $regPath.TrimStart("\")
                    $objSubKey = $objRootKey.OpenSubKey($regPath, $false)    # $false --> ReadOnly
                }
            }
            catch {
              Write-Warning ("Error opening $($objRootKey.Name)\$regPath" + "`r`n         " + $_.Exception.Message)
              return
            }
            $subKeys = $objSubKey.GetSubKeyNames()

            # Search for Keyname
            if ($SearchKeyName) {
                foreach ($keyName in $subKeys) {
                    if ($script:resultCount -lt $MaximumResults) {
                        if ($useRegEx) { $isMatch = ($keyName -match $RegexPattern) } 
                        else { $isMatch = ($keyName -like $Pattern) }
                        if ($isMatch) {
                            # for PowerShell < 3.0 use: New-Object -TypeName PSObject -Property @{ ... }
                            [PSCustomObject]@{
                                'ComputerName'     = $computer
                                'Hive'             = $objHive.ToString()
                                'HiveName'         = $hiveName
                                'HiveShortName'    = $hiveShort
                                'Path'             = $objSubKey.Name
                                'SubKey'           = "$regPath\$keyName".TrimStart("\")
                                'ItemType'         = 'RegistryKey'
                                'DataType'         = $null
                                'ValueKind'        = $null
                                'PropertyName'     = $null
                                'PropertyValue'    = $null
                                'PropertyValueRaw' = $null
                            }
                            $script:resultCount++
                        }
                    }
                }
            }

            # search for PropertyName and/or PropertyValue
            if ($SearchPropertyName -or $SearchPropertyValue) {
                foreach ($name in $objSubKey.GetValueNames()) {
                    if ($script:resultCount -lt $MaximumResults) {
                        $data = $objSubKey.GetValue($name)
                        $raw  = $objSubKey.GetValue($name, '', [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)

                        if ($SearchPropertyName) {
                            if ($useRegEx) { $isMatch = ($name -match $RegexPattern) }
                            else { $isMatch = ($name -like $Pattern) }

                        }
                        else {
                            if ($useRegEx) { $isMatch = ($data -match $RegexPattern -or $raw -match $RegexPattern) } 
                            else { $isMatch = ($data -like $Pattern -or $raw -like $Pattern) }
                        }

                        if ($isMatch) {
                            $kind = $objSubKey.GetValueKind($name).ToString()
                            switch ($kind) {
                                'Binary'       { $dataType = 'REG_BINARY';    break }
                                'DWord'        { $dataType = 'REG_DWORD';     break }
                                'ExpandString' { $dataType = 'REG_EXPAND_SZ'; break }
                                'MultiString'  { $dataType = 'REG_MULTI_SZ';  break }
                                'QWord'        { $dataType = 'REG_QWORD';     break }
                                'String'       { $dataType = 'REG_SZ';        break }
                                default        { $dataType = 'REG_NONE';      break }
                            }
                            # for PowerShell < 3.0 use: New-Object -TypeName PSObject -Property @{ ... }
                            [PSCustomObject]@{
                                'ComputerName'     = $computer
                                'Hive'             = $objHive.ToString()
                                'HiveName'         = $hiveName
                                'HiveShortName'    = $hiveShort
                                'Path'             = $objSubKey.Name
                                'SubKey'           = $regPath.TrimStart("\")
                                'ItemType'         = 'RegistryProperty'
                                'DataType'         = $dataType
                                'ValueKind'        = $kind
                                'PropertyName'     = if ([string]::IsNullOrEmpty($name)) { '(Default)' } else { $name }
                                'PropertyValue'    = $data
                                'PropertyValueRaw' = $raw
                            }
                            $script:resultCount++
                        }
                    }
                }
            }

            # recurse through all subkeys
            if ($Recurse) {
                foreach ($keyName in $subKeys) {
                    if ($script:resultCount -lt $MaximumResults) {
                        $newPath = "$regPath\$keyName"
                        _RegSearch $objRootKey $newPath $computer
                    }
                }
            }

            # close opened subkey
            if (($objSubKey) -and $objSubKey.Name -ne $objRootKey.Name) { $objSubKey.Close() }
        }
    }
    Process{
       if ($isPipeLine) { $ComputerName = @($_) }
       $ComputerName | ForEach-Object {
            Write-Verbose "Searching the registry on computer '$ComputerName'.."
            try {
                $rootKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($objHive, $_)
                _RegSearch $rootKey $KeyPath $_
            }
            catch {
                Write-Error "$($_.Exception.Message)"
            }
            finally {
                if ($rootKey) { $rootKey.Close() }
            }
        }
        Write-Verbose "All Done searching the registry. Found $($script:resultCount) results."
    }
}

It returns a collection of objects with the following properties:

ComputerName     : MYMACHINE
Hive             : LocalMachine
HiveName         : HKEY_LOCAL_MACHINE
HiveShortName    : HKLM
Path             : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\{F3F5824C-AD58-4728-AF59-A1EBE3392799}
SubKey           : SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\{F3F5824C-AD58-4728-AF59-A1EBE3392799}
ItemType         : RegistryProperty
DataType         : REG_SZ
ValueKind        : String
PropertyName     : (Default)
PropertyValue    : Sticky Notes Namespace Extension for Windows Desktop Search
PropertyValueRaw : Sticky Notes Namespace Extension for Windows Desktop Search

The difference between PropertyValue and PropertyValueRaw is that in PropertyValue Environment names are expanded ('%SystemRoot%' in the data gets expanded to 'C:\Windows'), whereas in PropertyValueRaw the data is returned as-is. (Environment names return as '%SystemRoot%')

这篇关于Powershell 中的快速注册表搜索器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆