Skip to content

Instantly share code, notes, and snippets.

@PanosGreg
Last active February 12, 2022 21:01
Show Gist options
  • Save PanosGreg/98928611106c26b54478e00329ed1c25 to your computer and use it in GitHub Desktop.
Save PanosGreg/98928611106c26b54478e00329ed1c25 to your computer and use it in GitHub Desktop.
function Get-ProcessHandle {
<#
.SYNOPSIS
Get all the currently open handles of a process
NOTE: requires the handle.exe tool from Sysinternals
.EXAMPLE
Get-ProcessHandle -PID 12000 -IncludeMode
#>
[cmdletbinding()]
[OutputType('Sysinternals.Thread.Handle')] # <-- just a custom psobject type
param(
[Parameter(Mandatory=$true)]
[int]$Id,
[switch]$IncludeMode # <-- requires admin rights to work
)
try {handle.exe -? *>$null} catch {throw 'Handle.exe was not found'}
if ($IncludeMode.IsPresent) {
$CurrentId = [Security.Principal.WindowsIdentity]::GetCurrent()
$AdminRole = [Security.Principal.WindowsBuiltinRole]::Administrator
$IsAdmin = [Security.Principal.WindowsPrincipal]::new($CurrentId).IsInRole($AdminRole)
if (-not $IsAdmin) {Write-Warning 'IncludeMode requires Admin privileges to work';return}
}
# NOTE: unfortunately can't use #requires -RunAsAdministrator cause it applies globally anyhow
try {$proc = Get-Process -Id $Id -ErrorAction Stop}
catch {Write-Warning "Could not get process with ID $Id"; throw $_}
$rgx = '^\s*([0-9A-F]+):\s(\w+)\s+(\([RWD-]+\))?\s*(.+)$'
if ($IncludeMode.IsPresent) {$cmd = "handle.exe -p $Id -u -nobanner"}
else {$cmd = "handle.exe -p $Id -nobanner"}
Invoke-Expression $cmd | foreach {
$find = [regex]::Match($_,$rgx)
if ($find.Success) {
if ($IncludeMode.IsPresent) {
$Mode = $find.Groups[3].Value
$Mode = [char[]]$Mode | foreach {
switch ($_) {
'R' {'Read'}
'W' {'Write'}
'D' {'Delete'}
} #switch
} #foreach
} #if mode
else {$Mode = 'N/A'}
$obj = [PSCustomObject] @{
PSTypeName = 'Sysinternals.Thread.Handle'
Name = $proc.Name
ProcessID = $proc.Id
HandleID = $find.Groups[1].Value
HandleType = $find.Groups[2].Value
HandlePath = $find.Groups[4].Value
Mode = $Mode
} #psobject
$Def = 'ProcessID','HandleID','HandleType','HandlePath'
$Class = [Management.Automation.PSPropertySet]
$DDPS = $Class::new('DefaultDisplayPropertySet',[string[]]$Def)
$Std = [Management.Automation.PSMemberInfo[]]@($DDPS)
$obj | Add-Member MemberSet PSStandardMembers $std -PassThru # <-- this is the output
} #if find
} #foreach handle
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment