“不允许请求的注册表访问"尝试使用模拟在远程计算机上运行 PowerShell 脚本时 [英] "Requested registry access is not allowed" When Attempting to Run PowerShell Script on Remote Machine Using Impersonation

查看:27
本文介绍了“不允许请求的注册表访问"尝试使用模拟在远程计算机上运行 PowerShell 脚本时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我第一次尝试从 C# 应用程序执行 PowerShell 脚本.我正在使用 PowerShell,因为我需要我在远程机器上执行的 .exe 的输出.我能够使用 WMI 在远程计算机上运行 .exe,但无法获得所需的输出.

This is the first time I try to execute PowerShell scripts from a C# application. I'm using PowerShell because I need the output from the .exe I'm executing on the remote machine. I was able to run the .exe on the remote machine using WMI, but I couldn't get the output I needed.

无论如何,我过去一天左右一直在研究这个问题,我在网上和 SO 上查看了类似的问题,但似乎无法找出问题所在.我正在尝试从远程计算机上的 .NET 4.0 应用程序运行一个简单的 PowerShell 命令.当我以管理员身份运行 Visual Studio 2013 时,以下代码可以正常执行:

At any rate, I've been going at this for the past day or so, and I've looked around the web and here at SO for similar issues, but can't seem to figure out the problem. I'm trying to run a simple PowerShell command from my .NET 4.0 application on a remote machine. The following code executes fine when I run Visual Studio 2013 as an administrator:

PowerShell ps = PowerShell.Create();
ps.AddScript(@"Invoke-Command {c:path	ofile.exe /p} -computername <computerName>");
results = ps.Invoke();

我得到了预期的结果.但是,当我以非管理员身份运行 VS 时,代码似乎执行得很好(没有异常),但我没有得到任何结果.环顾四周后,我添加了如下模拟:

I get the expected results. However, when I run VS as a non-administrator, the code seems to execute fine (no exceptions), but I get no results back. After looking around a bit I added impersonation as follows:

using (var impersonator = new Impersonator("username", "domain", "password"))
{
    PowerShell ps = PowerShell.Create();
    ps.AddScript(@"Invoke-Command {c:path	ofile.exe /p} -computername <computerName>");
    results = ps.Invoke();
}

但是,ps.Invoke 方法开始抛出 System.Security.SecurityException -不允许请求的注册表访问."这是堆栈跟踪:

However, the ps.Invoke method starts throwing a System.Security.SecurityException - "Requested registry access is not allowed." Here is the stack trace:

在 Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)在 System.Environment.GetEnvironmentVariable(字符串变量,EnvironmentVariableTarget 目标)在 System.Management.Automation.ModuleIntrinsics.GetExpandedEnvironmentVariable(字符串名称,EnvironmentVariableTarget 目标)在 System.Management.Automation.ModuleIntrinsics.SetModulePath()在 System.Management.Automation.ModuleIntrinsics..ctor(ExecutionContext 上下文)在 System.Management.Automation.ExecutionContext.InitializeCommon(AutomationEngine 引擎,PSHost 主机接口)在 System.Management.Automation.ExecutionContext..ctor(AutomationEngine engine, PSHost hostInterface, RunspaceConfiguration runspaceConfiguration)在 System.Management.Automation.AutomationEngine..ctor(PSHost hostInterface, RunspaceConfiguration runspaceConfiguration, InitialSessionState iss)在 System.Management.Automation.Runspaces.LocalRunspace.DoOpenHelper()在 System.Management.Automation.Runspaces.LocalRunspace.OpenHelper(Boolean syncCall)在 System.Management.Automation.Runspaces.RunspaceBase.CoreOpen(Boolean syncCall)在 System.Management.Automation.Runspaces.RunspaceBase.Open()在 System.Management.Automation.PowerShell.Worker.CreateRunspaceIfNeededAndDoWork(Runspace rsToUse, Boolean isSync)在 System.Management.Automation.PowerShell.CoreInvokeHelper[TInput,TOutput](PSDataCollection1 input, PSDataCollection1 output, PSInvocationSettings settings)在 System.Management.Automation.PowerShell.CoreInvoke[TInput,TOutput](PSDataCollection1 input, PSDataCollection1 output, PSInvocationSettings settings)在 System.Management.Automation.PowerShell.CoreInvoke[TOutput](IEnumerable 输入,PSDataCollection`1 输出,PSInvocationSettings 设置)在 System.Management.Automation.PowerShell.Invoke(IEnumerable 输入,PSInvocationSettings 设置)在 System.Management.Automation.PowerShell.Invoke()

at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable) at System.Environment.GetEnvironmentVariable(String variable, EnvironmentVariableTarget target) at System.Management.Automation.ModuleIntrinsics.GetExpandedEnvironmentVariable(String name, EnvironmentVariableTarget target) at System.Management.Automation.ModuleIntrinsics.SetModulePath() at System.Management.Automation.ModuleIntrinsics..ctor(ExecutionContext context) at System.Management.Automation.ExecutionContext.InitializeCommon(AutomationEngine engine, PSHost hostInterface) at System.Management.Automation.ExecutionContext..ctor(AutomationEngine engine, PSHost hostInterface, RunspaceConfiguration runspaceConfiguration) at System.Management.Automation.AutomationEngine..ctor(PSHost hostInterface, RunspaceConfiguration runspaceConfiguration, InitialSessionState iss) at System.Management.Automation.Runspaces.LocalRunspace.DoOpenHelper() at System.Management.Automation.Runspaces.LocalRunspace.OpenHelper(Boolean syncCall) at System.Management.Automation.Runspaces.RunspaceBase.CoreOpen(Boolean syncCall) at System.Management.Automation.Runspaces.RunspaceBase.Open() at System.Management.Automation.PowerShell.Worker.CreateRunspaceIfNeededAndDoWork(Runspace rsToUse, Boolean isSync) at System.Management.Automation.PowerShell.CoreInvokeHelper[TInput,TOutput](PSDataCollection1 input, PSDataCollection1 output, PSInvocationSettings settings) at System.Management.Automation.PowerShell.CoreInvoke[TInput,TOutput](PSDataCollection1 input, PSDataCollection1 output, PSInvocationSettings settings) at System.Management.Automation.PowerShell.CoreInvoke[TOutput](IEnumerable input, PSDataCollection`1 output, PSInvocationSettings settings) at System.Management.Automation.PowerShell.Invoke(IEnumerable input, PSInvocationSettings settings) at System.Management.Automation.PowerShell.Invoke()

当我运行的管理员帐户可以访问注册表时,我不确定为什么会收到 SecurityException,不仅在我的机器上,而且在整个企业的机器上.而且我什至不确定它在哪个注册表上出现异常,我的机器还是远程机器.

I'm not sure why I'm getting the SecurityException when the administrator account I'm running as has access to the registry, not only on my machine but on machines across the enterprise. And I'm not even sure which registry it's getting the exception on, my machine or the remote machine.

推荐答案

在模拟之前为 PowerShell 对象创建底层 RunSpace:

Create the underlying RunSpace for your PowerShell object before impersonating:

PowerShell ps = PowerShell.Create();
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
powerShell.Runspace = runspace;

using (var impersonator = new Impersonator("username", "domain", "password"))
{
    ps.AddScript(@"Invoke-Command {c:path	ofile.exe /p} -computername <computerName>");
    results = ps.Invoke();
}
runspace.Close()

RunSpace 对象封装了用于脚本执行的 OS 环境.正在访问的密钥可能是 HKCUEnvironment.这就是我在使用 Perfmon 时所看到的.RunSpace 可能使用 HKCUEnvironment 来填充 $PATH 等变量.

The RunSpace object encapsulates the OS environment for script execution. the key being accessed is probably HKCUEnvironment. That is what I saw when using Perfmon. RunSpace probably uses the HKCUEnvironment to populate variables such as $PATH.

因此,在创建 RunSpace 时,您希望它是当前用户可以访问 HKCUEnvironment.

Therefore, when the RunSpace is created, you want it the current user to have access to HKCUEnvironment.

在别处提到拉模拟块的 RunSpace.Open 作为避免注册表访问的黑客问题.但是,仅仅创建 PowerShell 对象并不能保证调用 Runspace.Open().

Pulling RunSpace.Open of the impersonated block is mentioned elsewhere as a hack for avoiding the registry access problem. However, merely creating the PowerShell object does not guarantee that the Runspace.Open() is called.

这篇关于“不允许请求的注册表访问"尝试使用模拟在远程计算机上运行 PowerShell 脚本时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆