问题描述
我试图运行用C#PowerShell脚本,但我没有任何成功。这里是我的功能:
I am trying to run a PowerShell script with C#, but I don't have any success. Here is my function:
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();
}
这是我的错误:
访问注册表项HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell'被拒绝。
我怎样才能解决这个问题?我已经看到了假冒的想法,但我似乎没有找到任何很好的例子来冒充。我想运行此脚本作为管理员
How can I solve this issue? I have seen ideas for impersonation, but I didn't seem to find any good examples to impersonate. I would like to run this script as an administrator.
我已经做了如下声明:
[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);
我已经创建了模拟下列功能:
I have created the following function for impersonation:
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);
}
我创建了作为代表一个功能:
I have created a function which is used as a delegate:
private static void GIncognito(params object[] args)
{
RunspaceInvoke scriptInvoker = new RunspaceInvoke();
scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
}
和我已经修改我的方法:
And I have modified my method:
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();
}
结果是...
The result was...
...非常SAM错误,告诉我,我不能访问注册表项。
... the very sam error, telling me I can't access registry keys.
推荐答案
默认设置ExecutionPolicy
命令尝试设置计算机范围值。你只需要你的C#应用程序的范围内更改设置,所以你应该添加 -Scope过程
选项添加到命令。
The default Set-ExecutionPolicy
command attempts to set the machine-wide value. You only want to change the setting within the scope of your C# application, so you should add the -Scope Process
option to the command.
使用获取帮助的Set-ExecutionPolicy -detailed
显示以下信息:
注:要更改执行策略默认(LOCALMACHINE)范围,启动Windows PowerShell使用以管理员身份运行选项
...它也描述了 -Scope
选项。
... and it also describes the -Scope
option.
这具有的优势 仅 的影响的执行策略脚本从C#应用程序中运行,它不会不必要地更改默认的PowerShell行为的执行策略。 (所以这是一个安全很多,特别是如果你可以让你的应用程序运行的脚本的有效性的保证。)
This has the advantage of only impacting the execution policy for scripts run from your C# application, and it doesn't unnecessarily change the execution policy for the default PowerShell behavior. (So it's a lot safer, especially if you can make guarantees about the validity of the scripts your application runs.)
这篇关于如何运行C#PowerShell脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!