Reputation: 51
I can't for the life of me work out how to add elements to an array inside a foreach loop. I keep getting the error:
8 | $logs.Add(@{
| ~~~~~~~~~~~~
| Cannot find an overload for "Add" and the argument count: "1".
MethodException: C:\Users\michael.dawson\OneDrive - Sage Software, Inc\Documents\Source_Control\secrets-dashboard-script\function\Calculate\recreate-error2.ps1:8:5
I can get it to work outside of a foreach, but I've been scratching my head for ages :-( Here's the code:
$logs = New-Object System.Collections.ArrayList
$logs = $null
$logs = @{}
Get-Service | ForEach-Object {
$appCreds = $_
$logs.Add(@{
"test" = $appCreds.DisplayName;
"message" = "blah"
})
}
$logs | ConvertTo-Json -Depth 10
Appreciate any help guys. Cheers.
I'm expecting some JSON a bit like this:
{
"message": "blah",
"test": "Optimise drives"
},
{
"message": "blah",
"test": "Dell Client Management Service"
},
{
"message": "blah",
"test": "DeviceAssociationBroker_1592b90"
}
Upvotes: 2
Views: 836
Reputation: 437608
Try the following:
$logs =
Get-Service |
ForEach-Object {
@{
test = $_.DisplayName;
message = "blah"
}
}
$logs | ConvertTo-Json -Depth 10
The above takes advantage of:
Being able to use the results of entire commands as expressions, relying on PowerShell implicitly collecting the command's output objects in the target variable, $logs
- as-is in the case of a single output object, and as an array (of type [object[]]
in the case of two ore more output objects.
PowerShell's implicit output behavior, where the output (result) from a command or expression is implicitly output.
As for what you tried:
$logs = New-Object System.Collections.ArrayList
$logs = $null
$logs = @{}
Each statement overrides the previous one, so that $logs
ends up containing @{}
, i.e. an empty hashtable.
Thus, a later $logs.Add(...)
call with a single argument predictably fails, because a hashtable's .Add()
method requires two arguments, namely a key and and a value, separately - which isn't what you intended, however.
While you could have avoided this problem by making do with just $logs = New-Object System.Collections.ArrayList
as the variable initialization, given that that type's .Add()
method accepts any single object to append to the list, the solution at the top shows a PowerShell-idiomatic solution that is both simpler and more efficient.
Upvotes: 1
Reputation: 573
I am in rush but, I want to help. Try the example below.
$logs = New-Object System.Collections.ArrayList
Get-Service | ForEach-Object {
$appCreds = $_
$logs.Add(@{
"test" = $appCreds.DisplayName;
"message" = "blah"
}) | out-null
}
$logs | ConvertTo-Json -Depth 10
Upvotes: 0