Reputation: 128
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
}
Upvotes: 1
Views: 130
Reputation: 439058
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.
Upvotes: 3