PowerShell Defrag Analysis返回NULL值问题技术咨询
磁盘碎片分析脚本空值问题排查与解决
问题原因
- 属性名称混淆:脚本错误使用了
TotalFiles(总文件数)和TotalBytes(总字节数)这两个总统计字段,而实际需要的碎片化文件数和字节数对应的属性是TotalFragmentedFiles和TotalFragmentedBytes——这是导致字段为空的核心原因。 - 参数传递错误:远程调用时传递了本地未定义的
$volume变量,属于无效参数;同时用$_作为脚本块参数名,容易和PowerShell自动变量$_冲突,引发潜在逻辑问题。 - 过时Cmdlet兼容性:
Get-WmiObject已被官方弃用,部分环境下可能存在方法调用异常,推荐使用Get-CimInstance替代。
修复后的脚本
$computer = "Server" $drives = Invoke-Command -ComputerName $computer -ScriptBlock { Get-PSDrive -PSProvider FileSystem | Select-Object @{n = "Name"; e = { $_.Root.TrimEnd("\") } } } $drives.Name | ForEach-Object { $driveLetter = $_ Write-Host "分析驱动器: $driveLetter" Invoke-Command -ComputerName $computer -ScriptBlock { param($driveLetter) # 用Get-CimInstance替代过时的Get-WmiObject $volume = Get-CimInstance -Class Win32_Volume -Filter "DriveLetter = '$driveLetter'" if (-not $volume) { Write-Warning "未找到驱动器 $driveLetter" return } # 调用碎片分析方法 $fragmentation = $volume | Invoke-CimMethod -MethodName DefragAnalysis if (-not $fragmentation) { Write-Warning "驱动器 $driveLetter 碎片分析失败" return } # 正确映射碎片化统计属性 [PSCustomObject]@{ FragmentationStatusFor = $volume.Name TotalFragmentedFiles = $fragmentation.TotalFragmentedFiles TotalFragmentedBytes = $fragmentation.TotalFragmentedBytes # 可选:添加更多有用的碎片分析字段 PercentFragmentation = $fragmentation.PercentFragmentation TotalFiles = $fragmentation.TotalFiles TotalBytes = $fragmentation.TotalBytes } } -ArgumentList $driveLetter } | Select-Object * | Write-DbaDataTable -SqlInstance SomeServer -Database SomeDB -Schema GET -Table DbaDefragAnalysis ` -AutoCreateTable -Confirm -KeepNulls -bulkCopyTimeOut 180 -ErrorAction Continue -Verbose -EnableException
关键修改说明
- 修正属性映射:将原来的
TotalFiles/TotalBytes替换为TotalFragmentedFiles/TotalFragmentedBytes,获取正确的碎片化统计数据。 - 替换Cmdlet:用
Get-CimInstance和Invoke-CimMethod替代Get-WmiObject,提升兼容性和稳定性。 - 优化参数传递:使用明确的参数名
$driveLetter避免自动变量冲突,移除无效的$volume参数传递。 - 增加错误处理:添加驱动器不存在、分析失败的警告提示,提升脚本健壮性。
内容的提问来源于stack exchange,提问作者Vorster
相关产品推荐
相关产品推荐

