Powershell:将输出通过管道传递给方法并分离错误流

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

我试图将我的脚本的输出通过管道传输到一个单独的方法,并试图在那里分离错误流。这是 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

这里是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"

调用 & .\MyScript.ps1 | MyLogs 不会将错误流通过管道传输到 MyLogs() 但是,错误会显示在控制台中:

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

如果我喜欢 & .\MyScript.ps1 *>&2 | MyLogs,错误流将被读取为普通文本,我不知道如何将 errorsnormal text 分开。

主要是,您需要将 all streams (*>&1) 或至少 Error Stream 重定向到 Success Stream (2>&1) 以便您的函数可以捕获来自管道的对象。此外,您的函数的参数应采用 [object][object[]] 而不是 [string[]],以便您可以参考来自管道的对象类型。

最后,在 -is type comparison operator and a switch 的帮助下,您可以创建一个不错的日志记录功能。

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

我会把它留给你进一步更新作为练习,这是你可以从这个例子中得到的输出:

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!