Get-PrimaryToken.ps1
#Get the primary token for the specified processId function Get-PrimaryToken { param ( [Parameter(Position=0, Mandatory=$true)] [UInt32] $ProcessId, #Open the token with all privileges. Requires SYSTEM because some of the privileges are restricted to SYSTEM. [Parameter()] [Switch] $FullPrivs ) if ($FullPrivs) { $TokenPrivs = $Win32Constants.TOKEN_ALL_ACCESS } else { $TokenPrivs = $Win32Constants.TOKEN_ASSIGN_PRIMARY -bor $Win32Constants.TOKEN_DUPLICATE -bor $Win32Constants.TOKEN_IMPERSONATE -bor $Win32Constants.TOKEN_QUERY } $ReturnStruct = New-Object PSObject $hProcess = $OpenProcess.Invoke($Win32Constants.PROCESS_QUERY_INFORMATION, $true, [UInt32]$ProcessId) $ReturnStruct | Add-Member -MemberType NoteProperty -Name hProcess -Value $hProcess if ($hProcess -eq [IntPtr]::Zero) { #If a process is a protected process it cannot be enumerated. This call should only fail for protected processes. $ErrorCode = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() Write-Verbose "Failed to open process handle for ProcessId: $ProcessId. ProcessName $((Get-Process -Id $ProcessId).Name). Error code: $ErrorCode . This is likely because this is a protected process." return $null } else { [IntPtr]$hProcToken = [IntPtr]::Zero $Success = $OpenProcessToken.Invoke($hProcess, $TokenPrivs, [Ref]$hProcToken) #Close the handle to hProcess (the process handle) if (-not $CloseHandle.Invoke($hProcess)) { $ErrorCode = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() Write-Warning "Failed to close process handle, this is unexpected. ErrorCode: $ErrorCode" } $hProcess = [IntPtr]::Zero if ($Success -eq $false -or $hProcToken -eq [IntPtr]::Zero) { $ErrorCode = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() Write-Warning "Failed to get processes primary token. ProcessId: $ProcessId. ProcessName $((Get-Process -Id $ProcessId).Name). Error: $ErrorCode" return $null } else { $ReturnStruct | Add-Member -MemberType NoteProperty -Name hProcToken -Value $hProcToken } } return $ReturnStruct } |