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

PowerShell技术求助:如何用if/elseif语句为CSV添加显卡相关列?

问题分析与修正方案

核心错误点

  1. 语法错误:在创建[PsCustomObject]的哈希表内部直接嵌入if/elseif语句,PowerShell不允许在哈希表定义中使用流程控制逻辑,这是导致报错的直接原因。
  2. Job重复读取:多次调用Receive-Job $videocontroller,第一次读取后Job的输出就会被清空,后续的$nvidiavideocontroller_output和$AMDvideocontroller_output会获取不到数据。
  3. Wait-Job参数遗漏:Wait-Job中未包含$bioscontroller2,可能导致该Job未完成就接收输出,获取到空值。
  4. 显卡判断逻辑错误:使用-ilike "*Intel*"判断$intelvideocontroller_output对象,应该直接判断对象是否存在($null -ne $intelvideocontroller_output),因为之前已经通过过滤得到了对应显卡的对象。
  5. 显卡兼容性问题:原脚本用elseif会导致一台机器如果同时有Intel核显+NVIDIA独显的情况,只会记录其中一个,不符合需求。

修正后的完整脚本

# 用户需要创建包含主机名的txt文件
function ReadHostnames($initialDirectory) {   
    [void] [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
    $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    if ($initialDirectory) { $OpenFileDialog.initialDirectory = $initialDirectory }
    $OpenFileDialog.filter = '所有文件 (*.*)|*.*'
    [void] $OpenFileDialog.ShowDialog()
    return $OpenFileDialog.FileName
}

$FilePermissions = ReadHostnames C:\
$FilePermissions = Get-Content $FilePermissions

Write-Host "正在收集信息,请稍候..."

$counter = 0

foreach ($computername in $FilePermissions) {
    Write-Host "正在处理 $computername ($counter/$($FilePermissions.Count))" 

    if (Test-Connection -BufferSize 32 -Count 1 -ComputerName $computername -Quiet) { 
        # 启动所有异步Job
        $computersystemJob = Get-WmiObject Win32_ComputerSystem -ComputerName $computername -AsJob 
        $videocontrollerJob = Get-WmiObject win32_videocontroller -ComputerName $computername -AsJob
        $biosJob = Get-WmiObject win32_bios -ComputerName $computername -AsJob
        $computerSystemModelJob = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computername -AsJob
        $userlogon = Get-CimInstance -ClassName Win32_ComputerSystem -Property UserName -ComputerName $computername

        # 等待所有Job完成,超时10秒
        Wait-Job -Job $computersystemJob, $videocontrollerJob, $biosJob, $computerSystemModelJob -Timeout 10 | Out-Null 

        # 接收Job输出,只读取一次videocontrollerJob的结果
        $computersystemOutput = Receive-Job $computersystemJob
        $allVideoControllers = Receive-Job $videocontrollerJob
        $biosOutput = Receive-Job $biosJob
        $computerSystemModelOutput = Receive-Job $computerSystemModelJob

        # 过滤各品牌显卡
        $intelVideo = $allVideoControllers | Where-Object { $_.Name -ilike "*Intel*" }
        $nvidiaVideo = $allVideoControllers | Where-Object { $_.Name -ilike "*NVIDIA*" }
        $amdVideo = $allVideoControllers | Where-Object { $_.Name -ilike "*AMD*" }

        # 先初始化所有可能的列,确保CSV结构一致
        $newrow = [PSCustomObject]@{
            Host_name              = $computersystemOutput.Name
            Model_Name             = $computerSystemModelOutput.Model
            Serial_Number          = $biosOutput.SerialNumber
            BIOS_Version           = $biosOutput.SMBIOSBIOSVersion
            Last_User_Logon        = $userlogon.UserName
            Intel_Card             = $null
            IntelGraphics_Version  = $null
            Nvidia_Card            = $null
            NvidiaGraphics_Version = $null
            AMD_Card               = $null
            AMDGraphics_Version    = $null
        }

        # 分别判断各品牌显卡是否存在,填充对应字段(支持多显卡共存)
        if ($null -ne $intelVideo) {
            $newrow.Intel_Card = $intelVideo.Name -join "; "  # 多显卡用分号分隔
            $newrow.IntelGraphics_Version = $intelVideo.DriverVersion -join "; "
        }
        if ($null -ne $nvidiaVideo) {
            $newrow.Nvidia_Card = $nvidiaVideo.Name -join "; "
            $newrow.NvidiaGraphics_Version = $nvidiaVideo.DriverVersion -join "; "
        }
        if ($null -ne $amdVideo) {
            $newrow.AMD_Card = $amdVideo.Name -join "; "
            $newrow.AMDGraphics_Version = $amdVideo.DriverVersion -join "; "
        }

        $newrow | Export-Csv -Path C:\HostnameData.csv -Append -NoTypeInformation
        # 清理所有Job
        Remove-Job -Job $computersystemJob, $videocontrollerJob, $biosJob, $computerSystemModelJob -Force
        
        $counter++
    } else {
        Write-Host "远程计算机 $computername 处于离线状态"
    }
}

关键优化说明

  • 修正语法错误:将流程控制逻辑移到[PsCustomObject]创建之后,通过直接修改对象属性的方式填充显卡信息,避免在哈希表内使用if/else。
  • Job一次性读取:只读取一次$videocontrollerJob的输出,再从中过滤各品牌显卡,避免多次读取导致数据丢失。
  • 统一CSV列结构:初始化所有可能的显卡列(即使为空),确保导出的CSV文件列数一致,不会因为不同机器的显卡情况导致列错乱。
  • 支持多显卡共存:去掉elseif改用独立的if判断,同时处理同一台机器上的多个不同品牌显卡,多显卡时用分号分隔名称和版本。
  • 修复Wait-Job参数:添加$computerSystemModelJob到等待列表,确保所有Job完成后再接收输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:31:02