拆分 PowerShell 管道以分离文件
Split PowerShell pipelines to separate files
在测试期间,我正在创建的函数正在输出标准输出和详细输出。现在,它们都在同一个日志文件中。我想把它们分开。
举个例子:
Function Test-Output {
[CmdletBinding()]
Param ()
Get-Process PowerShell, none
Write-Warning "Test!"
Write-Verbose "Test Verbose"
Write-Debug "Test Debug"
}
如果我运行它:
Test-Output -Verbose -Debug
...我得到 none
-进程(管道 2)的错误流:
Get-Process : Cannot find a process with the name "none". Verify the process name and call the cmdlet again.
At line:4 char:1
+ Get-Process PowerShell, none
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (none:String) [Get-Process], ProcessCommandException
+ FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
...我的成功流(管道 1):
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
360 33 98736 109172 673 5.44 6220 powershell
...警告流(管道 3):WARNING: Test!
...详细流(管道 4):VERBOSE: Test Verbose
...和调试流(管道 5):DEBUG: Test Debug
到目前为止,我发现将每个流放入其自己的文件中的唯一(粗略)解决方案是这个(为了方便,我在这里将 Out-File
替换为 Write-Output
):
Test-Output -ErrorVariable ErrorVar -WarningVariable WarningVar -OutVariable OutVar -Debug -Verbose *> $Null
Write-Output "Error : $ErrorVar"
Write-Output "Warning : $WarningVar"
foreach ($Record in $Outvar) {
If ($Record.GetType().Name -eq 'VerboseRecord') { Write-Output "Verbose : $($Record.Message)" }
ElseIf ($Record.GetType().Name -eq 'DebugRecord') { Write-Output "Debug : $($Record.Message)" }
Else { $Record }
}
当我尝试更简单的解决方案时,我最终错过了错误和警告流(而且我仍然必须使用上面的 foreach
将它们分开):
Test-Output -Verbose -Debug *> $OutVar
# $OutVar contains Pipeline(1), Verbose(4) and Debug (5)
# Error(2) and Warning (3) seem to be gone (not counting $error[0])
Test-Output -Verbose -Debug 2>&1 3>&1 *> $OutVar
# Error(2) and Warning (3) still gone
Test-Output -Verbose -Debug *>&1 > $OutVar
# Same Thing
到目前为止,Tee-Object
似乎也不完全符合我的要求。
所以我的问题是:我在这里想的太复杂了,有没有更简单的解决方案?如果是,是什么?
一种选择是使用运行空间。然后你可以分别处理输出和每个流输出:
Function Test-Output {
[CmdletBinding()]
Param ()
$Code = {
$VerbosePreference,$WarningPreference,$DebugPreference = 'Continue'
Get-Process PowerShell, none
Write-Warning "Test!"
Write-Verbose "Test Verbose"
Write-Debug "Test Debug"
}
$newPowerShell = [PowerShell]::Create().AddScript($code)
$job = $newPowerShell.BeginInvoke()
While (-Not $job.IsCompleted) {}
[PSCustomObject]@{
OutPut = $newPowerShell.EndInvoke($job)
Verbose = $newPowerShell.Streams.Verbose.ReadAll()
Warning = $newPowerShell.Streams.Warning.ReadAll()
Error = $newPowerShell.Streams.Error.ReadAll()
}
$newPowerShell.Dispose()
}
$Result = Test-Output
这将return $Result 的自定义对象,调用中的每个流都具有单独的属性。
在测试期间,我正在创建的函数正在输出标准输出和详细输出。现在,它们都在同一个日志文件中。我想把它们分开。
举个例子:
Function Test-Output {
[CmdletBinding()]
Param ()
Get-Process PowerShell, none
Write-Warning "Test!"
Write-Verbose "Test Verbose"
Write-Debug "Test Debug"
}
如果我运行它:
Test-Output -Verbose -Debug
...我得到 none
-进程(管道 2)的错误流:
Get-Process : Cannot find a process with the name "none". Verify the process name and call the cmdlet again.
At line:4 char:1
+ Get-Process PowerShell, none
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (none:String) [Get-Process], ProcessCommandException
+ FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
...我的成功流(管道 1):
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
360 33 98736 109172 673 5.44 6220 powershell
...警告流(管道 3):WARNING: Test!
...详细流(管道 4):VERBOSE: Test Verbose
...和调试流(管道 5):DEBUG: Test Debug
到目前为止,我发现将每个流放入其自己的文件中的唯一(粗略)解决方案是这个(为了方便,我在这里将 Out-File
替换为 Write-Output
):
Test-Output -ErrorVariable ErrorVar -WarningVariable WarningVar -OutVariable OutVar -Debug -Verbose *> $Null
Write-Output "Error : $ErrorVar"
Write-Output "Warning : $WarningVar"
foreach ($Record in $Outvar) {
If ($Record.GetType().Name -eq 'VerboseRecord') { Write-Output "Verbose : $($Record.Message)" }
ElseIf ($Record.GetType().Name -eq 'DebugRecord') { Write-Output "Debug : $($Record.Message)" }
Else { $Record }
}
当我尝试更简单的解决方案时,我最终错过了错误和警告流(而且我仍然必须使用上面的 foreach
将它们分开):
Test-Output -Verbose -Debug *> $OutVar
# $OutVar contains Pipeline(1), Verbose(4) and Debug (5)
# Error(2) and Warning (3) seem to be gone (not counting $error[0])
Test-Output -Verbose -Debug 2>&1 3>&1 *> $OutVar
# Error(2) and Warning (3) still gone
Test-Output -Verbose -Debug *>&1 > $OutVar
# Same Thing
到目前为止,Tee-Object
似乎也不完全符合我的要求。
所以我的问题是:我在这里想的太复杂了,有没有更简单的解决方案?如果是,是什么?
一种选择是使用运行空间。然后你可以分别处理输出和每个流输出:
Function Test-Output {
[CmdletBinding()]
Param ()
$Code = {
$VerbosePreference,$WarningPreference,$DebugPreference = 'Continue'
Get-Process PowerShell, none
Write-Warning "Test!"
Write-Verbose "Test Verbose"
Write-Debug "Test Debug"
}
$newPowerShell = [PowerShell]::Create().AddScript($code)
$job = $newPowerShell.BeginInvoke()
While (-Not $job.IsCompleted) {}
[PSCustomObject]@{
OutPut = $newPowerShell.EndInvoke($job)
Verbose = $newPowerShell.Streams.Verbose.ReadAll()
Warning = $newPowerShell.Streams.Warning.ReadAll()
Error = $newPowerShell.Streams.Error.ReadAll()
}
$newPowerShell.Dispose()
}
$Result = Test-Output
这将return $Result 的自定义对象,调用中的每个流都具有单独的属性。