PowerShell中Get-WmiObject针对PSCustomObject的错误处理问题
PowerShell脚本异常处理问题排查与修复
问题背景
脚本核心需求:
- 将最终输出保存至TXT文件,无法获取的信息留空
- 从CSV文件读取PC名称与用户ID,适配用户无对应PC或工作站未开机的场景
- 目前Get-ADUser相关逻辑正常,但Get-WmiObject的try-catch未生效,异常时无法将对应信息留空
用户提供的原始脚本
$userName1 = "UserX" $Computernames = Import-CSV 'C:\PCnames.csv' -Delimiter ';' $pcName = $Computernames.Where({ $_."User ID" -match $userName1})."PC Name" $aProperties = @( 'Name' 'mail' 'OfficePhone' 'Description' 'PasswordLastSet' 'LastBadPasswordAttempt' 'LockedOut' 'Enabled' 'msDS-UserPasswordExpiryTimeComputed' ) $aUser = Get-Aduser -Identity $userName1 -Properties $aProperties $aUser $IP = try {Get-WmiObject Win32_NetworkAdapterConfiguration -Computername $pcName -ea stop | Where { $_.IPAddress } | Select -Expand IPAddress | Where { $_ -like '10.33*' -or $_ -like '10.44*'} } catch {""} $Model = try { (Get-WmiObject -Class Win32_ComputerSystem -ComputerName $pcName -ea stop ).Model} catch {""} $OS =try { Get-WmiObject win32_operatingsystem -Computername $pcName -ea stop | select csname, @{LABEL='LastBootUpTime';EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}} catch{""} [pscustomobject]@{ UserID = $aUser.Name Mail = $aUser.mail Phone = $aUser.OfficePhone Hostname = $pcName LockedStatus = $aUser.LockedOut AccountEnabled = $aUser.Enabled LastBadPasswordAttempt = $aUser.LastBadPasswordAttempt OSVersion = $OSVersion.Version OSName = $OSVersion.Name IPAddress = $IP Model = $Model }
问题分析与修复方案
1. 先处理$pcName为空的场景
当CSV中没有对应用户的PC记录时,$pcName会为空,此时WMI调用会抛出非终止错误(即使加了-ea stop),需要提前判断并初始化变量:
# 初始化所有WMI相关变量为空 $IP = "" $Model = "" $OSInfo = [pscustomobject]@{Version=""; Name=""; LastBootUpTime=""} if (-not [string]::IsNullOrEmpty($pcName)) { # 仅当PC名称存在时才执行远程查询 # ...后续WMI/CIM逻辑... }
2. 修复try-catch生效问题
Get-WmiObject的部分错误属于非终止错误,需确保-ErrorAction Stop正确传递;同时修正原始脚本中OSVersion未定义的变量引用错误,需调整WMI查询逻辑获取完整OS信息。
3. 替换为Get-CimInstance(推荐)
Get-WmiObject已被弃用,Get-CimInstance的异常处理更一致,且支持现代PowerShell特性,能更稳定捕获远程连接失败等异常。
4. 输出到TXT文件
将最终构建的自定义对象导出到TXT,可使用Out-File保证格式可读性:
$result | Out-File -Path "C:\UserInfo.txt" -Encoding UTF8
修改后的完整脚本
$userName1 = "UserX" $Computernames = Import-CSV 'C:\PCnames.csv' -Delimiter ';' $pcName = $Computernames.Where({ $_."User ID" -match $userName1})."PC Name" # 获取AD用户信息 $aProperties = @( 'Name','mail','OfficePhone','Description','PasswordLastSet', 'LastBadPasswordAttempt','LockedOut','Enabled','msDS-UserPasswordExpiryTimeComputed' ) $aUser = Get-Aduser -Identity $userName1 -Properties $aProperties # 初始化WMI相关变量为空 $IP = "" $Model = "" $OSInfo = [pscustomobject]@{ Version = "" Name = "" LastBootUpTime = "" } # 仅当PC名称有效时执行远程查询 if (-not [string]::IsNullOrEmpty($pcName)) { # 获取IP地址 $IP = try { Get-CimInstance Win32_NetworkAdapterConfiguration -ComputerName $pcName -ErrorAction Stop | Where-Object { $_.IPAddress } | Select-Object -ExpandProperty IPAddress | Where-Object { $_ -like '10.33*' -or $_ -like '10.44*' } } catch { "" } # 获取设备型号 $Model = try { (Get-CimInstance Win32_ComputerSystem -ComputerName $pcName -ErrorAction Stop).Model } catch { "" } # 获取OS信息 $OSInfo = try { $os = Get-CimInstance Win32_OperatingSystem -ComputerName $pcName -ErrorAction Stop [pscustomobject]@{ Version = $os.Version Name = $os.Name.Split("|")[0].Trim() LastBootUpTime = $os.LastBootUpTime } } catch { [pscustomobject]@{Version=""; Name=""; LastBootUpTime=""} } } # 构建结果对象 $result = [pscustomobject]@{ UserID = $aUser.Name Mail = $aUser.mail Phone = $aUser.OfficePhone Hostname = $pcName ?? "" LockedStatus = $aUser.LockedOut AccountEnabled = $aUser.Enabled LastBadPasswordAttempt = $aUser.LastBadPasswordAttempt OSVersion = $OSInfo.Version OSName = $OSInfo.Name LastBootUpTime = $OSInfo.LastBootUpTime IPAddress = $IP -join ", " # 多个IP用逗号分隔 Model = $Model } # 输出到TXT文件 $result | Out-File -Path "C:\UserInfo.txt" -Encoding UTF8 # 可选:输出为CSV便于后续处理 # $result | Export-Csv -Path "C:\UserInfo.csv" -Delimiter ";" -NoTypeInformation -Encoding UTF8
内容的提问来源于stack exchange,提问作者Toon
相关产品推荐
相关产品推荐

