How to Configure IIS Deployment with Web Deploy (MSDeploy) on Windows Server 2012 R2

Web Deploy (MSDeploy) is Microsoft’s tool for packaging, deploying, and synchronizing IIS web applications, their content, configuration, and associated components between servers. It is the standard mechanism used by Visual Studio’s “Publish” feature, Azure DevOps pipelines, and Octopus Deploy to push ASP.NET applications to IIS servers. On Windows Server 2012 R2, Web Deploy can be installed as a standalone tool or configured as a remote deployment agent service that accepts connections from CI/CD pipelines. This guide covers installing Web Deploy, configuring the deployment agent, creating deployment packages, deploying applications from the command line, and automating deployments from CI pipelines.

Prerequisites

  • Windows Server 2012 R2 with IIS installed and running
  • Administrator or delegated IIS Manager account
  • PowerShell 4.0
  • Network access on TCP 8172 (Web Deploy remote service) from deployment agents
  • .NET Framework 4.5.2

Step 1: Install Web Deploy

Download and install Web Deploy 3.6 for Hosting Servers, which includes the remote deployment agent service:

Invoke-WebRequest -Uri "https://download.microsoft.com/download/0/1/D/01DC28EA-638C-4A22-A57B-4CEF97755C6C/WebDeploy_amd64_en-US.msi" -OutFile "C:TempWebDeploy.msi"

Start-Process -FilePath "msiexec.exe" -ArgumentList `
    "/i C:TempWebDeploy.msi /quiet /norestart ADDLOCAL=ALL" `
    -Wait -PassThru

Write-Host "Web Deploy installed"

Verify the installation by checking for the MSDeploy executable and the deployment agent service:

Get-Command msdeploy -ErrorAction SilentlyContinue | Select-Object Source
Get-Service "MsDepSvc" | Select-Object Name, Status, StartType

Step 2: Configure the Web Deployment Agent Service

The Web Deployment Agent service (MsDepSvc) listens for remote deployment requests. Configure it to start automatically and open the required firewall port:

Set-Service -Name "MsDepSvc" -StartupType Automatic
Start-Service "MsDepSvc"

New-NetFirewallRule -DisplayName "Web Deploy Agent (8172)" -Direction Inbound -Protocol TCP -LocalPort 8172 -Action Allow

Write-Host "Web Deploy Agent service configured"
Get-Service "MsDepSvc" | Select-Object Name, Status

Step 3: Configure Delegated Web Deploy for Non-Admin Deployments

For security, configure Web Deploy to allow a non-administrator account to deploy to specific IIS sites without requiring full server admin rights. This is essential for CI/CD pipelines that should not have domain admin access:

Import-Module WebAdministration

# Create a deployment user account
net user deploy_svc "Deploy$Svc#2024!" /add /comment:"Web Deploy service account"

# Grant the deployment account IIS manager permissions for the specific site
Add-WebConfiguration /system.webServer/management/trustedProviders `
    -PSPath IIS: `
    -Value @{type='Microsoft.Web.Management.Server.ManagementUserProvider, Microsoft.Web.Management, Version=7.9.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'}

Set-WebConfiguration /system.webServer/management/authentication/@enabled `
    -PSPath IIS: `
    -Value "true"

# Grant the account deployment rights to the specific site
& "C:Program FilesIISMicrosoft Web Deploy V3msdeploy.exe" `
    -verb:sync `
    -source:appHostConfig="Default Web Site" `
    -dest:appHostConfig="Default Web Site",computerName="localhost",username="deploy_svc",password="Deploy$Svc#2024!",authType="Basic" `
    -enableRule:AppPoolExtension

Step 4: Create a Web Deployment Package

On the build server, use MSBuild to create a Web Deploy package from an ASP.NET project. The package is a ZIP file containing the application content, web.config transformations, and deployment manifests:

$MSBuild = "C:WindowsMicrosoft.NETFramework64v4.0.30319MSBuild.exe"
$SolutionPath = "C:BuildsMyWebAppMyWebApp.csproj"
$PackageOutputDir = "C:BuildsPackages"
$Configuration = "Release"

& $MSBuild $SolutionPath `
    /T:Package `
    /P:Configuration=$Configuration `
    /P:Platform="AnyCPU" `
    /P:PackageLocation="$PackageOutputDirMyWebApp_$Configuration.zip" `
    /P:DeployIisAppPath="Default Web Site/MyWebApp" `
    /P:AutoParameterizationWebConfigConnectionStrings=False `
    /nologo /verbosity:minimal

Write-Host "Package created at: $PackageOutputDirMyWebApp_$Configuration.zip"

Step 5: Deploy the Package to IIS via Command Line

Deploy the package to the target server using the msdeploy.exe command-line tool. This is the command that CI/CD tools execute during deployment:

$MsDeploy = "C:Program FilesIISMicrosoft Web Deploy V3msdeploy.exe"
$PackagePath = "C:BuildsPackagesMyWebApp_Release.zip"
$TargetServer = "webserver01.domain.local"
$SitePath = "Default Web Site/MyWebApp"
$DeployUser = "deploy_svc"
$DeployPass = "Deploy`$Svc#2024!"

& $MsDeploy `
    -verb:sync `
    -source:package="$PackagePath" `
    -dest:auto,computerName="https://${TargetServer}:8172/msdeploy.axd?site=$SitePath",userName="$DeployUser",password="$DeployPass",authType="Basic" `
    -setParam:name="IIS Web Application Name",value="$SitePath" `
    -allowUntrusted `
    -useCheckSum `
    -verbose

if ($LASTEXITCODE -eq 0) {
    Write-Host "Deployment successful" -ForegroundColor Green
} else {
    Write-Host "Deployment failed with exit code: $LASTEXITCODE" -ForegroundColor Red
    exit $LASTEXITCODE
}

Step 6: Deploy a Local IIS Application (No Remote Agent)

For deployments executed locally on the target server (e.g., from a scheduled task or Octopus Deploy Tentacle), use the local auto provider:

$MsDeploy = "C:Program FilesIISMicrosoft Web Deploy V3msdeploy.exe"
$PackagePath = "\buildserverPackagesMyWebApp_Release.zip"
$SitePath = "Default Web Site/MyWebApp"
$PhysicalPath = "C:inetpubwwwrootMyWebApp"

New-Item -ItemType Directory -Path $PhysicalPath -Force

& $MsDeploy `
    -verb:sync `
    -source:package="$PackagePath" `
    -dest:iisApp="$SitePath" `
    -setParam:name="IIS Web Application Name",value="$SitePath" `
    -useCheckSum `
    -verbose

Step 7: Perform Web.config Transformation During Deployment

Web.config transforms (XDT) modify configuration values based on the target environment. Create environment-specific transforms in your Visual Studio project, then apply them during packaging by specifying the configuration:

# Web.config Transform example (Web.Release.config):
# 
# 
#   
#     
#   
#   
#     
#   
# 

# Apply transform manually using MSDeploy:
& $MsDeploy `
    -verb:sync `
    -source:package="C:BuildsPackagesMyWebApp_Release.zip" `
    -dest:iisApp="Default Web Site/MyWebApp" `
    -setParamFile:"C:DeployParamsprod-parameters.xml" `
    -useCheckSum

Step 8: Create a Full Deployment Script with Pre/Post Steps

function Deploy-WebApplication {
    param(
        [string]$PackagePath,
        [string]$SiteName,
        [string]$AppPoolName,
        [string]$TargetServer = "localhost"
    )

    $MsDeploy = "C:Program FilesIISMicrosoft Web Deploy V3msdeploy.exe"

    Write-Host "Pre-deployment: stopping app pool $AppPoolName"
    Import-Module WebAdministration
    if ($TargetServer -eq "localhost") {
        Stop-WebAppPool -Name $AppPoolName -ErrorAction SilentlyContinue
        Start-Sleep -Seconds 3
    }

    Write-Host "Deploying: $PackagePath -> $SiteName"
    & $MsDeploy -verb:sync -source:package="$PackagePath" -dest:iisApp="$SiteName" -useCheckSum -verbose
    $deployResult = $LASTEXITCODE

    Write-Host "Post-deployment: starting app pool $AppPoolName"
    if ($TargetServer -eq "localhost") {
        Start-WebAppPool -Name $AppPoolName
        Start-Sleep -Seconds 3
        $state = (Get-WebAppPoolState -Name $AppPoolName).Value
        Write-Host "App pool state: $state"
    }

    return $deployResult
}

$result = Deploy-WebApplication -PackagePath "C:PackagesMyWebApp.zip" -SiteName "Default Web Site/MyWebApp" -AppPoolName "MyWebApp"
exit $result

Summary

Web Deploy (MSDeploy) is now configured on Windows Server 2012 R2 to accept remote deployments via the Web Deployment Agent service on port 8172, with a dedicated low-privilege deployment service account. The setup covers creating Web Deploy packages with MSBuild, deploying locally and remotely via command-line msdeploy.exe, applying Web.config environment transformations, and a complete deployment wrapper function with app pool management. This MSDeploy configuration integrates with any CI/CD system — Jenkins, GitHub Actions, Octopus Deploy, or Azure DevOps — that can invoke msdeploy.exe to push .NET web applications to IIS on Windows Server 2012 R2.