I'm wondering whether it's possible to create a self-elevating command?
Imagine a codeblock as follows:
function Foobar {
[CmdletBinding()]
param (
[Parameter(Position = 0, Mandatory = $true)]
[string]
$ArgOne,
[Parameter(Position = 1, Mandatory = $true)]
[string]
$ArgTwo,
[Parameter(Position = 2, Mandatory = $true)]
[string]
$ArgThree
)
if (RunAsAdministrator { Foobar $ArgOne $ArgTwo $ArgThree }) {
return
}
Write-Host "From an elevated prompt..."
}
The function I've been trying to write is RunAsAdministrator and it would work as follows:
- If the shell is elevated, it returns false, which means the write-host below will run.
- If the shell is not elevated, it runs the codeblock in an elevated shell and returns true, which means the write-host will not run a second time.
Simplified call graph:
Foobar (unlevated)
-> RunAsAdministrator (unelevated)
-> Foobar (elevated in new shell, prints message)
But I just can't figure out how to get RunAsAdministrator working. This is currently what it looks like:
function RunAsAdministrator {
param(
[Parameter(Position = 0)]
[scriptblock]
$Command
)
if (Test-AdministratorStatus) {
$false
}
else {
Start-Process "pwsh" -Verb RunAs -ArgumentList @(
# temp flags for debugging only
"-NoExit",
"-NoProfile",
"-Interactive",
# This doesn't work!
"-Command { Invoke-Command -ScriptBlock {$Command} }"
)
$true
}
}
When I try to run this, the elevated pwsh prompt pops up but it just displays the following text rather than running anything
Invoke-Command -ScriptBlock { Foobar $ArgOne $ArgTwo $ArgThree }
My question is, is this even possible to achieve, and if so, how?