Question

I am trying to create a function that creates a custom object but have encountered unusual behavior. If you run the below code, you'll find this output

function Test-CustomObject {
    function Create-CustomObject {

        $objProps = @{ 
            'property1' = 'Hello from property 1';
            'property2' = 'Hello from property 2';
        }

        $obj = New-Object -TypeName PSCustomObject -Prop $objProps

        $obj | Add-Member -MemberType ScriptMethod -Value { return 'Hello from method 1' } -Name Method1 -PassThru
        $obj | Add-Member -MemberType ScriptMethod -Value { return 'Hello from method 2' } -Name Method2 -PassThru

        write-host "in function: $obj"
        write-host "in function type: $($obj.GetType())"

        return $obj
    }

    $newObj = Create-CustomObject
    write-host "after function: $newObj"
    write-host "after function type: $($newObj.GetType())"
}

Test-CustomObject

Program Output:

in function: @{property1=Hello from property 1; property2=Hello from property 2}
in function type: System.Management.Automation.PSCustomObject
after function:
after function type: System.Object[]

Does anyone know why the returned object is System.Object[] instead of PSCustomObject?

Était-ce utile?

La solution

PowerShell returns everything that is not assigned to variable from function and not only statement after return keyword.

In your code it will also add result of this calls:

$obj | Add-Member -MemberType ScriptMethod -Value { return 'Hello from method 1' } -Name Method1 -PassThru
$obj | Add-Member -MemberType ScriptMethod -Value { return 'Hello from method 2' } -Name Method2 -PassThru

to function return.

To avoid this you can replace this lines with code (just adding [void] cast of call result):

[void]($obj | Add-Member -MemberType ScriptMethod -Value { return 'Hello from method 1' } -Name Method1 -PassThru)
[void]($obj | Add-Member -MemberType ScriptMethod -Value { return 'Hello from method 2' } -Name Method2 -PassThru)

after that it will work as expected.

Autres conseils

The updated answer to Nick's answer to this question is to assign the misbehaving commands to a variable. Special variable $null tends to fill this spot perfectly.

$null = $obj | Add-Member -MemberType ScriptMethod -Value { return 'Hello from method 1' } -Name Method1 -PassThru
$null = $obj | Add-Member -MemberType ScriptMethod -Value { return 'Hello from method 2' } -Name Method2 -PassThru

And then your function can Return what you tell it to.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top