PowerShell脚本中$recoveryPartitionNumber变量为Null的问题排查
问题诊断与修复方案
核心问题根源
- 硬编码位置提取的脆弱性:原脚本用
$rePath.substring(72,1)固定字符位置提取分区号,而reagentc /info的输出格式会因系统语言、分区数量变化而改变,一旦格式变动就会提取失败返回Null。 - 多分区场景匹配失效:当机器存在多个恢复分区时,原正则
"Windows RE.+partition\d+"会返回多行结果,直接调用substring会因无法处理数组而报错或返回Null。 - 变量拼写错误:日志和条件判断中多处使用
$recoveryParititonNumber(少写了一个t),与定义的$recoveryPartitionNumber不匹配,导致日志显示Null,后续逻辑判断也会出错。
分步修复方案
1. 修正变量拼写错误
将所有写错的$recoveryParititonNumber替换为$recoveryPartitionNumber,覆盖日志输出、条件判断等所有引用位置。
2. 改用正则捕获组提取分区号(适配多场景)
替换原分区号提取逻辑,用正则捕获组精准匹配活动恢复分区的编号,彻底摆脱硬编码的限制:
# 获取并存储活动恢复分区详情 $reInfo = reagentc /info $recoveryPartitionNumber = $null # 精准匹配当前活动的Windows RE分区行,提取分区号 if ($reInfo -match "Windows RE location:.+partition (\d+)") { $recoveryPartitionNumber = $matches[1] } # 只有分区号存在时才查询分区信息 $recoveryPartition = if ($recoveryPartitionNumber) { Get-Partition | Where-Object PartitionNumber -eq $recoveryPartitionNumber } else { $null }
3. 适配多恢复分区场景
当机器存在多个恢复分区时,reagentc /info会显示多个镜像位置,但Windows RE location:行指向的是当前活动的分区,上面的正则已经针对性提取该行的分区号,确保拿到的是实际在用的恢复分区。
4. 增强前置错误判断
在脚本中提前判断分区号是否为空,避免后续执行无效操作:
if (-not $recoveryPartitionNumber) { Log-Message "ERROR: 无法识别活动恢复分区,或Windows RE未启用" return }
修正后的关键代码片段
# 获取并存储活动恢复分区详情 $reInfo = reagentc /info $recoveryPartitionNumber = $null if ($reInfo -match "Windows RE location:.+partition (\d+)") { $recoveryPartitionNumber = $matches[1] } $recoveryPartition = if ($recoveryPartitionNumber) { Get-Partition | Where-Object PartitionNumber -eq $recoveryPartitionNumber } else { $null } # 获取并存储主分区详情(修正-contains为-eq,DriveLetter是单个字符串) $primaryPartition = Get-Partition | Where-Object DriveLetter -eq "C" # 用空值运算符避免空引用报错 $primaryPartitionNumber = $primaryPartition?.PartitionNumber # 修正变量名后的日志输出 Log-Message "Unpartitioned Disk Space: $unallocated" Log-Message "Active Recovery Partition: Partition $recoveryPartitionNumber" Log-Message "OS Partition: Partition $primaryPartitionNumber" Log-Message "" Log-Message "Windows Recovery Environment Details: $reInfo" if ($availableUpdates.kb -match "KB5034441" -and $recoveryPartitionNumber -ne $null) { # 后续逻辑保持不变,确保所有变量名正确 # ... } else { if ($recoveryPartitionNumber -eq $null) { Log-Message "" Log-Message "ERROR: Windows RE is not enabled. Update not applicable." } else { Log-Message "" Log-Message "Machine does not require this update." } }
额外优化点
- 原代码中
Where-Object DriveLetter -contains "C"改为-eq "C":DriveLetter是单个字符串属性,-contains用于集合匹配,此处用-eq更准确。 - 使用
?.空值条件访问运算符:避免$primaryPartition为空时,访问PartitionNumber引发空引用错误。
内容的提问来源于stack exchange,提问作者Mike M
相关产品推荐
相关产品推荐

