Created
March 5, 2011 18:52
-
-
Save idavis/856603 to your computer and use it in GitHub Desktop.
Impersonate a user and execute a script block as that user
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
param( [ScriptBlock] $scriptBlock ) | |
<# | |
.SYNOPSIS | |
Impersonates a user and executes a script block as that user. This is an interactive script | |
and a window will open in order to securely capture credentials. | |
.EXAMPLE | |
Use-Impersonation.ps1 {Get-ChildItem 'C:\' | Foreach { Write-Host $_.Name }} | |
This writes the contents of 'C:\' impersonating the user that is entered. | |
#> | |
$logonUserSignature = | |
@' | |
[DllImport( "advapi32.dll" )] | |
public static extern bool LogonUser( String lpszUserName, | |
String lpszDomain, | |
IntPtr 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 | |
$credentials = Get-Credential | |
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, $unmanagedString, $Logon32LogonInteractive, $Logon32ProviderDefault, [Ref] $tokenHandle) | |
} | |
finally | |
{ | |
[System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode($unmanagedString); | |
} | |
if (!$success ) | |
{ | |
$retVal = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
Write-Host "LogonUser was unsuccessful. Error code: $retVal" | |
return | |
} | |
Write-Host "LogonUser was successful." | |
Write-Host "Value of Windows NT token: $tokenHandle" | |
$identityName = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name | |
Write-Host "Current Identity: $identityName" | |
$newIdentity = New-Object System.Security.Principal.WindowsIdentity( $tokenHandle ) | |
$context = $newIdentity.Impersonate() | |
$identityName = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name | |
Write-Host "Impersonating: $identityName" | |
Write-Host "Executing custom script" | |
& $scriptBlock | |
} | |
catch [System.Exception] | |
{ | |
Write-Host $_.Exception.ToString() | |
} | |
finally | |
{ | |
if ( $context -ne $null ) | |
{ | |
$context.Undo() | |
} | |
if ( $tokenHandle -ne [System.IntPtr]::Zero ) | |
{ | |
$Kernel32::CloseHandle( $tokenHandle ) | |
} | |
} |
Can you advise how to perform impersonation and exit the context if there is no $CONTEXT variable left in memory? Or is this impossible?
Maybe like this ? UPD:
$RtS = @"
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
"@
$CRTS = Add-Type -MemberDefinition $RtS -Name "CRTS2" -Namespace "PsInvoke.NativeMethods" -PassThru
$CRTS::RevertToSelf()
How to perform impersonation by also increasing administrator rights?
@yuzhaninan Sorry, I don't know.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
windows powershell ISE crashes exactly at this $context = $newIdentity.Impersonate()
my scenario is i will be calling a powershell scripit as domain1/user1 and in this powershell script the user has to be changed to domain2/user2 so can i do this using this script ???.. and also i need to end impersonation once the task is completed. any thoughts would be greatly helpful. ( Can you change the script to change to a new user instead of logged in user ?? or some sample code ???)
I do not know why the windows powershell is crashing exactly at this step. ???