我的PowerShell脚本在从批处理文件或命令行打开时不起作用,但直接运行时却起作用

问题描述 投票:0回答:1

我正在尝试做的事情:

使用 .bat 文件调用 .ps1 文件(不要问)生成自签名证书和密钥对 (.pem),然后 .bat 文件会将每个 .pem 移动到新目录。

我做了什么:

我的 .ps1 文件工作正常,它生成这两个文件,但它确实需要以管理员身份运行 PowerShell。我有 .bat 文件在应该调用 .ps1 文件时。在批处理文件中,我打开 PowerShell,然后以管理员身份打开另一个 PowerShell 实例(因为无法从命令行以管理员身份运行 PS,如果我错了,请纠正我)。这是代码行:

PowerShell -Command "& {Start-Process PowerShell -ArgumentList '-NoExit -File ""cert-gen.ps1""' -Verb RunAs}"

发生了什么:

运行此行时,我看到弹出一个 PS 窗口并立即关闭,它不会生成我的证书和密钥。由于它立即关闭,我看不到该窗口中是否有任何错误,并且命令行确实显示了任何错误。我很确定我的

-NoExit
位于正确的位置。

奖金:

这需要完全自动化,无需用户交互,因此 UAC 提升的提示不起作用。我最终也需要找到解决这个问题的方法,所以如果有一个解决方案可以一次性解决所有这些问题,那就更好了!

powershell batch-file ssl-certificate
1个回答
1
投票
:: From a batch file
PowerShell -Command "Start-Process PowerShell -ArgumentList '-NoExit -File \"%CD%\cert-gen.ps1\"' -Verb RunAs"
  • 主要问题是,当

    powershell.exe
    (Windows PowerShell CLI)通过提升调用时,它总是使用C:\Windows\System32
    作为工作目录。因此,它无法找到您的
    cert-gen.ps1
    脚本
    there

    • %CD%\cert-gen.ps1

      确保脚本通过其
      完整路径传递,这解决了这个问题。 %CD%
       被前面的 
      cmd.exe
       扩展为当前目录的完整路径。

    • 请注意,您的脚本必须准备好处理以

      C:\Windows\System32

       作为工作目录的运行;例如,它使用 
      automatic $PSScriptRoot
       变量
      来引用它自己的目录。

    • 顺便说一句:不幸的是,如果未找到以

      -NoExit

      为目标的脚本,则通过
      -File调用的CLI会话会自动关闭
      (当使用
      -Command
      失败的命令时,会话保持打开状态) ; 
      GitHub 问题 #10471 建议更改此行为。

  • 不必要的

    & { ... }

    外壳已被移除:

      没有理由使用
    • "& { ... }"
       来调用通过 
      -Command
       (
      -c
      ) 参数传递到 PowerShell CLI 的代码 - 只需直接使用 
      "..."
       即可。旧版本的 
      CLI 文档 错误地建议 & { ... }
       是必需的,但这已得到纠正。
  • ""

     用于转义嵌入的 
    "
     字符。碰巧工作
    在这种情况下,它不工作稳健,所以使用\"
    来代替:

      但是,使用
    • pwsh.exe
      PowerShell (Core) 7+""
       确实可以稳定工作,并且优于 
      \"
      ,因为它避免了 
      cmd.exe
      的边缘情况解析可能会破坏命令 - 有关详细信息,请参阅
      此答案

至于问题的

UAC部分

  • 唯一

    安全方法防止批处理文件触发UAC提示从已提升的会话运行它 - 但启动此类会话本身不会触发UAC提示。

    • 如果您确保您的批处理文件

      作为一个整体以提升的方式运行(这本身就可以被视为安全风险,如果不是其中的所有操作实际上都需要提升),您可以将您的PowerShell CLI调用简化为(如果 -NoExit

       只是为了排除故障,请考虑将其删除):

      PowerShell -NoExit -File cert-gen.ps1
      
      
    • 也就是说,直接调用是可能的,因为从提升的进程启动的子进程也会提升。

  • 不安全替代方案这个答案中讨论。

© www.soinside.com 2019 - 2024. All rights reserved.