Set IIS Site-Scoped Environment Variables for ASP.NET Core Applications

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.config files.
  • 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:

  1. Open IIS Manager. Select the site in the left tree.
  2. Double-click Configuration Editor in the Features view.
  3. Set the Section dropdown to system.webServer > aspNetCore.
  4. Click the environmentVariables row. Click the button.
  5. Right-click in the Collection Editor. Select Add.
  6. Enter a name (e.g., ASPNETCORE_ENVIRONMENT).
  7. Enter a value (e.g., Staging).
  8. 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:

NamePurposeExample Value
ASPNETCORE_ENVIRONMENTRuntime environmentStaging
DOTNET_ENVIRONMENT.NET host environmentStaging
CDIS_PROFILEDeployment profile nameCDISV2SCPREPRODCOREWP
SiteNameIIS site nameCDISV2SCPREPRODCOREWP
SiteTitleBrowser tab titleCDISV2SCPREPRODCOREWP
ClientCodeHealth unit codesc (Sunshine Coast)
FileUpload__StoragePathImage storage locationE:/Images/SunshineCoast
FileUpload__PHUPrefixFile naming prefixCDISSC
AzureAd__ClientIdAzure AD app registratione95bf02f-c259-4fa2-a23a-d100fe8a3d63
AzureAd__TenantIdAzure tenant0b65b008-95d7-4abc-bafc-3ffc20c039c0
ConnectionStrings__DefaultConnectionSQL Server connectionServer=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.exe or 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/environmentVariables section.
  • Use appcmd for command-line automation across many servers.
  • Use IIS Manager Configuration Editor for one-off manual setups.
  • Use the WebAdministration PowerShell module for idempotent scripts.
  • These variables survive Web Deploy publishes. Set them once per site.
  • Restart the site after you change environment variables.

Posted

in

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *