2017-08-17 4 views
2

Get-ItemおよびGet-ItemPropertyを使用して、個々のレジストリ値が存在し、適切なデータがあるかどうかを確認することがPowershellで過度に複雑でないかどうかをテストします。私は何ができるようにするには、データだけでなく存在のレジストリ値の多数をチェックすることです。たとえば、次のレジストリエントリを与え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) "Test-Path"ステートメントは、キーテストでのみ有効で、値に対する完全なテストではありません。言い換えれば、 'HKLM:\ SOFTWARE \ Breakfast'では有効ですが、' HKLM:\ SOFTWARE \ Breakfast \ 1001'では有効ではありません。私はコードをいくつか編集しましたが、スペースや書式がないのでコメントに投稿することはできません。これは残念です。 – Beems

+0

この例では、 "1001"は値であり、キーではなく、問題です。 $ RegistryPath = Join-Path -Path $ _ .Path -ChildPath $ _。Key; '行を' $ RegistryPath = Join-Path -Path $ _。 'に変更しなければなりませんでした。テストに失敗しました。 – 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

Iは、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 

Iは、エラーハンドリングとよりよい出力の実装を残しておき

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をありがとう。私は元のコメントでそれを言及していない知っているが、これの唯一の欠点は、検証を完了するために私は各クライアントに2つのファイルを展開する必要があるということです。私は現在、以下の@Baconビットによって提案されたソリューションを使用して幸運を祈るが、これは非常に便利になる他の状況があるので、これもブックマークしている。 – Beems

関連する問題