首页 > 解决方案 > Start-Job 将结果保存到 CSV

问题描述

我有以下 PowerShell (v5) 代码,我想将作业结果写入文件。在第一行我想要标题,在下一行我只想要结果。

$siteToCheck = "google.com","stackoverflow.com","codeoverflow.com"
$alljobs     = $true
$fistLine    = $true

function AsyncJobs([array]$siteADDRs) {
    $sb = {
        Param($site)
        $baseSite = 'https://api.ssllabs.com/api/v3/analyze?host='
        $siteParams = '&publish=off'
        $fullSite = [String]::Format("{0}{1}{2}", $baseSite, $site, $siteParams)
        $results = Invoke-WebRequest -Uri $fullSite | ConvertFrom-Json
        while ($results.status -ne "READY" -and $results.status -ne "ERROR" ) {
            sleep 30
            $results = Invoke-WebRequest -Uri $fullSite | ConvertFrom-Json
        }
        (($results | select endpoints).endpoints) |
            ft @{Label="Site_Address"; exp={$site}}, grade, ipAddress
    }

    foreach ($site in $siteADDRs) {
        Start-Job -Name $site -ScriptBlock $sb -ArgumentList $site | Out-Null
    }
}

AsyncJobs -siteADDR $siteToCheck

while ($alljobs -eq $true) {
    $ourJobs = Get-Job
    foreach ($job in $ourJobs) {
        $jobResults = $null
        switch ($job.State) {
            {$_ -eq 'Running'} {
                Write-Host $job.Name " is still in runing sate"
            }
            {$_ -eq 'Completed'} {
                $jobResults = Receive-Job -Id $job.Id
                if ($fistLine -eq $true) {
                     ($jobResults | Out-String)
                     $fistLine = $false
                 } else {
                     $tmpR = ($jobResults | Out-String)
                 }
                 Remove-Job -Id $job.Id
            }
            {$_ -eq 'Failed'} {}
        }
    }
    $ourJobs = $null
    $ourJobs = Get-Job

    if ($ourJobs) {
        $alljobs = $true
    } else {
        $alljobs = $false
    }

    Start-Sleep -Seconds 10
}

标签: jsonpowershellpowershell-5.0start-job

解决方案


在您的脚本块更改中

(($results | select endpoints).endpoints) |
    ft @{Label="Site_Address"; exp={$site}}, grade, ipAddress

$results | Select-Object -Expand endpoints |
    Select-Object @{Label="Site_Address"; exp={$site}}, grade, ipAddress

这样您就可以将输出作为自定义对象而不是Format-Table生成的格式化对象。每当需要进一步处理数据时,通常应避免使用Format-*cmdlet。cmdlet 仅在直接向用户显示数据时才有用。

像这样导出已完成作业的数据:

while (Get-Job -State 'Running') {
    $jobs = Get-Job -State 'Completed'
    $jobs | Receive-Job | Export-Csv 'output.csv' -NoType -Append
    $jobs | Remove-Job
    Start-Sleep -Milliseconds 200
}

循环完成后,对剩余的已完成作业进行最终导出,然后报告并删除失败的作业:

$jobs = Get-Job -State 'Completed'
$jobs | Receive-Job | Export-Csv 'output.csv' -NoType -Append
$jobs | Remove-Job

Get-Job
Get-Job | Remove-Job

推荐阅读