2014-09-02 82 views
0

我想比較兩臺Servers註冊表項,以確保它們都匹配。使用Powershell比較兩臺服務器上的註冊表項

一些簡單的像,這是最初的計劃:

$remote1 = (invoke-command -computername hostname ` 
{Get-ItemProperty  "HKLM:SOFTWARE\VENDOR\APP\SUBFOLDER"}) 
$local1 = (invoke-command ` 
{Get-ItemProperty "HKLM:SOFTWARE\VENDOR\APP\SUBFOLDER"}) 

$compare1 = Compare-Object $local1 $remote1 

,對於一個單一的指定鍵的偉大工程,但我有一個子文件多個密鑰。我無法提供我想檢查(和循環)的列表,因爲我想確保沒有添加任何新內容。所以我畫這條路線讓所有指定的分支下的鍵在註冊表(讓我的列表):

$local1 = Get-ChildItem HKLM:SOFTWARE\MICROSOFT\DirectShow -Recurse ` 
-ErrorAction SilentlyContinue 

所以我現在有一個對象,它會告訴我的所有註冊表子服務器然後我可以循環繞行$ local1.PSPath給我所有的路徑,但我注意到了對象這一點是很有趣的:

$local1 | select -first 1 -prop * 

這將返回:

Property  : {dbl3, dbl4, dbl5, dbl6...} 
PSPath  : A path 
PSParentPath : A Parent Path 
PSChildName : 0 
PSDrive  : HKLM 
PSProvider : Microsoft.PowerShell.Core\Registry 
PSIsContainer : True 
SubKeyCount : 0 
View   : Default 
Handle  : Microsoft.Win32.SafeHandles.SafeRegistryHandle 
ValueCount : 8 
Name   : A Name 

所以Objec t成員「屬性」包含看起來像所有鍵的數組或者它是一個子對象?

如果它是一個子對象,它是否包含我期待比較的鍵值?

我可以搶奪$ local.Name成員並循環比較使用上面的代碼並存儲任何差異,但我只是想知道,如果使用我已經擁有的數據(如果它包含信息的話)會更有效我需要?

我希望有人可以證實,如果我這樣做:

$local1 = Get-ChildItem HKLM:SOFTWARE\MICROSOFT\DirectShow -Recurse ` 
-ErrorAction SilentlyContinue 

$remote1 (invoke-command -computername remoteserver1 ` 
{Get-ChildItem HKLM:SOFTWARE\MICROSOFT\DirectShow -Recurse ` 
-ErrorAction SilentlyContinue}) 

當我做比較我在實際比較的鍵和值匹配或只是鍵存在嗎? :

Compare-Object $local1 $remote1 

爲了削減長話短說,我想我有所有我需要比較的註冊表項值匹配(通過運行此)的數據:

$local1 

返回(摘錄):

Hive: HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\DirectShow 


Name       Property                                      
----       --------                                      
Debug                                               
DoNotUse                                              
DoNotUseDrivers32                                            
Preferred      {00001602-0000-0010-8000-00aa00389b71} : {E1F1A0B8-BEEE-490D-BA7C-066C40B5E2B9}                     
           {e06d8032-db46-11cf-b4d1-00805f6cbbea} : {E1F1A0B8-BEEE-490D-BA7C-066C40B5E2B9}                     
           {00000160-0000-0010-8000-00aa00389b71} : {2eeb4adf-4578-4d10-bca7-bb955f56320a}                     
           {41564D57-0000-0010-8000-00AA00389B71} : {82d353df-90bd-4382-8bc2-3f6192b76e34}                     
           {e06d8026-db46-11cf-b4d1-00805f6cbbea} : {212690FB-83E5-4526-8FD7-74478B7939CD} 

我是否正確,沒有人知道如何訪問$ local1對象中的單個項目?以上例爲例,什麼是Hive?假設我想要「00001602-0000-0010-8000-00aa00389b71」值,我將如何從$ local1對象獲取它。

需要注意的一點是,當我在Powershell 4上進行測試時(我無法在生產服務器上測試)服務器正在運行Powershell 2。我提到這是在v2服務器上運行$ local1,我得到了不同的輸出,因爲這些屬性似乎不是成對的。

Hive: HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\DirectShow 


SKC VC Name       Property 
--- -- ----       -------- 
0 0 Debug       {} 
0 0 DoNotUse      {} 
0 0 DoNotUseDrivers32    {} 
0 10 Preferred      {{00000050-0000-0010-8000-00AA00389B71}, {e436eb80-524f-11ce-9f53-0020af0ba77... 

這種情況下,v4對象將做我想做的事情,但v2不會?

回答

0

好吧,我爲了回答我自己的問題而奮鬥了一番,通過翻滾雜草回來了。我必須假設的PowerShell V2不包含鍵值,因爲我無法找到他們提取的一種方式,以便以確保我執行鍵和鍵值的比較,我這個去:

foreach ($KeyPath in $RegPath) 
{ 
    $_Path = (invoke-command {Get-ChildItem $KeyPath -Recurse -ErrorAction SilentlyContinue}) 

    ForEach ($key in $_Path) 
    { 

     $local = @() 
     $remote = @() 
     ForEach ($Property in $key.Property) 
     {   
      if ($Key.Name -like "*HKEY_LOCAL_MACHINE*") 
      { 
       $KeyPath = [regex]::Replace($key.Name,[regex]"HKEY_LOCAL_MACHINE\\","HKLM:") 
      } elseif ($Key.Name -like "*HKEY_CURRENT_USER*") { 
       $KeyPath = [regex]::Replace($key.Name,[regex]"HKEY_CURRENT_USER\\","HKCU:") 
      } else { 
       Write-Host "I was unable to set the Registry Hive path, exiting........" 
       exit 1 
      } 

      $lentry = (invoke-command {Get-ItemProperty -Path $KeyPath -Name $Property}) 
      $lfound = New-Object -TypeName PSObject 
      $lfound | Add-Member -Type NoteProperty -Name Path -Value $KeyPath 
      $lfound | Add-Member -Type NoteProperty -Name Name -Value $Property 
      $lfound | Add-Member -Type NoteProperty -Name Data -Value $lentry.$Property 

      $local += $lfound 

      $rentry = (invoke-command -computername remoteservername -Script {Get-ItemProperty -Path $args[0] -Name $args[1]} -Args $KeyPath, $Property -ErrorVariable errmsg 2>$null) 

      if ($errmsg -like "*does not exist at path*") 
      { 
       $Value = "KEY IS MISSING" 
      } else { 
       $Value = $rentry.$Property 
      } 

      $rfound = New-Object -TypeName PSObject 
      $rfound | Add-Member -Type NoteProperty -Name Path -Value $KeyPath 
      $rfound | Add-Member -Type NoteProperty -Name Name -Value $Property 
      $rfound | Add-Member -Type NoteProperty -Name Data -Value $Value 

      $remote += $rfound 

     } 
     $compare = Compare-Object -ReferenceObject $local -DifferenceObject $remote -Property Path,Name,Data 
     $results += $compare 
    } 
} 

然後,您可以在可以處理的$ results對象中獲得所有結果。我在類似於這個Powershell Hash Table to HTML的HTML表格中使用了該對象。

我認爲在PowerShell第四版中這將會簡單得多,不需要構建$ lfound和$ rfound。

0

在PowerShell中V4你可以導出你想要的任何點的註冊表項,然後使用以下方法來對它們進行比較:

$badReg = Get-content C:\Data\badReg.reg 

$goodReg = Get-ChildItem C:\Data\goodReg.reg 

$results = Compare-Object -ReferenceObject $goodReg -DifferenceObject $badReg 
+0

謝謝 - 是的,你可以在PowerShell中V4但當時我僅限於生產服務器無法升級,我們正在運行Powershell v2。 – Chris 2017-02-02 06:46:29

+0

可以理解。我剛剛發現了這個,因爲現在人們可能想要查看比較對象的更新方法,因此v4更爲流行。 – 2017-02-02 13:21:36

相關問題