2017-08-17 54 views
2

在Powershell中使用Get-ItemGet-ItemProperty測試單個註冊表值是否存在並檢查它們是否存在適當的數據不會過於複雜。我希望能夠做的是檢查存在以及數據的大量註冊表值。在Powershell中測試大量的註冊表值

例如,給出以下注冊表項:

HKLM:\SOFTWARE\Breakfast\1001 = 3 [DWORD] 
HKLM:\SOFTWARE\Breakfast\1003 = 3 [DWORD] 
HKLM:\SOFTWARE\Breakfast\1004 = 3 [DWORD] 
HKLM:\SOFTWARE\Breakfast\1005 = 1 [DWORD] 

一個大的,醜陋的腳本,每個值進行測試和數據分別是並不複雜,但我很樂意看它是否是可能會將一個友好名稱,註冊表路徑/值以及所需的數據放入一個數組中,以便我們可以有一個執行我們測試的函數。

該陣列可以是這個樣子:

$registry_list = @() 
$registry_list.gettype() 
$registry_list += ,@('Poptarts','HKLM:\SOFTWARE\Breakfast\','1001','3') 
$registry_list += ,@('Toast','HKLM:\SOFTWARE\Breakfast\','1002','3') 
$registry_list += ,@('Muffins','HKLM:\SOFTWARE\Breakfast\','1003','3') 
$registry_list += ,@('Bagels','HKLM:\SOFTWARE\Breakfast\','1004','3') 
$registry_list += ,@('Biscuits','HKLM:\SOFTWARE\Breakfast\','1005','3') 

由於我是新來的陣列,我不知道如何將這些反饋到可以輸出不同的是,僅顯示錯誤

Toast 
    Value Missing (HKLM:\SOFTWARE\Breakfast\1002) 
Biscuits 
    Value Set Incorrectly (HKLM:\SOFTWARE\Breakfast\1005) Desired: 3. Actual: 1 
功能

如果任何人都可以權衡以幫助弄清楚函數或類似函數如何迭代每個註冊表值,那將是值得讚賞的。這裏的例子很簡短,但我真的希望能夠通過這個測試運行數百個註冊表值。

+0

每個數組中第一個字符串的意義是什麼? (Poptarts,Toast等) –

+3

@ MathiasR.Jessen當他們指定數組的內容時,它們會引用友好名稱:*友好名稱,註冊表路徑/值和所需數據* – TheMadTechnician

回答

3

我從來沒有成爲PowerShell中多維數組的巨大粉絲。他們最終感覺非常脆弱或不穩定。 PowerShell中的數組也很吸引人,因爲當您使用+=運算符時,系統必須用新元素構建一個新數組,然後丟棄舊數組。這在計算上很昂貴。

對於這種情況,我會創建一個ArrayList,並將數組添加到該列表中。我也可能會使用哈希表的每一個項目,所以我可以使用一個名稱,而不是一個索引號來指代項目:

$registry_list = New-Object System.Collections.ArrayList; 

# Use the Add() function to add records. The [void] type is here because the function 
# normally returns the number of records in the ArrayList, and we don't want that to go to output. 
[void]$registry_list.Add(@{Value='Poptarts';Path='HKLM:\SOFTWARE\Breakfast';Key='1001';Data='3'}); 
[void]$registry_list.Add(@{Value='Toast';Path='HKLM:\SOFTWARE\Breakfast';Key='1002';Data='3'}); 

$registry_list | ForEach-Object { 
    $RegistryPath = Join-Path -Path $_.Path -ChildPath $_.Key; 
    if (Test-Path -Path $RegistryPath) { 
     Write-Host "Path '$RegistryPath' exists." 
     $RegistryData = (Get-ItemProperty -Path $RegistryPath).($_.Value) 
     if ($RegistryData -eq $_.Data) { 
      Write-Host "Check OK. Value $($_.Value) data is set to '$RegistryData'. Desired data is '$($_.Data)'." 
     } 
     else { 
      Write-Host "Check Failed. Value $($_.Value) data is set to '$RegistryData'. Desired data is '$($_.Data)'." 
     } 
    } 
    else { 
     Write-Host "Path '$RegistryPath' does not exist." 
    } 
} 

請注意,我沒有經過嚴格測試的代碼。值得注意的是,我對所有情況下的正確if ($RegistryData -eq $_.Data)表示懷疑。

+0

這是強大的關閉,謝謝。我發現的唯一問題是: 1)「測試路徑」語句僅對密鑰測試有效,而不是對該值的完整測試。換句話說,它對'HKLM:\ SOFTWARE \ Breakfast'有效,但對'HKLM:\ SOFTWARE \ Breakfast \ 1001'不適用。我已經對代碼進行了一些編輯,但由於我沒有空間或格式,我無法將它們重新發布到評論中,這是一種恥辱。 – Beems

+0

在這個例子中,「1001」是一個值而不是一個鍵,這是問題所在。我不得不改變'$ RegistryPath = Join-Path -Path $ _。Path -ChildPath $ _ .Key;'line to'$ RegistryPath = Join-Path -Path $ _。Path -ChildPath'\';'否則每個測試失敗。 – Beems

+0

@Beems是的,你的數據解釋不好,所以我不得不猜測它描述的是什麼。很高興你能弄明白。 –

0

我強烈建議使用大型數組來使用對象數組。創建對象可以使用屬性很容易地引用數組的不同部分。

然後,您也可以使用具有適當值的模板服務器,然後構建對象/對象數組,然後用它來驗證其他系統。

以下是構建對象的基本示例。創建一個爲你構建這些對象的簡單函數效率更高,這樣你就不會有太多的代碼重複,但這是實現它的基本方法。如果你想要一個更高級的創建對象的方法,讓我知道,我會發佈一個例子。

$registrySet = @() 

$registryObj = New-Object -TypeName psobject 
$registryObj | Add-Member -MemberType NoteProperty -Name Name -Value 'Toast' 
$registryObj | Add-Member -MemberType NoteProperty -Name Key -Value 'HKLM:\SOFTWARE\Breakfast\' 

$subKeySet = @() 
$subKeyObj = New-Object -TypeName psobject 
$subKeyObj | Add-Member -MemberType NoteProperty -Name Name -Value '1001' 
$subKeyObj | Add-Member -MemberType NoteProperty -Name Type -Value 'DWORD' 
$subKeyObj | Add-Member -MemberType NoteProperty -Name Value -Value '3' 
$subKeySet += $subKeyObj 

$subKeyObj = New-Object -TypeName psobject 
$subKeyObj | Add-Member -MemberType NoteProperty -Name Name -Value '1002' 
$subKeyObj | Add-Member -MemberType NoteProperty -Name Type -Value 'DWORD' 
$subKeyObj | Add-Member -MemberType NoteProperty -Name Value -Value '3' 
$subKeySet += $subKeyObj 

$subKeyObj = New-Object -TypeName psobject 
$subKeyObj | Add-Member -MemberType NoteProperty -Name Name -Value '1003' 
$subKeyObj | Add-Member -MemberType NoteProperty -Name Type -Value 'DWORD' 
$subKeyObj | Add-Member -MemberType NoteProperty -Name Value -Value '1' 
$subKeySet += $subKeyObj 

$registryObj | Add-Member -MemberType NoteProperty -Name SubKeySet -Value 
$subKeySet 

$registrySet += $registryObj 

$registrySet | Where {$_.Name -ieq 'toast'} | select SubKeySet 
1

我會存儲在一個CSV文件中的數據:

friendlyName,key,value,data 
Poptarts,HKLM:\SOFTWARE\Breakfast\,1001,3 
Toast,HKLM:\SOFTWARE\Breakfast\,1002,3 
Muffins,HKLM:\SOFTWARE\Breakfast\,1003,3 
Bagels,HKLM:\SOFTWARE\Breakfast\,1004,3 
Biscuits,HKLM:\SOFTWARE\Breakfast\,1005,3 

然後遍歷各行的文件

foreach($row in Import-Csv .\breakfast.csv) 
{ 
    # retrieve key 
    $key = Get-Item $row.key 

    # retrieve value 
    $value = $key |Get-ItemProperty -Name $row.value 

    # compare data 
    $valid = $value."$($row.value)" -eq $row.data 

    # output result 
    $outParams = @{ 
     Object = if($valid){"$($row.friendlyName) is correct"} else {"$($row.friendlyName) is incorrect"} 
     ForegroundColor = @('Red','Green')[+$valid] 
    } 
    Write-Host @outParams 
} 

我會留下執行錯誤處理和更好的輸出OP的練習:-)

+0

感謝您深思熟慮的想法Mathias。我知道我沒有在原始評論中提到它,但唯一的缺點是我必須將兩個文件部署到每個客戶端才能完成驗證。我目前使用@Bacon Bits提出的解決方案獲得了很好的運氣,但我已經爲此添加了書籤,因爲還有其他一些情況,這些將會非常方便。 – Beems

相關問題