Setting up MSDeploy for CI/CD deployments to IIS

@ ~ about 3 mis to read

Just a few months ago I was 100% sure I’ll never hear about Windows Server ever again, but not everyone is on Kubernetes or even dotnet core yet, so if you are as lucky as me, and have to setup deployment to the IIS server in 3rd decade of 21st century, here are the detailed instructions how to do it.

First Let me first clarify something. There is a product name called Web Deploy which provides 2 main components:

  • Command-line tool MSDeploy.exe what we use, to make a deployment to an IIS server.
  • A service that must be installed on a server running IIS, where we want to make deployments to.

Just a few tips in advance

Install IIS Management Service

  1. Run (Win + R) -> appwiz.cpl
  2. Click “Turn Windows features on or off”
  3. On “Add Roles and Features Wizard” proceed to “Server Roles” (on non-server versions of windows you’ll be taken to the same screen immediately)
  4. Select “Management service”
  5. Proceed to confirmation and press install (appears instead of Next button)

Step by step screenshots:

  • 'appwiz.cpl'
  • 'Turn Windows features on or off'
  • 'Add Roles and Features Wizard'
  • 'Server Roles'
  • 'Press Install'

Install Microsoft Web Deploy

This is a tool that should be installed on both the server (the machine running IIS) and the client (the machine making a deployment).

Getting it is is a bit tricky though. There are two actual versions of web deploy.

The versions are not compatible. In other words, you cannot use Web Deploy 4 to deploy to the server with Web Deploy 3.6

Yet another important detail is that the “Typical” installation of MS Deploy doesn’t include the server components. Therefore installing MS Deploy choose either Complete install either Custom and ensure all the components will be installed as shown on the screenshots below.

  • 'webdeploy_amd64_en-us.msi welcome screen'
  • 'webdeploy_amd64_en-us.msi choose type screen'
  • 'webdeploy_amd64_en-us.msi install screen'

Things to verify

Windows services should be up and running

  1. Open Services Manager. Run (Win + R) services.msc
  2. Locate “Web Deployment Agent Service” and ensure it’s started. (this is MSDeploy)
  3. Locate “Web Management Service” and ensure it’s started.
  • 'Open Services Manager. Run (Win + R) services.msc'
  • 'Locate "Web Deployment Agent Service" and ensure it is started'
  • 'Locate "Web Management Service" and ensure it is started'

Management service should be present in IIS configuration.

You might also want to adjust some settings

  1. Open IIS Manager. Run (Win + R) inetmgr
  2. Locate “Management Service” in the Management section of the Server Features view

If you want to change the settings you’ll need to stop the service using the stop button on the right panel. The interface might seem a bit confusing, but feel free to do so, it stops only the management service itself, not the IIS.

  • 'Open IIS Manager'
  • 'Locate Management Service in IIS'
  • 'Management Service Screen'

The port should be open

As you could see on Management Service screen in IIS settings, by default it listens to port 8172. The installer also opens the port in Firewall settings for all IP addresses.

  1. Open Windows Defender Firewall with Advanced Security. Run (Win + R) wf.msc
  2. Locate “Web Management Service (HTTP Traffic-In)” rule
  • 'Run Windows Firewall with Advanced security'
  • 'Open IIS Management Service Port'

Pack and deploy legacy asp.net app to IIS

That deploy part is way easier or at least doesn’t require clicks.

To make a package with msbuild

$proejctPath = '.\MyProject.csproj'

msbuild $projectPath `
  /p:OutDir=.\dist\ `
  /p:Configuration=Release `
  /p:GenerateSerializationAssemblies=False `
  /p:DeployOnBuild=true `
  /p:WebPublishMethod=Package `
  /p:PackageAsSingleFile=true `
  /p:IncludeSetAclProviderOnDestination=False `
  /p:AutoParameterizationWebConfigConnectionStrings=false

To deploy using msdeploy


$package = '.\dist\_PublishedWebsites\MyProject_Package\MyProject.zip'
$username = ''
$password = ''
$serverIpOrHostname = '127.0.0.1'
$msDeployPort = '8172'
$endpoint = "https://${serverIpOrHostname}:${msDeployPort}/MSDeploy.axd"
$iisWebsiteName = 'My Website'

# with -whatIf flag provided, msdeploy just shows what's gonna happen without
# remove the line with -whatIf flag to make real deployment
msdeploy -source:package=$package `
     -whatIf `
     -verb:sync `
     -allowUntrusted `
     -dest:auto,ComputerName=`"$endpoint`",UserName=`"$username`",Password=`"$password`",IncludeAcls=False,AuthType=Basic `
     -setParam:name=`"IIS Web Application Name`",value=`"$iisWebsiteName`" `
     -disableLink:AppPoolExtension `
     -disableLink:ContentExtension `
     -disableLink:CertificateExtension

where is msdeploy.exe

Typically it’s: C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe and yet, no matter how rediculous it is, the Web Deploy 4 is going to be in the same directory :)

where is msbuild.exe

With visual studio installed it should be in C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe Obviously the version number and edition might differ.

However you don’t have to have to install Visual Studio, to have MSBuild on a build agent. You can download and install Build Tools for Visual Studio 2019.

© 2020 - 2021, Dennis Tretyakov