2

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"
  }

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

Comments

0

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 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.