How to Publish .NET Apps from Visual Studio to IIS Using Web Deploy

FTP-based deployments are fragile. A dropped connection mid-upload, a missing web.config, or mismatched file permissions can take a site offline for minutes. Microsoft Web Deploy (MSDeploy) solves this by using a sync engine that understands IIS structure: it uploads only changed files, applies web.config transformations, and can take the application offline during the swap. This guide walks through setting up Web Deploy on a Windows VPS, configuring Visual Studio to publish via Web Deploy, and troubleshooting the most common errors.

Step 1: Install Web Deploy on the Server

Web Deploy is available as a standalone installer from Microsoft. On your Windows VPS, download and run the Web Deploy 4.0 MSI. When prompted, choose the Complete installation type. The Typical option installs only the client tool, but the Complete installation adds the handler service, which is required for remote publishing:

# Verify the installation after setup
& "$env:ProgramFilesIISMicrosoft Web Deploy V4msdeploy.exe" -version

# Expected output: "Microsoft (R) Web Deployment Tool Version 4.x"

After installation, confirm that the Web Management Service (WMSvc) is running and set to Automatic start:

Get-Service WMSvc | Format-List Name, Status, StartType

# If not running:
Set-Service WMSvc -StartupType Automatic
Start-Service WMSvc

Step 2: Configure Remote Management

Open IIS Manager on the server. Select the server node in the left panel, then double-click Management Service. Enable remote management on port 8172 with HTTPS. If you do not have a certificate installed, IIS can generate a self-signed one for testing.

Next, open the Windows Firewall to allow inbound traffic on port 8172:

netsh advfirewall firewall add rule name="Web Deploy 8172" dir=in action=allow `
  protocol=TCP localport=8172

Step 3: Create a Dedicated Deploy User

Instead of handing out Windows Administrator credentials, create an IIS Manager user scoped to the specific web site. In IIS Manager:

  • Under the server node, double-click IIS Manager Users and create a new user (e.g., webdeploy).
  • Navigate to your target site, double-click IIS Manager Permissions, and add the new user.
  • Grant Content Management delegation so the user can read and write the site folder but nothing else.

Test the endpoint from your local workstation before setting up Visual Studio:

msdeploy.exe -verb:dump `
  -dest:computerName="https://yourserver:8172/msdeploy.axd",`
        userName="webdeploy",password="YourPassword",authType="Basic" `
  -allowUntrusted

Step 4: Configure the Publish Profile in Visual Studio

With the server ready, set up the publish profile in Visual Studio:

  • Right-click the project and select PublishNew profileWeb Deploy.
  • Server: https://yourserver:8172/msdeploy.axd.
  • Site name: The exact name of the IIS site (e.g., contoso).
  • User name and password: The IIS Manager user you created.
  • Check Validate Connection to confirm everything works before the first deployment.

For clean builds, enable Remove additional files at destination. This deletes orphaned files from previous deployments. Disable it if users upload content to the site folder that should not be removed.

Use Web.config transforms to swap connection strings and app settings per environment. Add a Web.Release.config file to your project:

<!-- Web.Release.config -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <connectionStrings>
    <add name="Default"
         connectionString="Server=.;Database=app;User ID=app;Password=***"
         xdt:Transform="SetAttributes"
         xdt:Locator="Match(name)" />
  </connectionStrings>
  <appSettings>
    <add key="Environment" value="Production"
         xdt:Transform="SetAttributes"
         xdt:Locator="Match(key)" />
  </appSettings>
</configuration>

Before the first real deploy, use Visual Studio’s Preview step in the publish dialog. It lists every file that will be added, updated, or deleted without touching the server. A quick scan of the preview catches the classic mistakes: a missing appsettings.json, a stray bin folder, or a transform that dropped a connection string.

The 5 Most Common Errors and Their Fixes

ErrorCauseFix
ERROR_USER_UNAUTHORIZEDIIS Manager user lacks delegation on the siteGrant Content Management in IIS Manager Permissions on the site node
ERROR_DESTINATION_NOT_REACHABLEPort 8172 blocked or Management Service stoppedOpen the firewall rule; verify WMSvc is running and set to Automatic
ERROR_INSUFFICIENT_ACCESS_TO_SITE_FOLDERACLs on the web root block the deploy identityGrant the IIS Manager user or app pool identity Modify permission on the site folder via icacls
ERROR_FILE_IN_USEw3wp.exe holds the old DLLsPlace app_offline.htm in the site root before syncing (Web Deploy removes it after)
500 on msdeploy.axdHandler not installedRe-run the Web Deploy installer and choose Complete; restart the Management Service

The locked-file error is the most common on busy sites. The reliable pattern is to place an app_offline.htm file in the site root before publishing, then delete it after. IIS sees the file, unloads the app pool, and no process holds the files. For automated deployments, add -enableRule:AppOffline to the msdeploy command — it drops the file automatically before syncing and removes it afterward.

Step 5: Automate with CI/CD

The Visual Studio publish profile is a wrapper around msdeploy.exe. Your build agent can use the same command directly:

msdeploy.exe -verb:sync -source:package="artifactssite.zip" `
  -dest:auto,computerName="https://yourserver:8172/msdeploy.axd",`
        userName="webdeploy",password="***",authType="Basic" `
  -setParam:name="IIS Web Application Name",value="contoso" `
  -allowUntrusted -enableRule:AppOffline

Store the password in your build agent’s secret store, never in the repository. Use a dedicated IIS Manager user per site so that one compromised pipeline cannot deploy to another site.

Locking Down the Deploy Endpoint

The msdeploy.axd endpoint accepts authentication from anywhere that can reach port 8172, so treat it like an admin interface. Restrict the firewall rule to your build agents or office IP range instead of all addresses:

netsh advfirewall firewall set rule name="Web Deploy 8172" `
  new remoteip=203.0.113.10,198.51.100.0/24

Also rotate the IIS Manager user password whenever a developer leaves the project. Web Deploy works best when the server is cleanly provisioned with a dedicated app pool per site, known ACLs on the web root, and a firewall that only exposes 8172 to trusted sources. If you are still choosing a hosting provider, the Windows VPS plans on our homepage list the IIS-related capabilities worth confirming before you sign up.

Leave a Comment