i have listed all the processes with handle.exe that access one directory.
function Get-FileHandle ($HPath){
$handles = handle $HPath
}
the output seems like:
Nthandle v4.11 - Handle viewer Copyright (C) 1997-2017 Mark Russinovich Sysinternals - www.sysinternals.com
jabra-direct.exe pid: 12716 type: File 838: C:\Windows\System32\drivers\etc
Creative Cloud.exe pid: 4280 type: File 9D0: C:\Windows\System32\drivers\etc
Adobe CEF Helper.exe pid: 12916 type: File 494: C:\Windows\System32\drivers\etc
brave.exe pid: 2920 type: File 690: C:\Windows\System32\drivers\etc
brave.exe pid: 13828 type: File 344: C:\Windows\System32\drivers\etc
Now I am trying to list only the processnames without all the other values. tha code i have, is:
foreach ($handle in $gethandle) {
$handle.Split(" ") | ?{$_ -like "*exe"}
}
The output is:
jabra-direct.exe
Cloud.exe
Helper.exe
brave.exe
brave.exe
everything fine untill the processname contains a space. It should be creative cloud.exe and not cloud.exe.
How can i make it work ? sothat creative cloud.exe will be shown and not only cloud.exe ?
CodePudding user response:
Here is a way using the Select-String
cmdlet.
$handles = handle $HPath # assuming handle.exe can be found via PATH env var
$selected = $handles | Select-String -Pattern '.*?(?= pid:)'
$processNames = $selected.Matches.Value # array of process names
The Select-String
line extracts the process names from the output using a regular expression:
.*?
- everything up to the following pattern (as little as possible to trim trailing whitespace)(?=
- starts a positive lookahead patternpid:
- literal "pid:"
)
- ends the positive lookahead pattern
The positive lookahead makes sure that we only find sub strings followed by " pid:"
, without including " pid:"
in the result.
The expression $selected.Matches.Value
is a shortcut for:
$processNames = @()
foreach( $sel in $selected ) {
foreach( $match in $sel.Matches ) {
$processNames = $match.Value
}
}
When PowerShell can't find a property on an object that is an array, it automatically searches each array member for that property and returns an array of all values that is has found. This is called member enumeration.
CodePudding user response:
Try the following code and adapt if necessary.
Regex is (.*)(?=pid:)pid:\s(\d )\stype:\s([^\d] )\s([\dABCDEF] ):\s(.*)
that combine a positive lookahead and capturing groups. Then just use the auto property $Matches
to extract capturing group values.
$output = @"
Nthandle v4.11 - Handle viewer Copyright (C) 1997-2017 Mark Russinovich Sysinternals - www.sysinternals.com
jabra-direct.exe pid: 12716 type: File 838: C:\Windows\System32\drivers\etc
Creative Cloud.exe pid: 4280 type: File 9D0: C:\Windows\System32\drivers\etc
Adobe CEF Helper.exe pid: 12916 type: File 494: C:\Windows\System32\drivers\etc
brave.exe pid: 2920 type: File 690: C:\Windows\System32\drivers\etc
brave.exe pid: 13828 type: File 344: C:\Windows\System32\drivers\etc
"@
$output = $output.Split("`r`n")
$output | ForEach-Object {
if ($_ -match "(.*)(?=pid:)pid:\s(\d )\stype:\s([^\d] )\s([\dABCDEF] ):\s(.*)") {
$props = [ordered]@{
Name = $Matches[1]
PID = $Matches[2]
Type = $Matches[3]
Handle = $Matches[4]
Path = $Matches[5]
}
New-Object -TypeName PSObject -Property $props
}
} | Format-Table -AutoSize