Author Posts

October 31, 2013 at 9:38 am

How come when I do a Measure-Command with no parameters and when it asks for the parameter you can't enter anything but a string even though it expects an object to be entered?

October 31, 2013 at 9:51 am

Its to do with the parameters. When you run measure-command without parameters you get this

£> Measure-Command
cmdlet Measure-Command at command pipeline position 1
Supply values for the following parameters:

If you look at the help file -Expression ie PowerShell code is a mandatory parameter and so you will be prompted for the expression you want to measure. If you look at the examples they are both inputting expressions

November 1, 2013 at 12:23 pm


I understand this much. The prompt in your example only accepts a string although it is expecting an object. Why is this?

November 2, 2013 at 9:55 am

I'm guessing it's an artifact of how mandatory parameters are prompted for and then read in. Maybe the actual cmdlet Read-Host is used? Or possibly whatever method Read-Host itself uses under the hood.

This reminded me of a similar experience I had when at first I tried to use a cmdlet that took a script block, and got the prompt rather than supplying it on the command line. What I saw was something like this:

PS E:\temp> Measure-Command

cmdlet Measure-Command at command pipeline position 1
Supply values for the following parameters:
Expression: { 42 }
Measure-Command : Cannot bind parameter 'Expression'. Cannot convert the "{ 42 }" value of type "System.String" to type
At line:1 char:16
+ Measure-Command < <<< + CategoryInfo : InvalidArgument: (:) [Measure-Command], ParentContainsErrorRecordException + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.MeasureCommandCommand

I think I was playing with Invoke-Command at the time.

Of course, this works:

PS E:\temp> Measure-Command { 42 } | select -exp TotalMilliseconds

I believe that's what's being asked about. It has to do with parsing on the command line vs. how things are read in with Read-Host (or whatever's being used to read in), as far as I can tell. Someone who knows how the actual "read in code" is implemented would have to answer to explain properly, I think, but this attempt at an answer should hopefully provide some enlightenment.

November 2, 2013 at 10:31 am

The syntax for measure-command is:
Measure-Command [-Expression] [-InputObject ] []

-Expression is mandatory – You must have an expression to measure.

What is an expression?

Its a string of text that PowerShell can interpret and use to create a pipeline.

When you don't supply an Expression – PowerShell will prompt you for one. It uses the prompt in the PowerShell console or ISE. At that point all you can enter is a string of text characters. You can't cut and paste an object or type in an object. PowerShell will then take that text and attempt to run it and measure the time it takes. It automatically converts your text into a script block.

November 4, 2013 at 6:36 am


My question is when I don't supply an Expression, why can't I enter an object if that is what it is expecting?

November 4, 2013 at 6:53 am

Because its NOT expecting an object when it prompts you for the mandatory parameter. Its expecting a script block and the only way you can enter that is to type it in

November 4, 2013 at 8:07 am

Joakim – I think your example is the closest to describing what Mike wants to know..

If you have a cmdlet with a mandatory parameter that you fail to specify, PowerShell with prompt you for that parameter. The issue is, PowerShell always interprets the entry as a string. What Mike wants to know, is there any syntax or trick that will allow PowerShell to interpret the string correctly.

$foo = get-myfoo

cmdlet Measure-Foo at command pipeline position 1
Supply values for the following parameters:
Foo: $foo
Measure-Foo: Cannot bind parameter 'Foo'. Cannot convert the "$foo" value of type "System.String"
to type "FOO".
At line:1 char:1
+ Measure-Foo
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Measure-Foo], ParameterBindingException

November 4, 2013 at 11:48 am

The Mandatory attribute is a safety net. Its best practice to pass the correct data into a cmdlet rather than rely on the cmdlet prompt you for the missing data

November 4, 2013 at 1:03 pm

Yes Jim that is exactly what I was looking to find out about. I understand the best practice for passing the correct data Richard, but I must know if it is possible to avoid to string parser or if there is any syntax that alert PowerShell that the input is not a string.

November 4, 2013 at 1:42 pm

What Mike is trying to figure out is if there is PowerShell syntax to pass the correct object to the cmdlet, or if every cmdlet you write has to handle string equivalents of its mandatory parameters and attempt to resolve them itself?. This isn't a question about best practices from a user perspective, it is a question about how to pass non-string values to a cmdlet that doesn't accept strings; or alternately cmdlets need to be coded differently.

Is there anyway to pass a script or object in PowerShell when prompted for the input instead of explicitly setting it as an argument or piping it in. Based on the conversation in the thread, I suspect the answer is either 'No' or 'I don't know of a way'.