Parse output of handle.exe into objects for use with PowerShell

There are times when you need to determine the process that is locking a file.  Using the SysInternals “handle.exe” command line tool, we can search for processes that are using (i.e. locking) a particular file or directory. The code below translates the output of handle.exe into objects that are more friendly for use with PowerShell.


Add-Type -Language CSharp @"
public class Handle{
    public string ProcessName { get;set;}
    public int ProcessId {get;set;}
    public string Type {get;set;}
    public string User {get;set;}
    public string HandleId { get;set;}
    public string Name { get; set;}
    public string AppPoolName {get;set;}
}
"@;

function Get-HandlesAndProcessIds {
    [OutputType([Handle[]])]
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object[]]$HandleInfo)
<# .Description Converts the text output of the SysInternals tool "handle.exe" into an object array .Example $handles = & handle.exe -a  -u -accepteula "MY_LOCKED_ASSEMBLY.dll" $allHandles = Get-HandlesAndProcessIds -HandleInfo $handles $allHandles --------------------------- ProcessName : dllhost.exe ProcessId   : 6960 Type        : File User        : DOMAIN\user HandleId    : B34 Name        : MY_LOCKED_ASSEMBLY.dll AppPoolName :  #>
    $handle = new-object Handle
    foreach ($line in $handles) {
        $line=$Line.trim()
        if($line -like "*pid:*") {
            $result = $line | Select-String –pattern '^([^ ]*)\s*pid: ([0-9]*)\s*type: ([^ ]*)\s*([^ ]*)\s*(.*?): (.*)'

            $handle.ProcessName =  $result.Matches[0].Groups[1].Value
            $handle.ProcessId = [int]::Parse( $result.Matches[0].Groups[2].Value)
            $handle.Type = $result.Matches[0].Groups[3].Value
            $handle.User = $result.Matches[0].Groups[4].Value
            $handle.HandleId =  $result.Matches[0].Groups[5].Value
            $handle.Name = $result.Matches[0].Groups[6].Value

            if($handle.ProcessName -like "w3wp.exe") {
                $process = Get-AppPoolProcesses | where { $_.ProcessId -eq $handle.ProcessId }
                if($process) {
                    $handle.AppPoolName = $Process.AppPoolName
                }
            }

            $handle
        }
    }
}

function Get-AppPoolProcesses {
    Get-WmiObject -NameSpace 'root\WebAdministration' -class 'WorkerProcess' -ComputerName 'LocalHost' |
        select AppPoolName, ProcessId |
            sort -Property AppPoolName
}

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s