1

I have the following in a Powershell script - InstallApp.ps1 - to download an executable, then install the executable, and finally, to run a batch file to apply the necessary configurations within the app:

#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

If I open PowerShell as Administrator and run this script, everything works without issue. The problem is, I need to pass this on and have other people run it as admin. My go to in this situation is to create a batch file called _RunMeAsAdmin.bat and include it in the package. With that I will have:

@echo off

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

When I run this, the Powershell script goes all the way through installing the application, but never calls the additional ConfigureApp.bat to finalize the configurations.

I realize this is probably a roundabout way of accomplishing what I want, but curious if anyone has any input on how I can get this to work?

Christopher Cass
  • 817
  • 4
  • 19
  • 31

1 Answers1

2

powershell.exe, the Windows PowerShell CLI, doesn't directly support -Verb RunAs in order to launch a process with elevation (as admin).

Instead, you must use use the -Command (-c) parameter to pass a command that calls Start-Process -Verb RunAs, which in turn requires a nested powershell.exe call in order to execute the .ps1 file with elevation:

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

Note:

  • Since -Verb RunAs in Windows PowerShell makes the elevated process default to the SYSTEM32 directory instead of the caller's, the .ps1 file path was explicitly prefixed with the caller's working directory, %CD%.

    • Note: Since your .ps1 script explicitly sets its own working directory (CD $PSScriptRoot), there is no need to preset the working directory for the elevated process.
    • Doing so would complicate the call, because you cannot simply use the -WorkingDirectory parameter of Start-Process in combination with -Verb RunAs. Instead, you'd have to switch the nested powershell.exe call to a -Command (-c) invocation that executes Set-Location (cd) in the elevated process, before calling the target script, which complicates quoting and escaping - see this answer for an example.
  • I've omitted -ep bypass from the outer powershell.exe call, as it isn't necessary there (only a cmdlet - Start-Process - is executed in its session, which isn't subject to the effective execution policy).

    • However, I've substituted -noprofile to suppress execution of any profile scripts - which are subject to the execution policy.
    • Routine use of -noprofile is advisable for automated execution, both for a more predictable execution environment and to eliminate unnecessary processing.
  • Add -Wait to the Start-Process call if you want to wait for the elevated script to exit.

  • Since your .ps1 script is then elevated via the batch file, you don't need Start-Process -Verb RunAs inside the script anymore, and you can simply place a
    #Requires -RunAsAdministrator line at the start to prevent direct, non-elevated execution.

Finally, as an alternative to using a helper batch file, consider making your .ps1 script self-elevating, as shown in this answer (the linked answer is complex, because it tries to provide a generic, robust solution that supports arbitrary arguments; for argument-less invocations it can be greatly simplified).

mklement0
  • 382,024
  • 64
  • 607
  • 775