尝试通过 PowerShell 脚本查找并终止进程
Trying to find and kill a process by PowerShell script
我有以下脚本来查找进程 "dotnet.exe"。在我的系统中,我有很多 dotnet.exe 个进程 运行。但我想杀死具有命令行参数 "MyService\Web\argument" 的 "dotnet.exe"。我正在尝试通过以下脚本来做到这一点。但是它没有找到任何东西,尽管我在任务管理器中看到了进程。
$process = Get-WmiObject Win32_Process | select name, commandline
foreach ($p in $process)
{
if ($p.name -contains "dotnet.exe" -and $p.commandline -contains "web")
{
$kp = Get-Process $p;
$kp.CloseMainWindow();
if (!$kp.HasExited)
{
$kp | Stop-Process -Force
}
}
else
{
Write-Host name: $p.name and param: $p.commandline;
}
}
Get-WmiObject
cmdlet returns 非常有用的对象,但您通过仅选择 Name 和 CommandLine[ 剥离了所有内容=27=] 参数:
$process = Get-WmiObject Win32_Process | select name, commandline
如果删除 | select name, commandline
部分,您仍然可以遍历每个过程,但也可以使用像 Terminate()
这样仍然可用的方法。
根据@ansgar-wiechers 的评论,您可以一次完成,或者仍然使用循环并添加更多日志记录等。如果您愿意:
$process = Get-WmiObject Win32_Process
foreach($p in $process){
if($p.Name -eq "*dotnet.exe" -and $p.CommandLine -like "*web*"){
$p.Terminate()
# and so on...
}
}
另请注意@TheIncorrigible1 关于使用比较运算符的评论。我使用 -eq
作为进程名称,使用 -like
作为命令行。
你需要做的就是直接通过Get-WmiObject
过滤进程列表,然后终止匹配进程:
$fltr = "name like '%dotnet.exe%' and commandline like '%web%'"
Get-WmiObject Win32_Process -Filter $fltr | ForEach-Object {
$_.Terminate()
}
您也可以直接在 Get-WmiObject
的输出上调用 Terminate()
,如下所示:
(Get-WmiObject Win32_Process -Filter $fltr).Terminate()
但是,在某些情况下这可能会失败,例如如果 Get-WmiObject
没有 return 任何结果,或者如果您使用的是 PowerShell v2 或更早版本并且 Get-WmiObject
return 有多个结果(将方法调用传递给数组的成员需要成员枚举,这是在 PowerShell v3 中引入的)。使用 ForEach-Object
循环既更健壮又向后兼容。
我有以下脚本来查找进程 "dotnet.exe"。在我的系统中,我有很多 dotnet.exe 个进程 运行。但我想杀死具有命令行参数 "MyService\Web\argument" 的 "dotnet.exe"。我正在尝试通过以下脚本来做到这一点。但是它没有找到任何东西,尽管我在任务管理器中看到了进程。
$process = Get-WmiObject Win32_Process | select name, commandline
foreach ($p in $process)
{
if ($p.name -contains "dotnet.exe" -and $p.commandline -contains "web")
{
$kp = Get-Process $p;
$kp.CloseMainWindow();
if (!$kp.HasExited)
{
$kp | Stop-Process -Force
}
}
else
{
Write-Host name: $p.name and param: $p.commandline;
}
}
Get-WmiObject
cmdlet returns 非常有用的对象,但您通过仅选择 Name 和 CommandLine[ 剥离了所有内容=27=] 参数:
$process = Get-WmiObject Win32_Process | select name, commandline
如果删除 | select name, commandline
部分,您仍然可以遍历每个过程,但也可以使用像 Terminate()
这样仍然可用的方法。
根据@ansgar-wiechers 的评论,您可以一次完成,或者仍然使用循环并添加更多日志记录等。如果您愿意:
$process = Get-WmiObject Win32_Process
foreach($p in $process){
if($p.Name -eq "*dotnet.exe" -and $p.CommandLine -like "*web*"){
$p.Terminate()
# and so on...
}
}
另请注意@TheIncorrigible1 关于使用比较运算符的评论。我使用 -eq
作为进程名称,使用 -like
作为命令行。
你需要做的就是直接通过Get-WmiObject
过滤进程列表,然后终止匹配进程:
$fltr = "name like '%dotnet.exe%' and commandline like '%web%'"
Get-WmiObject Win32_Process -Filter $fltr | ForEach-Object {
$_.Terminate()
}
您也可以直接在 Get-WmiObject
的输出上调用 Terminate()
,如下所示:
(Get-WmiObject Win32_Process -Filter $fltr).Terminate()
但是,在某些情况下这可能会失败,例如如果 Get-WmiObject
没有 return 任何结果,或者如果您使用的是 PowerShell v2 或更早版本并且 Get-WmiObject
return 有多个结果(将方法调用传递给数组的成员需要成员枚举,这是在 PowerShell v3 中引入的)。使用 ForEach-Object
循环既更健壮又向后兼容。