ASP.NET Core applications read configuration from environment variables. When you deploy to IIS, environment variables set in the application pool do not apply. You must set them at the site level. This article shows three methods to configure IIS site-scoped environment variables.
What Are IIS Site-Scoped Environment Variables?
IIS stores site-scoped environment variables in the aspNetCore/environmentVariables section of the site configuration. The ASP.NET Core Module reads these variables at application startup. They override values in appsettings.json and web.config.
These variables live in applicationHost.config. They are not part of the published web.config file. Web Deploy and dotnet publish do not touch them. They survive every deployment.
Why Use Site-Scoped Variables?
- They persist across Web Deploy publishes from Visual Studio.
- They do not store secrets in
web.configfiles. - Each IIS site can have different values for the same application code.
- Only server administrators can read
applicationHost.config.
For applications deployed to multiple environments (Dev, UAT, Production), use one build artifact. Configure each site with its own environment variables.
Method 1: appcmd (Command Line)
appcmd.exe is the IIS command-line management tool. It is available on every IIS server. Use the full path if it is not in your PATH:
%systemroot%\system32\inetsrv\appcmd set config "SiteName" /section:system.webServer/aspNetCore /+environmentVariables.[name='ASPNETCORE_ENVIRONMENT',value='Staging'] /commit:site
To set multiple variables from PowerShell, use a loop to handle the square brackets:
$appcmd = "$env:SystemRoot\system32\inetsrv\appcmd.exe"
$site = "CDISV2SCPREPRODCOREWP"
$vars = @(
@{n="ASPNETCORE_ENVIRONMENT"; v="Staging"},
@{n="DOTNET_ENVIRONMENT"; v="Staging"},
@{n="CDIS_PROFILE"; v=$site},
@{n="SiteName"; v=$site},
@{n="ClientCode"; v="sc"},
@{n="AzureAd__ClientId"; v="e95bf02f-c259-4fa2-a23a-d100fe8a3d63"}
)
foreach ($v in $vars) {
$arg = "/+environmentVariables.[name='$($v.n)',value='$($v.v)']"
& $appcmd set config $site /section:system.webServer/aspNetCore $arg /commit:site
}
# Verify
& $appcmd list config $site /section:system.webServer/aspNetCore
Each variable adds a new entry. If a variable already exists, you will see a duplicate error. Use the foreach pattern to add only new variables.
Method 2: IIS Manager (GUI)
Use IIS Manager when you configure one site manually:
- Open IIS Manager. Select the site in the left tree.
- Double-click Configuration Editor in the Features view.
- Set the Section dropdown to
system.webServer > aspNetCore. - Click the environmentVariables row. Click the … button.
- Right-click in the Collection Editor. Select Add.
- Enter a name (e.g.,
ASPNETCORE_ENVIRONMENT). - Enter a value (e.g.,
Staging). - Click Close. Click Apply in the right Actions pane.
This method works for a small number of variables. For many variables, use the command-line methods.
Method 3: PowerShell WebAdministration
The WebAdministration PowerShell module gives full control over IIS configuration. It requires Windows PowerShell 5.1 and Administrator rights. It does not work in PowerShell 7 (pwsh).
Import-Module WebAdministration
$site = "CDISV2SCPREPRODCOREWP"
function Set-SiteEnvVar($name, $value) {
Remove-WebConfigurationProperty -PSPath "IIS:\" -Filter "system.webServer/aspNetCore/environmentVariables" -Name "." -AtElement @{name=$name} -Location $site -ErrorAction SilentlyContinue
Add-WebConfigurationProperty -PSPath "IIS:\" -Filter "system.webServer/aspNetCore/environmentVariables" -Name "." -Value @{name=$name; value=$value} -Location $site
}
Set-SiteEnvVar -name "ASPNETCORE_ENVIRONMENT" -value "Staging"
Set-SiteEnvVar -name "FileUpload__StoragePath" -value "E:/Images/SunshineCoast"
The Remove-WebConfigurationProperty call makes this idempotent. You can run the script many times. It removes old values before adding new ones.
Real-World Example: CDIS Pre-Production Deployment
The CDIS application is an ASP.NET Core 8.0 health system deployed to six IIS sites. Each site serves a different Public Health Unit. The same build artifact deploys to all sites. Per-site configuration comes from environment variables.
A typical site needs these environment variables:
| Name | Purpose | Example Value |
|---|---|---|
ASPNETCORE_ENVIRONMENT | Runtime environment | Staging |
DOTNET_ENVIRONMENT | .NET host environment | Staging |
CDIS_PROFILE | Deployment profile name | CDISV2SCPREPRODCOREWP |
SiteName | IIS site name | CDISV2SCPREPRODCOREWP |
SiteTitle | Browser tab title | CDISV2SCPREPRODCOREWP |
ClientCode | Health unit code | sc (Sunshine Coast) |
FileUpload__StoragePath | Image storage location | E:/Images/SunshineCoast |
FileUpload__PHUPrefix | File naming prefix | CDISSC |
AzureAd__ClientId | Azure AD app registration | e95bf02f-c259-4fa2-a23a-d100fe8a3d63 |
AzureAd__TenantId | Azure tenant | 0b65b008-95d7-4abc-bafc-3ffc20c039c0 |
ConnectionStrings__DefaultConnection | SQL Server connection | Server=host;Database=CDISSC;… |
Double underscore (__) maps to the colon separator in .NET configuration. FileUpload__StoragePath maps to FileUpload:StoragePath. This follows the standard .NET configuration key format.
How It Works in .NET Core
The ASP.NET Core host builder reads configuration from multiple sources:
builder.Configuration
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env}.json", optional: true)
.AddEnvironmentVariables();
AddEnvironmentVariables() reads both process environment variables and IIS site-scoped variables. IIS site-scoped variables override appsettings.json values. They are the highest-precedence source after command-line arguments.
Verification
After you set the variables, restart the site:
%systemroot%\system32\inetsrv\appcmd stop site "CDISV2SCPREPRODCOREWP"
%systemroot%\system32\inetsrv\appcmd start site "CDISV2SCPREPRODCOREWP"
Check the variables are set:
%systemroot%\system32\inetsrv\appcmd list config "CDISV2SCPREPRODCOREWP" /section:system.webServer/aspNetCore
The output shows all environment variables for the site:
<aspNetCore processPath=".\CDISV2Core.exe" hostingModel="inprocess">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" />
<environmentVariable name="CDIS_PROFILE" value="CDISV2SCPREPRODCOREWP" />
<environmentVariable name="ClientCode" value="sc" />
</environmentVariables>
</aspNetCore>
Common Problems
- appcmd not found in PowerShell 7: Use the full path
$env:SystemRoot\system32\inetsrv\appcmd.exeor switch to Windows PowerShell 5.1. - Administrator rights required: Both appcmd and WebAdministration need elevated privileges. Run as Administrator.
- Square bracket parsing in PowerShell: Put appcmd arguments in a string variable. Use the foreach pattern shown above.
- Variables not visible to the application: Restart the IIS site after changing environment variables. The ASP.NET Core Module reads them only at startup.
Summary
- Set IIS site-scoped environment variables in the
aspNetCore/environmentVariablessection. - Use
appcmdfor command-line automation across many servers. - Use IIS Manager Configuration Editor for one-off manual setups.
- Use the
WebAdministrationPowerShell module for idempotent scripts. - These variables survive Web Deploy publishes. Set them once per site.
- Restart the site after you change environment variables.
Leave a Reply