Home > Enterprise >  Send live CMD output to function
Send live CMD output to function

Time:10-23

I am trying to run a PowerShell script that runs CMD command and send the live stream back to PowerShell.

Each line that comes back from the stream, I am trying to send to a function; However, it is passed to the function only at the end of the cmd run instead of during it.

Important to mention that if I pass the stream to 'out-host' instead, I can see the results.

Can you assist?


    function get-ValidateProgress
    {
         param ([Parameter(Mandatory,HelpMessage='Value Passed from ValidateLDS.exe',Position=0,ValueFromPipeline)]$ValidateLine)
         IF($ValidateLine -like 'Proccessing Active Users record*' )
         {
            $Current=$ValidateLine -replace 'Proccessing Active Users record ','' -replace 'of.*','' -replace ' ',''
            $TotalValue=$ValidateLine -replace "Proccessing Active Users record $Current of ",''
            [INT]$Progress=(($Current/$TotalValue)*100)
            Write-Progress -Id 1 -Activity ValidateDBLDS -Status 'Proccessing LDS User records' -PercentComplete $Progress -CurrentOperation 'Active Users'
            IF($Current -eq $TotalValue){write-host 'Finished procccsing Active Users' -ForegroundColor Green}
         }
         ELSEIF($ValidateLine -like 'Proccessing Deleted Users record*' )
         {
            $Current=$ValidateLine -replace 'Proccessing Deleted Users record ','' -replace 'of.*','' -replace ' ',''
            $TotalValue=$ValidateLine -replace "Proccessing Deleted Users record $Current of ",''
            [INT]$Progress=(($Current/$TotalValue)*100)
            Write-Progress -Id 1 -Activity ValidateDBLDS -Status 'Proccessing LDS User records' -PercentComplete $Progress -CurrentOperation 'Deleted Users'
            IF($Current -eq $TotalValue){write-host 'Finished procccsing Deleted Users' -ForegroundColor Green}
         }
    }



    Try{
    $cmdOutput = cmd.exe /c "cd /d D:\$Campus\Code\Utilities && ValidateDBLDS.exe /viewonly:false" 2>&1 | get-ValidateProgress

    Write-Host "Successfully finished LDS Validation." -ForegroundColor Green
    sleep -Seconds 2
    }
    Catch{
    Write-host "An Error occured during validating LDS. See full expection below.`nExecption:"$Error[0].Exception"`nTargetObject:"$Error[0].TargetObject"`nInvocationInfo:"$Error[0].InvocationInfo -ForegroundColor Red
    }


CodePudding user response:

In order for your function to receive streaming input via the pipeline - i.e., output objects (which in the case of external programs are lines) as they're being emitted by the upstream command - it must use a process block.

To use a simplified example:

function foo {
  # A process block is executed for each pipeline input object.
  # In the case of *external programs*, each *line* of output constitutes
  # an input object.
  process {
    "[$_]"
  }
}

cmd /c 'echo 1 & timeout 2 >NUL & echo 2 ' | foo

Executing this will echo [1 ] before the 2-second sleep timeout.exe call kicks in, proving that the cmd /c output was processed in a streaming fashion.

A function that lacks a process block is processed as if its body were enclosed in an end block, i.e. the block that is invoked after all pipeline input has been received.

See Piping Objects to Functions.

  • Related