Search code examples
powershellfor-loopvariables

Conditionally format a string in a for-each loop


This is my scenario:

I have an API that I'm calling via Powershell, the payload is a JSON file, this API needs to be called multiple times and each time, the payload is slightly different (think adding items to a list).

Here's an example of the JSON template.

$JSONpaylod = @"
{
  "Config":
  {
  "address": $variable1,
  "authPassword": $variable2,
  "authUsername": $variable3}
}
"@

Because it needs to be done multiple times, I'm going to use a For-Each loop, e.g:

For-each($_.item in $list){
Do things, then call the API}

However, where I'm stuck is that based on the current item in $list, I want to update $variable1, $variable2 and so on based on a lookup.

Is there an elegant way to do this in PowerShell? One thought is that in my Hash table for $list, to have it like this:

Item, var1, var2, var3  
1, 23, 1111, admin  
2, 10, 1234, admin  

but it seems like that would be clunky to have

$variable1 = $_.var1 etc.

Is there a better way to do this, or am I overthinking this?


Solution

  • I would recommend you to use a CSV as input and construct objects that follow the structure of your Json payload then from there you can use ConvertTo-Json to convert them into a Json string. The benefit from doing this is that ConvertTo-Json handles the escaping of characters that must be escaped in a Json string, i.e. ", \, / and so on.

    $csv = @'
    var1, var2, var3
    23, 1111, admin
    10, 1234, admin
    '@ | ConvertFrom-Csv
    
    foreach($item in $csv) {
        $payload = [pscustomobject]@{
            Config = [pscustomobject]@{
                address      = $item.var1
                authPassword = $item.var2
                authUsername = $item.var3
            }
        } | ConvertTo-Json
    
        # do stuff with payload
    }
    

    As an example, the following would fail exactly where the " would be interpolated (line 3, position 20.).

    Conversion from JSON failed with error: After parsing a value an unexpected character was encountered: b. Path 'Config.address', line 3, position 20.

    $item = 'foo"bar'
    
    @"
    {
      "Config": {
        "address": "$item"
      }
    }
    "@ | ConvertFrom-Json
    

    And this would work:

    [pscustomobject]@{
        Config = [pscustomobject]@{
            address = 'foo"bar'
        }
    } | ConvertTo-Json | ConvertFrom-Json