Skip to content
WSLDeep Dive Published Updated 7 min readViews unavailable

Engineering Windows Terminal Profiles for WSL Distributions

Build predictable Windows Terminal profiles for named WSL distributions, Linux working directories, dynamic entries, command-line launches, and troubleshooting.

Windows Terminal is a Windows host for console applications, not a Linux shell itself. A WSL profile tells that host which Windows-side WSL launcher to start and how to present the session. The launched distribution then supplies its own Linux user, shell, filesystem, and processes. Keeping those layers explicit prevents a profile that looks like Ubuntu from silently launching the wrong distribution or starting in an unexpected directory.

This guide treats a profile as a reproducible launch contract: name the distribution, choose a Linux working directory, keep generated profiles distinct from custom ones, and verify the result from both sides of the boundary. It is about Terminal configuration, not a replacement for the WSL command-line interface.

Inventory the WSL identities before editing Terminal

Profile names are user-facing labels; they are not guaranteed to be the registered distribution names. List the actual names and versions from PowerShell:

wsl.exe --list --verbose
wsl.exe --list --quiet

The distribution value passed to WSL must match a registered name such as Ubuntu-24.04, not a guess based on a tab title. Also identify the intended Linux account and directory inside that distribution:

wsl.exe --distribution Ubuntu-24.04 --user alice --exec id
wsl.exe --distribution Ubuntu-24.04 --user alice --exec pwd

If the distribution is imported, its registered name may differ from the original archive name. Treat this output as the source of truth. Avoid renaming profiles to mask an incorrect distribution mapping.

Understand generated and custom profiles

Windows Terminal can discover WSL distributions and create dynamic profiles for them. Those generated entries are associated with a profile source; Terminal uses that source to refresh generated settings. A manual profile should have its own stable name and should not copy an internal source identifier from a generated entry. Otherwise, a later WSL install, removal, or Terminal refresh can make an edited profile difficult to reason about.

One useful arrangement is to keep the automatically generated distro profile intact, then create a separately named project profile. The custom profile can have its own icon, color scheme, starting directory, and keyboard shortcut without pretending that it is the distribution’s canonical generated entry.

Use a Linux path for a Linux working directory

Terminal’s profile setting named startingDirectory is interpreted by Windows Terminal, so a WSL home directory is addressed through the Windows network namespace that exposes a running distribution. Microsoft documents both the legacy \wsl$ spelling and the current \wsl.localhost spelling. A settings JSON string must escape each backslash. This example is valid JSON:

{
  "name": "Ubuntu 24.04 - project",
  "commandline": "wsl.exe --distribution Ubuntu-24.04",
  "startingDirectory": "\\\\wsl.localhost\\Ubuntu-24.04\\home\\alice\\src",
  "tabTitle": "ubuntu-project"
}

Before relying on it, confirm that /home/alice/src exists and that the default user for this profile can traverse it. A stale UNC path can result in a fallback directory or a launch error, depending on the Terminal and WSL state. Do not point the profile at the VHDX backing file under AppData; Linux files must be accessed through WSL’s supported filesystem interface.

There is a second valid approach: invoke wsl.exe with its documented –cd option and let Linux choose the directory. Do not configure conflicting working directories casually. A host-side UNC startup path and a guest-side –cd are two different controls; one can obscure whether the other is working. Pick one as the authoritative setting and test it from a fresh Terminal launch.

Keep the profile launch command simple

For a custom profile, a direct command line is usually enough:

{
  "name": "Debian - diagnostics",
  "commandline": "wsl.exe --distribution Debian",
  "startingDirectory": "//wsl.localhost/Debian/home/ops"
}

Use the registered distribution spelling exactly. The profile can select a specific user with WSL’s user option when that user exists in the distro. If the distro’s default user is deliberately managed in its configuration, prefer that single source of identity rather than creating multiple contradictory account settings.

Avoid embedding long shell programs in commandline. Windows Terminal starts a Windows executable, WSL starts Linux, and an optional Linux shell parses another command string. This introduces multiple quoting layers. Put nontrivial automation in a version-controlled Linux script and launch that script with a short, explicit WSL command. This keeps the profile declarative and makes script failures independently testable.

Launch a profile from scripts without assuming a shell

Terminal’s command-line interface can select a profile by its displayed name. For example, from PowerShell:

wt.exe -w 0 new-tab --profile "Ubuntu 24.04 - project"

Terminal commands and options are parsed by Windows Terminal, while PowerShell first parses the invocation. When calling wt.exe from a WSL shell, Microsoft documents using cmd.exe /c because Windows execution aliases do not work directly in WSL distributions. Keep that cross-boundary behavior separate from a Linux command that happens to run inside a tab.

Automated launchers should not depend on the active default WSL distro. A profile name is convenient for people, but scripts can invoke wsl.exe –distribution <registered-name> directly when they need a deterministic distro selection. Capture the exit code from the actual process that performs the work; opening a Terminal window is not evidence that a later build or test command succeeded.

Treat default profile and defaults as separate settings

The Terminal default profile determines which entry opens when a new tab is created without a profile selector. It does not change the default WSL distribution. These are independent defaults owned by different programs. A default profile can be configured in Terminal settings, while WSL’s default distro is managed by WSL. Set both deliberately if the workstation should open in a particular environment.

Profile-level properties belong on that profile. Shared visual properties can live under the Terminal defaults object, but launch behavior should remain clear. If all profiles share a starting directory or command line accidentally, inspect whether a global default was placed where it affects more entries than intended.

Diagnose an incorrect startup directory in layers

When a tab opens in the wrong location, inspect the WSL launch context first:

wsl.exe --distribution Ubuntu-24.04 --exec pwd
wsl.exe --distribution Ubuntu-24.04 --exec sh -lc 'printf "HOME=%s\nPWD=%s\n" "$HOME" "$PWD"'

Then inspect the Terminal profile’s effective settings and check whether a shell startup file immediately changes directories. A shell can override the directory that WSL received after startup. PowerShell profiles can similarly change a Windows Terminal host directory before WSL starts. Terminal’s troubleshooting guidance explicitly calls out shell startup scripts as a possible reason that a profile’s starting directory appears to be ignored.

Compare three paths rather than assuming they are identical: Windows Terminal’s starting directory, WSL’s initial current directory, and the final directory after shell initialization. If they differ, test with a minimal profile and a shell launched without user startup files. This isolates the profile from shell configuration without deleting or rewriting the user’s dotfiles.

Acceptance checks for a profile change

Test after editing the JSON in Terminal settings:

  1. Confirm the settings file parses and Terminal opens without showing a configuration warning.
  2. Open each custom profile from the dropdown and by its keyboard shortcut or wt.exe command.
  3. In the Linux shell, run printf ‘%s\n’ “$WSL_DISTRO_NAME”, id -un, and pwd; compare the distro, user, and working directory with the intended values.
  4. Close the tab, then launch a new one. A profile is not verified merely because an already-running shell stayed open.
  5. Test after wsl.exe –shutdown when the change depends on a distribution restart, then launch again and repeat the identity checks.
  6. Keep one unchanged profile available as a recovery path while testing custom JSON.

The result should be a visible, predictable entry point, not a claim that Terminal changes WSL’s lifecycle or security boundary. Terminal manages tabs and console presentation; WSL owns distribution selection and Linux execution.

Related:

Sources:

Comments