PowerShell的ForEach-Object语句遇错终止,如何让其继续执行后续项?
问题核心原因
在 ForEach-Object 的 -Process 脚本块中,Continue 关键字的作用对象是外层的结构化循环(如for/foreach/while)而非管道迭代,直接使用会终止整个管道执行,不会实现跳过当前项的效果。
同时当前代码还有一个隐藏问题:你在try块内设置的$ErrorActionPreference = "Continue"会让AzureAD相关命令抛出的非终止性错误无法被try/catch捕获,导致错误直接暴露、代码进入终止逻辑。
修复方案
按如下两点调整即可实现需求:
- 将catch块中的
Continue替换为return:ForEach-Object的脚本块中return仅代表结束当前对象的处理逻辑,自动进入下一个对象的迭代,刚好符合跳过异常项的需求 - 将try块开头的错误行为配置改为
$ErrorActionPreference = "Stop",或者给每个AzureAD命令添加-ErrorAction Stop参数,确保所有错误都能被catch块捕获
修正后的代码
$objects | ForEach-Object -Process { try { $ErrorActionPreference = "Stop" $extensionproperty_all = Get-AzureADUserExtension -ObjectID $_.UserPrincipalName $extensionproperty_workemail = $extensionproperty_all.get_item("extension_appID_WorkDay_WorkEmail") Set-AzureADUser -objectid $_.UserPrincipalName -OtherMails $extensionproperty_workemail Write-Output "email updated for $extensionproperty_workemail" } catch { Write-Warning "Error encountered with user: $($_.UserPrincipalName), skip to next entry" # return 直接结束当前项处理,进入下一个对象迭代 return } }
如果要缩小错误行为配置的生效范围,也可以单独给命令加参数,避免全局修改偏好设置:
# 仅单命令启用终止性错误,不需要修改全局$ErrorActionPreference $extensionproperty_all = Get-AzureADUserExtension -ObjectID $_.UserPrincipalName -ErrorAction Stop Set-AzureADUser -objectid $_.UserPrincipalName -OtherMails $extensionproperty_workemail -ErrorAction Stop
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

