6

I am bit confused of the behaviour of the script below:

Test.ps1:

param(
    [array]$Value = $(throw "Give me a value")
)

Write-Host $Value 
$Value | Get-Member -MemberType Method
$Value.ToUpper()

Running the script:

PS C:\Temp> .\weird.ps1 test
TypeName: System.String
Name MemberType Definition
—- ———- ———-
…
ToUpper Method string ToUpper(), string ToUpper(System.Globalization.CultureInfo culture)
…
Method invocation failed because [System.Object[]] doesn’t contain a method named ‘ToUpper’.
At C:\Temp\weird.ps1:6 char:15
+ $Value.ToUpper <<<< ()
+ CategoryInfo : InvalidOperation: (ToUpper:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound

Why do I get a MethodNotFound exception? Get-Member clearly says it is a string.

3 Answers 3

5

What's happening here is that the variable $value is typed to Object[] in the script. The call to Get-Member works because you are piping the value into the function. Hence instead of seeing the array it sees the values in the array which are indeed typed to String. This can be viewed by using the following Get-Member call without piping

Get-Member -MemberType Method -InputObject $value

This is also why ToUpper correctly fails (it's an array not a String).

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

Comments

4

When you pipe a collection of anything in powershell, it gets "unrolled" and sent one by one to the right hand side of the bar (pipe) character. This means that the contents of the array get sent to get-member. Get-member only accepts the first item sent to it, so it shows you the members of the string. Your parameter is of type [array], so the parameter binder sets $value to an array of length 1, containing your string "test."

Example:

ps> @(1,"hello",3) | gm
... shows members of int32

ps> @("hello", 1, 3) | gm
... shows members of string

In order to see the members of an array when you pipe it, you should wrap it in another array, so it becomes the unrolled item:

ps> ,@("hello", 1, 3) | gm
... shows members of array

The leading comma "," creates a wrapping array.

-Oisin

Comments

2

$Value is actually an array, because that is how you declare the parameter in your param block.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.