Public/Invoke-AsCurrentUser.ps1
function Invoke-AsCurrentUser { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [scriptblock] $ScriptBlock, [Parameter(Mandatory = $false)] [switch]$NoWait, [Parameter(Mandatory = $false)] [switch]$UseWindowsPowerShell, [Parameter(Mandatory = $false)] [switch]$NonElevatedSession, [Parameter(Mandatory = $false)] [switch]$Visible, [Parameter(Mandatory = $false)] [switch]$CacheToDisk ) if (!("RunAsUser.ProcessExtensions" -as [type])) { Add-Type -TypeDefinition $script:source -Language CSharp } if ($CacheToDisk) { $ScriptGuid = new-guid $ExpandedScriptBlock = $ExecutionContext.InvokeCommand.ExpandString($ScriptBlock) $null = New-item "$($ENV:TEMP)\$($ScriptGuid).ps1" -Value $ExpandedScriptBlock -Force $pwshcommand = "-ExecutionPolicy Bypass -Window Normal -file `"$($ENV:TEMP)\$($ScriptGuid).ps1`"" } else { $ExpandedScriptBlock = $ExecutionContext.InvokeCommand.ExpandString($ScriptBlock) $encodedcommand = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($ExpandedScriptBlock)) $pwshcommand = "-ExecutionPolicy Bypass -Window Normal -EncodedCommand $($encodedcommand)" } $OSLevel = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").CurrentVersion if ($OSLevel -lt 6.2) { $MaxLength = 8190 } else { $MaxLength = 32767 } if ($encodedcommand.length -gt $MaxLength -and $CacheToDisk -eq $false) { Write-Error -Message "The encoded script is longer than the command line parameter limit. Please execute the script with the -CacheToDisk option." return } $privs = whoami /priv /fo csv | ConvertFrom-Csv | Where-Object { $_.'Privilege Name' -eq 'SeDelegateSessionUserImpersonatePrivilege' } if ($privs.State -eq "Disabled") { Write-Error -Message "Not running with correct privilege. You must run this script as system or have the SeDelegateSessionUserImpersonatePrivilege token." return } else { try { # Use the same PowerShell executable as the one that invoked the function, Unless -UseWindowsPowerShell is defined if (!$UseWindowsPowerShell) { $pwshPath = (Get-Process -Id $pid).Path } else { $pwshPath = "$($ENV:windir)\system32\WindowsPowerShell\v1.0\powershell.exe" } if ($NoWait) { $ProcWaitTime = 1 } else { $ProcWaitTime = -1 } if ($NonElevatedSession) { $RunAsAdmin = $false } else { $RunAsAdmin = $true } [RunAsUser.ProcessExtensions]::StartProcessAsCurrentUser( $pwshPath, "`"$pwshPath`" $pwshcommand", (Split-Path $pwshPath -Parent), $Visible, $ProcWaitTime, $RunAsAdmin) if ($CacheToDisk) { $null = remove-item "$($ENV:TEMP)\$($ScriptGuid).ps1" -Force } } catch { Write-Error -Message "Could not execute as currently logged on user: $($_.Exception.Message)" -Exception $_.Exception return } } } |