advapi32/DuplicateToken.ps1

function DuplicateToken
{
    <#
    .SYNOPSIS
 
    The DuplicateToken function creates a new access token that duplicates one already in existence.
 
    .DESCRIPTION
 
    The DuplicateToken function creates an impersonation token, which you can use in functions such as SetThreadToken and ImpersonateLoggedOnUser. The token created by DuplicateToken cannot be used in the CreateProcessAsUser function, which requires a primary token. To create a token that you can pass to CreateProcessAsUser, use the DuplicateTokenEx function.
 
    .PARAMETER TokenHandle
 
    A handle to an access token opened with TOKEN_DUPLICATE access.
 
    .NOTES
     
    Author: Jared Atkinson (@jaredcatkinson)
    License: BSD 3-Clause
    Required Dependencies: SECURITY_IMPERSONATION_LEVEL (Enum)
    Optional Dependencies: None
 
    (func advapi32 DuplicateToken ([bool]) @(
        [IntPtr] #_In_ HANDLE ExistingTokenHandle,
        [UInt32] #_In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
        [IntPtr].MakeByRefType() #_Out_ PHANDLE DuplicateTokenHandle
    ) -EntryPoint DuplicateToken -SetLastError)
 
    .LINK
 
    https://msdn.microsoft.com/en-us/library/windows/desktop/aa446616(v=vs.85).aspx
 
    .EXAMPLE
 
    #>


    param
    (
        [Parameter(Mandatory = $true)]
        [IntPtr]
        $TokenHandle
    )

    $DuplicateTokenHandle = [IntPtr]::Zero

    $success = $Advapi32::DuplicateToken($TokenHandle, $SECURITY_IMPERSONATION_LEVEL::SecurityImpersonation, [ref]$DuplicateTokenHandle); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
    
    if(-not $success)
    {
        Write-Debug "DuplicateToken Error: $(([ComponentModel.Win32Exception] $LastError).Message)"
    }

    Write-Output $DuplicateTokenHandle
}