'Trapping a PowerShell Statement from Win32_Process into a Variable for Taskkill Command
This powershell statement looks for a long commandline string from a process java.exe - it uses the string server1 to trap this specific process. It returns the words Processid and Commandline with its relative values.
gwmi win32_process | select Processid,Commandline | where-object CommandLine -match "server1"
returns this line where 15112 is all I need:
Processid Commandline
--------- -----------
15112 D:\ ..a long command string.
How would you trap the single PID number returned from the above PS statement in a variable to run a taskkill /pid $PIDNUM on ? Not sure how to extract that single number from the statement.
Solution 1:[1]
Very simple, we store the entire result into the variable $PIDNUM, and we can access the result object's properties using dot-notation
$PIDNUM = (gwmi win32_process | select Processid,Commandline | where-object CommandLine -match "server1").ProcessID
taskkill /pid $PIDNUM
or
$PIDNUM = gwmi win32_process | select Processid,Commandline | where-object CommandLine -match "server1"
taskkill /pid $PIDNUM.ProcessID
If your first statement finds multiple tasks, you'll need to run a loop to execute the taskkill for each object stored in the $PIDNUM variable
foreach ($num in $PIDNUM)
{
taskkill /pid $num.processid
}
Solution 2:[2]
First, the obligatory pointer:
- The CIM cmdlets (e.g.,
Get-CimInstance) superseded the WMI cmdlets (e.g.,Get-WmiObject, whose built-in alias isgwmi) in PowerShell v3 (released in September 2012). Therefore, the WMI cmdlets should be avoided, not least because PowerShell (Core) v6+, where all future effort will go, doesn't even have them anymore. Note that WMI still underlies the CIM cmdlets, however. For more information, see this answer.
$pidOfInterest =
(
Get-CimInstance win32_process |
Where-Object CommandLine -match server1
).ProcessId
Note:
$pidOfInterestmay receive multiple PIDs (process IDs), given that multiple processes may match yourWhere-Objectfilter; that accessing.ProcessIddirectly on a potential array of values still works to extract its elements' property values is courtesy of PowerShell's member-access enumeration feature.If
$pidOfInterestdoes end up containing multiple PIDs, you can pass them totaskkill.exeas follows:taskkill $pidOfInterest.ForEach({ '/pid', $_ })With
Stop-Process(see below), it is simpler, because its-Idparameter accepts an array of PIDs:Stop-Process -Id $pidOfInterest
The
select Processid,Commandlinepart of your command just creates unnecessary overhead, so it was omitted above - theGet-CimInstanceoutput objects can be filtered directly.You don't strictly need
taskkill.exefor terminating processes, given that PowerShell has aStop-Processcmdlet.However, an important difference is that
taskkill.exeattempts graceful, cooperative termination by default, whereasStop-Process(as of PowerShell 7.2.3) invariably terminates forcefully - which is whattaskkill.exeoffers as an opt-int with/f- Improving
Stop-Processin the future to support graceful, cooperative termination too is the subject of GitHub issue #13664.
- Improving
Attempting graceful termination means that termination may not be effective, however.
See this answer for more information.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
