从进程中设置执行策略

9
我正在使用C#为Outlook开发一个VSTO插件,该插件调用PowerShell脚本与Office 365的Exchange Online进行交互。
在我的Windows 10机器上,所有操作都能完美运行,这是因为我的机器没有限制PowerShell执行策略。但是,我无法在客户的Windows 7机器上运行代码。
我认为有两个问题。一种可能是他的Windows 7 PowerShell需要更新才能与我的代码配合使用,第二个是我没有正确设置进程执行策略。以下是我尽力将执行策略设置为无限制(绕过更好吗?)。
using (PowerShell PowerShellInstance = PowerShell.Create())
{
    StringBuilder OSScript = new StringBuilder("Set-ExecutionPolicy -Scope Process -ExecutionPolicy Unrestricted;");
    OSScript.Append(@"other really exciting stuff");
    PowerShellInstance.AddScript(OSScript.ToString());
    PowerShellInstance.Invoke();
} 

有人可以指引我正确的方向吗?我知道这样做行不通,如果我将机器策略设置为受限制的话,其他真正令人兴奋的东西就不会发生,但如果我将其设置为不受限制,则一切都能正常运作。


1
你是以管理员身份运行吗? - Camilo Terevinto
是的,这是作为Office 365管理员运行的。该代码在我的Windows 10 PowerShell 5无限制机器上正常执行。我还将一个Windows 7机器升级到了PowerShell 5,并且在无限制的情况下也可以成功运行该代码。似乎由于某种原因,我的“Set-ExecutionPolicy -Scope Process -ExecutionPolicy Unrestricted;”命令在受限制的机器上无法工作。我希望该命令能够允许进程即使在受限制的机器上也能运行。 - Pug
我看了一下我的代码块,发现与我发布时有所不同。最后一行的调用已被删除。删除调用是标准做法吗?我只是想理解这些编辑。除了调用之外,大部分编辑似乎只是清理明显糟糕的英语技巧。 - Pug
删除Invoke调用可能是一个错误,被错误地批准了。 - Camilo Terevinto
2个回答

9

我刚刚创建了一个新的控制台项目,并在 Main 函数中添加了以下内容:

using (PowerShell PowerShellInstance = PowerShell.Create())
{
    string script = "Set-ExecutionPolicy -Scope Process -ExecutionPolicy Unrestricted; Get-ExecutionPolicy"; // the second command to know the ExecutionPolicy level
    PowerShellInstance.AddScript(script);
    var someResult = PowerShellInstance.Invoke();
    someResult.ToList().ForEach(c => Console.WriteLine(c.ToString()));
    Console.ReadLine();
}   

这对我来说完美地运行,即使不以管理员身份运行代码也可以。我在Windows 10中使用Visual Studio 2015和Powershell 5。
根据Powershell 4.0 Set-ExecutionPolicyPowershell 5.0 Set-ExecutionPolicy,Set-ExecutionPolicy在Powershell 4和5中的工作方式相同。

2
所以我测试了上面的代码。它确实正常工作了。这是我需要的推动力,谢谢。我改成了绕过,我认为问题在于我需要分两步来完成。第一步切换我的绕过,我的第二个调用呼叫能够成功完成,但如果我试图在单个脚本中调用它,所有其他项目都会失败。感谢您们的时间和帮助。 - Pug

1

尝试使用反射来实现这个。

using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Reflection;
using Microsoft.PowerShell;
...
InitialSessionState iss = InitialSessionState.CreateDefault();
// Override ExecutionPolicy
PropertyInfo execPolProp = iss.GetType().GetProperty(@"ExecutionPolicy");
if (execPolProp != null && execPolProp.CanWrite)
{
    execPolProp.SetValue(iss, ExecutionPolicy.Bypass, null);
}
Runspace rs = RunspaceFactory.CreateRunspace(iss);
rs.Open();

请注意:PowerShell 中有 5 个执行策略 (scope) 级别 (参见 about_execution_policies)。这将设置 Process 的 ExecutionPolicy。这意味着如果该 ExecutionPolicy 是通过组策略或本地策略 (UserPolicy 或 MachinePolicy) 定义的,则不会覆盖 ExecutionPolicy。
检查 Get-ExecutionPolicy -List,以查看当前进程中定义在不同范围内的 ExecutionPolicies 列表。

这在处理旧的Microsoft.PowerShell.5.ReferenceAssemblies时特别有用,因为它不像后续的6+版本那样直接支持InitialSessionState.ExecutionPolicy - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接