Skip to content

Instantly share code, notes, and snippets.

@pstephenson02
Created June 4, 2021 02:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save pstephenson02/800d134d22bea3ffc959092779af97e1 to your computer and use it in GitHub Desktop.
Save pstephenson02/800d134d22bea3ffc959092779af97e1 to your computer and use it in GitHub Desktop.
function Use-Impersonation
{
param(
[string] $Username,
[securestring] $Password,
[string] $Domain = '.\',
[scriptblock] $ScriptBlock
)
<#
.SYNOPSIS
Impersonates a user and executes a script block as that user.
.PARAMETER Username
The username with which you'd like to impersonate
.PARAMETER Password
A SecureString representing the user's password
.PARAMETER Domain
An optional domain. You may omit this parameter if you wish to impersonate a local user.
.PARAMETER ScriptBlock
The code to execute
.EXAMPLE
Use-Impersonation -Username "myuser" `
-Password (ConvertTo-SecureString "mypassword" -AsPlainText -Force) `
-Domain "WORKGROUP" `
-ScriptBlock { Write-Host "Hello World!" }
#>
$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
$unmanagedString = [IntPtr]::Zero;
$success = $false
try
{
$unmanagedString = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($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()
Write-Host "LogonUser was unsuccessful. Error code: $retVal"
return
}
$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"
& $scriptBlock
}
catch [System.Exception]
{
Write-Host $_.Exception.ToString()
}
finally
{
if ($null -ne $context)
{
$context.Undo()
}
if ($tokenHandle -ne [System.IntPtr]::Zero)
{
$Kernel32::CloseHandle($tokenHandle) | Out-Null
}
}
}
Export-ModuleMember -Function "Use-Impersonation"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment