MickyD
MickyD

Reputation: 51

Error adding to array: Cannot find an overload for "Add" and the argument count: "1"

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

Answers (2)

mklement0
mklement0

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

Aaron
Aaron

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

Related Questions