In IIS7, is it possible to have custom environment variables per web site?

I'm setting up IIS7.5 for a company intranet. The server will host both a 'test' and a 'prod' site. The environment variable I want to customize per site is 'PERL5LIB.

I want this web server to contain a Perl CGI (not FastCGI) environment. (ActiveState Perl v5.16, using PerlIs.dll and PerlEx30.dll). I want this Perl CGI environment to have both a 'test' and a 'prod' modules, so test modules can be loaded when hitting the 'test' site. Likewise, prod modules will be loaded when hitting the 'prod' site. Setting PERL5LIB per site is the key.

Apache would do this with a SetEnv directive associated with the URL of the site.


Solution 1:

Sure it is possible, you use two different application pool, run them under different user accounts and set user-based environment variables.

The following PowerShell script demonstrates how to do this. I'm using ASP.NET in the pages but you should be able to do they same in Perl. You also need IIS PowerShell scripting enabled to use the script

 Import-Module WebAdministration

 Function Prepare([string]$name,[int]$port)
 {
     # create a new directory for the site
     md c:\inetpub\site$name

     # create a new application pool
     New-WebAppPool "pool$name"

     # create a new site using the folder and pool we just created
     New-WebSite -name "site$name" -port $port -physicalpath "c:\inetpub\site$name" -applicationpool "pool$name"

     # Make sure the pool runs as applicationpoolidentity and loads its user profile
     set-webconfigurationproperty -pspath 'machine/webroot/apphost'  -filter "system.applicationhost/applicationpools/add[@name='pool$name']/processmodel" -name "identitytype" -value "applicationpoolidentity"
     set-webconfigurationproperty -pspath 'machine/webroot/apphost'  -filter "system.applicationhost/applicationpools/add[@name='pool$name']/processmodel" -name "loaduserprofile" -value "true"

     # create two pages, one to show the environment variable, the other to set it.
     "<%@ page %><html># <% response.write(system.environment.getenvironmentvariable(`"myvar`")) %> #</html>" | out-file  "c:\inetpub\site$name\default.aspx"
     "<%@ page %><%  system.environment.setenvironmentvariable(`"myvar`", `"i am site $name`", system.environmentvariabletarget.user) %>" | out-file "c:\inetpub\site$name\setenv.aspx"

     # hit the home page, just to get it started
     (new-object net.webclient).DownloadString("http://localhost:$port")
     # set our environment variable
     (new-object net.webclient).DownloadString("http://localhost:$port/setenv.aspx")
     # recycle the pool
     Restart-WebAppPool -Name "Pool$name"
     # wait a little bit to restart
     Start-Sleep -Milliseconds 500
     # hit the home page again to show our variable
     (new-object net.webclient).DownloadString("http://localhost:$port")
 }

 # call the function for two sites
 Prepare A 81
 Prepare B 82   

I only tested this on 2012 R2, but it should run fine on 2008 R2, you don't have to use the script, you can do the same steps in the GUI.