Commands/Invoke-CommandWithToken.ps1
Function Invoke-CommandWithToken { <# .SYNOPSIS Uses a PSCredential object to build a token .DESCRIPTION Uses the PSCredential and win32 apis to log the user in and create a local or network only token .PARAMETER Credential Credential to execute the scriptblock as .PARAMETER NetOnly Credential to execute the scriptblock as .PARAMETER Token what token should be used to run the script block .PARAMETER Binary a hash table of the parameters you want to pass into your scriptblock .PARAMETER CommandLine What exe block should be run .PARAMETER ShowUI What exe block should be run .EXAMPLE PS> .LINK http://www.JPScripter.com https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessasuserw #> param( [Parameter(ParameterSetName = "Token")] [Security.Principal.WindowsIdentity]$Token, [System.IO.FileInfo]$Binary = $env:ComSpec, [string]$Parameters, [Pinvoke.LogonFlags] $logonFlag = [Pinvoke.LogonFlags]::DEFAULT, [int] $CreationFlags = ([Pinvoke.CreationFlags]::CREATE_NEW_CONSOLE -bor [Pinvoke.CreationFlags]::CREATE_NEW_PROCESS_GROUP -bor [Pinvoke.CreationFlags]::CREATE_UNICODE_ENVIRONMENT), [int]$StartInfoFlags = ([Pinvoke.StartInfoFlags]::STARTF_USESHOWWINDOW), [string]$Desktop, [switch] $ShowUI ) Begin{ $LogonType = [Pinvoke.dwLogonType]::Interactive if ($NetOnly.IsPresent){[Pinvoke.dwLogonType]::NewCredentials} if ($null -NE $Credential){ $token = Get-CredentialToken -Credential $Credential -LogonType $LogonType } Set-ProcessPrivilage -ProcessPrivilege SeAssignPrimaryTokenPrivilege Set-ProcessPrivilage -ProcessPrivilege SeIncreaseQuotaPrivilege } Process { $SecurityAttibutes = New-object pinvoke.SECURITY_ATTRIBUTES $SecurityAttibutes.nLength = [System.Runtime.InteropServices.Marshal]::SizeOf($SecurityAttibutes) [intptr]$pToken = 0 $Access = [System.Security.Principal.TokenAccessLevels]::MaximumAllowed $ImpersionationLevel = [pinvoke.SECURITY_IMPERSONATION_LEVEL]::SecurityIdentification $TokenType = [Pinvoke.TOKEN_TYPE]::TokenPrimary $ptoken = Get-DuplicateToken -Token $token -TokenAccess $Access -ImpersionationLevel $ImpersionationLevel -TokenType $TokenType -returnPointer $Filename = $Binary.FullName if ($Null -eq $Binary) {$Filename = $null} $NewProcessPid = [Pinvoke.advapi32]::LaunchProcessAsToken( $Binary.FullName, $Parameters, $ShowUI.IsPresent, $logonFlag, $CreationFlags, $StartInfoFlags, $Desktop, $pToken, [intptr]::Zero ) if ($NewProcessPid -eq 0){ # $Lasterr = ([System.ComponentModel.Win32Exception][System.Runtime.InteropServices.Marshal]::GetHRForLastWin32Error()).message Write-Error -Message "Failed to start process $lasterr" } } End { $NewProcessPid } } |