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