Created
June 20, 2018 14:35
-
-
Save NotNotWrongUsually/6352a29c168aa5e83cf82f1086e69417 to your computer and use it in GitHub Desktop.
Invoke-AsOtherUser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# The below code is a somewhat modified version of original work from | |
# https://gist.github.com/idavis/856603/818f50f1d6d862ca5458e5b87bca034e567b387f | |
# All credit to the author. | |
function Invoke-AsOtherUser { | |
[CmdletBinding()] | |
param ( | |
[parameter(Mandatory = $true)][PSCredential] $Credentials, | |
[parameter(Mandatory = $true)][ScriptBlock] $ScriptBlock | |
) | |
$logonUserSignature = @' | |
[DllImport( "advapi32.dll" )] | |
public static extern bool LogonUser( String lpszUserName, | |
String lpszDomain, | |
String lpszPassword, | |
int dwLogonType, | |
int dwLogonProvider, | |
ref IntPtr phToken ); | |
'@ | |
$AdvApi32 = Add-Type -MemberDefinition $logonUserSignature -Name "AdvApi32" -Namespace "PsInvoke.NativeMethods" -PassThru | |
$closeHandleSignature = @' | |
[DllImport( "kernel32.dll", CharSet = CharSet.Auto )] | |
public static extern bool CloseHandle( IntPtr handle ); | |
'@ | |
$Kernel32 = Add-Type -MemberDefinition $closeHandleSignature -Name "Kernel32" -Namespace "PsInvoke.NativeMethods" -PassThru | |
try { | |
$Logon32ProviderDefault = 0 | |
$Logon32LogonInteractive = 2 | |
$tokenHandle = [IntPtr]::Zero | |
$userName = Split-Path $credentials.UserName -Leaf | |
$domain = Split-Path $credentials.UserName | |
$unmanagedString = [IntPtr]::Zero; | |
$success = $false | |
try { | |
$unmanagedString = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($credentials.Password); | |
$success = $AdvApi32::LogonUser($userName, $domain, [System.Runtime.InteropServices.Marshal]::PtrToStringUni($unmanagedString), $Logon32LogonInteractive, $Logon32ProviderDefault, [Ref] $tokenHandle) | |
} | |
finally { | |
[System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode($unmanagedString); | |
} | |
if (!$success ) { | |
$retVal = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
$retVal | |
} | |
$identityName = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name | |
$newIdentity = New-Object System.Security.Principal.WindowsIdentity( $tokenHandle ) | |
$context = $newIdentity.Impersonate() | |
$identityName = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name | |
& $scriptBlock | |
} | |
catch [System.Exception] { | |
Write-Host $_.Exception.ToString() | |
} | |
finally { | |
if ( $context -ne $null ) { | |
$context.Undo() | |
} | |
if ( $tokenHandle -ne [System.IntPtr]::Zero ) { | |
$Kernel32::CloseHandle( $tokenHandle ) | out-null | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment