0

I'm fairly new to Powershell. I'm trying to build the body for an Invoke-PowerBIRestMethod to update parameters in the Power BI report. The format is

Invoke-PowerBIRestMethod -Url $url -Method Post -Body ("$body")

This is the body I've been using in my testing and it works, the parameter ServerName in the report is updated with the $NewServerName value:

$body = @"
{
    "updateDetails": [
        {
            "name": "ServerName", "newValue": "$NewServerName"
        }
    ]
}
"@

Requirements have changed and I need to make this more dynamic. Instead of hardcoding the parameter that needs to be updated the users will manually enter the ordered pair. And there could be more than one parameter that needs updating.

I'm not sure the best way to format the input parameters. I'm thinking they type param1:newvalue;param2:newvalue;param3:newvalue, etc. It needs to be as simple as possible since users will be entering this. Then in the Powershell script I'll parse that into the $body format.

And I'm not sure how to parse the input parameter into the $body format. The format will end up being like this:

$body = @"
{
    "updateDetails": [
        {
            "name": "$param1", "newValue": "$newvalue1"
        },
        {
            "name": "$param2", "newValue": "$newvalue2"
        }
    ]
}
"@

Can anyone offer some suggestions?

mklement0
  • 382,024
  • 64
  • 607
  • 775
Rich Uchytil
  • 457
  • 1
  • 7
  • 16
  • Deserialize using [`ConvertFrom-Json`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertfrom-json), make your changes to the PowerShell object and serialize it with `ConvertTo-Json`. – iRon Nov 23 '21 at 18:51
  • Thanks! I didn't end up using this but it did help me find the solution and was something I didn't know about, so good to learn new things. – Rich Uchytil Nov 23 '21 at 22:00

2 Answers2

1

Using your example name/value inputs, Better create the body like below:

$UpdateData = 'ServerName;facetsmo03;Dataset;Interop Oversight'.Split(';')

$body = [PsCustomObject]@{
    updateDetails = for ($i = 0; $i -lt $UpdateData.Count; $i += 2) {
                        [PsCustomObject]@{name = $UpdateData[$i]; newvalue = $UpdateData[$i + 1]}
                    }
} | ConvertTo-Json

$body now contains this JSON string:

{
    "updateDetails":  [
                          {
                              "name":  "ServerName",
                              "newvalue":  "facetsmo03"
                          },
                          {
                              "name":  "Dataset",
                              "newvalue":  "Interop Oversight"
                          }
                      ]
}

You may want to post a condensed version of this, and for that append switch -Compress to the ConvertTo-Json cmdlet creating a $body like this:

{"updateDetails":[{"name":"ServerName","newvalue":"facetsmo03"},{"name":"Dataset","newvalue":"Interop Oversight"}]}
Theo
  • 57,719
  • 8
  • 24
  • 41
0

I figured a way to get what I need. It's simply parsing a string and creating a string. I was trying to figure out arrays and all that but in the end all I needed to do was create a string formatted correct. Here's the code that works in case anyone is interested. $UpdateParams will be a parameter and what's in that is what someone will type. There's probably better ways to do this but this works, so I'm good for now. :)

$UpdateParams = "ServerName;facetsmo03;Dataset;Interop Oversight"
$UpdateData = $UpdateParams.split(';')


# SETUP BEGINNING OF BODY
$body = '@"' + "`n" + "{" + "`n" + '"updateDetails": [ ' + "`n"

foreach ($item in $UpdateData) {
    if ($UpdateData.IndexOf($item) % 2 -eq 0) {
        # ADD NAME OF PARAMETER TO CHANGE
        $body += "{`n" + '"name":' + '"' + $item + '"' + ",`n"
    }
    else {
        # ADD NEW VALUE FOR PARAMETER
        $body += '"newValue":' + '"' + $item + '"' + "`n" + "},`n"
    }
}

# ADD ENDING BODY TEXT
$body = $body.Substring(0,$body.Length - 2) + "`n]`n}`n" + '"@'
$body
Rich Uchytil
  • 457
  • 1
  • 7
  • 16
  • With all respect, directly peeking and poking into serialized strings (as e.g. [`json`](https://en.wikipedia.org/wiki/JSON) is a bad practice (as is hard to accommodate for rules as potential special characters). Instead use the related cmdlets (or methods) to deserialize and serialize it such as [`ConvertFrom-Json`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/convertfrom-json) and [`ConvertTo-Json`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/convertto-json). – iRon Nov 24 '21 at 09:06
  • Besides using the increase assignment operator (`+=`) to create a string might get pretty expensive. Instead use the PowerShell pipeline as explained in [Is there a string concatenation shortcut in PowerShell?](https://stackoverflow.com/a/70093215/1701026) – iRon Nov 24 '21 at 09:06
  • I'm sure there's a better way than what I came up with. I don't know what cmdlets to use and how to write the code, which is why I asked this question. The answer below looks good, I'm going to play with it. – Rich Uchytil Nov 24 '21 at 16:00