---
title: "Using the Windows execution environment"
description: "Learn how to configure a your jobs to run in the Windows execution environment."
platform: "Cloud, Server"
doc_version: "unversioned"
last_updated: "2026-10-15"
cloud_plans: "Free, Performance, Scale"
version_control: "All supported providers"
---

> For current CircleCI product defaults, deprecated patterns, and Cloud/Server differences, see [AGENTS.md](https://circleci.com/docs/AGENTS.md).
>
> For the complete documentation index and site structure, see [llms.txt](https://circleci.com/docs/llms.txt).

# Using the Windows execution environment

**Cloud plans:** Free, Performance, Scale

**Version control:** [All supported providers](https://circleci.com/docs/guides/integration/version-control-system-integration-overview/)

The Windows execution environment provides the tools to build Windows projects, such as a Universal Windows Platform (UWP) application, a .NET executable, or Windows-specific (like the .NET framework) projects. The following specifications detail the capacities and included features of the Windows executor:

*   Is VM-based to guarantee full job isolation.
    
*   Can use either the Server Core version of Windows Server 2019 Datacenter Edition, or Windows Server 2022 Datacenter edition.
    
*   PowerShell is the default shell (Bash and CMD are available to be manually selected).
    
*   Docker Engine - Enterprise is available for running Windows containers.
    

You can access the Windows execution environment by using the machine executor and specifying a Windows image, or by using the Windows orb and specifying the default executor.

## Quickstart

Configuration options for using the Windows execution environment are shown below.

<Tabs>
<Tab title="Cloud">

```yaml
version: 2.1

jobs:
  build: # name of your job
    resource_class: 'windows.medium'
    machine:
      image: 'windows-server-2022-gui:current'
      shell: 'powershell.exe -ExecutionPolicy Bypass'
    steps:
      # Commands are run in a Windows virtual machine environment
        - checkout
        - run: Write-Host 'Hello, Windows'
```

</Tab>
<Tab title="Server">

```yaml
version: 2.1

jobs:
  build: # name of your job
    machine:
      image: windows-default
    steps:
      # Commands are run in a Windows virtual machine environment
        - checkout
        - run: Write-Host 'Hello, Windows'
```

</Tab>
</Tabs>

### The Windows orb

To keep your configuration simple and to ensure you are using the most up-to-date image, you can use the [Windows orb](https://circleci.com/developer/orbs/orb/circleci/windows). Then specify the default executor from the orb in your job configuration. CircleCI strongly encourages using the [Windows orb](https://circleci.com/developer/orbs/orb/circleci/windows) as it helps simplify your configuration.

```yaml
version: 2.1

orbs:
  win: circleci/windows@5.0 # The Windows orb gives you everything you need to start using the Windows executor.

jobs:
  build: # name of your job
    executor: win/default # executor type

    steps:
      # Commands are run in a Windows virtual machine environment
      - checkout
      - run: Write-Host 'Hello, Windows'
```

To use a specific image with the Windows orb, for example, Windows Server 2022, it must be specified in the `executor` type, as shown in the following snippet:

```yaml
version: 2.1

orbs:
  win: circleci/windows@5.0

jobs:
  build:
    executor: win/server-2022
    steps:
      - run: Write-Host 'Hello, Windows'
workflows:
  my-workflow:
    jobs:
      - build
```

## Available resource classes

| Class | vCPUs | RAM | Disk Size | Cloud | Server |
| --- | --- | --- | --- | --- | --- |
| `windows.medium` (default) | 4 | 16GB | 200 GB | **Yes** | **Yes** |
| `windows.large` | 8 | 32GB | 200 GB | **Yes** | **Yes** |
| `windows.xlarge` | 16 | 64GB | 200 GB | **Yes** | **Yes** |
| `windows.2xlarge` | 32 | 128GB | 200 GB | **Yes** | **Yes** |

**Using server?** Check with your systems administrator whether you have access to the Windows execution environment.

<Tabs>
<Tab title="Cloud with orb">

```yaml
version: 2.1 # Use version 2.1 to enable Orb usage.

orbs:
  win: circleci/windows@5.0 # The Windows orb gives you everything you need to start using the Windows executor.

jobs:
  build: # name of your job
    executor:
      name: win/default # executor type
      size: medium # can be medium, large, xlarge, 2xlarge

    steps:
      # Commands are run in a Windows virtual machine environment
      - checkout
      - run: Write-Host 'Hello, Windows'
```

</Tab>
<Tab title="Cloud with machine">

```yaml
version: 2.1

jobs:
  build: # name of your job
    machine:
      image: 'windows-server-2022-gui:current'
    resource_class: windows.medium # can be medium, large, xlarge, 2xlarge
    steps:
      # Commands are run in a Windows virtual machine environment
        - checkout
        - run: Write-Host 'Hello, Windows'
```

</Tab>
<Tab title="Server">

```yaml
version: 2.1

jobs:
  build: # name of your job
    machine:
      image: windows-default
    resource_class: windows.medium # can be medium, large, xlarge, 2xlarge
    steps:
      # Commands are run in a Windows virtual machine environment
        - checkout
        - run: Write-Host 'Hello, Windows'
```

</Tab>
</Tabs>

### View resource usage

To view the compute resource usage for the duration of a job in the CircleCI web app:

1.  In the [CircleCI web app](https://app.circleci.com), select your org from the org cards on your user homepage.
    
2.  Select **Pipelines** from the sidebar and locate your pipeline from the list. You can use the project, branch, date, and status search options to help.
    
3.  Select the job you want to access by selecting the job name.
    
4.  Select the **Resources** tab to view CPU and RAM usage for the duration of the job.
    

You can use these insights to decide whether to make changes to the job’s configured resource class.

> **Image:** Resources tab

Figure 1. Resources tab in web app for a job

## Windows machine executor images

CircleCI supports Windows Server 2019 with Visual Studio 2019 and Windows Server 2022 with Visual Studio 2022. For information on what software is pre-installed on the Windows image, visit the [Developer Hub](https://circleci.com/developer/images?imageType=machine), or the [Discuss forum](https://discuss.circleci.com/). The Windows image page on the Developer Hub lists links to the most recent updates.

Details on the Windows Server 2022 image can be found on this [Discuss post](https://discuss.circleci.com/t/march-2022-support-for-new-operating-system-for-windows-executors-windows-server-2022/43198/1).

The Windows images are updated approximately every 30 days. If a tag is not specified when using the Windows image, by default the latest stable version will be applied. The tagging scheme for the Windows image is as follows:

*   Current (formerly Stable): This image tag points to the latest production-ready Windows image. Use this image for projects that want a decent level of stability, but would like to get occasional software updates. It is typically updated once a month.
    

The `current` tag is available for Windows images. The `current` and `stable` tags are equivalent, and are currently both supported. Refer to the [Discuss forum](https://discuss.circleci.com/t/april-2022-windows-image-updates-available-for-stable-tags/43511) for more information.

*   Previous: This image tag points to the previous production-ready Windows image. This image can be used in cases where there was a breaking change in the latest software updates. It is typically updated once a month.
    
*   Edge: This image tag points to the latest version of the Windows image, and is built from the HEAD of the main branch. This tag is intended to be used as a testing version of the image with the most recent changes, and not guaranteed to be stable.
    

## Specifying a shell with the Windows executor

You can use one of three shells to run job steps on Windows:

*   PowerShell (default in the Windows orb).
    
*   Bash.
    
*   Command.
    

You can configure the shell at the job level or at the step level. It is possible to use multiple shells in the same job. Consider the example below, where we use Bash, PowerShell, and CMD by adding a `shell:` argument to our `job` and `step` declarations:

<Tabs>
<Tab title="Cloud">

```yaml
version: 2.1

orbs:
  win: circleci/windows@5.0

jobs:
  build:
    executor:
      name: win/default
    steps:
      # default shell is PowerShell
      - run:
         command: $(echo hello | Out-Host; $?) -and $(echo world | Out-Host; $?)
         shell: powershell.exe
      - run:
         command: echo hello && echo world
         shell: bash.exe
      - run:
         command: echo hello & echo world
         shell: cmd.exe
```

</Tab>
<Tab title="Server">

```yaml
version: 2.1
jobs:
  build: # name of your job
    machine:
      image: windows-default # Windows machine image
    resource_class: windows.medium
    steps:
      # default shell is PowerShell
      - run:
         command: $(echo hello | Out-Host; $?) -and $(echo world | Out-Host; $?)
         shell: powershell.exe
      - run:
         command: echo hello && echo world
         shell: bash.exe
      - run:
         command: echo hello & echo world
         shell: cmd.exe
```

</Tab>
</Tabs>

It is possible to install updated or other Windows shell-tooling. For example, you could install the latest version of PowerShell Core with the `dotnet` CLI and use it in a job’s successive steps:

<Tabs>
<Tab title="Cloud">

```yaml

version: 2.1

orbs:
  win: circleci/windows@5.0

jobs:
  build:
    executor: win/default
    steps:
      - checkout
      - run: dotnet tool install --global PowerShell
      - run: pwsh ./<my-script>.ps1
```

</Tab>
<Tab title="Server">

```yaml
version: 2.1
jobs:
  build: # name of your job
    machine:
      image: windows-default # Windows machine image
    resource_class: windows.medium
    steps:
      - checkout
      - run: dotnet tool install --global PowerShell
      - run: pwsh ./<my-script>.ps1
```

</Tab>
</Tabs>

## Running Windows Docker containers on the Windows executor

You can run Windows Docker containers on the Windows executor like so:

<Tabs>
<Tab title="Cloud">

```yaml
version: 2.1

orbs:
  win: circleci/windows@5.0

jobs:
  build:
    executor:
      name: win/default
      shell: powershell.exe
    steps:
      - checkout
      - run: systeminfo
      - run:
          name: "Check docker"
          shell: powershell.exe
          command: |
            docker info
            docker run -it mcr.microsoft.com/windows/nanoserver:ltsc2022 cmd.exe
```

</Tab>
<Tab title="Server">

```yaml
version: 2.1
jobs:
  build: # name of your job
    machine:
      image: windows-default # Windows machine image
    resource_class: windows.medium
    steps:
      - checkout
      - run: systeminfo
      - run:
          name: "Check docker"
          shell: powershell.exe
          command: |
            docker info
            docker run hello-world:nanoserver-1809
```

</Tab>
</Tabs>

## SSH into your Windows build

It is possible to SSH into a Windows build container, which can be useful for troubleshooting problems in your pipeline. Follow these steps to SSH into a Windows container:

### Steps

The steps described in this section apply to all CircleCI accounts. If you are using Bitbucket Cloud, or your account is integrated through the GitHub OAuth app, you can add an SSH key to your VCS account ([GitHub](https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/) or [Bitbucket](https://confluence.atlassian.com/bitbucket/set-up-an-ssh-key-728138079.html)). Do this rather than adding it in the CircleCI app under [User Settings](https://app.circleci.com/settings/user/job-ssh-keys), if you prefer.

1.  If you have not already done so, add an SSH key to your [User Settings](https://app.circleci.com/settings/user/job-ssh-keys). This key will be used to connect to the container or VM that is running your job.
    
2.  To start a job with SSH enabled, select the **Rerun job with SSH** option from the "Rerun Workflow" dropdown menu.
    
3.  To see the connection details, expand the "Enable SSH" section in the job output where you will see the SSH command needed to connect.
    

Ensure that you are passing the name of the shell you want to run when you SSH in. To run `cmd.exe` in the build above you would run: `ssh -p <remote_ip> -- cmd.exe`

The available options are:

*   `powershell.exe`
    
*   `bash.exe`
    
*   `cmd.exe`
    

You can read more about using SSH in your builds [Here](https://circleci.com/docs/guides/execute/ssh-access-jobs/).

## Known issues and limitations

These are the issues with the Windows executor that we are aware of and will address as soon as we can:

*   The `add_ssh_keys` step is required for _any_ SSH key used in the job.
    
*   It is currently not possible to do nested virtualization (for example, using the `--platform linux` flag).
    
*   The Windows executor currently only supports Windows containers. Running Linux containers on Windows is not possible for now.
    

## Next steps

Check out the [Hello World on Windows](https://circleci.com/docs/guides/execute/hello-world-windows/) page.