Running IIS Express on a Random Port

I have found myself using IIS Express for a bunch of web projects these days, and each of these projects is using different frameworks and different authoring systems. (Like Windows Notepad, which is still the one of the world's most-used code editors.)

Anyway, there are many times when I need multiple copies of IIS Express running at the same time on my development computer, and common sense would dictate that I would create a custom batch file for each website with the requisite parameters. To be honest, for a very long time that's exactly how I set things up; each development site got a custom batch file with the path to the content and a unique port specified. For example:

@echo off

iisexpress.exe /path:c:\inetpub\website1\wwwroot /port:8000

The trouble is, after a while I had so many batch files created that I could never remember which ports I had already used. However, if you don't specify a port, IIS Express will always fall back on the default port of 8080. What this means is, my first IIS Express command would work like the example shown below:

CMD> iisexpress.exe /path:c:\inetpub\website1\wwwroot

Copied template config file 'C:\Program Files\IIS Express\AppServer\applicationhost.config' to 'C:\Users\joecool\AppData\Local\Temp\iisexpress\applicationhost2018321181518842.config'
Updated configuration file 'C:\Users\joecool\AppData\Local\Temp\iisexpress\applicationhost2018321181518842.config' with given cmd line info.
Starting IIS Express ...
Successfully registered URL "http://localhost:8080/" for site "Development Web Site" application "/"
Registration completed
IIS Express is running.
Enter 'Q' to stop IIS Express

But my second IIS Express command would fail like the example shown below:

CMD> iisexpress.exe /path:c:\inetpub\website2\wwwroot
Copied template config file 'C:\Program Files\IIS Express\AppServer\applicationhost.config' to 'C:\Users\joecool\AppData\Local\Temp\iisexpress\applicationhost2018321181545562.config'
Updated configuration file 'C:\Users\joecool\AppData\Local\Temp\iisexpress\applicationhost2018321181545562.config' with given cmd line info.
Starting IIS Express ...
Failed to register URL "http://localhost:8080/" for site "Development Web Site" application "/". Error description: Cannot create a file when that file already exists. (0x800700b7)
Registration completed
Unable to start iisexpress.

Cannot create a file when that file already exists.
For more information about the error, run iisexpress.exe with the tracing switch enabled (/trace:error).

I began to think that I was going to need to keep a spreadsheet with all of my paths and ports listed in it, when I realized that what I really needed was a common, generic batch file that would suit my needs for all of my development websites - with no customization at all.

Here is the batch file that I wrote, which I called "IISEXPRESS-START.cmd", and I will explain what it does after the code listing:

@echo off

pushd "%~dp0"

setlocal enabledelayedexpansion

if exist "wwwroot" (
  if exist "%ProgramFiles%\IIS Express\iisexpress.exe" (
    set /a RNDPORT=8000 + %random% %%1000
    "%ProgramFiles%\IIS Express\iisexpress.exe" /path:"%~dp0wwwroot" /port:!RNDPORT!
  )
)

popd

Here's what the respective lines in the batch file are doing:

  1. Push the folder where the batch file is being run on the stack; this is a cool little hack that also allows running the batch file in a folder on a network share and still have it work.
  2. Enable delayed expansion of variables; this ensures that variables would work inside of conditional code blocks.
  3. Check to see if there is a subfolder named "wwwroot" under the batch file's path; this is optional, but it helps things run smoothly. (I'll explain more about that below.)
  4. Check to make sure that IIS Express is installed in the correct place
  5. Configure a local variable with a random port number between 8000 and 8999; you can see that it uses modulus division to force the random port into the desired range.
  6. Start IIS Express by passing the path to the child "wwwroot" folder and the random port number.

One last piece of explanation: I almost always use a "wwwroot" folder under each parent folder for a website, with the goal of managing most of the parts of each website in one place. With that in mind, I tend to create folder hierarchies like the following example:

  • C:
    • Production
      • Website1
        • wwwroot
      • Website2
        • ftproot
        • wwwroot
      • Website3
        • wwwdata
        • wwwroot
    • Staging
      • Website1
        • wwwroot
      • Website2
        • ftproot
        • wwwroot
      • Website3
        • wwwdata
        • wwwroot

Using this structure, I can drop the batch file listed in this blog into any of those Website1, Website2, Website3 folders and it will "just work."


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

Comments are closed