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

使用Get-WmiObject查询C盘存储时结果延迟的问题求助

PowerShell存储查询脚本异常的原因与解决方法

问题描述

编写了一段PowerShell脚本用于查询计算机存储信息,遇到以下异常:

  • 输入计算机名后,首次选择菜单选项1调用Show-Storage函数查询C盘存储时无结果返回;再次选择选项1时,会同时返回两次查询的结果。
  • 单独测试Show-Storage函数或Get-WmiObject语句时运行正常。
  • 测试单独的Get-WmiObject代码段时发现:保留$result变量时,查询结果在"WMI End"前输出;移除该变量则结果在"WMI End"后输出。

相关脚本代码

主脚本

$ComputerNumber = (read-host "Provide computer number").trim()

function Show-Storage{
Get-WmiObject -Class win32_logicaldisk -Filter "DeviceID='C:'" -ComputerName $ComputerNumber|select PSComputerName,DeviceID,@{n='size(GB)';e={$_.size/1gb -as [int]}},@{n='Free(GB)';e={$_.freespace/1gb -as [int]}}
}

function Show-Menu
{
    param (
        [string]$Title = 'Computer Info'
    )
    Write-Host "================ $Title ================"
    Write-Host ""
    Write-Host "1: Press '1' to get Current Computer Usage"
    Write-Host "2: Press '2' to delete Local User Profile"
    Write-Host "Q: Press 'Q' to quit."
}

$a=1
While ($a -eq 1)
{
    write-host ""
    Show-Menu
    write-host ""
    if ($ComputerNumber -ne $null){
        write-host "Selected Computer '$ComputerNumber'"
    }
    else{write-host "No Computer selected"}
    $selection = Read-Host "Please make a selection"

    switch($selection)
    {
    '1'{
        write-host ""
        Show-Storage
        write-host ""
    }
    '2'{
        delete-profile
    }
        'Q'{$a=0}
    }
}

测试代码段

Write-Host "WMI Start"
$result = Get-WmiObject -query "SELECT * FROM Win32_logicalDisk WHERE DeviceID = 'C:'" -ComputerName $PC
$result 
$result  |select PSComputerName,DeviceID,@{n='size(GB)';e={$_.size/1gb -as [int]}},@{n='Free(GB)';e={$_.freespace/1gb -as [int]}}
Write-Host "WMI End"

异常原因分析

1. 输出流与缓冲机制差异

PowerShell存在两种核心输出流:

  • Success输出流:用于传递脚本/命令的返回值,默认会被缓冲,直到当前执行块(如循环迭代、switch分支)完成后才统一输出到控制台。
  • Host流:Write-Host的输出直接发送到控制台,无缓冲,实时显示。

主脚本中,Show-Storage函数直接返回Get-WmiObject的结果(进入Success流),而后续的Write-Host ""属于Host流会先显示。第一次调用时,Success流的结果被缓冲,当循环进入下一次迭代(显示菜单)时,缓冲的输出被菜单内容覆盖,导致用户看不到结果;第二次调用时,两次的缓冲结果在执行块完成后一同输出,因此出现两次结果。

2. 变量赋值对输出顺序的影响

测试代码中:

  • 当将Get-WmiObject结果赋值给$result时,会自动抑制其向Success流的隐式输出,后续手动调用$result才会触发输出,此时输出位于Write-Host "WMI End"之前。
  • 若不赋值,Get-WmiObject的结果直接进入Success流,会在整个脚本执行完成后才输出,因此出现在"WMI End"之后。

解决方法

方法1:强制实时输出结果

在调用Show-Storage时,通过Out-Host强制将Success流的内容实时输出到控制台,绕过缓冲机制:

# switch分支中修改为:
'1'{
    write-host ""
    Show-Storage | Out-Host
    write-host ""
}

方法2:显式控制函数输出

在Show-Storage函数内部捕获结果后,通过Write-Output显式输出,确保结果及时进入输出流:

function Show-Storage{
    $storageData = Get-WmiObject -Class win32_logicaldisk -Filter "DeviceID='C:'" -ComputerName $ComputerNumber | 
        select PSComputerName,DeviceID,@{n='size(GB)';e={$_.size/1gb -as [int]}},@{n='Free(GB)';e={$_.freespace/1gb -as [int]}}
    Write-Output $storageData
}

方法3:改用推荐的CIM命令

Get-WmiObject已被PowerShell官方弃用,推荐使用Get-CimInstance替代,其输出行为更稳定,无延迟缓冲问题:

function Show-Storage{
    Get-CimInstance -Class win32_logicaldisk -Filter "DeviceID='C:'" -ComputerName $ComputerNumber | 
        select PSComputerName,DeviceID,@{n='size(GB)';e={$_.size/1gb -as [int]}},@{n='Free(GB)';e={$_.freespace/1gb -as [int]}}
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 12:43:28