从WMI运行exe时的网络身份验证

时间:2010-03-09 16:46:16

标签: c# .net wmi windows-authentication unc

我有一个需要使用WMI运行并访问网络共享的C#exe。但是,当我访问共享时,我得到一个UnauthorizedAccessException。如果我直接运行exe,则可以访问共享。我在两种情况下都使用相同的用户帐户。

我的应用程序有两个部分,一个在本地PC上运行的GUI客户端和一个在远程PC上运行的后端进程。当客户端需要连接到后端时,它首先使用WMI启动远程进程(下面转载的代码)。远程进程执行许多操作,包括使用Directory.GetDirectories()访问网络共享并向客户端报告。

当客户端使用WMI自动启动远程进程时,它无法访问网络共享。但是,如果我使用远程桌面连接到远程计算机并手动启动后端进程,则可以成功访问网络共享。

WMI调用中指定的用户和远程桌面会话登录的用户是相同的,因此权限应该相同,不应该是吗?

我在Directory.Exists()的MSDN条目中看到它声明“Exists方法不执行网络身份验证。如果您在未经过预先身份验证的情况下查询现有网络共享,则Exists方法将返回false。”我认为这是相关的?如何确保在WMI会话中正确验证用户身份?

ConnectionOptions opts = new ConnectionOptions();

opts.Username = username;
opts.Password = password;

ManagementPath path = new ManagementPath(string.Format("\\\\{0}\\root\\cimv2:Win32_Process", remoteHost));

ManagementScope scope = new ManagementScope(path, opts);

scope.Connect();

ObjectGetOptions getOpts = new ObjectGetOptions();
using (ManagementClass mngClass = new ManagementClass(scope, path, getOpts))
{
    ManagementBaseObject inParams = mngClass.GetMethodParameters("Create");
    inParams["CommandLine"] = commandLine;
    ManagementBaseObject outParams = mngClass.InvokeMethod("Create", inParams, null);
}

4 个答案:

答案 0 :(得分:2)

按照上面Isalamon建议的链接(谢谢)我遵循了Jestro的建议并使用psexec.exe(可以从http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx下载而不是WMI)重写。以这种方式做这件事感觉有点像傻瓜,但似乎有效。

遇到类似问题的任何人的新代码:

Process proc = new Process();
proc.StartInfo.FileName = "PsExec.exe";
proc.StartInfo.Arguments = string.Format("\\\\{0} -d -u {1}\\{2} -p {3} {4}",
                                         remoteHost,
                                         domain,
                                         username,
                                         password,
                                         commandLine);
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();

答案 1 :(得分:1)

WMI在执行远程进程时只使用模拟,而不会为您提供网络访问权限。如果您可以在托管代码之外进行操作,则可以在远程进程中映射UNC路径,并使用您想要的任何凭据启动WMI。然后,您拥有所需的网络访问权限。我使用netapi32.dll中的NetUseAdd和NetUseDel来映射UNC路径。有关使用API​​的详细信息,请参阅http://pinvoke.net/

答案 2 :(得分:1)

我知道你已经使用PSEXEC对它进行了排序,这是一个很棒的程序,但是如果你确实想要回到WMI,你是否尝试在ConnectionOptions中启用以下内容:

  • 标志EnablePrivileges
  • 将Impersonation设置为ImpersonationLevel.Impersonate

以下是:

  
    

获取或设置一个值,该值指示是否需要用户权限     已启用连接操作。这个属性应该只是     当执行的操作需要某个用户权限时使用     启用(例如,机器重启)。

  
     

http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.enableprivileges.aspx


  
    

获取或设置要用于此连接中的操作的COM模拟级别。

  
     

http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.impersonation.aspx

我认为他们应该告诉您的WMI实际上允许程序拥有正确的凭据,从而访问您的网络共享

答案 3 :(得分:0)

您可以将批处理文件的所有命令写入远程计算机,其中包括net use(不需要使用驱动器号)进行身份验证。这样做很好。我还在努力寻找替代方案。