Skip to content

Instantly share code, notes, and snippets.

@NotNotWrongUsually
Created June 20, 2018 14:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save NotNotWrongUsually/6352a29c168aa5e83cf82f1086e69417 to your computer and use it in GitHub Desktop.
Save NotNotWrongUsually/6352a29c168aa5e83cf82f1086e69417 to your computer and use it in GitHub Desktop.
Invoke-AsOtherUser
# 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