How can I capture .NET trace output from a Powershell job?

I use the .NET component in Powershell, which uses Trace.TraceWarning , Trace.TraceInformation , etc.

I want to print these traces to the console when I run my Powershell script.

This works when I use the component in the current session. For example, (simulating the effect of tracing), I get the output "Hello" to the console:

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

But if I do the same in the Powershell job, I do not get any output, although the ConsoleTraceListener should write in STDOUT, which, in turn, I expected to get as a result of work. (Interestingly, Console.WriteLine does not work from a job - but Write-Host does).

I start my work like this:

 $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 
+6
source share
2 answers

It is not clear where you want the captured output to go through. Most of the discussions still revolve around the console, but since you called it a β€œtask” (I suppose you mean a scheduled task), I'm not sure if the console is the best place. You will never see results. The log file sounds much more appropriate. In this case, you must create a TextWriteTraceLister . This will allow you to set the log file for the results.

In addition, one of the nice tracing features in .NET is that you can hook up more than one listener. Therefore, if you want to see the output during its launch, you can also connect the ConsoleTraceListener, and it will not interfere with writing to the log file.

Finally, you can also write your own TraceListener. This is useful for things like writing to a logging database or web service. To use your own TraceListener from PowerShell, you will need to create a listener using the .NET language, which can be compiled into a class library assembly (dll), which can be deployed to the GAC for use in your project.

0
source

I remember that I went into something similar to these years ago, where the expected STDOUT and STDIN did not behave as expected using start-job and exe. I ended up using System.Diagnostics.Process and redirected STDIN and STDOUT. Here is an example that demonstrates this workaround in a way that can help you with what you are trying to do.

 #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() } 

Output:

 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 
0
source

Source: https://habr.com/ru/post/981609/


All Articles