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

PowerShell Invoke-Command结果导出Excel格式异常求助

PowerShell Export-Excel 格式异常问题解决

问题描述

我在使用PowerShell脚本检查远程服务器D盘空间并导出到Excel时遇到格式异常问题。需求是将$env:COMPUTERNAME、Drive $name、$usedPercent% Full、$Global:issue作为表头,把每个Invoke-Command获取的数据导出至Excel,但实际导出的Excel结果格式混乱;而使用Out-File导出至文本文件时,数据格式符合预期。

原脚本代码:

$vmslist = Import-Csv -Path .\vmsList.csv -Delimiter ',' | ForEach-Object {
    $_.Servers
    $vms = [string]$env:COMPUTERNAME
    $currentVms = $_.App_Central
    function Check-DiskSpace {
        $results = Invoke-Command -ComputerName $currentVms -Credential $Cred -ScriptBlock {
            $driveDetails = Get-PSDrive | Where-Object { $_.Name -eq 'D' } | ForEach-Object {
                $totalSpace = $_.Free + $_.Used
                $name = $_.Root
                $vms = $env:COMPUTERNAME

                $dDriveFreeSpace = [int]('{0:N2}' -f ($_.Free / 1Gb))
                $dDriveUsedSpace = [int]('{0:N2}' -f ($_.Used / 1Gb))
                $dDriveTotalSpace = [int]('{0:N2}' -f ($dDriveFreeSpace + $dDriveUsedSpace))

                $freePercent = '{0:N1}' -f ( ($dDriveFreeSpace / $dDriveTotalSpace) * 100)
                $usedPercent = '{0:N1}' -f ( ($dDriveUsedSpace / $dDriveTotalSpace) * 100)
                Write-Host 'Used % of' $_.Root "is $usedPercent%"
                Write-Host 'Free % of' $_.Root "is $freePercent%"
            }


            if($freePercent -le '30') {
                $Global:issue = 'Nearly Full!'
            }
            if ($freePercent -eq '0.0') {
                $Global:issue = 'WARNING - FULL CLEAR SPACE NOW!'
            }
            if($freePercent -gt '30') {
                $Global:issue = 'No Issues'
            }

            Write-Output "$env:COMPUTERNAME, Drive $name, $usedPercent% Full, $Global:issue"
            $Global:test3 = @()
            $Global:test3 += [PSCustomObject]@{
                ComputerName = "$env:COMPUTERNAME"
                Drive        = "$name" 
                UsedPercent  = "$usedPercent%"
                Comments     = "$Global:issue"
            }

            $test3 | Format-Table

        }
        Export-Excel -Path 'C:\temp\ProcessData.xlsx' -InputObject $results -AutoSize -AutoFilter -Append
        return $results
    }
}

问题根源

  1. 输出内容混杂:远程会话中同时输出了逗号分隔字符串、Format-Table格式化对象,$results接收的混合数据无法被Export-Excel正确解析为结构化数据。
  2. 全局变量滥用:远程会话中使用Global:修饰的变量容易引发作用域冲突,且属于冗余操作。
  3. 函数定义位置错误:Check-DiskSpace函数定义在ForEach-Object循环内部,每次循环都会重复定义。
  4. 未执行函数:脚本仅定义了函数,未实际调用,导致远程检查和导出操作从未触发。

修正后的脚本

# 定义检查磁盘空间的函数(放在循环外,避免重复定义)
function Check-DiskSpace {
    param(
        [Parameter(Mandatory=$true)]
        [string]$ComputerName,
        [Parameter(Mandatory=$true)]
        [PSCredential]$Credential
    )

    Invoke-Command -ComputerName $ComputerName -Credential $Credential -ScriptBlock {
        Get-PSDrive -Name D | ForEach-Object {
            # 计算磁盘空间数据
            $totalSpace = $_.Free + $_.Used
            $dDriveFreeSpace = [math]::Round($_.Free / 1Gb, 2)
            $dDriveUsedSpace = [math]::Round($_.Used / 1Gb, 2)
            $dDriveTotalSpace = [math]::Round($totalSpace / 1Gb, 2)
            
            $freePercent = [math]::Round(($dDriveFreeSpace / $dDriveTotalSpace) * 100, 1)
            $usedPercent = [math]::Round(($dDriveUsedSpace / $dDriveTotalSpace) * 100, 1)

            # 确定磁盘状态
            switch ($freePercent) {
                0.0 { $issue = 'WARNING - FULL CLEAR SPACE NOW!' }
                { $_ -le 30 } { $issue = 'Nearly Full!' }
                default { $issue = 'No Issues' }
            }

            # 返回结构化对象,确保Export-Excel能识别表头
            [PSCustomObject]@{
                ComputerName = $env:COMPUTERNAME
                Drive        = $_.Root
                UsedPercent  = "$usedPercent%"
                Comments     = $issue
            }
        }
    }
}

# 主执行逻辑
$vmslist = Import-Csv -Path .\vmsList.csv -Delimiter ','
$exportPath = 'C:\temp\ProcessData.xlsx'

# 预先清理旧文件(可选,避免重复表头)
if (Test-Path $exportPath) { Remove-Item $exportPath }

foreach ($vm in $vmslist) {
    $currentVm = $vm.App_Central
    # 调用函数获取结构化磁盘数据
    $diskData = Check-DiskSpace -ComputerName $currentVm -Credential $Cred
    # 导出到Excel
    $diskData | Export-Excel -Path $exportPath -AutoSize -AutoFilter -Append
}

关键修正说明

  • 返回结构化对象:远程会话直接输出PSCustomObject,而非字符串或格式化表,确保Export-Excel能正确识别表头和对应数据。
  • 优化函数结构:将函数移至循环外,通过参数传递服务器名和凭据,提升代码可维护性。
  • 移除冗余输出:删除Write-Host、Format-Table等非结构化输出,只保留需要导出的对象。
  • 修复执行逻辑:在循环中实际调用函数,确保远程检查和导出操作正常执行。
  • 简化条件判断:用switch替代多个if语句,逻辑更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 09:37:53