13

I've found answers for both tasks separately, but not together:

  • Run PowerShell as an administrator from a batch file

  • Run PowerShell with arguments from a batch file

But I want to run PowerShell as an administrator AND with arguments from a batch file.

For this reason, I'm convinced this isn't a duplicate so far.

This problem is complicated for this reason:

I'm using the ArgumentList switch to point to the file path when running an elevated PowerShell. I'm also using it to pass in arguments. Separately, I have been able to use this switch with success. It doesn't seem as though I can use it for both tasks though.

Here's how I'm using PowerShell currently:

As an administrator:

powershell -Command "& {Start-Process powershell -ArgumentList '-File "filePath.ps1' -Verb RunAs}"

With arguments:

powershell -ExecutionPolicy unrestricted Import-Module "filePath.ps1" -ArgumentList "arg1","arg2"

What I've tried:

I've tried just adding my arguments to the ArgumentList where the file is passed in, but they weren't recognized.

I also tried adding -Verb RunAs to the working argument line, but PowerShell thought that I was trying to pass in another argument called Verb, and failed to run PowerShell as and admin.

Is it possible to accomplish both running PowerShell as an administrator, and with arguments, by switching up how I'm passing in arguments, or how I'm elevating the PowerShell?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kyle Stoflet
  • 1,194
  • 3
  • 16
  • 27

4 Answers4

8

It is possible to solve your problem without third-party tools, but the solution is somewhat arcane.

Therefore, consider downloading Bill Stewart's helpful elevate32 and elevate64 tools instead, as described in his answer, which simplifies the solution.

Here's a simple example that invokes the Get-Date cmdlet with arguments in an elevated PowerShell session launched from cmd.exe (or a batch file):

powershell -command "Start-Process -verb runas powershell" "'-noexit -command get-date -UFormat %s'"

Note how the command line to pass through to the elevated PowerShell session that the intermediary -command argument creates is passed as a single argument enclosed in embedded single quotes.

Quoting may get tricky, but this approach also works with invoking *.ps1 files in principle:

  • powershell -command "Start-Process -verb runas powershell" is the invariant part of the command line.

  • The remaining "..."-enclosed string must contain a nested single string with quoting that PowerShell recognizes (single quotes are easiest) containing all arguments that you would pass directly to a powershell ... command-line invocation.

Applied to your example:

... "'-File C:\path\to\filePath.ps1 arg1 arg2'"

Note: Be sure to use the full path to your script file, because the elevated PowerShell session does not (necessarily) run in the same directory as the calling session.

If you need to quote the arguments inside the nested string, use \":

... "'-File \"c:\path with spaces\to\filePath.ps1\" arg1 arg2'"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    This approach still displays the Windows _Do you want to allow this app_ pop-up, which defeats (my) purpose of running it in an automated environment. – vesperto Feb 07 '22 at 17:09
  • 1
    @vesperto, the only way to avoid UAC prompts is to either run in an elevated process to begin with or to disable UAC altogether, _which is strongly discouraged_. Otherwise, there's only a limited workaround: Assuming that you are an administrator in principle, you can set up a scheduled task with a preconfigured command to be run with elevation, which you can then invoke on demand without triggering a UAC prompt - see [this answer](https://stackoverflow.com/a/50555081/45375). – mklement0 Feb 07 '22 at 20:59
4

You can do this by grabbing a short command-line executable I wrote called Elevate32.exe (or Elevate64.exe for the 64-bit version). You can get it here:

http://www.westmesatech.com/misctools.html (ElevationToolkit1.zip)

Example:

elevate64 -- powershell.exe -file C:\scripts\myscriptfile.ps1

Everything after -- is the command line you want to elevate.

Bill_Stewart
  • 22,916
  • 4
  • 51
  • 62
  • 1
    So, I'm pretty confident that this worked. The only reason I accepted the other answer is because it doesn't require a call to an external process, and just seems like a more elegant solution. This is a nifty tool and I plan to apply it to other applications! Thanks again. – Kyle Stoflet Nov 03 '16 at 23:09
1

If you happen to have NirCmd by well-known NirSoft yet, you have a nice elevate command at your service (and a myriad more).

nircmd elevate powershell.exe -File script.ps1 arg1 arg2 ...

NirCmd is available in both x86 and x64 flavors and free, like all software from NirSoft.

cdlvcdlv
  • 952
  • 1
  • 9
  • 22
0

Mi solution a self elevating script. If is not executed with Administrator rights. The script checks administrator rol and executes as Administrator.

Run Script.ps1 from bath file (*.bat)

Powershell Core

pwsh.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 -Param1 Hello -Param2 World"

pwsh.exe -NoLogo -ExecutionPolicy Bypass -Command "path-to-script/Script.ps1 -Param1 Hello -Param2 World"

Powershell

powershell.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 -Param1 Hello -Param2 World"

powershell.exe -NoLogo -ExecutionPolicy Bypass -Command "path-to-script/Script.ps1 -Param1 Hello -Param2 World"

Script.ps1 Code

param(
    [Parameter(Mandatory=$True, Position=0, ValueFromPipeline=$false)]
    [System.String]
    $Param1,

    [Parameter(Mandatory=$True, Position=1, ValueFromPipeline=$false)]
    [System.String]
    $Param2
)

if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) 
{ 
    Start-Process pwsh "-NoLogo -ExecutionPolicy Bypass -Command $PSCommandPath -Param1 $Param1 -Param2 $Param2" -Verb RunAs; # //Run this script as Administrator.
    exit # //Exit from this non elevated context.
}

# // Executed in elevated Mode
Write-Host $Param1
Write-Host $Param2
Joma
  • 3,520
  • 1
  • 29
  • 32