Result of Invoke-RestMethod not working in pipeline?

Hi,

I wrote a function that uses Invoke-RestMethod:

process
{
    $body = @{ }
     
    # Building the body... 
            
    $url = $script:url + 'OrgUnits'
    Invoke-RestMethod -Uri $url -Credential $cred -Method Get -Body $body -ContentType "application/json"
}

Now I tried filtering the result by piping it to Where-Object:

Get-bmaOrgUnit | Where-Object { $_.HierarchyPath -match '^Log*' }

However, the result is not filtered as expected. If I assign the result to a variable and apply the filtering to the variable, it works as expected.

$orgunits = Get-bmaOrgUnit
$orgunits | Where-Object { $_.HierarchyPath -match '^Log*' }

What am I missing in my function to get the piping to work?

It’s likely the object type messing with parameter binding. I’d need to run both of those inside Trace-Command.

Trace-Command -Name parameterbinding,cmdlet -Expression { Your code here } -PSHost

I’d run both commands that way and compare the results. Somewhere, there’s a different. Unfortunately, I obviously can’t run your command myself, and “not filtered as expected” isn’t super-helpful because I don’t know what you expected or what it did. If the first example is simply doing nothing, then I’d suspect parameter binding was the problem, meaning for some reason the result of your command isn’t binding to the -InputObject parameter of Where-Object. It’s also possible that what’s being bound isn’t the object you expected, and so it doesn’t have a HierarchyPath parameter. Again… I’d have to do some tracing and debugging.

(As a note, please don’t post the entire Trace-Command output here - it’ll be a ton of text. If you do this, narrow it down to what’s different, and share that.)

Thanks for your help and sorry for expressing myself so vague.

What I meant by ‘not filtered as exprected’ was that the output of

Get-bmaOrgUnit

and

Get-bmaOrgUnit | Where-Object { $_.HierarchyPath -match '^Log*' }

is identical. I did expect the output of the second command to be a subset of the output from the first command because the ‘HierarchyPath’-Property of some of the Objects does not match the regular expression.

However, if I assign the output to a variable first, it works as expected: Only objects matching the regular expression are returned.

$orgunits = Get-bmaOrgUnit
$orgunits | Where-Object { $_.HierarchyPath -match '^Log*' }

So I ran both commands in Trace-Command, with the following differences:

The output from

Get-bmaOrgUnit | Where-Object { $_.HierarchyPath -match '^Log*' }

contained the following additional information at the beginning

DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Get-bmaOrgUnit]
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Get-bmaOrgUnit]
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Get-bmaOrgUnit]
DEBUG: ParameterBinding Information: 0 :     BIND arg [] to parameter [ParentId]
DEBUG: ParameterBinding Information: 0 :         Executing DATA GENERATION metadata:
[System.Management.Automation.ArgumentTypeConverterAttribute]
DEBUG: ParameterBinding Information: 0 :             result returned from DATA GENERATION:
DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.String]
DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :         BIND arg [] to param [ParentId] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     BIND arg [] to parameter [Id]
DEBUG: ParameterBinding Information: 0 :         Executing DATA GENERATION metadata:
[System.Management.Automation.ArgumentTypeConverterAttribute]
DEBUG: ParameterBinding Information: 0 :             result returned from DATA GENERATION:
DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.String]
DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :         BIND arg [] to param [Id] SUCCESSFUL

The next difference is after

DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Where-Object]
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing

The output from

Get-bmaOrgUnit | Where-Object { $_.HierarchyPath -match '^Log*' }

contained the following additional information (I changed the Uri-Parameter in the output)

DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Invoke-RestMethod]
DEBUG: ParameterBinding Information: 0 :     BIND arg ['My-Uri'] to parameter
[Uri]
DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.Uri]
DEBUG: ParameterBinding Information: 0 :             Trying to convert argument value from System.String to System.Uri
DEBUG: ParameterBinding Information: 0 :             CONVERT arg type to param type using LanguagePrimitives.ConvertTo
DEBUG: ParameterBinding Information: 0 :             CONVERT SUCCESSFUL using LanguagePrimitives.ConvertTo:
['My-Uri']
DEBUG: ParameterBinding Information: 0 :         Executing VALIDATION metadata:
[System.Management.Automation.ValidateNotNullOrEmptyAttribute]
DEBUG: ParameterBinding Information: 0 :         BIND arg ['My-Uri'] to param
[Uri] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     BIND arg [System.Management.Automation.PSCredential] to parameter
[Credential]
DEBUG: ParameterBinding Information: 0 :         Executing DATA GENERATION metadata:
[System.Management.Automation.CredentialAttribute]
DEBUG: ParameterBinding Information: 0 :             result returned from DATA GENERATION:
System.Management.Automation.PSCredential
DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.Management.Automation.PSCredential]
DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :         BIND arg [System.Management.Automation.PSCredential] to param
[Credential] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     BIND arg [Get] to parameter [Method]
DEBUG: ParameterBinding Information: 0 :         COERCE arg to [Microsoft.PowerShell.Commands.WebRequestMethod]
DEBUG: ParameterBinding Information: 0 :             Trying to convert argument value from System.String to
Microsoft.PowerShell.Commands.WebRequestMethod
DEBUG: ParameterBinding Information: 0 :             CONVERT arg type to param type using LanguagePrimitives.ConvertTo
DEBUG: ParameterBinding Information: 0 :             CONVERT SUCCESSFUL using LanguagePrimitives.ConvertTo: [Get]
DEBUG: ParameterBinding Information: 0 :         BIND arg [Get] to param [Method] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     BIND arg [System.Collections.Hashtable] to parameter [Body]
DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.Object]
DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :         BIND arg [System.Collections.Hashtable] to param [Body] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     BIND arg [application/json] to parameter [ContentType]
DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.String]
DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :         BIND arg [application/json] to param [ContentType] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Invoke-RestMethod]
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Invoke-RestMethod]
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing

After that, the output is identical for one line:

DEBUG: ParameterBinding Information: 0 : BIND PIPELINE object to parameters: [Where-Object]

Then, the output from

Get-bmaOrgUnit | Where-Object { $_.HierarchyPath -match '^Log*' }

is simply

DEBUG: ParameterBinding Information: 0 :     PIPELINE object TYPE = [System.Object[]]

the output from

$orgunits = Get-bmaOrgUnit
$orgunits | Where-Object { $_.HierarchyPath -match '^Log*' }

is

DEBUG: ParameterBinding Information: 0 :     PIPELINE object TYPE = [System.Management.Automation.PSCustomObject]
DEBUG: ParameterBinding Information: 0 :     RESTORING pipeline parameter's original values
DEBUG: ParameterBinding Information: 0 :     Parameter [InputObject] PIPELINE INPUT ValueFromPipeline NO COERCION
DEBUG: ParameterBinding Information: 0 :     BIND arg [@{Id=06D3D15A-5A54-4F51-97D4-3B0CBBC35369;
ParentId=3B95BC5C-7902-4FBE-BD30-02D979E58BC7; Name=Hotfix; GuidParent=3B95BC5C-7902-4FBE-BD30-02D979E58BC7; Comment=;
HierarchyPath=[Applications]\Software\Basis\Hotfix; Extension=}] to parameter [InputObject]
DEBUG: ParameterBinding Information: 0 :         BIND arg [@{Id=06D3D15A-5A54-4F51-97D4-3B0CBBC35369;
ParentId=3B95BC5C-7902-4FBE-BD30-02D979E58BC7; Name=Hotfix; GuidParent=3B95BC5C-7902-4FBE-BD30-02D979E58BC7; Comment=;
HierarchyPath=[Applications]\Software\Basis\Hotfix; Extension=}] to param [InputObject] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Where-Object]
DEBUG: ParameterBinding Information: 0 : BIND PIPELINE object to parameters: [Where-Object]

This output is repeated for every object that is returned.

After this, there a similar differences at

DEBUG: ParameterBinding Information: 0 :     RESTORING pipeline parameter's original values
DEBUG: ParameterBinding Information: 0 :     Parameter [InputObject] PIPELINE INPUT ValueFromPipeline NO COERCION

and

DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Where-Object]

I can post these differences if needed but from what I understand those are the result from the differences at

DEBUG: ParameterBinding Information: 0 : BIND PIPELINE object to parameters: [Where-Object]

I hope this contains the information you need.

I finally got it to work. I changed the Invoke-RestMethod call from

process
{
    $body = @{ }
     
    # Building the body... 
            
    $url = $script:url + 'OrgUnits'
    Invoke-RestMethod -Uri $url -Credential $cred -Method Get -Body $body -ContentType "application/json"
}

to

process
{
    $body = @{ }
     
    # Building the body... 
            
    $url = $script:url + 'OrgUnits'
    $response = Invoke-RestMethod -Uri $url -Credential $cred -Method Get -Body $body -ContentType "application/json"

    $response
}