Forum Discussion

Procradminator's avatar
Procradminator
Copper Contributor
Oct 16, 2023

API calls with Invoke-RestMethod being funny!

Hello all   I suspect I'm missing something simple and hopefully someone will quickly point me in the right direction.   Please excuse the terrible code - I'll try and sort it once it works.....h...
  • LainRobertson's avatar
    Oct 16, 2023

    Procradminator 

     

    Hi, Andrew.

     

    This is expected, as the stream output from your first command produces an object that is not the same as the stream output from the second command.

     

    When you run the two commands together within the script, generally, their separate output will be written to the parent script's output stream, meaning what was separate is now "concatenated" into one stream.

     

    When you have objects of different types written to the same stream in close proximity like what you've described, PowerShell only looks at the first object type from the stream (from which it builds a dictionary of attribute names) and outputs - to the screen - attributes from subsequent objects that existed in the first object.

     

    You can reproduce this "first object type wins" scenario with the following contrived example.

     

    Example

    $Output = @(
        # First object with two properties.
        [PSCustomObject] @{
            "Property1" = "Value1";
            "Property2" = "Value2";
        },
    
        # Second object with three different properties.
        [PSCustomObject] @{
            "Property3" = 3;
            "Property4" = 4;
            "Property5" = $true;
        }
    )

     

    Output

    The first command shows PowerShell only displaying the first object within Output since the second doesn't match, yet it's still present as shown when the second object is explicitly referenced.

     

    Notice how the second object is not written to the screen at all since it has no attributes in common with the first object? Yet it still clearly exists in the data?

     

     

    So, how does this relate to your script? After all, you're running separate commands, not an array like my example.

     

    This comes back to what I said about "close proximity".

     

    From the first command, you're getting output that includes two attributes:

     

    • status
    • statusDescription

     

    From the second command, you get seven attributes, however, only one of those is common with the first command:

     

    • status

     

    This is why you see the full output from your first command but only the "status" attribute from the second.

     

    If all you care about is the displayed output rather than the actual data stream, you can "control" this "issue" by appending a "Out-Default" command to the end of each command like so:

     

    # First command.
    Invoke-RestMethod <blah blah blah> | Out-Default;
    
    # Second command.
    Invoke-RestMethod <blee blee blee> | Out-Default;

     

    The Out-Default will force the output of each command to be written to the display (which is typically the default device).

     

    In summary, the issue is that the two commands produce different output which impacts what is displayed on the screen when run inside a script, but not what is returned in the data stream of that script.

     

    You can "fix" the screen output by appending Out-Default to your individual commands.

     

    Cheers,

    Lain

Resources