C# 作为远程进程读取/写入网络位置时拒绝访问

C# 作为远程进程读取/写入网络位置时拒绝访问,c#,wmi,C#,Wmi,我目前正在尝试使用C#中的WMI在远程计算机上启动进程。该进程读取和写入存储在单独服务器上的文件 当我手动登录到远程机器时,我可以运行该进程,并且一切正常 但是,当我尝试使用WMI从本地计算机远程启动进程时,出现以下错误: System.UnauthorizedAccessException: Access to the path '\\server\path\input.txt' is denied. 我尝试了多种连接选项,但我不确定如何重新创建手动登录时似乎拥有的权限。。。我需要做什么 本

我目前正在尝试使用C#中的WMI在远程计算机上启动进程。该进程读取和写入存储在单独服务器上的文件

当我手动登录到远程机器时,我可以运行该进程,并且一切正常

但是,当我尝试使用WMI从本地计算机远程启动进程时,出现以下错误:

System.UnauthorizedAccessException: Access to the path '\\server\path\input.txt' is denied.
我尝试了多种连接选项,但我不确定如何重新创建手动登录时似乎拥有的权限。。。我需要做什么

本地机器代码

static void LaunchRemoteProcess(string remoteMachine, string command)
{
    ConnectionOptions connectionOptions = new ConnectionOptions
    {
        Impersonation = ImpersonationLevel.Impersonate,
        EnablePrivileges = true
    };

    var managementScope = new ManagementScope(string.Format(@"\\{0}\root\cimv2", remoteMachine), connectionOptions);
    managementScope.Connect();
    var managementPath = new ManagementPath("Win32_Process");
    var objectGetOptions = new ObjectGetOptions();
    var managementClass = new ManagementClass(managementScope, managementPath, objectGetOptions);

    // Launch the command asynchronously
    var inParams = managementClass.GetMethodParameters("Create");
    inParams["CommandLine"] = command;
    var outParams = managementClass.InvokeMethod("Create", inParams, null);
}
string networkPath = @"\\server\path";
string inputFile = "input.txt";
string inputText = File.ReadAllText(Path.Combine(networkPath, inputFile));

string outputFile = "output.txt";
File.WriteAllText(Path.Combine(networkPath, outputFile), inputText);
远程机器代码

static void LaunchRemoteProcess(string remoteMachine, string command)
{
    ConnectionOptions connectionOptions = new ConnectionOptions
    {
        Impersonation = ImpersonationLevel.Impersonate,
        EnablePrivileges = true
    };

    var managementScope = new ManagementScope(string.Format(@"\\{0}\root\cimv2", remoteMachine), connectionOptions);
    managementScope.Connect();
    var managementPath = new ManagementPath("Win32_Process");
    var objectGetOptions = new ObjectGetOptions();
    var managementClass = new ManagementClass(managementScope, managementPath, objectGetOptions);

    // Launch the command asynchronously
    var inParams = managementClass.GetMethodParameters("Create");
    inParams["CommandLine"] = command;
    var outParams = managementClass.InvokeMethod("Create", inParams, null);
}
string networkPath = @"\\server\path";
string inputFile = "input.txt";
string inputText = File.ReadAllText(Path.Combine(networkPath, inputFile));

string outputFile = "output.txt";
File.WriteAllText(Path.Combine(networkPath, outputFile), inputText);
编辑1

如果我手动登录到远程计算机,我已经尝试使用进程所针对的用户的凭据,但进程仍然失败,并出现相同的错误:

    ConnectionOptions connectionOptions = new ConnectionOptions
    {
        Username = "username",
        Password = "password",
        Authority = "ntlmdomain:COMPANYNAME.CO.UK,
        EnablePrivileges = true
    };

我是否缺少有关
权限
身份验证
、或
模拟
属性的信息?

原因是,您在PC上使用的用户id似乎无法访问另一台计算机的位置(虽然它是服务器,但它是另一台计算机)

您可以访问您的用户id,也可以使用模拟来使用已经有权访问该位置的用户id

请在此处查找更多详细信息:


编辑:添加用户名和密码。这可能会有所帮助。

模拟与委派

WMI代码使用模拟,因此服务器端在客户端调用代码的用户的安全上下文中运行。但这仅在服务器本身上有效,不适用于访问远程CIFS共享(如您的情况)

你必须使用授权

首先,改变

Impersonation = ImpersonationLevel.Impersonate,

如果您遇到异常,那么委托在您的环境中还不起作用

检查:

  • 呼叫用户帐户:不得在用户属性(Active Directory用户和计算机)中选中“帐户敏感且无法委派”

  • 必须选中服务器计算机帐户:“信任此计算机以委派给任何服务…”

  • 服务器上的本地安全策略:“允许信任计算机和用户帐户进行委派”必须包括调用用户

有关此主题的更多信息


补充:(见以下评论):

如果您的环境中没有
Delegate
选项(例如,集团策略不允许这样做,并且您无权更改这些策略),您可以选择其他方法

你可能听说过psexec

或者,我几年前所做的,在企业环境中在几台服务器上运行多年,非常成功:

我创建了一个计划任务,它启动一个程序并为此任务设置技术用户+密码。任务配置为“2200年运行一次:-)”

然后我在队列中编写命令(我使用了一个简单的命令文件),并从远程机器启动任务


这样做,不需要委派,因为计划任务本身以技术用户帐户登录(“以批处理方式登录”priv是必需的)

我已经试过了(见上面我的编辑),但是没有成功。我觉得我缺少了一些关于连接选项的信息……这是理解权限的有用链接,谢谢:)不幸的是,
ImpersonationLevel.Delegate
是“仅在Windows 2000下受支持的”。(请参见此处:)Upps,这句话似乎是从一个非常旧的文档中1:1取出来的,我认为这句话应该理解为“仅在Windows 2000及以上版本下,不使用NT 4”。在我编写答案之前,我已成功地使用服务器2008R2(AD域控制器)和Windows 7测试了您的代码。至少在这种环境下,委派工作正常,我甚至还测试了安全选项(如果不信任委派,则它不工作…).尽管如此,可能还有更好的选择,请看我编辑的anwer。啊,奇怪的是,他们没有更新更新更新的.NET版本的文档。是的,我已经开始使用PsExec,但很高兴终于知道WMI可以用于此。