Skip to content

Instantly share code, notes, and snippets.

@wgross
Last active August 29, 2015 14:14
Show Gist options
  • Save wgross/dc0dbb9b9a6f149972ae to your computer and use it in GitHub Desktop.
Save wgross/dc0dbb9b9a6f149972ae to your computer and use it in GitHub Desktop.
function elevated {
<#
.SYNOPSIS
Runs a scriptblock in an elevated shell
.DESCRIPTION
A given script block is executed in a an elevated powershell, if the current host isn't elevated.
The elevated shell location is moved to the current directory. A profiole isn't loaded for the
elevated shell because of performance reasons.
The output of the shell is captured and exported as CLI-Xml to a temorary file and imported by the
original shell after the the elevated process ended.
.EXAMPLE
Runs a elevated explorer in current directory
elevated { ii . }
.LINK
Based on http://blogs.msdn.com/b/virtual_pc_guy/archive/2010/09/23/a-self-elevating-powershell-script.aspx
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true,Position=0)]
[scriptblock]$ContinueWith
)
process {
$myWindowsPrincipal=New-Object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())
if ($myWindowsPrincipal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) {
# this is an admin process. do ot elevate
Write-Verbose "Host is already elevated..."
$ContinueWith.InvokeReturnAsIs()
} else {
# Start scriptblock in elevated process
Write-Verbose "Host isn't elevated yet. Starting elevated process."
# Start script block execution at current location. All generated obejcts are exported to temporary file
$tempFileName = [System.IO.Path]::GetTempFileName();
$commandString = "Push-Location {0}; {{ {1} }}.InvokeReturnAsIs() | Export-Clixml -Path {2}; Pop-Location" -f $PWD,$ContinueWith.ToString(),$tempFileName
Write-Verbose "Executing script block in $PWD and storing results temporarily in $tempFileName"
Start-Process "powershell" `
-ArgumentList @("-noprofile","-Command",$commandString) `
-Verb runas `
-WindowStyle Hidden `
-Wait
# has no effect: # -WorkingDirectory $PWD
# Now read temorary file and show them in shell
Write-Verbose "Importing results from $tempFileName"
if(Test-Path $tempFileName) {
if((Get-Item $tempFileName).Length -gt 0) {
# read output from eleveted shell as powershell objects
Import-Clixml -Path $tempFileName -ErrorAction SilentlyContinue
}
# clean up existing temp file
Remove-Item $tempFileName | Out-Null
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment