I am trying to use the following code (poorly written, but this is just a proof of concept) to edit the computer registry in the domain. I have a domain account, and I verified that the domain administration group is present in the local administrators group on the machines I am trying to influence. I connected to these other machines to perform other administrative type tasks, so I am sure that I have administrative privileges on these hosts.
All the "get" StdRegProv methods work fine ( http://msdn.microsoft.com/en-us/library/aa393664%28VS.85%29.aspx ), but the "install" or "create" methods, and also check access to all return "5", which is "Error_Access_Denied" according to winerror.h. Thus, the problem arises: why do I get access when I refuse to try to change the registry? If anyone helps me figure this out, you would really appreciate it!
I almost forgot when I run Visual Studio in administrator mode on my local machine and run the code on the local computer, it works flawlessly. If I do not start in administrator mode on the local computer, the code does not work, so I suspect that there may be a problem with UAC?
UPDATE: Using regedit and connecting to a remote computer, I can change the registry key, which makes me think that this is not a UAC problem, but it runs with a local WMI connection when running in elevated mode on my own machine, so maybe this is UAC. In addition, winXP machines return the same error code (5, ERROR_ACCESS_DENIED), which makes me think that this is not UAC ... it sucks.
SOLVED: The ManagementClass object uses an incorrect override; it must be parameterized using ManagementScope, otherwise you just execute functions locally.
ManagementClass mc = new ManagementClass(scope, new ManagementPath("StdRegProv"), null);
Yes, I am an epic failure: / 9K lines of code, and this line held me the longest.
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";
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);
Console.WriteLine("CreateKey Method returned " + outParams["returnValue"]);
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);
Console.WriteLine("SetStringValue returned " + outParams6["returnValue"]);
Console.ReadKey();
}
}