Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Requested registry access is not allowed" When Attempting to Run PowerShell Script on Remote Machine Using Impersonation

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.

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\to\file.exe /p} -computername <computerName>");
results = ps.Invoke();

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\to\file.exe /p} -computername <computerName>");
    results = ps.Invoke();
}

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

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()

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.

like image 917
dotnetesse Avatar asked Mar 25 '14 14:03

dotnetesse


People also ask

How do I run a PowerShell script as administrator?

Use PowerShell in Administrative Mode If you need to run a PowerShell script as an administrator, you will need to open PowerShell in administrative mode. To do so, find PowerShell on the Start menu, right click on the PowerShell icon, and then select More | Run as Administrator from the shortcut menu.

How do I elevate a PowerShell script?

The easiest way to start elevated Powershell windows is by searching for the Powershell application. Press the Windows button to open the start menu and type Powershell. Select Run as administrator to launch run a Powershell window with full privileges. Press Yes in the UAC prompt, and you are good to go!

What does “requested registry access is not allowed” mean?

This problem is non critical and can be ignored, Despite the error "Requested registry access is not allowed" being displayed, A user can click (ok) and proceed to login normally. This error is reported when a non administrator user first attempts to logon to vSphere or VI client.

How to run PowerShell scripts remotely?

Only the simple remote control tasks are typically performed on computers in the interactive mode. To run a complex command or run the PowerShell script remotely, use should the Invoke-Command cmdlet. The following command will create a remote connection with the computer Server1 and run the block of commands specified in the ScriptBlock parameter.

What is PowerShell remoting and how to use it?

With PowerShell Remoting, you can run commands on one or several remote computers. You can use the interactive session mode with remote computers, a temporary, or permanent connection. Earlier we’ve covered how to run PowerShell script from Task Scheduler.

Is it possible to request registry access from the vCenter Server?

System.Security.SecurityException: Requested registry access is not allowed. 1. Log in Windows as "administrator" on the vCenter server 2. Open regedit


1 Answers

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\to\file.exe /p} -computername <computerName>");
    results = ps.Invoke();
}
runspace.Close()

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

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

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.

like image 107
Donal Lafferty Avatar answered Sep 28 '22 11:09

Donal Lafferty