You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell脚本Get-ADUser抛ContinueException,Catch块失效且脚本终止求助

问题排查:PowerShell处理AD用户特殊字符时Catch块失效及脚本终止问题

问题描述

在Windows Server 2012上使用PowerShell v5编写脚本,用于替换AD用户属性中的特殊字符。已添加Catch块尝试捕获错误,但无法记录错误详情;脚本顶部已设置$ErrorActionPreference = 'Stop',并将错误输出改为$_.Exception.Message,但日志中仍无错误痕迹。控制台报错显示Get-ADUser抛出System.Management.Automation.ContinueException,当遇到displayName为空的用户时,脚本直接停止,无法处理后续用户。

报错信息

Get-ADUser : System error.
At C:\Users\test\Documents\Skripts\replace_umlaute.ps1:10 char:1
+ Get-ADUser -Filter * -SearchBase $OUpath -properties $paramlist | Sel ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-ADUser], ContinueException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.Management.Automation.ContinueException,Microsoft.ActiveDirectory.Management.Commands.GetADUser

原脚本代码

Get-ADUser -Filter * -SearchBase $OUpath -properties $paramlist | Select-object $paramlist |
foreach{
    try{
    if([bool]$_.sAMAccountName -And $_.displayName -match "[üäßöÜÄÖ]"){
       $aux = [regex]::Replace($_.displayName,'[äöü](?:(?=ß)|\p{L})?',{ 
        param($m) 
        ([string] $m.Value[0]).Normalize('FormD')[0] +
          $(if ([char]::IsUpper($(if ($m.Value[1]) { $m.Value[1] } 
          else { $m.Value[0] }))) { 'E' } 
          else { 'e' }) + $m.Value[1]
        },'IgnoreCase'
    )  
            $dnp = $aux -creplace '(?<=\p{Ll})ß','ss' -creplace '(?<=\p{Lu})ß','SS'
                  

            if(!($_.displayNamePrintable -ceq $dnp))
            {
                $dp = $_.displayName
                try{
                Set-ADUser -Identity $_.sAMAccountName -Replace @{displayNamePrintable=$dnp}
                
                "`r$(Get-Date -Format "dd.MM.yyyy - HH':'mm':'ss") [$dp] displayNamePrintable of User $($_.cn) updated to $dnp`r" | out-file $log -Append -Encoding UTF8                
                
                }catch{
                "`r" | out-file $log -Append -Encoding UTF8
                $_.Exception.Message | out-file $log -Append -Encoding UTF8
                "`r" | out-file $log -Append -Encoding UTF8
                continue
                       }
            }
         
      }else{
        continue
        }
        }catch{
           "`r" | out-file $log -Append -Encoding UTF8
           $_.Exception.Message | out-file $log -Append -Encoding UTF8
           "`r" | out-file $log -Append -Encoding UTF8
        }
}

问题原因分析

  1. 错误发生在管道起始阶段,未被当前Catch块捕获:现有脚本的try/catch仅包裹了foreach内部逻辑,但ContinueException是Get-ADUser执行时抛出的,此时尚未进入foreach循环,后续Catch块无法捕获该错误。
  2. 空值触发正则匹配异常:当displayName为空时,执行$_.displayName -match "[üäßöÜÄÖ]"会触发异常;由于$ErrorActionPreference = 'Stop',该异常被升级为终止错误,直接导致管道终止,脚本停止运行。

修复方案

1. 给Get-ADUser添加错误捕获

将Get-ADUser单独处理,使用-ErrorAction SilentlyContinue和-ErrorVariable捕获阶段错误,避免管道终止:

# 获取AD用户并捕获阶段错误
$adUsers = Get-ADUser -Filter * -SearchBase $OUpath -properties $paramlist -ErrorAction SilentlyContinue -ErrorVariable adErrors

# 记录Get-ADUser的错误
if ($adErrors) {
    foreach ($err in $adErrors) {
        "`r$(Get-Date -Format "dd.MM.yyyy - HH':'mm':'ss") Get-ADUser错误: $($err.Exception.Message)`r" | Out-File $log -Append -Encoding UTF8
    }
}

# 继续处理正常获取到的用户
$adUsers | Select-object $paramlist | ForEach-Object {
    # 原有foreach逻辑
}

2. 提前判断displayName非空

在正则匹配前,先检查displayName是否存在且非空,避免触发空值异常:

if([bool]$_.sAMAccountName -And $_.displayName -and $_.displayName -match "[üäßöÜÄÖ]"){
    # 原有替换逻辑
}

3. 优化错误日志记录

将日志内容补充时间戳和用户标识,便于定位问题:

# 替换原有Catch块中的日志代码
"`r$(Get-Date -Format "dd.MM.yyyy - HH':'mm':'ss") 处理用户$($_.cn)错误: $($_.Exception.Message)`r" | Out-File $log -Append -Encoding UTF8

修复后的完整脚本示例

$ErrorActionPreference = 'Stop'
$log = "C:\path\to\your\logfile.log"
$OUpath = "OU=Users,DC=domain,DC=com"
$paramlist = @("sAMAccountName", "displayName", "displayNamePrintable", "cn")

# 获取AD用户并捕获阶段错误
$adUsers = Get-ADUser -Filter * -SearchBase $OUpath -properties $paramlist -ErrorAction SilentlyContinue -ErrorVariable adErrors

# 记录Get-ADUser的错误
if ($adErrors) {
    foreach ($err in $adErrors) {
        "`r$(Get-Date -Format "dd.MM.yyyy - HH':'mm':'ss") Get-ADUser错误: $($err.Exception.Message)`r" | Out-File $log -Append -Encoding UTF8
    }
}

$adUsers | Select-object $paramlist | ForEach-Object {
    try {
        # 提前判断displayName非空再执行匹配
        if([bool]$_.sAMAccountName -And $_.displayName -and $_.displayName -match "[üäßöÜÄÖ]"){
            $aux = [regex]::Replace($_.displayName,'[äöü](?:(?=ß)|\p{L})?',{ 
                param($m) 
                ([string] $m.Value[0]).Normalize('FormD')[0] +
                $(if ([char]::IsUpper($(if ($m.Value[1]) { $m.Value[1] } 
                else { $m.Value[0] }))) { 'E' } 
                else { 'e' }) + $m.Value[1]
            },'IgnoreCase'
            )  
            $dnp = $aux -creplace '(?<=\p{Ll})ß','ss' -creplace '(?<=\p{Lu})ß','SS'

            if(!($_.displayNamePrintable -ceq $dnp))
            {
                $dp = $_.displayName
                try{
                    Set-ADUser -Identity $_.sAMAccountName -Replace @{displayNamePrintable=$dnp}
                    "`r$(Get-Date -Format "dd.MM.yyyy - HH':'mm':'ss") [$dp] displayNamePrintable of User $($_.cn) updated to $dnp`r" | Out-File $log -Append -Encoding UTF8                
                }catch{
                    "`r$(Get-Date -Format "dd.MM.yyyy - HH':'mm':'ss") 更新用户$($_.cn)错误: $($_.Exception.Message)`r" | Out-File $log -Append -Encoding UTF8
                    continue
                }
            }
        }
    }catch{
        "`r$(Get-Date -Format "dd.MM.yyyy - HH':'mm':'ss") 处理用户$($_.cn)错误: $($_.Exception.Message)`r" | Out-File $log -Append -Encoding UTF8
    }
}

内容的提问来源于stack exchange,提问作者Zombievirus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 21:15:44