Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Powershell: Pipe the output to a method and separate the error stream

I’m trying to pipe the output of my script to a separate method and trying to separate the error stream there. Here is the pipeline.ps1

Function MyLogs{
    [CmdletBinding()]
    Param(
      [Parameter(ValueFromPipeline=$True)]
      [String[]] $Log
    )
  
    Begin {
       Write-Verbose "initialize stuff"
       # code to initialize stuff
    }
  
    Process {
       Write-Output " $Log"
       
    }
  
    End {    
       # code to clean stuff
    }
 }

#--- pipe the script output to it
& .\MyScript.ps1 | MyLogs

And here is MyScript.ps1

Write-Output "********** This is a normal text message ************* `n`r " 

# this would create a divide by zero error
1/0

Write-Warning "example warning"

Write-Output "after the errors"

The call & .\MyScript.ps1 | MyLogs would not pipe the error stream to MyLogs() however, errors would be displayed in the console:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

PS D:\Learn\powershell> .\pipelines.ps1
VERBOSE: initialize stuff
 ********** This is a normal text message *************  
 
Attempted to divide by zero.
At D:\Learn\powershell\MyScript.ps1:3 char:1
+ 1/0
+ ~~~
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException
 

WARNING: example warning
 after the errors

And if I do like & .\MyScript.ps1 *>&2 | MyLogs, the error stream would be read as a normal text and I can’t figure-out how to separate the errors from normal text.

>Solution :

Mainly, you would need to redirect all streams (*>&1) or at least the Error Stream to the Success Stream (2>&1) so that your function can capture the objects coming from pipeline. In addition, your function’s parameter should take [object] or [object[]] instead of [string[]] so that you can have a reference of what type of object is coming from the pipeline.

Lastly, with the help of -is type comparison operator and a switch you can create a nice logging function.

using namespace System.Management.Automation

function MyLogs {
    [CmdletBinding()]
    Param(
      [Parameter(ValueFromPipeline = $True)]
      [object] $Log
    )

    begin {
       # code to initialize stuff
    }
    process {
        # this could be reduced to:
        # `@{ $Log.GetType().Name = $Log }`
        switch($Log) {
            { $_ -is [ErrorRecord] } {
                @{ 'Error Record' = $_ }
                break
            }
            { $_ -is [WarningRecord] } {
                @{ 'Warning Record' = $_ }
                break
            }
            { $_ -is [VerboseRecord] } {
                @{ 'Verbose Record' = $_ }
                break
            }
            { $_ -is [InformationRecord] } {
                @{ 'Information Record' = $_ }
                break
            }
            Default {
                @{ 'Success Stream' = $_ }
            }
        }
    }
    end {
       # code to clean stuff
    }
}

& {
    Write-Output 'This is a normal text message'
    1/0
    Write-Host 'Information here...'
    Write-Warning 'example warning'
    Write-Output 'after the errors'
    Write-Verbose 'Hello world!' -Verbose
} *>&1 | MyLogs

I’ll leave it to you further updates as an exercise, this is the output you can expect from this example:

Name                           Value
----                           -----
Success Stream                 This is a normal text message
Error Record                   Attempted to divide by zero.
Information Record             Information here...
Warning Record                 example warning
Success Stream                 after the errors
Verbose Record                 Hello world!
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading