运行 用于执行 PowerShell 的批处理文件和其他批处理文件

Running Batch File To Execute PowerShell and Additional Batch file

我在 Powershell 脚本中有以下内容 - InstallApp.ps1 - 下载可执行文件,然后安装可执行文件,最后 运行 一个批处理文件以在其中应用必要的配置应用程序:

#Change directory to script location
    CD $PSScriptRoot

#Download Application
    $AppSource = "www.url.com/application.exe;
    $AppDestination = "$PSScriptRoot\application.exe"
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    Invoke-WebRequest -URi $AppSource -OutFile $AppDestination

#Install Application

    .\application.exe --platform minimal --script silent-install.js InstallDir=C:\Application

#Configure Application

    Start-Process .\ConfigureApp.bat -Verb RunAs

    Write-host "Configuring Application. Do not proceed until addittional Command Prompt window closes"

    Pause

如果我以管理员身份打开 PowerShell 并 运行 这个脚本,一切正常。问题是,我需要将其传递给其他人 运行 作为管理员。在这种情况下,我要做的是创建一个名为 _RunMeAsAdmin.bat 的批处理文件并将其包含在包中。有了它,我将拥有:

@echo off

:: Install App
cd /D "%~dp0"
Powershell.exe -ep bypass -file InstallApp.ps1 -Verb RunAs

当我 运行 这样做时,Powershell 脚本会一直执行到安装应用程序的所有过程,但从不调用额外的 ConfigureApp.bat 来完成配置。

我意识到这可能是完成我想要的事情的一种迂回方式,但很好奇是否有人对我如何使它起作用有任何意见?

powershell.exe,Windows PowerShell CLI,不直接支持-Verb RunAs以启动进程提升(作为管理员)。

相反,您必须使用 -Command (-c) 参数来传递调用 Start-Process -Verb RunAs 的命令,这又需要 nested powershell.exe 调用以执行带有提升的 .ps1 文件:

powershell.exe -noprofile -c Start-Process -Verb RunAs powershell.exe '-ep bypass -file \"%CD%\InstallApp.ps1\"'

注:

  • 由于 -Verb RunAs 在 Windows PowerShell 中使提升的进程默认为 SYSTEM32 目录而不是调用者的目录,因此 .ps1 文件路径明确地带有前缀调用者的工作目录,%CD%.

    • 注意:由于您的 .ps1 脚本明确设置了自己的工作目录 (CD $PSScriptRoot),因此无需为提升的进程预设工作目录。
    • 这样做会使调用复杂化,因为您不能简单地将 Start-Process-WorkingDirectory 参数与 -Verb RunAs 结合使用。相反,您必须将嵌套的 powershell.exe 调用切换为执行 Set-Location (cd) -Command (-c) 调用在提升的进程 中,在调用目标脚本之前,这会使引用和转义变得复杂 - 请参阅 示例。
  • 我从 outer powershell.exe 调用中省略了 -ep bypass,因为那里没有必要(只有 cmdlet - Start-Process - 在其会话中执行,不受有效执行策略的约束。

    • 但是,我用 -noprofile 代替了任何 profile 脚本的执行 - 受执行策略约束。
    • 对于自动执行,建议常规使用 -noprofile,这既是为了更可预测的执行环境,也是为了消除不必要的处理。
  • 如果要等待提升的脚本退出,请将 -Wait 添加到 Start-Process 调用。

  • 由于您的 .ps1 脚本是通过批处理文件提升的,因此您不再需要 Start-Process -Verb RunAs 脚本内部 , 你可以简单地在开头放置一个
    #Requires -RunAsAdministrator 行以防止直接 non-elevated 执行。

最后,作为使用辅助批处理文件的替代方法,考虑制作 .ps1 脚本 self-elevating,如 所示(链接的答案很复杂,因为它试图提供支持任意参数的通用、健壮的解决方案;对于 argument-less 调用,它可以大大简化)。