Skip to content

Instantly share code, notes, and snippets.

@jborean93
Last active January 20, 2025 01:30
Show Gist options
  • Select an option

  • Save jborean93/3c148df03545023c671ddefb2d2b5ffc to your computer and use it in GitHub Desktop.

Select an option

Save jborean93/3c148df03545023c671ddefb2d2b5ffc to your computer and use it in GitHub Desktop.
Invoke a scriptblock in powershell with impersonation
Add-Type -Namespace PInvoke -Name NativeMethods -MemberDefinition @'
[DllImport("Kernel32.dll")]
public static extern bool CloseHandle(
IntPtr hObject);
[DllImport("Advapi32.dll", SetLastError = true)]
public static extern bool ImpersonateLoggedOnUser(
IntPtr hToken);
[DllImport("Advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool LogonUserW(
string lpszUsername,
string lpszDomain,
IntPtr lpszPassword,
UInt32 dwLogonType,
UInt32 dwLogonProvider,
out IntPtr phToken);
[DllImport("Advapi32.dll")]
public static extern bool RevertToSelf();
'@
Function Invoke-WithImpersonation {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[ScriptBlock]
$ScriptBlock,
[Parameter(Mandatory=$true)]
[PSCredential]
$Credential
)
$user = $Credential.UserName
$domain = $null
if ($user.Contains('\')) {
$domain, $user = $user -split '\\', 2
}
$passPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($Credential.Password)
try {
$token = [IntPtr]::Zero
$res = [PInvoke.NativeMethods]::LogonUserW(
$user,
$domain,
$passPtr,
2, # LOGON32_LOGON_INTERACTIVE
0, # LOGON32_PROVIDER_DEFAULT
[ref]$token
); $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
} finally {
[System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode($passPtr)
}
if (-not $res) {
$exp = [System.ComponentModel.Win32Exception]$res
Write-Error -Message "Failed to log on user: $($exp.Exception.Message)" -Exception $exp
return
}
try {
$res = [PInvoke.NativeMethods]::ImpersonateLoggedOnUser(
$token
); $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
if (-not $res) {
$exp = [System.ComponentModel.Win32Exception]$res
Write-Error -Message "Failed to impersonate user: $($exp.Exception.Message)" -Exception $exp
return
}
try {
&$ScriptBlock
} finally {
$null = [PInvoke.NativeMethods]::RevertToSelf()
}
} finally {
$null = [PInvoke.NativeMethods]::CloseHandle($token)
}
}
Invoke-WithImpersonation -Credential (Get-Credential) -ScriptBlock {
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
}.GetNewClosure()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment