Your output implies that $GetInfo.data is an array, which means that a property access such as .Date uses member-access enumeration, which means that the .Date values of all array elements are returned.
Thus, you need an inner loop as well:
foreach($GetInfo in $IDInfo)
{
# Loop over the elements of the array in .data
foreach ($element in $GetInfo.data) {
$Id = $element.Date
$Name = $element.ProductId
# ... work with these variables here;
# e.g., output their values (don't use Write-Host, unless
# you want to print to the display only).
$Id, $Name
}
}
Note that, as Jeroen Mostert points out, passing your sample JSON text to ConvertFrom-Json conveniently parses the JSON array into .NET objects (of type [pscsustomobject]), whose properties you can access:
However, there is a caveat in Windows PowerShell (no longer in PowerShell (Core) 7+):
Note: Given that your sample JSON input has extraneous trailing , chars. after each object's final property, I'm assuming you're using PowerShell (Core), because Windows PowerShell would complain about that; however, the pitfall discussed below is still worth pointing out for future readers.
If you're directly processing the output from a ConvertFrom-Json or Invoke-RestMethod call that parses a JSON array and you want to process the resulting objects one by one, force ConvertFrom-Json to enumerate the top-level array parsed from JSON by enclosing the call in (...):
$json = @'
[
{
"Date": "19/5/2022",
"ProductId": "0001",
"ProductName": "Fizzy Drink",
"Cost": "2.32",
"Currency": "USD"
},
{
"Date": "16/5/2022",
"ProductId": "0002",
"ProductName": "Dark Chocolate",
"Cost": "6.52",
"Currency": "USD"
},
{
"Date": "10/5/2022",
"ProductId": "0003",
"ProductName": "Snacks",
"Cost": "4.2",
"Currency": "USD"
}
]
'@
# Note the (...) around the ConvertFrom-Json call, required in Windows PowerShell.
# The same would apply if you send the ConvertFrom-Json output to the *pipeline*:
# (ConvertFrom-Json $json) | ForEach-Object { "This date: " + $_.Date }
foreach ($obj in (ConvertFrom-Json $json)) {
"This date: " + $obj.Date
}
Background:
In versions before PowerShell (Core) 7.0, ConvertFrom-Json and Invoke-RestMethod send arrays parsed from JSON as a whole through the pipeline, rather than element by element, leading to unexpected behavior.
Enclosing a command (pipeline) in (...), the grouping operator causes these arrays to be enumerated.
See this answer for more information.