2010-04-02 159 views
3

我試圖使用下面的代碼(寫得不好,但它只是一個概念證明)來編輯域上的計算機註冊表。我有一個域帳戶,並且我已驗證域管理員組存在於我試圖影響的計算機上的本地管理員組中。我連接到這些其他機器來執行其他管理類型任務,所以我確信我擁有這些主機的管理權限。WMI:遠程編輯註冊表

根據winerror.h,StdRegProv的所有「get」方法都正常工作(http://msdn.microsoft.com/en-us/library/aa393664%28VS.85%29.aspx),但「set」或「create」方法以及檢查訪問都返回「Error_Access_Denied」的「5」。所以有這樣的問題:當我試圖修改註冊表時,爲什麼我的訪問被拒絕?如果有人能幫我弄清楚這一點,我會非常感謝!

我差點忘了,當我在本地機器上以管理員模式啓動Visual Studio並在本地機器上運行代碼時,它完美地工作。如果我沒有在本地機器上以管理員模式啓動,則代碼失敗,因此我懷疑可能存在UAC問題?

UPDATE:使用註冊表編輯器並連接到遠程計算機,我可以改變這使我相信這不是一個UAC問題的註冊表項,但它在提升模式下運行時,與當地的WMI連接執行我自己的機器,所以也許它是UAC。此外,winXP機器返回相同的錯誤代碼(5,ERROR_ACCESS_DENIED),這導致我相信它不是UAC ......這很糟糕。

已解決:ManagementClass對象使用錯誤覆蓋;它必須使用ManagementScope進行參數化,否則,您只是在本地執行功能。

ManagementClass mc = new ManagementClass(scope, new ManagementPath("StdRegProv"), null); 

是的,我是一個史詩失敗:代碼/ 9K行,該行舉辦了我最長的這一切。

using System; 
using System.Management; 


public class EditRemoteRegistry 
{ 
    public static void Main(string[] args) 
    { 
     ConnectionOptions options = new ConnectionOptions(); 
     options.EnablePrivileges = true; 
     options.Impersonation = ImpersonationLevel.Impersonate; 
     options.Password = "password goes here"; 
     //options.Authority = "my company's domain"; 
     //options.Username = "Admin username"; 

     ManagementScope scope = new ManagementScope("\\\\arbitraryhost\\root\\default", options); 
     scope.Connect(); 

     ManagementClass mc = new ManagementClass("StdRegProv"); 

     ManagementBaseObject inParams = mc.GetMethodParameters("CreateKey"); 
     inParams["hDefKey"] = (UInt32)2147483650; 
     inParams["sSubKeyName"] = "Software\\Test"; 
     ManagementBaseObject outParams = mc.InvokeMethod("CreateKey", inParams, null); 
     //Should return a 0, but returns a 5, "Error_Access_Denied" 
     Console.WriteLine("CreateKey Method returned " + outParams["returnValue"]); 

     //This chunk works fine 
     ManagementBaseObject inParams5 = mc.GetMethodParameters("GetDWORDValue"); 
     inParams5["hDefKey"] = 2147483650; 
     inParams5["sSubKeyName"] = "Software\\Test"; 
     inParams5["sValueName"] = "testDWORDvalue"; 
     ManagementBaseObject outParams5 = mc.InvokeMethod("GetDWORDValue", inParams5, null); 
     Console.WriteLine("GetDWORDValue returned " + (UInt32)outParams5["returnValue"] + " "); 
     Console.WriteLine((UInt32)outParams5["uValue"]); 


     ManagementBaseObject inParams6 = mc.GetMethodParameters("SetStringValue"); 
     inParams6["hDefKey"] = 2147483650; 
     inParams6["sSubKeyName"] = "Software\\Test"; 
     inParams6["sValueName"] = "TestStringValue"; 
     inParams6["sValue"] = "Hello World!"; 
     ManagementBaseObject outParams6 = mc.InvokeMethod("SetStringValue", inParams6, null); 
     //Should return a 0, but returns a 5, "Error_Access_Denied" 
     Console.WriteLine("SetStringValue returned " + outParams6["returnValue"]); 

     Console.ReadKey(); 
    } 
} 

回答

2

也可以關閉遠程UAC過濾。

不建議通過更改控制遠程UAC的註冊表項來禁用遠程UAC,但在工作組中可能需要禁用遠程UAC。註冊表項HKLM \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Policies \ system \ LocalAccountTokenFilterPolicy。當此條目的值爲零(0)時,啓用遠程UAC訪問令牌篩選。值爲1時,遠程UAC被禁用。

http://msdn.microsoft.com/en-us/library/aa826699(VS.85).aspx

+0

好的提示,但不幸的是,UAC需要通過策略在整個域中啓用。另外,註冊表值更改後,計算機是否需要重新啓動? – Quanta 2010-04-02 20:20:43

+0

是的,它需要重新啓動。似乎應該有辦法解決這個問題... – 2010-04-02 20:52:12

+0

您是否嘗試將您的用戶添加到本地管理員組?根據我發佈的鏈接:'如果您的計算機是域的一部分,請使用遠程計算機的本地管理員組中的域帳戶連接到目標計算機。然後,UAC訪問令牌篩選將不會影響本地管理員組中的域帳戶。我不知道在你的情況下這是否可能。 – 2010-04-02 20:54:30

0

看起來有問題運行WMI setter對UAC上的機器。

報價

從我們從現場收到報告,它出現UAC需要遠程WMI查詢工作被禁用。在UAC運行時,管理員帳戶實際上具有兩個安全令牌,一個普通用戶令牌和一個管理員令牌(僅在您通過UAC提示時激活)。不幸的是,通過網絡進入的遠程請求會爲管理員獲取正常的用戶令牌,並且由於無法遠程處理UAC提示,所以令牌不能提升爲真實管理員安全令牌。

來源: http://www.poweradmin.com/help/enableWMI.aspx

嘗試編輯遠程計算機的註冊表項:

HKLM \ SOFTWARE \微軟\的Windows \ CurrentVersion \政策\系統\ LocalAccountTokenFilterPolicy。

0 - 建立篩選的令牌(啓用遠程UAC) 1 - 構建提升的令牌(遠程UAC禁用)

+0

這就是問題所在,我不能遠程因爲UAC是對編輯的關鍵。我將在數千臺機器上運行此代碼,並且他們都需要運行UAC,不幸的是:/ – Quanta 2010-04-02 20:21:33