使用 PowerShell 在注册表项和值中搜索字符串 [英] Use PowerShell to search for string in registry keys and values

查看:34
本文介绍了使用 PowerShell 在注册表项和值中搜索字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 PowerShell 来查找特定配置单元中包含字符串 foo 的所有注册表项和值,可能嵌入在更长的字符串中.找到钥匙并不难:

I'd like to use PowerShell to find all registry keys and values within a particular hive that contain a string foo, possibly embedded within a longer string. Finding the keys is not hard:

Get-ChildItem -path hkcu:\ -recurse -ErrorAction SilentlyContinue | Where-Object {$_.Name -like "*foo*"}

问题是我不知道找到值的最佳方法,因为我不知道提前知道属性的名称.我试过这个:

The problem is that I don't know the best way to find the values, given that I don't know the names of the properties ahead of time. I tried this:

Get-ChildItem -path hkcu:\ -recurse -erroraction silentlycontinue | get-itemproperty | where {$_.'(default)' -like "*foo*"}    

但是我收到了这个错误:

But I got this error:

get-itemproperty : Specified cast is not valid.
At line:1 char:69
+ ... u:\ -recurse -erroraction silentlycontinue | get-itemproperty | where ...
+                                                  ~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-ItemProperty], InvalidCastException
    + FullyQualifiedErrorId : System.InvalidCastException,Microsoft.PowerShell.Commands.GetItemPropertyCommand

即使我将 -ErrorAction SilentlyContinue 添加到 get-itemproperty.

even when I added -ErrorAction SilentlyContinue to the get-itemproperty.

此外,它只能找到 (default) 键的值.

Furthermore, that only finds the values of the (default) keys.

此外,是否可以在单个命令中搜索所有配置单元?

Also, is it possible to search all hives within a single command?

推荐答案

每个键都有一个 GetValueNames()GetValueKind()GetValue() 方法可让您枚举子值.您还可以使用 GetSubKeyNames() 而不是依赖于 Get-ChildItem -Recurse 来枚举键.

Each key has a GetValueNames(), GetValueKind(), and GetValue() method that let you enumerate child values. You can also use the GetSubKeyNames() instead of depending on Get-ChildItem -Recurse to enumerate keys.

回答关于搜索多个蜂巢的问题:如果您从 Get-ChildItem Registry::\ 开始,您可以看到所有蜂巢并从那里开始搜索.您可能希望坚持使用 HKLM 和 HKCU(如果加载了其他用户配置单元,则可能是 HKU).

To answer your question about searching multiple hives: if you start with Get-ChildItem Registry::\, you can see all hives and start your search there. You'll probably want to stick with HKLM and HKCU (maybe HKU if there are other user hives loaded).

这是我在 上创建的示例实现TechNet 画廊:

function Search-Registry { 
<# 
.SYNOPSIS 
Searches registry key names, value names, and value data (limited). 

.DESCRIPTION 
This function can search registry key names, value names, and value data (in a limited fashion). It outputs custom objects that contain the key and the first match type (KeyName, ValueName, or ValueData). 

.EXAMPLE 
Search-Registry -Path HKLM:\SYSTEM\CurrentControlSet\Services\* -SearchRegex "svchost" -ValueData 

.EXAMPLE 
Search-Registry -Path HKLM:\SOFTWARE\Microsoft -Recurse -ValueNameRegex "ValueName1|ValueName2" -ValueDataRegex "ValueData" -KeyNameRegex "KeyNameToFind1|KeyNameToFind2" 

#> 
    [CmdletBinding()] 
    param( 
        [Parameter(Mandatory, Position=0, ValueFromPipelineByPropertyName)] 
        [Alias("PsPath")] 
        # Registry path to search 
        [string[]] $Path, 
        # Specifies whether or not all subkeys should also be searched 
        [switch] $Recurse, 
        [Parameter(ParameterSetName="SingleSearchString", Mandatory)] 
        # A regular expression that will be checked against key names, value names, and value data (depending on the specified switches) 
        [string] $SearchRegex, 
        [Parameter(ParameterSetName="SingleSearchString")] 
        # When the -SearchRegex parameter is used, this switch means that key names will be tested (if none of the three switches are used, keys will be tested) 
        [switch] $KeyName, 
        [Parameter(ParameterSetName="SingleSearchString")] 
        # When the -SearchRegex parameter is used, this switch means that the value names will be tested (if none of the three switches are used, value names will be tested) 
        [switch] $ValueName, 
        [Parameter(ParameterSetName="SingleSearchString")] 
        # When the -SearchRegex parameter is used, this switch means that the value data will be tested (if none of the three switches are used, value data will be tested) 
        [switch] $ValueData, 
        [Parameter(ParameterSetName="MultipleSearchStrings")] 
        # Specifies a regex that will be checked against key names only 
        [string] $KeyNameRegex, 
        [Parameter(ParameterSetName="MultipleSearchStrings")] 
        # Specifies a regex that will be checked against value names only 
        [string] $ValueNameRegex, 
        [Parameter(ParameterSetName="MultipleSearchStrings")] 
        # Specifies a regex that will be checked against value data only 
        [string] $ValueDataRegex 
    ) 

    begin { 
        switch ($PSCmdlet.ParameterSetName) { 
            SingleSearchString { 
                $NoSwitchesSpecified = -not ($PSBoundParameters.ContainsKey("KeyName") -or $PSBoundParameters.ContainsKey("ValueName") -or $PSBoundParameters.ContainsKey("ValueData")) 
                if ($KeyName -or $NoSwitchesSpecified) { $KeyNameRegex = $SearchRegex } 
                if ($ValueName -or $NoSwitchesSpecified) { $ValueNameRegex = $SearchRegex } 
                if ($ValueData -or $NoSwitchesSpecified) { $ValueDataRegex = $SearchRegex } 
            } 
            MultipleSearchStrings { 
                # No extra work needed 
            } 
        } 
    } 

    process { 
        foreach ($CurrentPath in $Path) { 
            Get-ChildItem $CurrentPath -Recurse:$Recurse |  
                ForEach-Object { 
                    $Key = $_ 

                    if ($KeyNameRegex) {  
                        Write-Verbose ("{0}: Checking KeyNamesRegex" -f $Key.Name)  

                        if ($Key.PSChildName -match $KeyNameRegex) {  
                            Write-Verbose "  -> Match found!" 
                            return [PSCustomObject] @{ 
                                Key = $Key 
                                Reason = "KeyName" 
                            } 
                        }  
                    } 

                    if ($ValueNameRegex) {  
                        Write-Verbose ("{0}: Checking ValueNamesRegex" -f $Key.Name) 

                        if ($Key.GetValueNames() -match $ValueNameRegex) {  
                            Write-Verbose "  -> Match found!" 
                            return [PSCustomObject] @{ 
                                Key = $Key 
                                Reason = "ValueName" 
                            } 
                        }  
                    } 

                    if ($ValueDataRegex) {  
                        Write-Verbose ("{0}: Checking ValueDataRegex" -f $Key.Name) 

                        if (($Key.GetValueNames() | % { $Key.GetValue($_) }) -match $ValueDataRegex) {  
                            Write-Verbose "  -> Match!" 
                            return [PSCustomObject] @{ 
                                Key = $Key 
                                Reason = "ValueData" 
                            } 
                        } 
                    } 
                } 
        } 
    } 
} 

我有一段时间没看它了,我肯定可以看到它的某些部分应该进行更改以使其更好,但它应该作为您的起点.

I haven't looked at it in a while, and I can definitely see some parts of it that should be changed to make it better, but it should work as a starting point for you.

这篇关于使用 PowerShell 在注册表项和值中搜索字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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