Reputation: 238
I have a powershell script that checks if it's admin, and if not relaunches as admin. However, I've had to add a parameter to tell the script what interpreter to use on relaunch (pwsh.exe or powershell.exe in particular). Is there a way to tell which .exe is executing the script?
param (
[string]$AdminShell = "powershell.exe"
)
# Check if the script is running as administrator
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
# Restart the script as administrator
Start-Process -FilePath $AdminShell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File $($MyInvocation.MyCommand.Path)" -Verb RunAs
Exit
}
Upvotes: 2
Views: 71
Reputation: 439822
To complement Santiago's helpful answer:
An alternative cross-edition solution (i.e. one that works in both Windows PowerShell and PowerShell (Core) 7, as you requested):
[System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName
A simpler, PowerShell 7-only solution that is the equivalent of the above:
[Environment]::ProcessPath
A note re [System.Environment]::GetCommandLineArgs()[0]
:
It is only .NET executables invoked from PowerShell that are guaranteed to see a full path, because PowerShell itself resolves relative or $env:PATH
-based executable paths to full ones before invocation.
.NET executables invoked from outside PowerShell, such as via cmd.exe
or when using the System.Diagnostics.Process
API, see the target executable as specified on the invocation command line, which therefore may be a relative path, or a name only.
The latter introduces ambiguity, as an invocation name of foo
may either refer to an executable by that name in the current directory or one that can be located via $env:PATH
.
It is for that reason that the solutions in the top section are generally preferable, as is (Get-Process -Id $PID).Path
.
Upvotes: 1
Reputation: 60848
You can use GetCommandLineArgs
to determine it. The first argument (index 0
) will be the shell's absolute path.
[System.IO.Path]::ChangeExtension([System.Environment]::GetCommandLineArgs()[0], 'exe')
Another option is with Get-Process
using $PID
automatic variable:
(Get-Process -Id $PID).Path
A third option is pointed out by Mathias in comments, using either $PSVersionTable
or $IsCoreCLR
, both options should be valid:
if ($IsCoreCLR) {
Join-Path $PSHOME pwsh.exe
}
else {
Join-Path $PSHOME powershell.exe
}
Upvotes: 2