"Break" 导致 PowerShell 脚本失败
"Break" causes a PowerShell script to fail
(GSV).Name|%{If($_ -like "*net*"){ $_ ; Break }};Pause
当我 运行 来自 PowerShell window 的上述行时,将输出“Netlogon”。
当我运行一个包含相同行的PS1文件时,会出现一个PowerShell window,然后立即消失,没有任何输出。
那条线有什么问题?
来自 the about_Break
help topic:
Do not use break outside of a loop, switch
, or trap
When break
is used outside of a construct that directly supports it
(loops, switch
, trap
), PowerShell looks up the call stack for an
enclosing construct. If it can't find an enclosing construct, the
current runspace is quietly terminated.
This means that functions and scripts that inadvertently use a break
outside of an enclosing construct that supports it can inadvertently
terminate their callers.
Using break inside a pipeline break, such as a ForEach-Object
script block, not only exits the pipeline, it potentially terminates
the entire runspace.
重写您的脚本以使用 Where-Object
过滤输入,然后在对象与过滤器匹配时使用 Select-Object -First 1
终止管道:
(GSV).Name |Where-Object { $_ -like "*net*" } |Select-Object -First 1; Pause
在这种特殊情况下,您还可以使用 Get-Service
的过滤功能将初始查询范围缩小到仅匹配服务,从而避免对 Where-Object
的需要:
Get-Service -Name *net* |Select -ExpandProperty Name -First 1
(GSV).Name|%{If($_ -like "*net*"){ $_ ; Break }};Pause
当我 运行 来自 PowerShell window 的上述行时,将输出“Netlogon”。
当我运行一个包含相同行的PS1文件时,会出现一个PowerShell window,然后立即消失,没有任何输出。
那条线有什么问题?
来自 the about_Break
help topic:
Do not use break outside of a loop,
switch
, ortrap
When
break
is used outside of a construct that directly supports it (loops,switch
,trap
), PowerShell looks up the call stack for an enclosing construct. If it can't find an enclosing construct, the current runspace is quietly terminated.This means that functions and scripts that inadvertently use a break outside of an enclosing construct that supports it can inadvertently terminate their callers.
Using break inside a pipeline break, such as a
ForEach-Object
script block, not only exits the pipeline, it potentially terminates the entire runspace.
重写您的脚本以使用 Where-Object
过滤输入,然后在对象与过滤器匹配时使用 Select-Object -First 1
终止管道:
(GSV).Name |Where-Object { $_ -like "*net*" } |Select-Object -First 1; Pause
在这种特殊情况下,您还可以使用 Get-Service
的过滤功能将初始查询范围缩小到仅匹配服务,从而避免对 Where-Object
的需要:
Get-Service -Name *net* |Select -ExpandProperty Name -First 1