skip to Main Content

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:Usersmichael.dawsonOneDrive - Sage Software, IncDocumentsSource_Controlsecrets-dashboard-scriptfunctionCalculaterecreate-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"
  }

2

Answers


  1. 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, $logsas-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.

    Login or Signup to reply.
  2. 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 
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search