2

In PowerShell I can use Trace-Command to troubleshoot parameter binding, type conversion etc. Ex:

Trace-Command -PSHost -Name ParameterBinding -Expression { $null = "c:\" | dir}
...
DEBUG: ParameterBinding Information: 0 :     Parameter [Path] PIPELINE INPUT ValueFromPipeline NO COERCION
DEBUG: ParameterBinding Information: 0 :     BIND arg [c:\] to parameter [Path]
DEBUG: ParameterBinding Information: 0 :         Binding collection parameter Path: argument type [String], parameter type [System.String[]], collection type Array, eleme
nt type [System.String], no coerceElementType
...

While debugging some strange behavious in PS I wanted to trace how -lt comparison works (maybe it converts to [int][char]"x" for each character etc.). I tried to use Trace-Command but it doesn't return anything.

Trace-Command -PSHost -Name TypeMatch, TypeConversion -Expression { "Less" -lt "less" }
#No trace-output, only returned value
False

#Get any type of trace-informatino
Trace-Command -PSHost -Name * -Expression { "Less" -lt "less" }
#No trace-output, only returned value
False

Is there any way to find out how these internal operators work behind-the-scenes? Trace information? Verbose output? I've used -lt and -gt as an example, but this could just as well have been the &-operator and how it parses the command or something else.

1
  • I have a similar issue. I have implemented my own class which inherits DynamicObject, IEnumerable and override TryBinaryOperation. But looks like PS comparison operators does not call TryBinaryOperator method at all if the leftmost operand of my type, instead if the right operand was a string then GetEnumerator was called. I need to figure out what is the AST PS builds for comparison operators to properly implement them for my custom type. Commented Sep 7, 2017 at 0:58

1 Answer 1

1

Not sure it helps but -lt and -gt are case un-sensitive operators they behaves like -ilt and -igt. If you want case sensitive operators you should use -clt and -cgt.

Here is the result I obtain in PowerShell 5.0, I'am not sure it helps

Trace-Command -PSHost -Name TypeMatch, TypeConversion -Expression { "Less" -lt "less" }
DÉBOGUER : TypeConversion Information: 0 : Converting "System.Object[]" to "System.Object".
DÉBOGUER : TypeConversion Information: 0 :     Result type is assignable from value to convert's type
DÉBOGUER : TypeConversion Information: 0 : Converting "" to "System.String".
DÉBOGUER : TypeConversion Information: 0 :     Result type is assignable from value to convert's type
DÉBOGUER : TypeConversion Information: 0 : Converting "" to "System.String".
DÉBOGUER : TypeConversion Information: 0 :     Result type is assignable from value to convert's type
DÉBOGUER : TypeConversion Information: 0 : Converting "System.Management.Automation.InvocationInfo" to "System.Management.Automation.InvocationInfo".
DÉBOGUER : TypeConversion Information: 0 :     Result type is assignable from value to convert's type
DÉBOGUER : TypeConversion Information: 0 : Converting "System.Object[]" to "System.Object[]".
DÉBOGUER : TypeConversion Information: 0 :     Result type is assignable from value to convert's type
False

I obtain the same trace if I use -cgt but the result is True.

Sign up to request clarification or add additional context in comments.

2 Comments

Huh.. I've tried that on three different computers running PS 5.0 and it didn't return anything. Guess it's time for clean install. This kinda answers the question, but I was hoping to get a bit deeper. Ex. be able to get a callstack or something for the operator so I could see which class, method etc. is called. Maybe it's not possible, but I'm used to getting surprised by the knowledge of people like you on SO so I'll wait a bit more to see if someone has a magic solution. :-) Thanks
As of Windows PowerShell v5.1 / PowerShell Core v6.0-alpha.17, the above command produces no tracing output at all. Additionally, the tracing output shown in this answer, obtainable in Windows PowerShell v5.0.10586.117, for instance, contains no information about the specific expression in the script block - you get the very same tracing output if you pass {}, i.e., an empty script block.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.