Laj*_*pad 5 c# registry powershell impersonation
我正在尝试使用C#运行PowerShell脚本,但是没有任何成功。这是我的功能:
private void ExecutePowerShellCommand(string scriptfile)
{
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke();
scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
Pipeline pipeline = runspace.CreatePipeline();
//Here's how you add a new script with arguments
Command myCommand = new Command(scriptfile);
//CommandParameter testParam = new CommandParameter("key", "value");
//myCommand.Parameters.Add(testParam);
pipeline.Commands.Add(myCommand);
// Execute PowerShell script
pipeline.Invoke();
}
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误:
拒绝访问注册表项'HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ PowerShell \ 1 \ ShellIds \ Microsoft.PowerShell'。
我该如何解决这个问题?我已经看到过模仿的想法,但是似乎没有找到任何好的模仿例子。我想以管理员身份运行此脚本。
我做了以下声明:
[DllImport("advapi32.dll")]
private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr handle);
public delegate void IncognitoDelegate(params object[] args);
Run Code Online (Sandbox Code Playgroud)
我创建了以下用于模拟的功能:
public static void Impersonate(IncognitoDelegate incognitoDelegate, params object[] args)
{
System.IntPtr token = new IntPtr();
WindowsIdentity wi;
if (LogonUser("myusername", "", "mypassword", 8, 0, ref token))
{
wi = new WindowsIdentity(token);
WindowsImpersonationContext wic = wi.Impersonate();
incognitoDelegate(args);
wic.Undo();
}
CloseHandle(token);
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个用作委托的函数:
private static void GIncognito(params object[] args)
{
RunspaceInvoke scriptInvoker = new RunspaceInvoke();
scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
}
Run Code Online (Sandbox Code Playgroud)
而且我修改了我的方法:
private void ExecutePowerShellCommand(string scriptfile)
{
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
Impersonate(new Util.IncognitoDelegate(GIncognito));
//RunspaceInvoke scriptInvoker = new RunspaceInvoke();
//scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
Pipeline pipeline = runspace.CreatePipeline();
//Here's how you add a new script with arguments
Command myCommand = new Command(scriptfile);
//CommandParameter testParam = new CommandParameter("key", "value");
//myCommand.Parameters.Add(testParam);
pipeline.Commands.Add(myCommand);
// Execute PowerShell script
pipeline.Invoke();
}
Run Code Online (Sandbox Code Playgroud)
结果是...
...非常严重的错误,告诉我我无法访问注册表项。
默认Set-ExecutionPolicy
命令尝试设置机器范围的值。您只想在 C# 应用程序范围内更改设置,因此您应该将该-Scope Process
选项添加到命令中。
使用Get-Help Set-ExecutionPolicy -detailed
揭示了这些信息:
注意:要更改默认 (LocalMachine) 范围的执行策略,请使用“以管理员身份运行”选项启动 Windows PowerShell。
...它还描述了该-Scope
选项。
这样做的优点是仅影响从 C# 应用程序运行的脚本的执行策略,并且不会不必要地更改默认 PowerShell 行为的执行策略。(所以它更安全,特别是如果您可以保证应用程序运行的脚本的有效性。)