Introduction to Web Deploy on Windows Server 2022

Web Deploy (msdeploy.exe) is Microsoft’s deployment tool for synchronizing web applications, databases, and server configurations between machines. It integrates with IIS, Visual Studio, and CI/CD pipelines to enable one-command deployments that transfer only changed files, transform configuration, and execute pre/post-deployment scripts. This guide covers every component from service installation to pipeline integration and troubleshooting.

Installing Web Deploy on IIS Server

Web Deploy is installed separately from IIS. Download the Web Deploy 4.0 MSI from the Microsoft IIS Downloads page at https://www.iis.net/downloads/microsoft/web-deploy. Run the installer and choose Complete installation to include all components including the agent service. Alternatively install via PowerShell using the WebPI command-line tool or Chocolatey:

choco install webdeploy -y

Verify the installation path and version:

& "C:Program FilesIISMicrosoft Web Deploy V3msdeploy.exe" -version

After installation you will see two new Windows services:

Get-Service WMSVC     # IIS Management Service (port 8172)
Get-Service MsDepSvc  # Web Deployment Agent Service (port 80/443)

IIS Management Service Configuration

The IIS Management Service (WMSVC) must be running on the target server and configured to allow remote connections. Open IIS Manager on the server, navigate to the server node, and double-click Management Service. Enable remote connections and configure the binding:

# Enable IIS Management Service via PowerShell
Set-ItemProperty "HKLM:SOFTWAREMicrosoftWebManagementServer" -Name "EnableRemoteManagement" -Value 1
Start-Service WMSVC
Set-Service WMSVC -StartupType Automatic

Open the firewall port for the Management Service (default 8172):

New-NetFirewallRule -DisplayName "IIS Management Service" -Direction Inbound `
    -Protocol TCP -LocalPort 8172 -Action Allow

Web Deployment Agent Service

The Web Deployment Agent Service (MsDepSvc) provides an alternative endpoint for Web Deploy operations on port 80. It runs as Local System and handles deployments authenticated with Windows credentials. This service is typically used in domain environments where the deploying user has local administrator rights on the target server.

Start-Service MsDepSvc
Set-Service MsDepSvc -StartupType Automatic

The agent endpoint URL follows this pattern:

http://targetserver/msdeployagentservice

Configuring Web Deploy Permissions

For non-administrator deployments, create a dedicated IIS user and grant it permissions. This is the recommended approach for build server deployments where you do not want to use domain admin credentials. In IIS Manager, navigate to Management Service Delegation under the server node. Add rules for the deployment user to allow the iisApp, contentPath, and setAcl providers.

# Create a local IIS management user
New-LocalUser -Name "DeployUser" -Password (ConvertTo-SecureString "D3pl0y@Pass" -AsPlainText -Force)

# Add to IIS_IUSRS group
Add-LocalGroupMember -Group "IIS_IUSRS" -Member "DeployUser"

# Grant write access to the site content directory
icacls "C:inetpubwwwrootMyApp" /grant "DeployUser:(OI)(CI)M"

Create the delegation rules programmatically using the appcmd.exe tool:

%windir%system32inetsrvappcmd.exe set config -section:management/delegation `
    /+"[path='Default Web Site/MyApp',username='DeployUser',password='D3pl0y@Pass',`
    allowed='true',providers='iisApp,contentPath,setAcl,recycleApp']"

Deploying from Visual Studio

In Visual Studio right-click the project and select Publish. Choose Web Server (IIS) then Web Deploy. Configure the publish profile:

Server: targetserver:8172
Site name: Default Web Site/MyApp
User name: DeployUser
Password: D3pl0y@Pass
Destination URL: http://targetserver/MyApp

The publish profile is saved as a .pubxml file in PropertiesPublishProfiles within the project. This file can be committed to source control (credentials should use environment variable references):



  
    MSDeploy
    targetserver:8172
    Default Web Site/MyApp
    DeployUser
    False
    True
  

Deploying from the Command Line with msdeploy.exe

The msdeploy.exe command-line tool gives full control over deployments. The basic sync operation copies a local directory to a remote IIS application:

"C:Program FilesIISMicrosoft Web Deploy V3msdeploy.exe" `
    -verb:sync `
    -source:contentPath="C:buildMyApppublish" `
    -dest:iisApp="Default Web Site/MyApp",`
         computername="https://targetserver:8172/msdeploy.axd",`
         userName="DeployUser",`
         password="D3pl0y@Pass",`
         authtype="Basic" `
    -allowUntrusted `
    -enableRule:AppOffline

The -enableRule:AppOffline flag drops an App_Offline.htm file before deployment so IIS takes the app offline gracefully, then removes it after sync completes. To deploy only specific changed files and skip configuration files:

"C:Program FilesIISMicrosoft Web Deploy V3msdeploy.exe" `
    -verb:sync `
    -source:contentPath="C:buildMyApppublish" `
    -dest:iisApp="Default Web Site/MyApp",computername="https://targetserver:8172/msdeploy.axd",userName="DeployUser",password="D3pl0y@Pass",authtype="Basic" `
    -skip:objectName=filePath,absolutePath="web.config$" `
    -enableRule:DoNotDeleteRule `
    -allowUntrusted

Delta Sync — Deploying Only Changed Files

Web Deploy automatically computes a delta and transfers only files that differ. This is built into the sync verb and requires no special configuration. You can observe what would be transferred without actually deploying by using the -whatif flag:

"C:Program FilesIISMicrosoft Web Deploy V3msdeploy.exe" `
    -verb:sync `
    -source:contentPath="C:buildMyApppublish" `
    -dest:iisApp="Default Web Site/MyApp",computername="https://targetserver:8172/msdeploy.axd",userName="DeployUser",password="D3pl0y@Pass",authtype="Basic" `
    -whatif `
    -allowUntrusted

The output lists each file action: Add, Delete, Update. Web Deploy compares file hashes and modification dates to determine what needs transferring.

Web.config Transformations

Config transforms allow environment-specific settings. Add a transform file named web.Release.config to your project. Example that replaces the connection string and removes debug mode:



  
    
  
  
    
  

During publish, MSBuild applies the transform before Web Deploy packages the application. Run the transform manually:

dotnet publish -c Release -o C:buildMyApppublish

Deploying ASP.NET Core Apps

For ASP.NET Core, publish the app self-contained or as framework-dependent, then deploy the publish output. Enable the ASP.NET Core Module (ANCM) in IIS:

# Install the ASP.NET Core Hosting Bundle on the target server
# Download from https://dotnet.microsoft.com/download
# Run the installer, then restart IIS
iisreset /restart

Configure the IIS site to use a No Managed Code application pool:

New-WebAppPool -Name "MyAppPool"
Set-ItemProperty "IIS:AppPoolsMyAppPool" -Name managedRuntimeVersion -Value ""
New-Website -Name "MyApp" -PhysicalPath "C:inetpubwwwrootMyApp" `
    -ApplicationPool "MyAppPool" -Port 80

Deploying from Azure DevOps

Add a Web Deploy step to your Azure DevOps pipeline using the IIS Web App Deploy task. In your azure-pipelines.yml:

- task: IISWebAppDeploymentOnMachineGroup@0
  displayName: 'Deploy to IIS'
  inputs:
    WebSiteName: 'Default Web Site/MyApp'
    Package: '$(Pipeline.Workspace)/drop/MyApp.zip'
    TakeAppOfflineFlag: true
    XmlTransformation: true
    XmlVariableSubstitution: true

This task runs on a deployment group agent installed on the target server. Install the agent on the server by navigating to Project Settings > Deployment groups in Azure DevOps and running the provided registration script.

Deploying from GitHub Actions

GitHub Actions can deploy to IIS via Web Deploy using the self-hosted runner or via direct msdeploy.exe invocation:

name: Deploy to IIS
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: windows-latest
    steps:
    - uses: actions/checkout@v4
    - name: Build
      run: dotnet publish -c Release -o ./publish
    - name: Deploy via Web Deploy
      run: |
        & "C:Program FilesIISMicrosoft Web Deploy V3msdeploy.exe" `
          -verb:sync `
          -source:contentPath="${{ github.workspace }}publish" `
          -dest:iisApp="Default Web Site/MyApp",computername="https://${{ secrets.SERVER_HOST }}:8172/msdeploy.axd",userName="${{ secrets.DEPLOY_USER }}",password="${{ secrets.DEPLOY_PASS }}",authtype="Basic" `
          -allowUntrusted `
          -enableRule:AppOffline

Store SERVER_HOST, DEPLOY_USER, and DEPLOY_PASS as GitHub Actions secrets. Never hardcode credentials in workflow files.

Troubleshooting Web Deploy Connectivity

Common Web Deploy errors and resolutions:

Error: Could not connect to the remote computer — Verify the Management Service is running, port 8172 is open in Windows Firewall, and the service URL is correct. Test connectivity:

Test-NetConnection -ComputerName targetserver -Port 8172

Error: A specified logon session does not exist — The Management Service may not have the delegation rule for the user. Re-check the Management Service Delegation configuration in IIS Manager.

Error: Web deployment task failed. (The site does not exist) — The site name in the destination must exactly match the IIS site and application path. List sites to verify:

Get-Website | Select Name, PhysicalPath, State
Get-WebApplication | Select Site, Path, PhysicalPath

Certificate validation errors with -allowUntrusted — In production, install a valid TLS certificate for the Management Service. In IIS Manager, select the server node, open Management Service, and change the SSL certificate to your trusted cert, then restart WMSVC.

Verbose logging — Add -verbose to the msdeploy command line for detailed operation-by-operation output that identifies exactly which files are failing and why:

"C:Program FilesIISMicrosoft Web Deploy V3msdeploy.exe" -verb:sync ... -verbose 2>&1 | Tee-Object -FilePath C:logsdeploy.log

Summary

Web Deploy on Windows Server 2022 provides a robust, delta-aware deployment mechanism for IIS-hosted applications. By configuring dedicated deployment users with minimal required permissions, leveraging config transforms for environment promotion, and integrating with Azure DevOps or GitHub Actions, teams can achieve repeatable, automated deployments that minimize downtime. The combination of the Management Service for non-administrator deployments, AppOffline rules for graceful shutdowns, and verbose logging for diagnostics covers the full deployment lifecycle for enterprise ASP.NET applications.