> ## Documentation Index
> Fetch the complete documentation index at: https://celesto.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# celesto windows

> Build a reusable Windows 11 qcow2 image with celesto windows build-image — an unattended install that produces a ready-to-boot Celesto guest.

## Synopsis

```bash theme={null} theme={null}
celesto windows build-image --iso PATH --virtio-win-iso PATH --output PATH [OPTIONS]
```

## Description

The `windows` command group bundles helpers for working with Windows guests. Today it has one subcommand:

* `celesto windows build-image` — produce a ready-to-use Windows 11 `qcow2` from a stock Windows ISO. The install runs unattended end to end (no clicks), and the resulting image has OpenSSH Server, the virtio-win drivers, and a known local admin account baked in — exactly what `Celesto(os="windows", image=...)` needs to boot.

After you build the image once, you can spin up as many Windows sandboxes as you want from it; Celesto creates per-VM overlay disks on top of the baseline so your original image is never modified.

> [!NOTE]
>
> The build takes 15–30 minutes. It runs an unattended Windows Setup inside a temporary QEMU VM, so plan accordingly — kick it off, walk away, come back to a finished image.

## Prerequisites

* A Linux host with KVM enabled (the same host requirements as [running Windows guests](https://celesto.ai/docs/celesto/guides/windows-guests.md#before-you-start)).
* A Windows 11 ISO. Download from [microsoft.com/software-download/windows11](https://www.microsoft.com/software-download/windows11).
* The virtio-win driver ISO. One-time download (\~750 MiB) from [fedorapeople.org](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso).
* `xorriso` installed on the host (used to package the unattended-install answer file). On Debian/Ubuntu: `sudo apt-get install -y xorriso`. On Fedora: `sudo dnf install -y xorriso`.

## Subcommands

### build-image

Drive an unattended Windows install and write the result to a qcow2 file.

```bash theme={null} theme={null}
celesto windows build-image \
  --iso ./Win11.iso \
  --virtio-win-iso ./virtio-win.iso \
  --output ~/.celesto/images/win11.qcow2
```

#### Required flags

**--iso** `path` *required*

Path to the Windows ISO (for example `./Win11.iso`).

**--virtio-win-iso** `path` *required*

Path to the virtio-win driver ISO. Required so Windows Setup can see the virtio-scsi disk and virtio NIC during install.

**--output** `path` *required*

Destination for the built qcow2 (for example `~/.celesto/images/win11.qcow2`). The directory is created if needed. The command refuses to overwrite an existing non-empty file as a safeguard.

#### Optional flags

**--username** `string` (default: celesto)

Local admin account to create inside Windows. Use this account name as `ssh_user=` when booting the image.

**--password** `string` (default: celesto)

Password for the local admin account. **Override the default** for any image you'll reuse beyond throwaway proof-of-concept work — the default is intentionally weak and public.

**--hostname** `string` (default: celesto-win)

Windows computer name baked into the install.

**--edition** `string` (default: Windows 11 Pro)

Edition name as it appears in `install.wim`. `Windows 11 Home` is also valid for a stock consumer ISO.

**--disk-size** `integer` (default: 65536)

Virtual size of the built qcow2, in MiB. The default is 65536 MiB (64 GiB). The qcow2 grows on demand — this is a ceiling, not a preallocation.

**--build-timeout** `number` (default: 2700)

Upper bound on the install duration, in seconds. The default (2700 s = 45 min) is generous; a typical install finishes in 15–20 minutes.

**--json** `flag`

Emit machine-readable JSON instead of human-friendly text.

#### Examples

Build with all defaults:

```bash theme={null} theme={null}
celesto windows build-image \
  --iso ./Win11.iso \
  --virtio-win-iso ./virtio-win.iso \
  --output ~/.celesto/images/win11.qcow2
```

Build with a custom account and a smaller virtual disk:

```bash theme={null} theme={null}
celesto windows build-image \
  --iso ./Win11.iso \
  --virtio-win-iso ./virtio-win.iso \
  --output ~/.celesto/images/win11-dev.qcow2 \
  --username dev \
  --password 'Str0ng-passphrase!' \
  --hostname dev-box \
  --disk-size 32768
```

Build Windows 11 Home and emit JSON:

```bash theme={null} theme={null}
celesto windows build-image \
  --iso ./Win11.iso \
  --virtio-win-iso ./virtio-win.iso \
  --output ~/.celesto/images/win11-home.qcow2 \
  --edition 'Windows 11 Home' \
  --json
```

JSON output shape:

```json theme={null}
{
  "command": "windows build-image",
  "exit_code": 0,
  "data": {
    "output_qcow2": "/home/you/.celesto/images/win11-home.qcow2",
    "size_bytes": 8345128448,
    "username": "celesto",
    "hostname": "celesto-win",
    "edition": "Windows 11 Home"
  }
}
```

## Boot the image you just built

Once the build finishes, point `Celesto(os="windows", image=...)` at the qcow2 with the credentials you chose:

```python theme={null}
from celesto import Celesto

with Celesto(
    os="windows",
    image="~/.celesto/images/win11.qcow2",
    ssh_user="celesto",
    ssh_password="celesto",
) as vm:
    vm.wait_for_ssh()
    print(vm.run("hostname").stdout.strip())
```

Celesto creates a per-VM overlay disk on top of the baseline, so the qcow2 you built stays read-only and you can launch many sandboxes from it in parallel. See [Windows sandboxes](https://celesto.ai/docs/celesto/guides/windows-guests.md) for the full guest API.

## Use it from Python

The same flow is available as a Python class, `WindowsImageBuilder`. Use it when you want to bake images programmatically — for example, from a CI job that rebuilds the baseline on a schedule.

```python theme={null}
from pathlib import Path
from celesto.windows import WindowsImageBuilder

builder = WindowsImageBuilder(
    windows_iso=Path("./Win11.iso"),
    virtio_win_iso=Path("./virtio-win.iso"),
    output_qcow2=Path("~/.celesto/images/win11.qcow2").expanduser(),
    username="celesto",
    password="celesto",
    hostname="celesto-win",
    edition="Windows 11 Pro",
    disk_size_mib=64 * 1024,
    build_timeout_s=45 * 60,
)
output = builder.build()
print(f"Built {output}")
```

`builder.build()` returns the `Path` of the finished qcow2 on success and raises `CelestoError` (or another exception) on failure.

## How the build works

The builder runs the same Windows Setup flow you'd run by hand, just driven by an answer file:

1. **Render** the bundled `autounattend.xml` template with your chosen username, password, hostname, and edition.
2. **Wrap** the rendered XML in a tiny ISO labeled `AUTOUNATTEND` (Windows Setup auto-discovers any attached removable media with that volume label).
3. **Create** an empty qcow2 at `--output` for Windows to install into.
4. **Spawn** a QEMU VM with the Windows ISO, the virtio-win ISO, the autounattend ISO, and the empty qcow2 all attached.
5. **Poll** the guest over SSH for `C:\celesto-ready.txt` every 30 seconds. The answer file writes this marker as the last step of `FirstLogonCommands`, after Windows installs OpenSSH, registers the sshd service, opens TCP/22 in the firewall, and installs the virtio-win guest tools.
6. **Shut down** the build VM cleanly. The qcow2 at `--output` is left behind as the build artifact.

Transient SSH failures across the install's multiple reboots (Setup → Specialize → OOBE → first login) are absorbed and retried automatically.

For a deep dive into the answer file and the reasoning behind each Setup pass, see [Windows guest QEMU deep dive](https://github.com/celestoai/celesto/blob/main/docs/deep-dive/windows-guest-qemu.md) in the Celesto repo.

## Exit codes

| Code | Description |
| - | - |
| `0` | Image built successfully |
| `1` | Build failed (missing ISO, `xorriso` not installed, install timed out, etc.) |
| `2` | Invalid usage (missing subcommand or required flag) |

## Troubleshooting

> [accordion] xorrisofs is required to build the autounattend answer-file ISO
>
> Install the `xorriso` package: `sudo apt-get install -y xorriso` on Debian/Ubuntu, `sudo dnf install -y xorriso` on Fedora, `brew install xorriso` on macOS.

> [accordion] The output path already exists
>
> The builder refuses to overwrite an existing non-empty file. Pass a different `--output` path, or delete the previous build first.

> [accordion] Build timed out before the ready marker appeared
>
> The install is normally finished in 15–20 minutes. If your host is slow or under heavy load, raise `--build-timeout` (in seconds) — for example `--build-timeout 5400` for 90 minutes.

> [accordion] Setup couldn't find a disk to install Windows on
>
> This almost always means `--virtio-win-iso` points at the wrong file or an old version. Re-download the latest stable ISO from the [virtio-win direct-downloads page](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso) and retry.

## Next steps

> [card] [Windows sandboxes](https://celesto.ai/docs/celesto/guides/windows-guests.md)
>
> Boot the image you just built and run PowerShell over SSH

> [card] [Environment variables](https://celesto.ai/docs/celesto/guides/environment-variables.md)
>
> Inject API keys and config into Windows guests

> [card] [CLI overview](https://celesto.ai/docs/celesto/cli/overview.md)
>
> All available Celesto CLI commands

> [card] [VM lifecycle](https://celesto.ai/docs/celesto/guides/vm-lifecycle.md)
>
> Start, stop, and delete sandboxes


## Related topics

- [Windows sandboxes in Celesto](https://celesto.ai/docs/celesto/guides/windows-guests.md)
- [CLI overview](https://celesto.ai/docs/celesto/cli/overview.md)
- [Custom Sandbox Images with Docker](https://celesto.ai/docs/celesto/guides/custom-images.md)
- [celesto sandbox create](https://celesto.ai/docs/celesto/cli/create.md)
- [Environment variables in Celesto sandboxes](https://celesto.ai/docs/celesto/guides/environment-variables.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.