Search code examples
powershellpowershell-3.0

How to pass argument to a function from a pipe output of another using powershell


I have written a function called Wait-UntilJobFailOrSuccess . This takes the output from Get-Job using pipe command line. For example.

 Get-Job|Remove-Job

The same way I want to do for my function. For example

Get-Job | Wait-UntilJobFailOrSuccess

I also attached Wait-UntilJobFailOrSuccess below. Please let us know. Do anyone has a solution for this.

Function Wait-UntilJobFailOrSuccess
{
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [System.Object[]]$jobs
        )
    while ($true) {
     if ('Failed' -in $jobs.State) {
        $jobs | Stop-Job 
        Write-Host "Aborting Jobs ${result}"
        break
    }

    Start-Sleep -Milliseconds 500
  }

  foreach ($job in $jobs) {
        if ($job.State -eq 'Failed') {
        Write-Host ($job.ChildJobs[0].JobStateInfo.Reason.Message) -ForegroundColor Red
    } else {
        Write-Host (Receive-Job $job) -ForegroundColor Green 
    }
  }
  $jobs|remove-Job
}

Solution

  • Solution for what exactly? You haven't stated a problem.

    Anyway, in your code you name you your parameter "Jobs" then make it as [ValueFromPipelineByPropertyName]. Job objects don't have a Jobs property so this will not work. Consider a separate parameter Id for this. Also, rather than typing the parameter as [object[]], type it as [System.Management.Automation.Job[]] which is the type of the job object.

    You should have logic in the process block to accumulate all of the Job objects then move the loops to the end block once all of the jobs have been gathered.

    I've reformatted your code and cleaned it up a bit, but I still can't figure out what you're actually trying to do:

    Function Wait-UntilJobFailOrSuccess
    {
        [CmdletBinding()]
        param(
            [Parameter(Mandatory, ValueFromPipeline)]
            [System.Management.Automation.Job[]]
                $jobs
        )
    
        begin
        {
            $joblist = @()
        }
    
        process 
        {
            $joblist += $jobs
        }
    
        end
        {
            foreach ($job in $joblist)
            {
                if ($job.State -eq 'Failed') 
                {
                    Stop-Job -Job $job 
                    Write-Host "Aborting Job $(job.name)"
                    break
                }
            }
    
            Start-Sleep -Milliseconds 500
    
            foreach ($job in $jobslist) 
            {
                if ($job.State -eq 'Failed')
                {
                    Write-Host ($job.ChildJobs[0].JobStateInfo.Reason.Message) -ForegroundColor Red
                } 
                else 
                {
                    Write-Host (Receive-Job $job) -ForegroundColor Green
                } 
            }
            $joblist | Remove-Job -Force # Is this what you really want to do?
        }
    }