使用Export-Csv而不是Write-Output / Out-File

时间:2017-05-30 20:39:20

标签: powershell

我有以下" ping脚本"我想在其中使用数组和Export-Csv cmdlet将输出写入CSV文件而不是txt文件。

我首先尝试将Write-Output管道传输到Export-Csv,直到读到您无法将字符串传递给Export-Csv并且必须先将它们转换为对象。

我不太了解如何在PowerShell中使用数组。

Param(
    [Parameter(Mandatory=$true, position=0)][string]$csvfile
)

$ColumnHeader = "Hostname"

Write-Host "Reading file" $csvfile
$ipaddresses = Import-Csv $csvfile | Select-Object $ColumnHeader

Write-Host "Started Pinging.."
foreach ($ip in $ipaddresses) {
    if (Test-Connection $ip.("Hostname") -Count 1 -Quiet) {
        Write-Output $ip.("Hostname") "Ping succeeded." |
            Out-File -FilePath "C:\temp\pingresults.txt" -Append
    } else {
        Write-Output $ip.("Hostname") "Ping failed." |
            Out-File -FilePath "C:\temp\pingresults.txt" -Append
    }
}

Write-Host "Pinging Completed."

2 个答案:

答案 0 :(得分:3)

当然,您可以将字符串输入Export-Csv。只是结果可能不是您所期望的,因为Export-Csv将输入对象的属性导出为输出文件的字段。 ;)String对象只有一个属性(Length),因此您最终会得到一个输出文件,列出输入字符串的长度。

要获取列出主机名(或IP地址)的输出CSV以及ping结果,您需要构建具有2个属性的对象。在PowerShell中执行此操作的最佳方法是管道:

Import-Csv $csvfile | ForEach-Object {
    New-Object -Type PSObject -Property ([ordered]@{
        Hostname = $_.Hostname
        Online   = [bool](Test-Connection $_.Hostname -Count 1 -Quiet)
    }
} | Export-Csv 'C:\path\to\output.csv' -NoType

由于您基本上只想在输入数据中添加属性,因此您可以采用更简单的方法并使用calculated property添加ping结果:

Import-Csv $csvfile |
    Select-Object Hostname,
        @{n='Online';e={[bool](Test-Connection $_.Hostname -Count 1 -Quiet)}} |
    Export-Csv 'C:\temp\pingresults.csv' -NoType

建议不要在循环中追加数组,因为追加主要创建一个大小增加的新数组,复制旧数组中的所有元素,然后将新元素添加到新(空)插槽并释放旧数组

答案 1 :(得分:0)

您可以创建$ pingresult数组:

[string[]] $pingresult= @()

然后填充它只需:

$pingresult += ip.("Hostname")," ping succeeded" -join"" 

$pingresult += ip.("Hostname")," ping failed" -join"" 

取决于条件。

最后你可以将数组导出到csv:

convertfrom-csv -inputobject $pingresult | export-csv -path ...