2017-03-22 118 views
1

PowerShellを使用して、文字列fooを含む特定のハイブ内のすべてのレジストリキーと値を検索したい場合があります。キーを見つけることは難しいことではありません。PowerShellを使用してレジストリキーと値の文字列を検索する

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 

私はget-itemproperty-ErrorAction SilentlyContinueを追加した場合でも。

さらに、(default)のキーの値のみが検索されます。

また、1つのコマンドですべてのハイブを検索することは可能ですか?

+2

'-ErrorAction SilentlyContinue'?値は、キーに対して 'Get-ItemProperty'を呼び出すことで列挙できます。 –

+0

@AnsgarWiechers、 '-ErrorAction SilentlyContinue'についての提案に感謝します。以前のコマンドでエラーを抑制できなかったので、私はそれをあきらめていましたが、これでうまくいくので、私はそれに応じて私の質問を編集しました。しかし、このコマンドを実行すると 'get-itemproperty:指定されたキャストは無効です'というエラーが表示されます: 'get-childitem -path hkcu:\ -recurse -erroraction silentlycontinue | | get-itemproperty | where {$ _ -like "* foo"} 'となります。私は何をする必要がありますか? – Alan

+0

scriptblockのどこにあるプロパティにアクセスする必要がありますか。 '{$ _。PSParentPath -like" * foo "}'のようなものです。 – pandemic

答えて

1

各キーには、子値を列挙できるようにGetValueNames(),、およびGetValue()というメソッドがあります。 Get-ChildItem -Recurseに依存する代わりにGetSubKeyNames()を使用してキーを列挙することもできます。

複数のハイブの検索に関する質問に答えてください:Get-ChildItem Registry::\で始まる場合は、すべてのハイブを表示して検索を開始できます。おそらく、HKLMとHKCU(他のユーザーハイブが読み込まれている場合はHKUかもしれません)に固執してください。

ここで私はTechNet galleryに戻ってしばらくを作成したサンプル実装です:

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" 
          } 
         } 
        } 
       } 
     } 
    } 
} 

私はしばらくそれを見ていない、と私は間違いなくに変更する必要があり、それの一部を見ることができますそれをより良くするが、それはあなたの出発点として機能するはずである。

+0

これは便利ですが、正しく使用しているかどうかわかりません。私は様々な試みを試みました: 'search-registry.ps1 -Path HKCU:\ -recurse -SearchRegex" DispFileName "'; 'search-registry.ps1 -Path HKCU:\ -recurse -KeyNameRegex" DispFileName "'; そして意図的に悪い呼び出しでさえ: 'search-registry.ps1 -bad'; しかし、決して出力がありません。私は間違って何をしていますか? – Alan

+1

これはスクリプトではなく関数として記述されます。あなたはファイルとして保存しているように見えるので、ソースにドットを付けることができます。 。\ search-registry.ps1'を実行し、コマンドとして 'Search-Registry'を呼び出すか、ファイルの最初と最後の行を取り除いて、すでに書いたように呼び出すことができます(最初の行は' function Search -Registry {'、最後の行は'} ') –

+0

これは素晴らしいことです!しかし、レジストリ内の2つの項目に移動するとエラーが表示されます。 -verboseフラグをオンにして、 'HKEY_CURRENT_USER \ System \ CurrentControlSet \ Control \ DeviceContainers \ {some_guid} 'のValueDataRegexをチェックしたときに発生したことを確認しました。レジストリエディタのレジストリキーに移動し、[プロパティ]をクリックすると同じエラーが発生するため、偽ではありません。しかし、私はそれを抑制したい。スクリプトの 'if($ ValueDataRegex)'ブロック内のtry/catchブロックを置くことは助けになると思いますが、どこに行かなければならないのか分かりません。 – Alan

関連する問題