Search code examples
jsondockerpowershellwindows-terminal

Edit Windows Terminal profiles settings JSON from PowerShell


I am working on a PowerShell script that creates a Fedora WSL using docker, it all works, but I cannot get to work the code part which sets the icon in the settings.json file.

Relevant part of the JSON:

"profiles": 
    {
        "defaults": {},
        "list": 
        [
            {
                "commandline": "PATH\\TO\\WSL",
                "guid": "{your-guid}",
                "hidden": false,
                "name": "fedora",
                "icon": "PATH\\TO\\ICON"
            },
            {
                "commandline": "cmd.exe",
                "guid": "{your-guid}}",
                "hidden": false,
                "name": "Command Prompt"
            },
            {
                "guid": "{your-guid}}",
                "hidden": false,
                "name": "Azure Cloud Shell",
                "source": "Windows.Terminal.Azure"
            },

Here is what I've tryied:

$settings = Get-Content $env:localappdata'\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json' -raw | ConvertFrom-Json
$settings.profiles.list | % {if($_.name -eq $WSLname){$_.icon=$InstallPath\fedora.ico}}
$settings | ConvertTo-Json -depth 32| set-content $env:localappdata'\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json'

Variables are taken from params in first part of the script.
My goal is to chech if the profile name with given input by the user exists, if so, changes or adds the "icon" property to the fedora.ico path.

Edit: This part of the script needs to run after windows terminal has been relaunched.


Solution

  • Here is how you can approach the logic for your code to check if the icon property exists and assign a new value to it and if it doesn't exist, add a new property to the object with the new value. Hope the inline comments helps you understand the logic.

    $settings = Get-Content 'path\to\settings.json' -Raw | ConvertFrom-Json
    # enumerate all objects in `.profiles.list`
    foreach($item in $settings.profiles.list) {
        # if the `Name` property is not equal to `$WSLName`
        if($item.name -ne $WSLname) {
            # we can skip this object, just go next
            continue
        }
        # if we're here we know `$item.name` is equal to `$WSLname`
        # so we need to check if the `icon` property exists, if it does
        if($item.PSObject.Properties.Item('icon')) {
            # assign a new value to it
            $item.icon = "$InstallPath\fedora.ico"
            # and go to the next element
            continue
        }
        # if we're here we know `$item.name` is equal to `$WSLname`
        # but the `icon` property does not exist, so we need to add it
        $item.PSObject.Properties.Add([psnoteproperty]::new('icon', "$InstallPath\fedora.ico"))
    }
    $settings | ConvertTo-Json -Depth 32 | Set-Content 'path\to\newsetting.json'