Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用PowerShell在注册表项和值中搜索字符串_Powershell - Fatal编程技术网

使用PowerShell在注册表项和值中搜索字符串

使用PowerShell在注册表项和值中搜索字符串,powershell,Powershell,我想使用PowerShell查找特定配置单元中包含字符串foo,可能嵌入较长字符串中的所有注册表项和值。找到钥匙并不难: Get-ChildItem -path hkcu:\ -recurse -ErrorAction SilentlyContinue | Where-Object {$_.Name -like "*foo*"} 问题是我不知道找到值的最佳方法,因为我事先不知道属性的名称。我试过这个: Get-ChildItem -path hkcu:\ -recurse -erroracti

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

Get-ChildItem -path hkcu:\ -recurse -ErrorAction SilentlyContinue | Where-Object {$_.Name -like "*foo*"}
问题是我不知道找到值的最佳方法,因为我事先不知道属性的名称。我试过这个:

Get-ChildItem -path hkcu:\ -recurse -erroraction silentlycontinue | get-itemproperty | where {$_.'(default)' -like "*foo*"}    
但我有一个错误:

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
添加到
获取项目属性中

此外,它只查找
(默认)
键的值


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

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

要回答有关搜索多个配置单元的问题,请执行以下操作:\“Get ChildItem Registry::\”,您可以查看所有配置单元并在那里开始搜索。您可能希望坚持使用HKLM和HKCU(如果加载了其他用户配置单元,可能是HKU)

下面是我不久前在上创建的一个示例实现:

函数搜索注册表{
[CmdletBinding()]
参数(
[参数(必需,位置=0,ValueFromPipelineByPropertyName)]
[别名(“PsPath”)]
#要搜索的注册表路径
[string[]]$Path,
#指定是否也应搜索所有子键
[开关]$Recurse,
[参数(ParameterSetName=“SingleSearchString”,必填)]
#将根据键名、值名和值数据进行检查的正则表达式(取决于指定的开关)
[字符串]$SearchRegex,
[参数(ParameterSetName=“SingleSearchString”)]
#使用-SearchRegex参数时,此开关意味着将测试密钥名称(如果三个开关均未使用,则将测试密钥)
[开关]$KeyName,
[参数(ParameterSetName=“SingleSearchString”)]
#使用-SearchRegex参数时,此开关表示将测试值名称(如果三个开关均未使用,则将测试值名称)
[开关]$ValueName,
[参数(ParameterSetName=“SingleSearchString”)]
#使用-SearchRegex参数时,此开关意味着将测试值数据(如果三个开关均未使用,则将测试值数据)
[开关]$ValueData,
[参数(ParameterSetName=“MultipleSearchString”)]
#指定将仅根据键名称检查的正则表达式
[字符串]$KeyNameRegex,
[参数(ParameterSetName=“MultipleSearchString”)]
#指定仅根据值名称检查的正则表达式
[字符串]$ValueNameRegex,
[参数(ParameterSetName=“MultipleSearchString”)]
#指定仅根据值数据检查的正则表达式
[字符串]$ValueDataRegex
) 
开始{
开关($PSCmdlet.ParameterSetName){
SingleSearchString{
$NoSwitchesSpecified=-非($PSBoundParameters.ContainsKey(“KeyName”)-或$PSBoundParameters.ContainsKey(“ValueName”)-或$PSBoundParameters.ContainsKey(“ValueData”))
如果($KeyName-或$NoSwitchesSpecified){$KeyNameRegex=$SearchRegex}
如果($ValueName-或$NoSwitchesSpecified){$ValueNameRegex=$SearchRegex}
如果($ValueData-或$NoSwitchesSpecified){$ValueDataRegex=$SearchRegex}
} 
多重搜索字符串{
#不需要额外的工作
} 
} 
} 
进程{
foreach($Path中的CurrentPath){
获取子项$CurrentPath-Recurse:$Recurse|
ForEach对象{
$Key=$\u
如果($KeyNameRegex){
详细写入(“{0}:检查KeyNamesRegex”-f$Key.Name)
如果($Key.PSChildName-匹配$KeyNameRegex){
写详细的“->找到匹配项!”
返回[PSCustomObject]@{
Key=$Key
Reason=“KeyName”
} 
}  
} 
如果($ValueNameRegex){
详细写入(“{0}:检查ValueNamesRegex”-f$Key.Name)
如果($Key.GetValueNames()-匹配$ValueNameRegex){
写详细的“->找到匹配项!”
返回[PSCustomObject]@{
Key=$Key
Reason=“ValueName”
} 
}  
} 
如果($ValueDataRegex){
详细写入(“{0}:检查ValueDataRegex”-f$Key.Name)
如果($Key.GetValueNames()|%{$Key.GetValue($|)})-match$ValueDataRegex{
写详细的“->匹配!”
返回[PSCustomObject]@{
Key=$Key
Reason=“ValueData”
} 
} 
} 
} 
} 
} 
} 

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

这是对get-itemproperty的替换,它以一种简单的方式转储注册表。它很容易与where对象一起使用。您还可以通过管道将其连接到集合项
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" 
                            } 
                        } 
                    } 
                } 
        } 
    } 
} 
function get-itemproperty2 {
  # get-childitem skips top level key, use get-item for that
  # set-alias gp2 get-itemproperty2
  param([parameter(ValueFromPipeline)]$key)
  process {
    $key.getvaluenames() | foreach-object {
      $value = $_
      [pscustomobject] @{
        Path = $Key -replace 'HKEY_CURRENT_USER',
          'HKCU:' -replace 'HKEY_LOCAL_MACHINE','HKLM:'
        Name = $Value
        Value = $Key.GetValue($Value)
        Type = $Key.GetValueKind($Value)
      }
    }
  }
}


ls -r hkcu:\key1 | get-itemproperty2 | where name -eq name

Path            Name Value  Type
----            ---- -----  ----
HKCU:\key1\key2 name     1 DWord


ls -r hkcu:\key1 | get-itemproperty2 | where name -eq name | set-itemproperty -value 0
ls -r hkcu:\key1 | get-itemproperty2 | where name -eq name

Path            Name Value  Type
----            ---- -----  ----
HKCU:\key1\key2 name     0 DWord


# pipe 2 commands to one
$(get-item hkcu:\key1; ls -r hkcu:\key1 ) | get-itemproperty2

Path                 Name  Value               Type
----                 ----  -----               ----
HKCU:\key1           multi {hi, there}  MultiString
HKCU:\key1\key2      name  0                  DWord
HKCU:\key1\key2      name2 0                 String
HKCU:\key1\key2\key3 name3 {18, 52, 80}      Binary
get-childitem -recurse HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall | 
  get-itemproperty | where { $_  -match 'Office16.PROPLUS' }