Applying web.config Transformations without MSBuild

Georg Dangl by Georg Dangl in Continuous Integration Thursday, June 09, 2016

Thursday, June 09, 2016

Posted in DotNet IIS

There are certain cases where you deploy a website to IIS, rely on a web.config file but don't have MSBuild in the build process, like deploying .Net Core or php apps.

ASP.Net Web Config Transform Runner to the rescue! That's a nice, little command line tool wrapper around the Microsoft.Web.Xdt package. I'm using that to deploy .Net Core and reverse proxy configurations to IIS where I'm not having any MSBuild step in the deployment process.

Applying the Transformations

The PowerShell script below can be used in Continuous Integration systems like Jenkins or simply as part of a scripted deployment.

$configuration = "Production"                  # The name of the configuration, e.g. "Release" to apply transformations from web.Release.config
$wwwRoot = $ENV:WORKSPACE + "\PublishFolder"   # The folder under which to recursively look for web.config files
$deleteAfterTransformation = true              # true if web.*.config files should be deleted after the process
# Get path to WebConfigTransformationRunner
# INFO: Supply manual value to "WebConfigTransformRunner.exe" for $latestWebConfigTranformator if it isnt restored via "dotnet restore"
$webConfigTransformatorPackages = Join-Path -Path $env:USERPROFILE -ChildPath "\.nuget\packages\WebConfigTransformRunner"
$latestWebConfigTranformator = Join-Path -Path ((Get-ChildItem -Path $webConfigTransformatorPackages | Sort-Object Fullname -Descending)[0].FullName) -ChildPath "Tools\WebConfigTransformRunner.exe"
# Find all directories containing web.config foles
$webConfigDirs = Get-ChildItem -Path $wwwRoot -Recurse -Filter "web*.config" | Select -Property Directory -Unique
ForEach ($directory in $webConfigDirs.Directory){
    # Check if file for transformation is present
    $transformationSource = (Get-ChildItem -Path $directory -Filter ("web." + $configuration + ".config"))
    if ($transformationSource) {
        # Found a file to apply transformations
        $guid = [Guid]::NewGuid().ToString()
        $transformArguments = @("""" + (Join-Path -Path $directory -ChildPath "web.config") + """",`
                                """" + $transformationSource[0].FullName + """",`
                                """" + (Join-Path -Path $directory -ChildPath $guid) + """")
        $transformationProcess = Start-Process -FilePath $latestWebConfigTranformator -ArgumentList $transformArguments -Wait -PassThru -NoNewWindow
        if ($transformationProcess.ExitCode -ne 0) {
            "Exiting due to web.config transformation tool having returned an error, exit code: " + $transformationProcess.ExitCode
            exit $transformationProcess.ExitCode
        # Delete original web.config and rename the created one
        Remove-Item -Path (Join-Path -Path $directory -ChildPath "web.config")
        Rename-Item -Path (Join-Path -Path $directory -ChildPath $guid) -NewName (Join-Path -Path $directory -ChildPath "web.config") 
    if ($deleteAfterTransformation) {
        # Delete all web.*.config files
        ForEach ($file in (Get-ChildItem -Path $directory -Filter "web.*.config")){
            Remove-Item -Path $file.FullName
  • The $configuration variable determines which sources for the transformations to use, e.g. setting it to Production will apply transformations from web.Production.config files
  • $wwwroot specifies which folder to search for web.config files. All child folders are searched as well
  • $deleteAfterTransformation indicates if web.*.config files should be deleted after the transformation has been applied. Set it to true to remove unnecessary files for publishing.
Attention: This script does automatically search for the latest WebConfigTransformRunner.exe in the default path on the system where dotnet caches NuGet packages to. If you manually download the tool, change $latestWebConfigTranformator to the full file path of the exe.


Share this post

comments powered by Disqus

About me

Hi, my name's George! I love coding and blogging about it. I focus on all things around .Net, Web Development and DevOps.


Need a consultant for BIM, GAEB or Software Development?

Contact me at [email protected], +49 (173) 56 45 689 or visit my professional page!

// Just 💗 Coding

Social Links