Powershell function call changing passed string into int

Your have a syntax problem:

FindInAD($nameOfDeviceInput.Text).Count # WRONG

Note: Wrong in this context means: the syntax is formally valid, but doesn’t do what you expect – see the bottom section.

It should be:

(FindInAD $nameOfDeviceInput.Text).Count

PowerShell commands – functions, cmdlets, scripts and external programs – are invoked like shell commandsfoo arg1 arg2 – and not like C# methods – foo('arg1', 'arg2').

That is:

  • Do not put (...) around the list of arguments.

    • However, you do need (...) around the call as a whole if you want a command call to participate in an expression, as shown above with the access to property .Count – see this answer for more information.
  • Separate arguments with whitespace (at least one space), both from each other and from the command name – do not use ,

    • , between arguments functions differently: It constructs an array that is passed as a single argument – see below.
  • You may pass simple strings (ones that contain neither spaces nor PowerShell metacharacters such as ; or &) as barewords; that is, quoting them is optional; e.g., instead of foo 'bar', you can call foo bar – see this answer for how PowerShell parses unquoted command arguments.

  • Also, if a target function or script has explicitly declared parameters (which binary cmdlets invariably do), such as -bar and -baz, you can pass your values as named arguments, i.e. by prepending them with the target parameter name; doing so is good practice in scripts: foo -bar arg1 -baz arg2

By contrast, calling methods of objects uses the syntax familiar from regular programming languages such as C# ($obj.foo('arg1', 'arg2'))

This difference relates two PowerShell’s two fundamental parsing modes, explained in detail in this answer:

  • Commands are parsed in argument mode – as in shells.

  • Method calls and operator-based expressions are parsed in expression mode – as in regular programming languages.

These modes are required in order to allow PowerShell serve double duty: as a shell on the one hand, and as a scripting (programming) language on the other.


PowerShell can help you avoid this syntax problem:

Note that the problem isn’t that using method syntax to call a command is invalid syntax, but that it doesn’t work as intended, which can be difficult to diagnose.

In short: When you call command foo as foo('foo', 'bar'), ('foo', 'bar')is a 2-element array, which is then passed to foo as a single argument.

To prevent the problem to begin with, you can set Set-StrictMode to -Version 2 or higher, which makes PowerShell report an error if you accidentally use method syntax when calling a command:

# Turn on the check for accidental method syntax.
# Note: This also turns on ADDITIONAL checks - see below.
Set-StrictMode -Version 2

# This call now produces an ERROR, because the proper syntax would be:
#    foo 'a' 'b'
foo('a', 'b')

Caveats:

  • Set-StrictMode -Version 2 comprises additional strictness checks that you must then also conform to, notably:

    • You must not reference non-existent variables.
    • You must not reference non-existent properties; see GitHub issue #2798 for an associated pitfall in connection with PowerShell’s unified handling of scalars and collections.
  • An error is reported only for pseudo method calls with multiple arguments (e.g.,
    foo('bar', 'baz')), not with only one; e.g., foo('bar') is accepted, because the single-argument case generally still (accidentally) works.

  • The errors reported for strictness violations are statement-terminating errors: that is, they only terminate the statement at hand, but by default the script continues; to ensure that overall execution aborts – on any type of error – you’d have to set
    $ErrorActionPreference="Stop" at the start of your code. See this answer for more information.


As for what you tried:

FindInAD($nameOfDeviceInput.Text).Count

is the same as:

FindInAD ($nameOfDeviceInput.Text).Count

That is, the result of expression ($nameOfDeviceInput.Text).Count is passed as an argument to function FindInAD.

Leave a Comment