从c#运行Powershell脚本

rqcrx0a6  于 2022-12-23  发布在  Shell
关注(0)|答案(3)|浏览(260)

我尝试从C#代码运行PowerShell脚本,但遇到了一些(可能是环境)问题:
在我尝试运行它的计算机上,出现以下情况:

  1. PowerShell以管理员身份启动和加载
  2. PowerShell窗口立即关闭(表面上),没有错误

备注:

  • 脚本工作正常,当我从伊势运行它时,它运行没有错误。
  • 如果我右键单击脚本并选择“使用PowerShell运行”,即使我没有在脚本中更改执行策略,也会收到执行策略错误。

设置执行策略:Windows PowerShell已成功更新你的执行策略,但该设置被在更具体的作用域中定义的策略重写。由于该重写,你的 shell 程序将保留其当前有效的RemoteSigned执行策略。键入“Get-ExecutionPolicy -List”以查看你的执行策略设置。有关详细信息,请参阅“Get-Help Set-ExecutionPolicy”。在第1行,字符数:46 + if((Get-ExecutionPolicy)-ne 'AllSigned'){ Set-ExecutionPolicy -Scope进程...+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~类别信息:许可被拒绝:(:)[设置执行策略],安全异常+完全限定的错误ID:执行策略覆盖、Microsoft、PowerShell、命令、设置执行策略命令

  • 获取执行策略列表
Scope                ExecutionPolicy
     -----                ---------------
 MachinePolicy              Unrestricted
    UserPolicy                 Undefined
       Process                    Bypass
   CurrentUser              Unrestricted
  LocalMachine              Unrestricted
  • 我认为这是环境问题,因为:
  • 前几天还好好的
  • 它在其他计算机上运行良好

这是我用来调用脚本的代码:

if (File.Exists("Start.ps1"))
{
    string strCmdText = Path.Combine(Directory.GetCurrentDirectory(), "Start.ps1");

    var process = System.Diagnostics.Process.Start(@"C:\windows\system32\windowspowershell\v1.0\powershell.exe ", strCmdText);
    process.WaitForExit();
}

脚本本身无关紧要,因为我已将其更改为简单的

Write-Host "Hello"
$d=Read-Host

我也有同样的问题。

twh00eeo

twh00eeo1#

问题出在脚本的路径上。它在这台特定的机器上有空格,我没有处理过。
窗口关闭太快,除了设置以外,看不到任何错误

process.StartInfo.RedirectStandardOutput = true;

帮我抓住了它。
执行策略与我的错误无关。
为了修复它,我改变了路径在C#代码解释如下:Executing a Powershell script in CMD.EXE from a location with "Illegal characters in path"
完整代码:

if (File.Exists("Start.ps1"))
            {
                File.GetAttributes("Start.ps1");
                string strCmdText =   Path.Combine(Directory.GetCurrentDirectory(), "Start.ps1");
                var process = new Process();
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.FileName = @"C:\windows\system32\windowspowershell\v1.0\powershell.exe";
                process.StartInfo.Arguments = "\"&'"+strCmdText+"'\"";

                process.Start();
                string s = process.StandardOutput.ReadToEnd();
                process.WaitForExit();

                using (StreamWriter outfile = new StreamWriter("StandardOutput.txt", true))
                {
                    outfile.Write(s);
                }

            }
bis0qfac

bis0qfac2#

先做重要的事:从. NET可执行文件执行PowerShell代码的一种替代、更高效、更灵活的方法是使用PowerShell SDK***,它支持 * 进程内执行 具有 * 完整的. NET类型支持**-有关示例,请参见this answer
虽然your own answer提供了一个有效的解决方案,但还有一个 * 更简单 * 的解决方案,它也适用于碰巧包含'字符的脚本文件路径:
通过powershell.exe(Windows PowerShell CLI)执行.ps1文件,请使用其-File参数r,如果使用.Arguments,则只需要将脚本文件路径括在嵌入的"..."中(. NET Framework)/将脚本文件路径按原样传递到.ArgumentList.Add()(. NET(Core)),并允许您根据需要将任何传递参数指定为文本(使用嵌入式双引号):

# ... 
string strCmdText = Path.Combine(Directory.GetCurrentDirectory(), "Start.ps1");
var process = new Process();
process.StartInfo.UseShellExecute = false;
# ...
process.StartInfo.FileName = @"C:\windows\system32\windowspowershell\v1.0\powershell.exe";
// Use '-File' with embedded "..." quoting.
process.StartInfo.Arguments = string.Format("-File \"{0}\"", strCmdText);
// In a .NET Core / .NET 5+ application you can alternatively use:
//   process.StartInfo.ArgumentList.Add("-File");
//   process.StartInfo.ArgumentList.Add(strCmdText);
# ...

注:

  • 如果没有指定-Filepowershell.exe会假设-Command为目标参数,在从所有后续参数中剥离(未转义)"后,* 然后 * 将它们解释为 * PowerShell代码 *-请参阅this answer了解背景信息。
  • 有关两个PowerShell版本中PowerShell CLI的全面概述,请参见this answer
q5lcpyga

q5lcpyga3#

在您列出策略时,显然存在针对您的计算机实施的组策略(即使它不在域中,仍然有本地GP有效),它将X1 M0 N1 X这是最重要的本地设置策略更改为“RemoteSigned”,这是在代码执行方面比“Unrestricted”更强大的策略。如果您的PC在域中,您可以运行“策略的结果集(正在登录)”并获取影响你电脑的域策略。如果没有,从“控制面板”/“管理工具”运行“本地安全策略”,然后导航到“计算机配置-管理模板- Windows组件- Windows PowerShell”,并检查其中的策略值(“启用场景执行”--大致翻译自本地化),如果需要,您可以更改其中的值。完成后,重新加载Powershell。

相关问题