Link to Parent: PowerShell - Deep Dive and Best Practice


 

This article provides details and examples of using the trace command to see what is going on behind the scenes with your command.

Introduction to Trace-Command

In practical, every day use, this cmdlet can take you a level or two deeper into the inner workings of commands (and expressions) than Step Into and Step Over (in the ISE's) or Debug tracing can in the shell. If you have some command that just is not working and cannot figure out where the disconnect between expectation and reality Trace-Command is the next tool in the arsenal. This article will give a high level overview of the basics and then dive into some of the ways to use it along with unexpected gotchas. 

Getting into the cmdlet itself is somewhat difficult at first. Trace-Command is a powerful tool but there is currently very little commentary about its application. Using the current release of Powershell v3 (BuildVersion 6.2.8158.0) you can get some basic ideas of what Trace-Command might be able to do, but, does not expand much upon the ideas of why and when you want to use it. You can see the general help with this command:

Get-Help Trace-Command -Full

The output of this command is not too overwhelming. The basic description can be understood a little better with this note,

Tracing is a method that developers use to debug and refine programs. When tracing, the program generates detailed messages about each step in its internal processing.

Realize, as you read it, that there is a lot you have to explore on your own to figure out how to use Trace-Command. Key to getting a grip on its use can be found in the Notes which says,

The Windows PowerShell tracing cmdlets are designed to help Windows PowerShell developers, but they are available to all users. They let you monitor nearly every aspect of the functionality of the shell.

By denoting the cmdlet is geared more for developers the Notes suggest this one will require a slightly different mindset than more shell-oriented cmdlets (like Get-ChildItem, Select-Object, etc). Before we get into learning how to think when using Trace-Command here are a few pieces of information that will help speed up the process.

Parameter Sets


One of the first things to note is two parameter sets: command or expression. The key is to realize that Trace-Command will work with a command (a cmdlet, script, or, function) or an expression (specifically, a scriptblock, as indicated  by the required curly braces {}), but, not both. So, you have to pick one road or the other. To read more about the differences between commands and expressions view the help in Powershell:

Get-Help Invoke-Command -Full
Get-Help Invoke-Expression -Full

or view the online articles:

Invoke-Command - http://go.microsoft.com/fwlink/?LinkID=135225
Invoke-Expression - http://go.microsoft.com/fwlink/?LinkID=113343 
Command
When you work with the Command parameter set the main difference is the inclusion of a -Command parameter and an -ArgumentList parameter. All remaining parameters are common to both the command and expression parameter sets. Later in the article specific details on both the command and expression parameter sets will be explored. If you look at Example 2 in the help for Trace-Command you can see how -ArgumentList is used.
Expression
When you work with the Expression parameter set its unique characteristic is the -Expression parameter. As noted above, and, in the help, this is a script block the requires a pair of curly braces. If you define your expression earlier in the script, or, use [ScriptBlock]::Create() you can avoid using the braces.

Tracesources


Without specifying a value for the -Name parameter Trace-Command will not run. This is, in fact, the only required parameter, aside from -Command or -Expression (depending on which parameter set you choose). As noted in the help, this is the first parameter (when using positional binding), it is required, and, there is neither a default nor (according to documentation) are pipeline and wildcards accepted. Ironically, in the Notes, it explicitly says wildcards are permitted. So, keep that in mind when reading over the help and experimenting.

Tracesources, in Powershell, are of type System.Management.Automation.PSTraceSource. You can get member information with this command:

Get-TraceSource | select -first 1 | Get-Member

and find out more on MSDN at this link:

PSTraceSource Class - http://msdn.microsoft.com/en-us/library/system.management.automation.pstracesource(v=vs.85).aspx 

For related information you can view the TraceSource Class page:

TraceSource Class - http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource(v=vs.85).aspx

To find out what Tracesources exist on the machine you are working with use the Get-TraceSource cmdlet as listed above. In general, Get-Tracesource simply tells you what sources you can use to trace commands. There is not much more to that class beyond showing what is accessible.

Videos


Below are videos related to Trace-Command, Get-Tracesource and debugging:

Links


Below are links related to Trace-Command, Get-Tracesource and debugging:

To be added...


I know there is a lot to work on from here, so, there are just placeholders for work to be done. Feel free to add content from Trace-Command as you have used it.

Using Trace-Command, simple examples
  • Don't use Trace-Command -Name *
  • Translating trace output 
Show how to work with debugger
  • PSHost
  • Visual studio

See Also