cancel
Showing results for 
Search instead for 
Did you mean: 

Building a nested JSON body in PowerShell - making a PUT call to JC's policy API

shawnsong
Rising Star III
Rising Star III

In the recent collaboration with @JuergenKlaassen by taking on a mini challenge on PowerShell:

Build a nested JOSN body to be able call a PUT (change settings) on policy API - appending on the existing setting (the nature of PUT request, you will have to append the changes with existing settings, otherwise the changes will overwrite the existing settings where is not ideal and disruptive).

The Use Case

Juergen has an idea for mass producing reg key entries on our "Windows - Advanced: Custom Registry Keys" policy (with recently updated capability for accepting multiple reg key entries in its setting).

Imagine the things you can do via the policy vehicle by moderating the Windows registry:

  • AppLocker - to restrict / block certain applications.
  • Edge policies - mandating the edge policies.
  • Windows Hardening - with CIS benchmark 😉 (I would suggest split into multiple policies considering the amount of reg keys to change)

So you can pre-config these settings on test Windows box, export the reg keys, use this script to export to CSV, update the policy roll out to your Windows flee.

How

TL;DR -

  • You can find the script for exporting a reg key path with all values recursively.
  • And the script for make changes to "Windows - Advanced: Custom Registry Keys" policy.

The Long Story

Let's take a look what are we dealing with here - the body to build in the PUT request:

Screenshot 2022-12-02 at 9.17.56 AM.png

so, first thing first - get and capture the existing settings:

$url = "https://console.jumpcloud.com/api/v2/policies/" + $policyID

$importedKeys = Import-Csv $csvPath
$response = Invoke-RestMethod -Uri $url -Method GET -Headers $headers
$existingkeys = $response.values.value

Then, let's prepare the structure:

# Constructing the body structure, and stitching with the existing values
$body = @{} | select name,values,template
$newvalue = @{} | select value,configFieldID,configFieldName,sensitive
$newkeysOut = @()

Now we have another layer - value array to build:

foreach ($iKey in $importedKeys){


    # Our reg key policy only supports HKLM at the moment:
    #https://support.jumpcloud.com/s/article/Create-Your-Own-Windows-Policy-Using-Registry-Keys

    if ($ikey.Path -contains "HKCU:") {
        Write-Output "$($iKey.path) $($ikey.Name) will not be imported as the policy doesn't support keys in HKCU"
    }
    else {
        $newKey =  [pscustomobject]@{
            "customLocation" = $ikey.path.replace("HKLM:\","")
            "customValueName" = $ikey.name
            "customRegType" = $type
            "customData" = $iKey.value
    
        }
    }
    $newkeysOut += $newKey
}

if ($null -ne $existingkeys) {
    $newkeysOut += $existingkeys
}

Putting it together with the existing reg keys:

# Contiune building the body - putting the structure together
$newvalue.value += $newkeysOut
$newvalue.configFieldID = $response.values.configFieldID
$newvalue.configFieldName = $response.values.configFieldName
$newvalue.sensitive = $response.values.sensitive

$body.name = $policyName
$body.template = @{"id"="5f07273cb544065386e1ce6f"} # hardcoding the universally applicable template ID
$body.values += $newvalue
$body = $body | ConvertTo-Json -Depth 10
$body = $body.Replace("Values","values")

Check your $body should look like this (after converting to JSON):

{
  "name": "your policy name",
  "values": [
    {
      "value": [
        {
          "customLocation": "SOFTWARE\\Policies\\Microsoft\\Edge",
          "customValueName": "AdsSettingForIntrusiveAdsSites",
          "customRegType": "DWORD",
          "customData": "2"
        },
        {
          "customLocation": "SOFTWARE\\Policies\\Microsoft\\Edge",
          "customValueName": "AllowedDomainsForApps",
          "customRegType": "String",
          "customData": "somestrings"
        },
        {
          "customData": "2",
          "customRegType": "DWORD",
          "customLocation": "SOFTWARE\\Policies\\Microsoft\\Edge",
          "customValueName": "AdsSettingForIntrusiveAdsSites"
        },
        {
          "customValueName": "AllowedDomainsForApps",
          "customData": "somestrings",
          "customRegType": "String",
          "customLocation": "SOFTWARE\\Policies\\Microsoft\\Edge"
        }
      ],
      "configFieldID": "",
      "configFieldName": "customRegTable",
      "sensitive": false
    }
  ],
  "template": {
    "id": "5f07273cb544065386e1ce6f"
  }
}

All good, let's make the change!

$change  = Invoke-RestMethod -Uri $url -Method Put -Headers $headers -Body $body

Changes applied!

Screenshot 2022-12-02 at 9.46.48 AM.png

Happy PowerShell-ing!

0 REPLIES 0