Powershell Return-作业有时 returns 空值
Powershell Return-Job sometimes returns empty values
我正在使用 Powershell 脚本通过 Start-Job API 并行检查多个 TFS 构建的状态。
一切似乎都工作正常,但如果我在构建开始后立即取消构建,那么接收作业似乎 return 为空,尽管任务已经完成。
这是充当看门人的代码:
While (@(Get-Job | Where { $_.State -eq "Running" }).Count -ne 0)
{
ForEach ($Job in (Get-Job)) {
$currentJobOutput = Receive-Job $job 6>&1
}
Start-Sleep -Seconds $buildCheckingIntervalInSeconds
}
$jobsReturnData = @()
ForEach ($Job in (Get-Job)) {
Write-Host $job.State
Wait-Job $job | out-null
$hastBaleResult = Receive-Job $Job -Wait:$true;
$jobsReturnData += New-Object PSObject -property $hastBaleResult
Remove-Job $Job
}
Write-Host "`n`nBuilds recap`n"
Write-Host "Build Definition Name".PadRight(29,' ')"Build Status".PadRight(14,' ')"Build Execution URL"
$hasAnyBuildFailed=$false;
foreach($jobReturnData in $jobsReturnData)
{
Write-Host "JobReturnedData"$jobReturnData
$currentForegroundColor="White";
switch($jobReturnData.buildStatus){
"succeeded" {$currentForegroundColor="Green"; break}
"partiallySucceeded" {$currentForegroundColor="Yellow"; break}
"failed" {$currentForegroundColor="Red"; break}
"canceled" {$currentForegroundColor="Red"; break}
}
Write-Host -ForegroundColor $currentForegroundColor "$($jobReturnData.buildDefinitionName.PadRight(30,' '))$($jobReturnData.buildStatus.PadRight(15,' '))$($jobReturnData.buildUrl)"
if(($jobReturnData.buildStatus -eq "failed") -or ($jobReturnData.buildStatus -eq "canceled")){
$hasAnyBuildFailed = $true;
}
}
if($hasAnyBuildFailed){
throw "Not all builds completed successfully";
}
大多数时候它工作正常,但如上所述,在某些情况下我得到的输出是
Completed
Completed
Pull Request - Full Build - ExecID=247764 - Build Status: canceled - You can access the build execution at myTfs/_build/index?buildId=247764&_a=summary
DeleteMe:Returning System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry
Builds recap
Build Definition Name Build Status Build Execution URL
JobReturnedData
You cannot call a method on a null-valued expression.
At myScript.ps1:377 char:60
+ ... undColor "$($jobReturnData.buildDefinitionName.PadRight(30,' '))$($jo ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At myScript.ps1:377 char:114
+ ... adRight(30,' '))$($jobReturnData.buildStatus.PadRight(15,' '))$($jobR ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
JobReturnedData @{buildStatus=canceled; buildDefinitionName=Pull Request - Full Build; buildUrl=myTfs/_build/index?buildI
d=247764&_a=summary}
Pull Request - Full Build canceled myTfs/_build/index?buildId=247764&_a=summary
Not all builds completed successfully
At myScript.ps1:384 char:5
+ throw "Not all builds completed successfully";
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Not all builds completed successfully:String) [], RuntimeException
+ FullyQualifiedErrorId : Not all builds completed successfully
这是因为什么?
我最终将排队的作业存储在一个数组中并对其进行迭代。
$jobsReturnData = @()
While (@($jobs | Where { $_.State -eq "Running" }).Count -ne 0) {
#Redirect the transient output from each job to the main output window
ForEach ($job in @($jobs | Where { $_.State -eq "Running" })) {
$currentJobOutput = Receive-Job $job 6>&1
if($job.HasMoreData){
Wait-Job $Job -Timeout $buildCheckingIntervalInSeconds
}
}
#Get return values from each completedjob without waiting for all jobs to finish
ForEach ($job in @($jobs | Where { ($_.State -eq "Completed")})) {
$jobReturnData = Receive-Job $Job -Wait:$true;
$jobsReturnData += New-Object PSObject -property $jobReturnData
Remove-Job $Job
$jobs[[array]::IndexOf($jobs, $Job)] = $null
}
Start-Sleep -Seconds $buildCheckingIntervalInSeconds
}
#Get return values from each completedjob
ForEach ($job in @($jobs | Where { ($_.State -eq "Completed")})) {
$jobReturnData = Receive-Job $Job -Wait:$true;
$jobsReturnData += New-Object PSObject -property $jobReturnData
Remove-Job $Job
$jobs[[array]::IndexOf($jobs, $Job)] = $null
}
我注意到有时作业已完成但会一直保持 运行 直到 Wait-Job 完成,这很令人费解。
我添加了 ttwo 检查以从已完成的作业中获取 return 值,这样就不必等待所有作业都完成后再在屏幕上显示更新。
我正在使用 Powershell 脚本通过 Start-Job API 并行检查多个 TFS 构建的状态。
一切似乎都工作正常,但如果我在构建开始后立即取消构建,那么接收作业似乎 return 为空,尽管任务已经完成。
这是充当看门人的代码:
While (@(Get-Job | Where { $_.State -eq "Running" }).Count -ne 0)
{
ForEach ($Job in (Get-Job)) {
$currentJobOutput = Receive-Job $job 6>&1
}
Start-Sleep -Seconds $buildCheckingIntervalInSeconds
}
$jobsReturnData = @()
ForEach ($Job in (Get-Job)) {
Write-Host $job.State
Wait-Job $job | out-null
$hastBaleResult = Receive-Job $Job -Wait:$true;
$jobsReturnData += New-Object PSObject -property $hastBaleResult
Remove-Job $Job
}
Write-Host "`n`nBuilds recap`n"
Write-Host "Build Definition Name".PadRight(29,' ')"Build Status".PadRight(14,' ')"Build Execution URL"
$hasAnyBuildFailed=$false;
foreach($jobReturnData in $jobsReturnData)
{
Write-Host "JobReturnedData"$jobReturnData
$currentForegroundColor="White";
switch($jobReturnData.buildStatus){
"succeeded" {$currentForegroundColor="Green"; break}
"partiallySucceeded" {$currentForegroundColor="Yellow"; break}
"failed" {$currentForegroundColor="Red"; break}
"canceled" {$currentForegroundColor="Red"; break}
}
Write-Host -ForegroundColor $currentForegroundColor "$($jobReturnData.buildDefinitionName.PadRight(30,' '))$($jobReturnData.buildStatus.PadRight(15,' '))$($jobReturnData.buildUrl)"
if(($jobReturnData.buildStatus -eq "failed") -or ($jobReturnData.buildStatus -eq "canceled")){
$hasAnyBuildFailed = $true;
}
}
if($hasAnyBuildFailed){
throw "Not all builds completed successfully";
}
大多数时候它工作正常,但如上所述,在某些情况下我得到的输出是
Completed
Completed
Pull Request - Full Build - ExecID=247764 - Build Status: canceled - You can access the build execution at myTfs/_build/index?buildId=247764&_a=summary
DeleteMe:Returning System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry
Builds recap
Build Definition Name Build Status Build Execution URL
JobReturnedData
You cannot call a method on a null-valued expression.
At myScript.ps1:377 char:60
+ ... undColor "$($jobReturnData.buildDefinitionName.PadRight(30,' '))$($jo ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At myScript.ps1:377 char:114
+ ... adRight(30,' '))$($jobReturnData.buildStatus.PadRight(15,' '))$($jobR ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
JobReturnedData @{buildStatus=canceled; buildDefinitionName=Pull Request - Full Build; buildUrl=myTfs/_build/index?buildI
d=247764&_a=summary}
Pull Request - Full Build canceled myTfs/_build/index?buildId=247764&_a=summary
Not all builds completed successfully
At myScript.ps1:384 char:5
+ throw "Not all builds completed successfully";
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Not all builds completed successfully:String) [], RuntimeException
+ FullyQualifiedErrorId : Not all builds completed successfully
这是因为什么?
我最终将排队的作业存储在一个数组中并对其进行迭代。
$jobsReturnData = @()
While (@($jobs | Where { $_.State -eq "Running" }).Count -ne 0) {
#Redirect the transient output from each job to the main output window
ForEach ($job in @($jobs | Where { $_.State -eq "Running" })) {
$currentJobOutput = Receive-Job $job 6>&1
if($job.HasMoreData){
Wait-Job $Job -Timeout $buildCheckingIntervalInSeconds
}
}
#Get return values from each completedjob without waiting for all jobs to finish
ForEach ($job in @($jobs | Where { ($_.State -eq "Completed")})) {
$jobReturnData = Receive-Job $Job -Wait:$true;
$jobsReturnData += New-Object PSObject -property $jobReturnData
Remove-Job $Job
$jobs[[array]::IndexOf($jobs, $Job)] = $null
}
Start-Sleep -Seconds $buildCheckingIntervalInSeconds
}
#Get return values from each completedjob
ForEach ($job in @($jobs | Where { ($_.State -eq "Completed")})) {
$jobReturnData = Receive-Job $Job -Wait:$true;
$jobsReturnData += New-Object PSObject -property $jobReturnData
Remove-Job $Job
$jobs[[array]::IndexOf($jobs, $Job)] = $null
}
我注意到有时作业已完成但会一直保持 运行 直到 Wait-Job 完成,这很令人费解。
我添加了 ttwo 检查以从已完成的作业中获取 return 值,这样就不必等待所有作业都完成后再在屏幕上显示更新。