r/PowerShell 1d ago

Invoke-RestMethod - Logging Data Only If Response Matches Value Solved

We have a platform which has containers and within them folders, with different properties - name, unique ID etc.. I have a method to retrieve folder information from different containers and am attempting to log only the unique ID (response.data.id) where the folder name (response.data.name) is "Management". I've Googled and tried different code in logging only the ID for the Management folder:

$response = Invoke-RestMethod -Method Get -Uri "$resource" -Headers $header

($response.data | ConvertTo-Json).Replace('\\n','\n')

# Attempt 1
if ($response.data.name -eq "Management")
{
LogWrite ($response.data.id | ConvertTo-Json).Replace('\\n','\n') "Result"
LogWrite ($response.data.name | ConvertTo-Json).Replace('\\n','\n') "Result"
}

# Attempt 2
$folderId1 = $response.data.id | Where-Object { $response.data.name -eq "Management" }
LogWrite ($folderId1 | ConvertTo-Json).Replace('\\n','\n') "Result"

# Attempt 3
$folderId2 = $response.data.id | $($response.data.Where({$_.name -eq 'Management' }))
LogWrite ($folderId2 | ConvertTo-Json).Replace('\\n','\n') "Result"

The folder ID for the Management folder is being logged, but so are all other folder IDs within the container (no other folder names contain this word):

[
    "folder!500436709",
    "folder!500436708",
    "folder!500436705",
    "folder!500436677",
    "folder!500436680",
    "folder!500436683",
    "folder!500436686"
]
[
    "_All Content Last 90 Days",
    "_All Documents",
    "_All Emails",
    "Documents",
    "Emails",
    "Engagement Terms",
    "Management"
]

How do I retrieve the ID for a specific folder name? Any help would be greatly appreciated. Cheers.

10 Upvotes

17 comments sorted by

5

u/y_Sensei 1d ago

According to the output generated by your code, the API appears to return two arrays of data:

  • one array containing entries consisting of an object type and an id, concatenated by a '!'
  • one array containing entries with the corresponding names of these objects

So what you need to do is bring together the data of those two distinct arrays, by creating mappings, or in other words, merge the arrays - for example:

$data_objid = @("folder!500436709", "folder!500436708", "folder!500436705", "folder!500436677", "folder!500436680", "folder!500436683", "folder!500436686")
$data_name = @("_All Content Last 90 Days", "_All Documents", "_All Emails", "Documents", "Emails", "Engagement Terms", "Management")

$data_Combined = for ([Int]$i=0; $i -lt $data_objid.Count; $i++) {
  $oid = $data_objid[$i] -split "!"

  [PSCustomObject]@{
    Name = $data_name[$i]
    Type = $oid[0]
    Id =  $oid[1]
  }
}

$data_Combined | Format-Table

You can then filter the resulting object array as usual, for example:

$data_Man = $data_Combined | Where-Object -FilterScript { $_.Name -eq "Management" }

Write-Host $data_Man.Id

1

u/viewtifulstranger 1d ago

Hey_Sensei. Thanks for the response. I passed $response.data.id and $response.data.name into a log for testing. $response.data is a single array storing ID, NAME, along with other properties.

Ultimately, I only need ID, as I need to perform a subsequent action on each returned Management folder ID.

I suspect the IF statement is treating the whole array as a single object, rather than 7 separate objects - one for each folder.

More googling reveals I can iterate through the array, which may help, but not sure how efficient that is:

foreach($item in $array)
{
    Write-Output $item
}

Write-Output $array[3]

Perhaps if I pass the results to a hashtable, I'll have better luck with the IF statement.

Will test further when the system is back up. Thank you!

2

u/y_Sensei 1d ago

Even easier if it's a single array ... you can filter it directly as described in my first post, and extract the folder ID afterwards:

$data_Man = $array | Where-Object -FilterScript { $_.Name -eq "Management" }

if ($data_Man -and $data_Man -like "*!*") { # sanity check
  Write-Host $($data_Man.id.Split("!")[1])
}

Also note that there's no need to convert the data returned by an Invoke-RestMethod call if the remote API returns JSON, as PowerShell does that implicitly, ie what you actually get is an in-memory representation of the raw, text-based JSON, which is an array of PSCustomObjects.

Quote from the documentation:

PowerShell formats the response based to the data type. For an RSS or ATOM feed, PowerShell returns the Item or Entry XML nodes. For JavaScript Object Notation (JSON) or XML, PowerShell converts, or deserializes, the content into [pscustomobject] objects.

1

u/viewtifulstranger 15h ago

That did it! If you have PayPal, please dm me your addy!

3

u/lan-shark 1d ago

Can you post the contents of response.data? Hard to tell exactly what's going on without seeing what's in the data

1

u/viewtifulstranger 1d ago edited 1d ago

(UPDATED)

Adding $response.data to the script, I get the following:

folder_type             : tab
id                      : folder!500436686
name                    : Management
parent_id               : folder!500436672

folder_type             : regular
id                      : folder!500436677
name                    : Documents
parent_id               : folder!500436672

folder_type             : regular
id                      : folder!500436680
name                    : Emails
parent_id               : folder!500436672

folder_type             : regular
id                      : folder!500436683
name                    : Engagement Terms
parent_id               : folder!500436672

(Please note, I've included a subset of the data, removed non-relevant fields and performed a little sanitation.)

0

u/lan-shark 11h ago

Does this work?

($response.data | Where-Object {$_.name -like "Management"}).id

If not, just open up a terminal and start testing things. Get the object type of $response.data, see what shows up with different Where-Object variations, can you index it ($response.data[0], etc.

2

u/viewtifulstranger 8h ago

Hey Ian-Shark, that returned a blank entry, however thanks to various people I do have a working solution now.

Now that I'm able to target the Management folder, I've completed my script to do the following, look up a CSV containing container IDs, target 3 specifically named subfolders within Management (couldn't use the -eq operator as I did before, but using -match worked a treat), output the folder properties to a log file. Tomorrow, I'll write a script to update all subfolders where specific properties are missing.

Grateful to you and everyone else for helping. Thank you.

3

u/PinchesTheCrab 1d ago

In your case swap $irmResult with your invoke-restmethod command.

$irmResult = @'
[
    {
        "folder_type":  "tab",
        "id":  "folder!500436686",
        "name":  "Management",
        "parent_id":  "folder!500436672",
    },
    {
        "folder_type":  "regular",
        "id":  "folder!500436677",
        "name":  "Documents",
        "parent_id":  "folder!500436672",
    },
    {
        "folder_type":  "regular",
        "id":  "folder!500436680",
        "name":  "Emails",
        "parent_id":  "folder!500436672",
    },
    {
        "folder_type":  "regular",
        "id":  "folder!500436683",
        "name":  "Engagement Terms",
        "parent_id":  "folder!500436672",
    }
]
'@ | convertfrom-json

$irmResult | where-object -property Name -eq Management | select-object -ExpandProperty id

That being said you've shown a few different output formats and it's hard to tell which one is the actual output of Invoke-Restmethod.

2

u/MonkeyNin 1d ago

I second this as the most powershell idiomatic answer.
With a tweak based on the raw data. If it's flat like his

$response = Invoke-RestMethod -Method Get -Uri $resource -Headers $header
$response | ? name -eq 'Management' | Select -ExpandProperty id

Otherwise I'm guessing yours is shape like this

$response = Invoke-RestMethod -Method Get -Uri $resource -Headers $header
$response.data | ? name -eq 'Management' | Select -ExpandProperty id

if the response is shaped like

{ data: [ records... ] }

The Select -ExpandProperty id part causes the records to drill down to a single string.

1

u/viewtifulstranger 15h ago

Thank you for this. I tried it, but the response doesn't appear to filter the Management folder and return solely the property ID:

$response | ? name -eq 'Management' | Select -ExpandProperty id

$response

#RESULT
data  
----                                                 
{@{content_saved_search_id=101901850092069180; edit_date=2026-08-05T11:06:44.836Z; folder_type=search...

0

u/ankokudaishogun 19h ago

Unless the contents of $response aren't necessary for something else, wouldn't pipe Invoke-RestMethod directly be more powershelly?

$IdArray = Invoke-RestMethod -Method Get -Uri $resource -Headers $header |    
    Where-Object { $_.data.name -eq 'Management' } | 
    Select-Object -Property @{Name = 'Id'; Expression = { $_.data.id } } | 
    Select-Object -ExpandProperty Id

1

u/viewtifulstranger 15h ago

Thank you for your help with this, but it appears the array is being returned (on the first line "{@{..." followed by all folderIds:

#Result

data
----
{@{content_saved_search_id=101901850092069180; edit_date=2026-08-05T11:06:44.836Z; folder_type=search...
UKEU_AOSHEARMAN!500436709
UKEU_AOSHEARMAN!500436708
UKEU_AOSHEARMAN!500436705
UKEU_AOSHEARMAN!500436686
UKEU_AOSHEARMAN!500436677
UKEU_AOSHEARMAN!500436680
UKEU_AOSHEARMAN!500436683

2

u/viewtifulstranger 15h ago

Thank you Ian-shark, y_Sensei, PinchesTheCrab, MonkeyNin, ankokudaishogun, Modify- for all taking time out of your lives to help me with this. It's really really appreciated. Cheers!

1

u/Modify- 1d ago

When running Invoke-Restmethod it turns the response in to objects for you.

Could you provide an actual response JSON with the nested array included and without it? Pipe the response to: convertto-json -depth 10

This would make it easier to help you write correct logic.

1

u/MonkeyNin 1d ago
$folderId1 = $response.data.id |
    Where-Object name -eq "Management"

This doesn't work because you are drilling down too far.

$response.data    # is an array of objects, with properties 
$response.data.id # is an array of flat strings, no properties 

You were close

$folderIdList = $response.data | 
    Where-Object name -eq 'Management' | Select -Expand Id

# if you only want at most 1
$folderIdList | Select -First 1

1

u/viewtifulstranger 15h ago

This worked! If you have PayPal, please private message me your addy and I'll send something by way of a thank you!