WiX not configuring IIS site correctly - iis

I have an installer which configures 2 websites, one of which has some applications under the root site. The top level site is configured for Windows Authentication only, as below:
<iis:WebSite Id="WebSite"
Description="Application"
Directory="WEBSITE_INSTALLLOCATION"
AutoStart="yes"
ConfigureIfExists="yes"
StartOnInstall="yes">
<iis:WebAddress Id="AllUnassigned" Port="80" />
<iis:WebApplication Id="WebApplication"
Name="Console"
WebAppPool="WebAppPool"/>
<iis:WebDirProperties Id="WebProperties"
AnonymousAccess="no"
WindowsAuthentication="yes"
AuthenticationProviders="NTLM,Negotiate"/>
</iis:WebSite>
Other (optional) components in the installer then declare applications/virtual directories as follows:
<iis:WebVirtualDir Id="HelpWebSite" Alias="Help" Directory="ApexHelpDir" WebSite="WebSite">
<iis:WebApplication Id="HelpApp" Name="Help" WebAppPool="WebAppPool"/>
<iis:WebDirProperties Id="HelpProps" AnonymousAccess="yes" WindowsAuthentication="no"/>
</iis:WebVirtualDir>
The behaviour I'm seeing is what I'd expect 9/10 times, but intermittently the installer will install the "Website" site with both anonymous authentication and windows authentication, rather than just the Help application with anonymous authentication. The only explanation for this that I can think of is that the act of adding a virtual directory/application underneath a root site occasionally causes the root to inherit the child authentication settings as well as its own.
Note: I tried to raise this as a bug on the wixtoolset.org site, but kept getting an error when trying to do so.

Alternatively, you can write a batch script to create a website and call from WIX as custom action.
Batch file
%systemroot%\system32\inetsrv\appcmd.exe add site /name:YourWebSite /PhysicalPath:%systemdrive%\inetpub\wwwroot /bindings:http/*:80:
WIX(product.wxs)
<CustomAction Id="CreateWebsite" Execute="deferred" Impersonate="no" Return="check" Directory="TARGETDIR" PatchUninstall="no" ExeCommand="Batchfilepath" />
<InstallExecuteSequence>
<Custom Action="CreateWebsite" Before="InstallFinalize">NOT Installed AND NOT PATCH</Custom>
</InstallExecuteSequence>
Change your ExeCommand attribute value to point to the correct batch file path.

The workaround for me was to disable Anonymous Authentication at the server level.
It seems that when this flakiness occurs it does inherit the setting from the server level, although I've no idea why it only happens sometimes.
Here's the Powershell script:
Set-WebConfigurationProperty -Filter "/system.webServer/security/authentication/anonymousAuthentication" -Name Enabled -Value False -PSPath IIS:\

Related

How to set permission for IIS AppPool identity when creating website in Wix Toolset?

I'm writing a Wix Toolset installer to install an Angular + asp.net core application in IIS on Windows Server 2016. I create a new Website and a new Application Pool. I want to grant full permission to the Application Pool identity on the newly created website folder path.
I followed the step given here : https://www.codeproject.com/Articles/115036/Creating-WIX-Installer-for-ASP-NET-Web-Application? so I have 3 files :
Setup.wxs
IISConfiguration.wxs
WebSiteContent.wxs
I set up the website and permissions in IISConfiguration.wxs.
<DirectoryRef Id="WEBSITE">
<Component Id="WebSiteSiteNameCmp" Guid="{ED376FD7-D4DB-4675-8BF4-1DCC1AF1C66B}" KeyPath="yes" >
<iis:WebSite Id="WebSiteName"
Description='WebSiteName'
Directory="WEBSITE"
AutoStart="no"
ConfigureIfExists="yes"
StartOnInstall="no" >
<iis:WebAddress Id="WebSiteAdressHttps" Port="443" IP="*" Secure="yes"/>
<iis:WebAddress Id="WebSiteAdressHttp" Port="80" IP="*" Secure="no"/>
<iis:WebDirProperties Id="WebSiteProperties" AnonymousAccess="yes"
BasicAuthentication="no" WindowsAuthentication="no" />
<iis:WebApplication Id="WebSiteNameSite" Name="WebSite" WebAppPool="WebSiteAppPool" />
</iis:WebSite>
</Component>
<!-- Configuring app pool -->
<Component Id="WebSiteAppPoolCmp" Guid="{009052A8-19AE-452e-AE34-6DC8E929DA08}"
KeyPath="yes" Permanent="yes" Win64="yes">
<iis:WebAppPool Id="WebSiteAppPool" Name="WebSiteAppPoolName" ManagedPipelineMode="integrated" />
</Component>
<Component Id="WebSitePermissionCmp" Guid="{4425EFB0-A580-44B7-9C04-54EBD2E4ECB1}">
<CreateFolder>
<util:PermissionEx User="IIS AppPool\WebSiteAppPoolName" GenericAll="yes"/>
</CreateFolder>
</Component>
</DirectoryRef>
But then the installer rollsback because the AppPool isn't created yet when trying to set permissions on the folder. I have the following error in my logs :
ExecSecureObjects: Error 0x80070534: failed to get sid for account: IIS AppPool\WebSiteAppPoolName.
What should I do to set the permissions at the "good" time ?
I finally used the custom action solution with icalcs to manage the permissions on the newly created application pool. This is what I add in my Setup.wxs :
<CustomAction Id='AppPoolPermission' Directory='WEBSITE'
ExeCommand='"[SystemFolder]icacls.exe" "[INSTALLDIR]." /grant "IIS AppPool\WebSiteAppPoolName:(OI)(CI)F" /T' Return='check'/>
<InstallExecuteSequence>
<Custom Action='AppPoolPermission' After='InstallFinalize' />
</InstallExecuteSequence>
I also removed the WebSitePermissionCmp from IISConfiguration.wxs.
It's not the ideal solution but for me it works. I don't know if this can be achieved only with WIX without custom action.
Another post concerning this issue : How to specify the AppPool Identity in a WiX Permission Element?
I don't fully understand the answer but it also seem to be using custom actions.

WIX classic ASP website for IIS 8

I wrote the following WIX settings for a classic ASP website for IIS 7:
<iis:WebSite Id='DefaultWebSite' Description='Default Web Site'>
<iis:WebAddress Id="AllUnassigned" Port="80" />
</iis:WebSite>
<Component Id="MyWebSite_IIS7" Guid="xxx" Transitive="yes" >
<Condition><![CDATA[IIS_VERSION >= "IIS 7.0" ]]></Condition>
<CreateFolder/>
<util:User Id="AnonymousUser7" CreateUser="no" Domain="[DOMAIN_NAME]" Name="[USERNAME]" Password="[PASSWORD]" UpdateIfExists="yes" LogonAsService="yes" />
<iis:WebAppPool Id="MyWebSitePool" Identity="other" Name="MyAppPool" ManagedPipelineMode="classic" User="AnonymousUser7" />
<iis:WebVirtualDir Id="MyWebSite_VirtualDir7" Alias="MyWebSite" Directory="INSTALLLOCATION" WebSite="DefaultWebSite" >
<iis:WebApplication Id="TestWebApplication7" Name="MyWebSite" WebAppPool="MyWebSitePool" />
<iis:WebDirProperties Id="MyWebSite_DirProperties7" Read="yes" LogVisits="yes" Index="yes" Script="yes" AnonymousAccess="yes" AnonymousUser="AnonymousUser7" />
</iis:WebVirtualDir>
</Component>
Now using IIS 8, I get HTTP 500 error.
How can I avoid this error using WIX?
Currently I am using Wix 3.7 and no plan to upgrade it to the latest Wix doe to the maintenance issue in our company.
Here is another question.
Someone said if I do the following manual steps, it would work:
1. Go to the website you want to add your application to, then double click on Handler Mappings.
2. Click "Add Script Map" and enter in the following information:
- RequestPath: *.asp
- Executable: C:\Windows\syswow64\inetsrv\asp.dll
- Name: anything
I googled "Add Script Map" and found "appcmd.exe" can add script map, so I tried
C:\windows\system32\inetsrv\appcmd.exe set config /section:handlers /+[name='anything',path='*.asp',verb='*',scriptProcessor='%windir%\syswow64\inetsrv\asp.dll',preCondition='MyWebSite']
Unfortunately this adds script map for all Default Web Site, not for "MyWebSite". Therefore, as a reault, it didn't resolve HTTP 500 error.
Is there any way to add Script Map using any kind of command / app?

WIX uninstall doesn't remove site on Windows server 2008 R2

I have installer which setups web site. Installer is implemented using WIX 3.5. The components installing site are in listing below:
<DirectoryRef Id="TARGETDIR">
<Directory Id="WWWROOT">
</Directory>
</DirectoryRef>
<Property Id="WWWROOT" Value="C:\inetpub\wwwroot">
<RegistrySearch Id="FindInetPubFolder" Root="HKLM" Key="SOFTWARE\Microsoft\InetStp" Name="PathWWWRoot" Type="directory" />
</Property>
<Component Id="CC_AppPoolConfigure" Guid="YOURGUID-9558-4CAE-A928-EACD27D69A0D" KeyPath="yes" Permanent="no">
<iis:WebAppPool Id="CC_AppPool" Name="[SITE_APP_POOL]" ManagedRuntimeVersion="v4.0" ManagedPipelineMode="integrated" />
</Component>
<Component Id="CC_Iis6SiteConfigure" Guid="YOURGUID-13E2-4980-A55A-E37E3E06FB67" KeyPath="yes" Permanent="no">
<Condition><![CDATA[Installed OR (IISMAJORVERSION AND (IISMAJORVERSION = "#6"))]]></Condition>
<iis:WebSite Id="CC_WebSite_IIS6" Description="[SITE_NAME]"
AutoStart="yes" StartOnInstall="yes" ConfigureIfExists="yes"
Directory="WWWROOT" ConnectionTimeout="360" SiteId="[SITE_ID]">
<iis:WebVirtualDir Id="CC_Site_IIS6_VDir" Directory="SITE_INSTALLDIR" Alias="[SITE_VIRT_DIR]">
<iis:WebApplication Id="CC_IIS6_WebApp" Name="[SITE_APP_NAME]" WebAppPool="CC_AppPool" >
<iis:WebApplicationExtension Verbs="GET,HEAD,POST" CheckPath="no" Script="yes" Executable="[FRAMEWORKROOT]v4.0.30319\aspnet_isapi.dll" />
</iis:WebApplication>
<iis:WebDirProperties Id="CC_Site_IIS6_Properties" WindowsAuthentication="yes" AnonymousAccess="yes"/>
</iis:WebVirtualDir>
<iis:WebAddress Id="CC_Site_IIS6_Header_Bindings" Port="[SITE_PORT]" Header="[SITE_HEADER]" />
</iis:WebSite>
</Component>
<Component Id="CC_IIS6_Config_Extentions" Guid="YOURGUID-009A-4545-8D4D-EC5437D7332F" KeyPath="yes" Permanent="yes">
<Condition><![CDATA[IISMAJORVERSION AND (IISMAJORVERSION = "#6")]]></Condition>
<iis:WebServiceExtension Id="CC_ExtensionASP4" Group="ASP.NET v4.0.30319" Allow="yes" File="[FRAMEWORKROOT]v4.0.30319\aspnet_isapi.dll" Description="ASP.NET v4.0.30319"/>
</Component>
<Component Id="CC_Iis7Site" Guid="YOURGUID-1738-476A-945F-A97721F5ECFC" KeyPath="yes" Permanent="no">
<Condition><![CDATA[IISMAJORVERSION AND (IISMAJORVERSION >= "#7")]]></Condition>
<iis:WebSite Id="CC_WebSite_IIS7" Description="[SITE_NAME]"
AutoStart="yes" StartOnInstall="yes" ConfigureIfExists="yes"
Directory="WWWROOT" ConnectionTimeout="360" SiteId="[SITE_ID]">
<iis:WebVirtualDir Id="CC_Site_IIS7_VDir" Directory="SITE_INSTALLDIR" Alias="[SITE_VIRT_DIR]">
<iis:WebApplication Id="CC_IIS7_WebApp" Name="[SITE_APP_NAME]" WebAppPool="CC_AppPool"></iis:WebApplication>
<iis:WebDirProperties Id="CC_Site_IIS7_Properties" WindowsAuthentication="yes" AnonymousAccess="yes"/>
</iis:WebVirtualDir>
<iis:WebAddress Id="CC_Site_IIS7_Header_Binding" Port="[SITE_PORT]" Header="[SITE_HEADER]" />
</iis:WebSite>
</Component>
As you can see, site needs to be installed on IIS 6, IIS 7 and IIS 7.5. Installation is fine on all listed environments. Installer performs per-machine installation. I use deffered custom actions for enabling required IIS components etc, so installer first is runned without admin permissions and asks for them when button "Install" is clicked.
But there is a problem uninstalling product using the same installer file which was used to install it - Site and virtual directory left on IIS. It only occurs on Windows Server 2008 R2 (IIS 7.5) when UAC is enabled and only when uninstalling through running installer file and selecting option "Remove" in first dialog. I tested this on few environments (Windows Server 2003, 2003 R2, 2008 x86, 2008 x64, 2008 R2) and it looks like 2008 R2 is the only environment where the issue is present. Other investigations shown that disabling UAC solves the problem. Uninstalling product through control panel or running the same msi from command line with uninstall parameter doesn't have this issue too. So there is very narrow case where issue is present, but it is still important.
I'm almost sure that the problem is because of UAC restrictions: maybe installer tries to uninstall site before UAC dialog is shown to give permissions. But I can't understand how can I fix it. Any help will be appreciated.
If you have better approach to installing site on so various environments, I would be happy to hear it too - my invented wheel probably isn't the best =).
If you need uninstall log, it is here:
We had the same issue and solved it by changing properties that contains Web site and application names to Secure="yes". In your case, make sure that:
<Property Id="SITE_NAME" Secure="yes">
<Property Id="SITE_APP_NAME" Secure="yes">

Convert folder under virtual directory to Application, using WIX

How can I convert a directory under a virtual directory to an application, using WIX?
WIX installs the following Virtual Directory to IIS, and I wish it to also convert the webservice folder to an application.
I could not find a way to do this through WIX or the IIS extension, so I resorted to calling an external command. For future reference, the commands are:
IIS 5
C:\Inetpub\AdminScripts\mkwebdir.vbs -c Localhost -w "Default Web Site" -v "sentry/webservice","{physical path}"
C:\Inetpub\AdminScripts\adsutil.vbs appcreateinproc w3svc/1/root/sentry/webservice
IIS 6
C:\Windows\System32\iisvdir.vbs /create "Default Web Site/Sentry/webservice" webservice "{physical path}"
IIS 7
C:\Windows\System32\inetsrv\appcmd add app /site.name:"Default Web Site" /path:/Sentry/webservice /physicalPath:"{physical path}"
This can be done with the IISExtension, as Daniel Morritt suggests. As it's very difficult to find sample code for this I thought I'd post how I did it.
<!-- Your example uses the default web site. -->
<iis:WebSite Id="DefaultWebSite" Description="Default Web Site" SiteId="*">
<iis:WebAddress Id="DefaultWebAddress" Port="80"/>
</iis:WebSite>
<!-- Web Dir Properties to enable access to a Web Application. -->
<iis:WebDirProperties Id="AnonymousExecuteAndScript"
Read="yes"
Write="no"
Execute="yes"
Script="yes"
AnonymousAccess="yes"
Index="no"
LogVisits="no"/>
<!-- Assumes the presence of this directory reference. -->
<DirectoryRef Id="SentryWebServiceDir">
<Component Id="SentryWebServiceComponent" Guid="{GUID-GOES-HERE}">
<iis:WebVirtualDir Id="SentryWebService"
DirProperties="AnonymousExecuteAndScript"
Alias="Sentry/webservice"
Directory="SentryWebServiceDir"
WebSite="DefaultWebSite">
<!-- Make this virtual directory a web application -->
<iis:WebApplication Id="SentryWebServiceApp" Name="webservice" WebAppPool="DefaultAppPool"/>
</iis:WebVirtualDir>
<!-- Workaround for the need for a KeyPath for this component. -->
<RegistryValue Root="HKLM"
Key="SOFTWARE\YourCompany\Sentry\WebService"
KeyPath="yes"
Value="1"
Type="binary"
Name="Installed"
Id="SentryWebServiceInstalled"/>
</Component>
</DirectoryRef>
All of the above can be nested in a <Fragment> element.
You can add a reference to the WiX IISExtension to your project and create one using this.
A good example of this can be found here: Using WiX to create an IIS virtual directory
I have tested this approach, and it works:
http://www.mail-archive.com/wix-users#lists.sourceforge.net/msg04374.html
It says to put the whole path in the Alias, for example
<iis:WebVirtualDir Id="VIRTDIR_Sentry_webservice"
Directory="WebService"
Alias="Sentry/webservice"
WebSite="SITE_Default"> ...

Setting the AppPool of a WebSite element in WiX 3.6

I have a WiX installer which sets up a couple of root IIS websites each of which has a number of WebApplications. We have a separate AppPool for each root and put each of the WebApplications into that AppPool.
Unfortunately I can't find a way of making sure the WebSites go into their required AppPools and WiX insists on putting them in DefaultAppPool.
Am I missing anything here?
<Component Id="INPUT" Guid="{43302D85-55B5-4C99-8C07-8AF5ED419E0A}" Directory="dirBBD4B479DF2AD0441616B5EB11867FA6" KeyPath="yes">
<iis:WebAppPool Id="INPUTPool" Name="RCMInput" ManagedPipelineMode="integrated" ManagedRuntimeVersion="v4.0"/>
</Component>
<Component Id="INPUTSITE" Directory="dirBBD4B479DF2AD0441616B5EB11867FA6" Guid="{E508497A-C485-4EB8-8A91-4299BD46291B}" KeyPath="yes">
<iis:WebSite Id="INPUTROOT" Description="RCMInput" Directory="dirBBD4B479DF2AD0441616B5EB11867FA6" AutoStart="yes" >
<iis:WebAddress Id="INPUTROOTADDRESS" IP="[RCMINPIP]" Port="443" Secure="yes" Header="[RCMINPHOST]" />
<iis:WebVirtualDir Id="INPUTVD" Alias="InputApp" Directory="dir0AC030D54BBE340DFFCC71C2724F6BF1">
<iis:WebApplication Id="INPUTWEBAPP" Name="InputApp" WebAppPool="RCMInpAppPool">
<iis:WebApplicationExtension CheckPath="no" Extension="svc" Executable="[NETFRAMEWORKROOT]v2.0.50727\aspnet_isapi.dll" Verbs="GET,HEAD,POST,PUT,DELETE"/>
</iis:WebApplication>
</iis:WebVirtualDir>
<iis:WebVirtualDir Id="INPUTVD2" Alias="Administration" Directory="dir78ADFB9F5CBB65D9A3E21EAB7F4C5911">
<iis:WebApplication Id="INPUTWEBAPP2" Name="Administration" WebAppPool="RCMInpAppPool">
<iis:WebApplicationExtension CheckPath="no" Extension="svc" Executable="[NETFRAMEWORKROOT]v2.0.50727\aspnet_isapi.dll" Verbs="GET,HEAD,POST,PUT,DELETE"/>
</iis:WebApplication>
</iis:WebVirtualDir>
</iis:WebSite>
</Component>
I would guess that when you reference the AppPool name "RCMInput" in the WebApplication, it cannot resolve it and is defaulting the the Default App Pool. Have you tried running your MSI with logging turned on and see if that gives any extra detail?
From command line
msiexec /i install.msi -L*v install.log
There's a good blog post on deploying web apps in WiX at http://ranjithk.com/2009/12/17/automating-web-deployment-using-windows-installer-xml-wix/ where he defines the AppPool in the same component as the WebApplication.
Not sure if it has changed in 3.6 but for 3.5 when the AppPool is referenced in WebApplication use the Id, instead of using RCMInpAppPool use INPUTPool.
Here's an excellent example
I was having the same problem, but I finally find a solution for it. Instead of nesting a WebApplication (which is referencing your app pool) inside a WebVirtualDir, put it directly inside your website. So, if you have this:
<iis:WebSite Id='WebSite' Description='My Website' Directory="WebsiteDir">
<iis:WebAddress Id='WebAddress' Port='80' />
<iis:WebVirtualDir Id="VirtualDir" Alias="mywebsite" Directory="WebsiteDir">
<iis:WebApplication Id="WebApplication" Name="MyWebApplication" WebAppPool="MyWebAppPool" />
</iis:WebVirtualDir>
</iis:WebSite>
Replace with this:
<iis:WebSite Id='WebSite' Description='My Website' Directory="WebsiteDir">
<iis:WebAddress Id='WebAddress' Port='80' />
<iis:WebVirtualDir Id="VirtualDir" Alias="mywebsite" Directory="WebsiteDir" />
<iis:WebApplication Id="WebApplication" Name="MyWebApplication" WebAppPool="MyWebAppPool" />
</iis:WebSite>

Resources