2017-03-22 47 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 

,甚至當我加入-ErrorAction SilentlyContinueget-itemproperty

此外,只找到(default)鍵的值。

此外,是否有可能在單個命令中搜索所有配置單元?

+2

'-ErrorAction SilentlyContinue'?可以通過調用鍵上的Get-ItemProperty來枚舉值。 –

+0

@AnsgarWiechers,感謝關於'-ErrorAction SilentlyContinue'的建議。我已經放棄了,因爲它沒有用我嘗試過的早期命令來壓制錯誤,但它確實與這個一起工作,所以我相應地編輯了我的問題。但是,當我執行此命令時,出現錯誤「get-itemproperty:指定的轉換無效」:'get-childitem -path hkcu:\ -recurse -erroraction silentlycontinue | get-itemproperty |其中{$ _ -like「* foo」}'。我需要做什麼改變? – Alan

+0

您需要訪問scriptblock中的屬性。 '其中{$ _。PSParentPath-like「* foo」}'例如 – pandemic

回答

1

每個鍵都有一個GetValueNames(),GetValueKind()GetValue()方法,可以枚舉子值。您也可以使用GetSubKeyNames()而不是依靠Get-ChildItem -Recurse來枚舉密鑰。

要回答您關於搜索多個蜂房的問題:如果您以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 - 註冊{',最後一行是'}') –

+0

這很好用!但是,當我遍歷註冊表中的兩個項目時,仍然會看到錯誤。我打開了-verbose標誌,看到它們在檢查HKEY_CURRENT_USER \ System \ CurrentControlSet \ Control \ DeviceContainers \ {some_guid}'的ValueDataRegex時發生了。去註冊表編輯器中的這些註冊表項並單擊「屬性」給出了同樣的錯誤,所以它不是假的。但是,我想壓制它。我認爲在腳本中的if($ ValueDataRegex)塊中放置一個try/catch塊會有所幫助,但我不確定它應該放在哪裏。 – Alan