Managing Ubuntu WSL Instances Remotely with Landscape's WSL API
Operate Ubuntu WSL fleets through Landscape: register Windows parents, provision named child distros, track asynchronous activities, and verify compliance.
Landscape’s WSL integration manages Ubuntu distributions as child instances of registered Windows computers. The split matters operationally: Landscape identifies a Windows parent host, then represents each Ubuntu WSL distribution as a child with its own installation, registration, running, and compliance state. A Windows host’s ordinary Landscape record is not proof that each WSL distro has been installed and registered, and a successful API request is not proof that a child installation has finished.
This workflow is distinct from configuring WSL locally with wsl.conf or installing a distro with wsl.exe. Ubuntu Pro for WSL and Landscape provide the remote management path; a profile can associate a desired Ubuntu image and optional cloud-init data with selected Windows hosts. Landscape’s WSL API also supports direct child creation and listing, which is useful for controlled automation and lifecycle reporting.
These API calls and PowerShell/WSL operations target Ubuntu Pro for WSL, Landscape, and Windows. They cannot be executed on the macOS authoring host; validate them against a non-production Landscape account and Windows test host first.
Confirm the control plane and feature prerequisites
Ubuntu’s current Landscape documentation lists WSL integration beginning with Landscape 25.10. For a self-hosted Landscape server, WSL management must be enabled in service.conf:
[features]
wsl_management = true
Remote deployment also requires Ubuntu Pro for WSL to be installed and configured on the Windows host, and the Windows host must be registered with Landscape before child distributions can be managed. Follow the current Ubuntu Pro for WSL registration guide for the exact host and subscription prerequisites. Do not confuse this control plane with registering a normal Linux Landscape client inside an arbitrary WSL distro; the documented integration has Windows-host and Ubuntu-child components.
Use Landscape terminology consistently in runbooks. “Windows host” or “parent computer” refers to the machine running WSL. “Child instance” refers to an Ubuntu distribution registered under that host. A child name, WSL distribution name, Landscape computer ID, and parent computer ID are different identifiers. Use the IDs returned by Landscape API responses rather than inferring them from a displayed name.
Inventory before creating or changing children
Start by enumerating Windows hosts that have registered WSL instances, then query the selected parent’s child list. The GET /computers/wsl-hosts endpoint is paginated with limit and offset; the WSL child listing endpoint is keyed by the parent computer’s numeric ID. The child response distinguishes states such as installed, registered, running, and pending. A record with computer_id: null can represent a child whose install or registration is still in progress, so an automation script should not treat every null child ID as a missing distro.
set -euo pipefail
: "${LANDSCAPE_JWT:?Set LANDSCAPE_JWT in the calling environment}"
base='https://landscape.canonical.com/api/v2'
curl --fail --silent --show-error \
-H "Authorization: Bearer ${LANDSCAPE_JWT}" \
"${base}/computers/wsl-hosts?limit=100&offset=0" | jq '.results[] | {id, title, hostname, num_child}'
parent_id=20 # Replace with the computer ID returned by Landscape.
curl --fail --silent --show-error \
-H "Authorization: Bearer ${LANDSCAPE_JWT}" \
"${base}/computers/${parent_id}/children" \
| jq '.children[] | {name, computer_id, version_id, installed, registered, is_running, compliance}'
The API examples use a Landscape-issued bearer JWT. Keep the base URL and parent ID explicit in automation so an operator can tell which control plane and host are being queried. The first endpoint’s limit/offset pagination means a single page is not necessarily the complete fleet; request subsequent pages when count exceeds the current result list. Before issuing a create request, inspect the parent child list and decide how your process handles an existing child with the same intended name.
Landscape also exposes GET /wsl-instance-names to list official Ubuntu WSL image names and GET /wsl-feature-limits to inspect limits available to the account. Query these rather than hard-coding an image alias or assumed fleet capacity into a long-lived deployment tool. The image names and feature limits are control-plane data that can change as Canonical updates supported releases and service plans.
Create a child as an asynchronous activity
POST /computers/<computer_id>/children creates an activity to install a WSL instance on a Windows host. computer_name is required; cloud_init and rootfs_url are optional. The request response is an activity record containing an activity ID and status, not a synchronous installation result. Store that ID in your deployment log, follow the activity in Landscape, and then query the parent child list to confirm the resulting instance state.
set -euo pipefail
: "${LANDSCAPE_JWT:?Set LANDSCAPE_JWT in the calling environment}"
base='https://landscape.canonical.com/api/v2'
parent_id=20
instance_name='Ubuntu-24.04'
cloud_init_file='./wsl-user-data.yaml'
cloud_init_b64=$(base64 --wrap=0 < "$cloud_init_file")
payload=$(jq -n \
--arg name "$instance_name" \
--arg cloud_init "$cloud_init_b64" \
'{computer_name: $name, cloud_init: $cloud_init}')
curl --fail --silent --show-error \
-H "Authorization: Bearer ${LANDSCAPE_JWT}" \
-H 'Content-Type: application/json' \
-X POST "${base}/computers/${parent_id}/children" \
--data "$payload" | jq '{id, type, summary, activity_status, completion_time, result_code}'
The cloud_init API field carries the cloud-init content encoded as base64; the base64 --wrap=0 form matches Canonical’s Linux example and prevents line wrapping inside the JSON string. The example uses jq to build JSON so quotes, line breaks, and YAML indentation are encoded as data rather than hand-escaped. The Ubuntu distribution name shown here is illustrative: query the current supported image names and use a name appropriate for the parent and image source.
If rootfs_url is supplied for a custom root filesystem, the API documentation describes name patterns that return HTTP 400 when they are used with that custom image path. Validate the naming rule before creating the activity. An image URL must be reachable by the Windows host doing the installation, not merely by the Landscape server or a developer’s Linux machine. A profile can be a better fit when the same image and cloud-init configuration should be associated with many hosts rather than submitted as one-off child creation requests.
Prefer profiles for repeatable fleet policy
WSL profiles define the rootfs image, optional cloud-init payload, access group, and association with Windows hosts. Landscape can associate a profile with all hosts in an access group or only hosts carrying selected tags. When a host is associated with a profile, Landscape creates provisioning activities. The profile view also makes it possible to see associated parents and the compliance state of those hosts.
Use profiles when an organization wants a named baseline such as “Web Developer workspace” or “Data Science Ubuntu image” and expects that baseline to be applied consistently to multiple computers. Direct child creation is useful for an explicit one-host operation; profiles make intent and association visible as managed configuration. Do not create both paths for the same target without defining which one owns the child name and rootfs selection.
The profile documentation calls out an important compliance condition: when using WSL profiles, a Windows host must not have unregistered child instances that conflict with the profile’s policy. Depending on the profile association and compliance settings, a manually created distro can be reported as non-compliant. Before associating profiles, inventory existing local WSL distributions and decide whether they will be imported into management, retained outside the profile’s scope, or removed after a backup. Treat “compliant” as the profile policy evaluation, not as a general quality or health score for every application inside Linux.
For custom images, supply a rootfs URL that remains available to target Windows hosts and version the image independently from the cloud-init payload. A new rootfs may replace packages or configuration in ways a later cloud-init file cannot undo. Test profile updates with a pilot host, compare the resulting child state, and document how rollback restores the previous image or instance. Landscape can configure Ubuntu instances with cloud-init at creation time, but cloud-init itself is a first-boot system rather than a continuous desired-state agent.
Read lifecycle fields as a state machine
The child list exposes multiple lifecycle dimensions because “exists” is not a single state. An instance can be associated with a profile but not installed; installed but not yet registered; installed and registered but stopped; or running and compliant. The API response examples include installed, registered, is_running, compliance, profile, and default. Build automation and dashboards around the fields that answer their question rather than collapsing them into one green/red boolean.
For a provisioning gate, wait for the create activity to complete and then verify the child appears under the intended Windows parent, reports installed and registered, and has the expected version/profile. Running state may be transient because a WSL distro can stop when idle; do not require is_running: true as a permanent fleet health predicate unless the operational task is specifically to start it. A pending or unregistered state is not equivalent to a failed install until the activity has had time to run and the error details have been examined.
Deletion is also an activity, not an immediate local wsl --unregister call issued from the API client. The API has a delete-children endpoint that creates activities to remove named child instances. Use the request body and field names from the current API documentation exactly; inspect its result and then reconcile the child’s presence through the parent listing. Do not erase the Windows registration or Linux data manually while Landscape is processing the same lifecycle operation.
Landscape returns a feature-limits endpoint for the account. Use it during capacity planning and automation preflight, particularly before enrolling many Windows parents or attaching multiple child profiles. If a limit changes, surface a clear provisioning error and leave the existing child inventory intact rather than treating the failure as a reason to rebuild unrelated distros.
Diagnose incomplete provisioning with evidence
When a create activity does not lead to an installed child, inspect the Landscape activity status and result before repeating the POST. Repeating a request without checking the first activity can create duplicate or conflicting lifecycle work. Then verify that the parent computer ID is correct, WSL and the Ubuntu Pro for WSL components are ready on the Windows host, the selected image exists, and a custom rootfs URL is accessible from that host.
When the instance appears as installed but not registered, check the host-side Ubuntu Pro for WSL registration and the Landscape integration status. When it is registered but non-compliant, inspect profile association, access group, and the presence of local child distributions that conflict with the profile. When it is compliant but stopped, that may simply be WSL’s normal idle lifecycle; use the Landscape or WSL control expected for the task instead of assuming a stopped distro is broken.
Keep deployment evidence together: Landscape server version, parent computer ID, target instance name, image identifier or rootfs URL, profile name, cloud-init revision, activity ID and final result, and the post-provisioning child-list fields. A reproducible record lets an operator distinguish a server feature flag problem from an image, registration, or profile-compliance issue.
Remote management extends WSL’s local registration model; it does not eliminate it. Windows remains the host that owns the WSL platform and distro storage, while Landscape coordinates selected Ubuntu lifecycle actions and reports the child state. Inventory first, create through a deliberate profile or API operation, wait for the activity, and verify the resulting child rather than treating an HTTP response as the finished deployment.
Related:
- Managing WSL at Enterprise Scale with Intune and WSL Policy
- How WSL Actually Packages and Distributes Linux Distros
Sources: