powershellmethod-invocationmethod-parameters

Powershell function call changing passed string into int


So I am using the kind of buggy Sapien powershell studio to make a powershell driven GUI application, and I am attempting to perform an ADSI query.

$nameOfDeviceInput is a System.Windows.Forms.TextBox

On one form, I have the following function:

$buttonPerformAction_Click={
    if (FindInAD($nameOfDeviceInput.Text).Count -gt 0)
    {
        $buttonPerformAction.BackColor = 'Red'
        $buttonPerformAction.Text = "System already exists in AD with that name. Try another name"
        return
    }
.....
}

On the "main" form, I have the function FindInAD

function FindInAd($nameOfSystem)
{
    Write-Host "seeking system" $nameOfSystem
    ([adsisearcher]"(CN=$nameOfSystem)").FindAll()
}

FindInAd() is failing because for whatever reason, $nameOfSystem is set to 1, and if I don't explicitly cast it as a string, it gets implicitly cast to Int32 (obviously)

I have tried the following:

Fully qualifying the textbox input by notating the form it belongs to ( $adObjectModifier )

 $buttonPerformAction_Click={
        if (FindInAD($adObjectModifier.$nameOfDeviceInput.Text).Count -gt 0)
        {
            $buttonPerformAction.BackColor = 'Red'
            $buttonPerformAction.Text = "System already exists in AD with that name. Try another name"
            return
        }
    .....
    }

Explicitly casting the $nameOfSystem parameter as a type of [string]

function FindInAd([string]$nameOfSystem)
{
    Write-Host "seeking system" $nameOfSystem
    ([adsisearcher]"(CN=$nameOfSystem)").FindAll()
}

Passing a raw string into FindInAD from the AdObjectModifier form.

.... 

if (FindInAD("Test").Count -gt 0)

....

There is nothing else on the output pipeline at the time, (at least not from me) in between the method invocation. It is EventHandler > Function Call with String parameter

Why are the strings I'm passing getting changed to a digit???

EDIT: I think my passed parameter is being automatically replaced with the resulting boolean somehow, but this doesn't make any sense to me....


Solution

  • 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 commands - foo arg1 arg2 - and not like C# methods - foo('arg1', 'arg2').

    That is:

    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:

    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:


    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.