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:
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
.
CodePudding user response:
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!