Result of Invoke-RestMethod not working in pipeline?

This topic contains 3 replies, has 2 voices, and was last updated by  Maurice 3 months, 2 weeks ago.

  • Author
    Posts
  • #73165

    Maurice
    Participant

    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?

  • #73184

    Don Jones
    Keymaster

    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.)

  • #73348

    Maurice
    Participant

    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.

  • #74414

    Maurice
    Participant

    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
    }
    

You must be logged in to reply to this topic.