这个问题已经有了很好的答案,但我有另一种基于 Get-Process(和其他几个 cmdlet)的方法:
Get-Process 'exce[l]'
将完全按照您的要求进行。
怪癖解释
Get-Process
cmdlet 和许多其他 cmdlet 以不同方式处理带有通配符的名称。尽管:
Get-Process 'NonExistentProc'
将产生错误,使用:
Get-Process 'NonExistentProc*'
在末尾添加通配符“*”,不会产生错误。您可能会猜到在这种情况下会返回一个空数组。这对我来说最有意义,但是当没有找到匹配项时,返回 $null。
对于您的情况,如果您使用:
get-process 'excel*'
如果 excel 没有运行,您不会收到错误,但您将匹配“excelHelper”和任何以“excel”开头的进程名称,这可能是一个问题。您可以通过使用非常窄的通配符模式来解决此问题:
get-process 'exce[l]'
括号通配符将匹配括号中的任何一个字符。通常给出一个集合或范围,但这里我们使用单个字符的退化大小写。只会匹配 'excel',但因为使用了通配符,所以找不到匹配项不会产生错误。
如果您想将其推广到任何给定的进程名称,您可以计算模式:
$procName = 'excel'
Get-Process "$($procName.Substring(0, $procName.length-1))[$($procName[-1])]"
(好吧,这很丑陋,但它有效,如果你愿意,你可以把它拆开。)
一些替代品。
@埃弗兰的:
$excel = Get-Process excel -ErrorAction SilentlyContinue
很好(我赞成),但是在 $error 中添加了一个错误。在一些较大的系统中,我看到了稍后检查或处理 $error 的脚本,因此我通常更喜欢使用-ErrorAction Ignore
:
$excel = Get-Process excel -ErrorAction Ignore
文档说:
与 SilentlyContinue 不同,Ignore 不会将错误消息添加到 $Error 自动变量。
但也要记住:
Ignore 值是在 Windows PowerShell 3.0 中引入的。
但这变得越来越不重要了。
@Peter 的答案简单且逻辑正确(忽略可能的竞争条件,见下文)。我投了赞成票。虽然在这种情况下没有真正的性能问题(我刚刚测试并且在我的机器上运行了 200 个进程,但他的代码仍然立即运行),但它让我感到烦恼的是,我正在创建 199 个不需要的进程对象。
真正的潜在问题是使用更大的 PID 集(允许我查看的所有进程的 PID)发生冲突的可能性更大,其中捕获的 PID 之一是用于终止的进程并且 PID 被重用时目标进程启动。在那个不太可能(因为时间窗口太小)但可能发生的事件中,目标进程将被排除在外(因为它的 PID 将在 $before 列表中)并且看起来没有进程启动。
这是一个非常小的窗口,可能不用担心,但是您可以跟踪进程的 StartTime 属性以及 ID 以使发生冲突的机会变得非常小。您可以消除 PID 重用的可能性,[System.Diagnostics.Process]::GetProcessById
用于打开进程(返回包含系统句柄的 Process 对象),但这可能不值得(但如果这样做,请务必通过调用 Process 对象的 Close 方法关闭句柄)。