![]() |
|
![]() |
IIS Configuration |
The "Adsi" and "/Adsi" macros are used
to configure IIS.
See the "TryMeCreateIisSite.MM" script for a good complete
example.
I have some useful
IIS related links
on my website,
"IIS FAQ
" site appear very useful.
To create a new WEB site you must create an object of type "IIsWebServer" and then within this object a "IIsWebVirtualDir" with the name "ROOT" (example below).
The "CLASS" parameter of the "Adsi" command must always be supplied when referring to objects of the type "IIsWebServer" and "IIsFtpServer" as these work differently from normal ADSI (and even "IIS") objects. For these objects the name represents an "alias" (servercomment) which maps to a unique numeric "name". For example after installing IIS you will have a "Default Web Site" server with an ADSI object name of "1".
Note that "IisWebDirectory" objects (and possibly others) will not show up in the "Internet Information Services" configuration tool if the directory the object represents does not physically exist. The IIS object is created but will not appear until you have created the directory. The directory will have the same name as the name of the IIS object you create.
Launch Condition - IIS Installed? |
When your install requires a particular environment (such as IIS) to be able to install and/or uninstall your product it is a good idea to generate a descriptive message to inform any user of these requirements rather than allow the install to continue and fail or worse still continue without detecting errors.
The following demonstrates how an MSI could check to see if IIS is installed (checks for the existance of a particular registry value):
#( ;--- Look for a service registry value ---------------------------------- <$RegistryRead Property="IISINSTALLED4CONFIG" HKEY="LOCAL_MACHINE" KEY="SYSTEM\CurrentControlSet\Services\W3SVC" NAME="DisplayName" Condition="not Installed" Default="NoIIS" > #) #( <$AbortIf condition=^IISINSTALLED4CONFIG = "NoIIS"^ Message=^The install of "<$ProdInfo.ProductName>" version <$Productversion> can't continue as it requires IIS (and IIS isn't installed on this machine).^ Seq="AppSearch-" SeqTable="InstallUISequence InstallExecuteSequence" > #)
MAKE IIS BACKUPS! |
Before testing any MSI or script that configures IIS I highly recommend that you manually perform a backup using the "Internet Information Services" configuration tool. Right click on the computer object and select the backup/restore option (under "All Tasks" menu on WinXP).
If nothing seems to be working stop/start IIS, if still no good, restore from a backup. I have seen IIS hang on a restore until Windows was rebooted. IIS is very touchy...
Once a manual backup has been performed you can relax in the knowledge that although IIS can get screwed up though your errors (unlikely) or IIS "features" (more likely - at least while developing your code) you can recover.
I'd also suggest that your install and uninstall steps should backup the configuration automatically as shown here:.
#define? IIS_MAX_BACKUPS_PER_DAY 5 ;;set a default value <$Adsi "LocalHost" PARENT="IIS:/" Dump="Y"> ;--- Need some VB constants (dumped the lot, you can search for doco) ---- const MD_BACKUP_FORCE_BACKUP = 4 ;;Backup const MD_BACKUP_HIGHEST_VERSION = &HFFFFFFFE ;;Backup, Delete, Restore const MD_BACKUP_MAX_VERSION = 9999 ;;Limit const MD_BACKUP_MAX_LEN = 100 ;;Limit const MD_BACKUP_NEXT_VERSION = &HFFFFFFFF ;;Backup const MD_BACKUP_OVERWRITE = 1 ;;Backup const MD_BACKUP_SAVE_FIRST = 2 ;;Backup const MD_BACKUP_NO_MORE_BACKUPS = &H80070103 ;--- Create a "today" based backup name (we may restrict backups under this name) --- dim BackupName : BackupName = "MAKEMSI - " & day(date()) & " " & MonthName(month(date())) & " " & year(date()) ;;Example = "MAKEMSI - 18 May 2006" ;--- Now perhaps we'd like to restrict number of backups made today? ----- dim MakeBackup #if ['<$IIS_MAX_BACKUPS_PER_DAY>' = '0'] CaDebug 0, "No restrictions on the number of backups made..." MakeBackup = true #elseif ;--- User does want to restrict number of backups ------------------- CaDebug 0, "We don't want more than <$IIS_MAX_BACKUPS_PER_DAY> backups made..." VbsCaLogInc(1) on error resume next dim Index : Index = 0 dim BuVersion, BuLocation, BuDateTime do while true ;--- See if this "index" exists ----------------------------- .EnumBackups BackupName, Index, BuVersion, BuLocation, BuDateTime if (err.number <> 0) then if (err.number = MD_BACKUP_NO_MORE_BACKUPS) then exit do End If end if ;--- Found a backup ------------------------------------------------- Index = Index + 1 CaDebug 0, "BACKUP #" & Index & " created at " & BuDateTime & " UTC" loop on error goto 0 CaDebug 0, "Found " & Index & " backups made today." 'Note backup name includes todays date! VbsCaLogInc(-1) if Index < <$IIS_MAX_BACKUPS_PER_DAY> then MakeBackup = true else MakeBackup = false end if #endif ;--- Backup the IIS configuration ---------------------------------------- if not MakeBackup then CaDebug 0, "We don't want to make any more backups today..." else CaDebug 0, "Backing up the complete IIS configuration..." .Backup BackupName, MD_BACKUP_NEXT_VERSION, (MD_BACKUP_SAVE_FIRST or MD_BACKUP_FORCE_BACKUP) CaDebug 0, "Successfully backed up the IIS configuration" end if <$/Adsi>
The valid character set allowed in a backup "filename" is undocumented (as expected) so if a backup fails the most likely reason is that the name contains one or more invalid characters.
Start/Stop IIS |
You will probably want to stop IIS while changing configuration and restart when complete, this is what I use:
<$Component "StopStartIisServices" Directory_="<$AnyDir>" LM="Y"> <$ServiceControl Name="IISADMIN" AtInstall="start stop" AtUnInstall="start stop" Wait="Y"> <$ServiceControl Name="W3SVC" AtInstall="start stop" AtUnInstall="start stop" Wait="Y"> ;;You may also want to restart ftp (maybe others)! <$/Component>
I used to always do this but lately I haven't found the need (maybe IIS more stable), so you may or may not need to do this...
EXAMPLE |
For a good complete self contained example that MAKEMSI installs have a look at the "TryMeCreateIisSite.MM" sample...
;--- Create a new IIS web server/site --------------------------------------- <$Adsi "ANewWebApplication" Class="IISWebServer" Create="Y"> ;--- Basic configuration ------------------------------------------------- .ServerBindings = array(":1234:") ;;Binds to TCP-IP port 1234 .ContentIndexed = False .DontLog = True ;--- A web server MUST have a "ROOT" entry ------------------------------- <$Adsi "ROOT" Class="IisWebVirtualDir" Create="Y"> ;--- Basic configuration (for this virtual directory) ---------------- .ContentIndexed = False .DontLog = True .path = "C:\tmp\Root" ;--- Modify characteristics for one specific file -------------------- <$Adsi "ThisAsp.asp" Class="IIsWebFile" create="Y"> .AuthAnonymous = True .AuthNTLM = True <$/Adsi> ;--- Make it possible to web "browse" the "C:\tmp\1" directory tree --- <$Adsi "BrowsableDirTree" Class="IisWebVirtualDir" Create="Y"> .path = "C:\tmp\1" .AuthAnonymous = False ;;No anonymous access .AuthNTLM = True ;;Use Windows Integrated security .AccessExecute = False .AccessNoRemoteExecute = False .AccessRead = True .AccessScript = False .AccessSource = False .AspEnableParentPaths = False .ContentIndexed = False .DefaultDoc = "" .DirBrowseShowExtension = True .DirBrowseShowLongDate = True .DirBrowseShowSize = True .DontLog = True .EnableDirBrowsing = True <$/Adsi> <$/Adsi> <$/Adsi> ;--- Create a new site under the standard IIS "Default Web Site" ------------ <$Adsi "Default Web Site" Class="IIsWebServer"> ;;/1 (normally? Always?) <$Adsi "ROOT"> ;;/1/ROOT <$Adsi "NewDirUnderDefault" Class="IisWebDirectory" Create="Y"> .ContentIndexed = False .DontLog = True <$/Adsi> <$/Adsi> <$/Adsi>
![]() ![]() |
| ![]() ![]() |