如何从Powershell作业捕获.NET跟踪输出?

时间:2015-01-27 14:44:20

标签: powershell tracing powershell-jobs

我在Powershell中使用.NET组件,它使用Trace.TraceWarningTrace.TraceInformation等。

我想在运行Powershell脚本时将这些跟踪输出到控制台。

当我在当前会话中使用该组件时,这是有效的。例如(模拟跟踪的效果)为控制台提供了“Hello”输出:

 $listener = new-object "system.diagnostics.consoletracelistener"
 [System.Diagnostics.Trace]::Listeners.Add($listener) | Out-Null
 [System.Diagnostics.Trace]::TraceInformation("Hello")

但是如果我在Powershell工作中做同样的事情我没有输出,即使ConsoleTraceListener应该写入STDOUT,而这反过来我希望被工作捕获。 (有趣的是,Console.WriteLine也不适合工作 - 但Write-Host确实如此。

我这样开始工作:

$work = {
     $listener = new-object "system.diagnostics.consoletracelistener"
     [System.Diagnostics.Trace]::Listeners.Add($listener) | Out-Null
     [System.Diagnostics.Trace]::TraceInformation("Hello")
}
$job = Start-Job -RunAs32 -ScriptBlock $work
$job | Receive-Job -Wait

2 个答案:

答案 0 :(得分:0)

目前尚不清楚您希望捕获的输出去哪里。到目前为止,大多数讨论围绕着控制台进行,但是因为你把它称为“工作”#34; (我认为你的意思是计划任务),我不太确定控制台是最好的地方。你永远不会看到结果。日志文件听起来更合适。如果是这种情况,则应创建TextWriteTraceLister。这将允许您为结果设置日志文件。

此外,在.Net中跟踪的一个很好的功能是你可以连接多个监听器。因此,如果您希望在运行时看到输出,您还可以附加ConsoleTraceListener,它不会干扰写入日志文件。

最后,还可以编写自己的TraceListener。这对于写入日志数据库或Web服务等内容非常有用。要从PowerShell使用自己的TraceListener,您需要使用.Net语言构建侦听器,该语言可以编译为类库程序集(dll),可以部署到GAC以便在项目中使用。

答案 1 :(得分:0)

我记得遇到类似于今年的事情,预期STDOUT和STDIN的行为与start-job和exe的预期不同。我最终使用System.Diagnostics.Process并重定向STDIN和STDOUT。以下是一个示例,以一种可以帮助您完成尝试的方式演示此变通方法。

#added extra trace messages with Get-Date and implemented a random delay for demo purpose
$work = {
     $listener = new-object "system.diagnostics.consoletracelistener"
     [System.Diagnostics.Trace]::Listeners.Add($listener) | Out-Null
     1..10 | % {
         Start-Sleep $(Get-Random 5)
         [System.Diagnostics.Trace]::TraceInformation((Get-Date))
    }
}
#Create a process
$process = New-Object System.Diagnostics.Process 
$process.StartInfo.UseShellExecute = $false
#redirect stdout
$process.StartInfo.RedirectStandardOutput = $true
#call powershell
$process.StartInfo.FileName = "powershell.exe"
#pass the $work scriptblock
$process.StartInfo.Arguments = "-noprofile -command $work"
#start the process
$process.Start() | Out-Null
#readlines as they come in and exit when process is done
while(-not $process.HasExited){
    $process.StandardOutput.ReadLine()
}

输出:

powershell.exe Information: 0 : 01/30/2015 12:27:17
powershell.exe Information: 0 : 01/30/2015 12:27:20
powershell.exe Information: 0 : 01/30/2015 12:27:21
powershell.exe Information: 0 : 01/30/2015 12:27:25
powershell.exe Information: 0 : 01/30/2015 12:27:26
powershell.exe Information: 0 : 01/30/2015 12:27:28
powershell.exe Information: 0 : 01/30/2015 12:27:29
powershell.exe Information: 0 : 01/30/2015 12:27:33
powershell.exe Information: 0 : 01/30/2015 12:27:36
powershell.exe Information: 0 : 01/30/2015 12:27:40