Modifying Files Dynamically in the Windows Executor
Overview
A common CI pattern is dynamically updating a configuration file during a build — for example, injecting an environment-specific URL, toggling a feature flag, or substituting a secret value before running tests or a deployment. On the Windows executor, these operations are performed using PowerShell.
This article covers how to modify the most common file formats: XML, JSON, and plain text / .env files.
Prerequisites
- Your job uses the Windows executor with PowerShell as the shell
- The value you want to inject is available as a CircleCI environment variable (set in your project settings, a context, or the
environmentkey in your config)
Basic config.yml job structure:
jobs:
build:
machine:
image: windows-server-2022-gui:current
shell: powershell.exe
environment:
NEW_URL: "https://newurl.org"
steps:
- checkout
- run:
name: Modify config file
command: |
# Your file modification steps here
Note: Use
windows-server-2022-gui:currentto stay on the latest supported Windows image. See the Windows executor docs for available images.
Modifying an XML file
Use PowerShell's built-in XML DOM support to target a specific node and update its value:
# Display original config
Write-Host("Displaying Original Config")
type C:\Users\circleci\project\test.config
# Load the XML file
[xml]$XmlDocument = Get-Content -Path C:\Users\circleci\project\test.config
# Select the node to update and set its value
$url = $XmlDocument.SelectSingleNode("configuration/Test/add[@value='https://something.com/']")
$url.value = $env:NEW_URL
# Save the updated file
$XmlDocument.Save("C:\Users\circleci\project\test.config")
# Display updated config
Write-Host("Displaying Updated Config")
type C:\Users\circleci\project\test.config
Modifying a JSON file
Use Get-Content with ConvertFrom-Json and ConvertTo-Json to read, modify, and write back a JSON config file:
# Load and parse the JSON file $config = Get-Content -Path C:\Users\circleci\project\config.json -Raw | ConvertFrom-Json # Update the desired property $config.apiUrl = $env:NEW_URL # Write the updated JSON back to disk $config | ConvertTo-Json -Depth 10 | Set-Content -Path C:\Users\circleci\project\config.json # Verify the change Write-Host "Updated config:" type C:\Users\circleci\project\config.json
Tip: Use
-Depth 10(or higher) withConvertTo-Jsonto avoid nested objects being truncated to a string representation.
Modifying a plain text or .env file
For simple key=value files, use (Get-Content) with -replace to substitute a specific line:
# Replace the value for a specific key (Get-Content -Path C:\Users\circleci\project\.env) ` -replace '^API_URL=.*', "API_URL=$env:NEW_URL" | Set-Content -Path C:\Users\circleci\project\.env # Verify the change Write-Host "Updated .env:" type C:\Users\circleci\project\.env
To append a new key-value pair if it doesn't already exist:
Add-Content -Path C:\Users\circleci\project\.env -Value "NEW_KEY=$env:SOME_VALUE"
Using CircleCI environment variables
The examples above reference values via $env:VARIABLE_NAME, which is PowerShell's syntax for accessing environment variables. CircleCI injects project environment variables, context variables, and environment block values into the job environment automatically — no additional setup is needed to use them in PowerShell.
To set a value for use in later steps (rather than in a file), use $env:VARIABLE_NAME = "value" or write to $PROFILE — but for most config file injection use cases, passing values through $env: directly is the simplest approach.
Comments
Article is closed for comments.