Did you save some changes in IIS that ended up breaking your website? We’ve all been there..
No need to panic, IIS (from version 7 upwards) saves the last 10 configuration changes so within minutes you can revert changes quite easy.
Application Host Help Service
Application Host Help Service is a Windows service that checks your IIS configuration every 2 minutes and backs up all changes to %SystemDrive%\inetpub\history directory.
Okay, that’s cool, but how to I recover configurations from that folder?
Well just copy the folder contents to the IIS working directory %Windir%\system32\inetsrv\config.
Restoring IIS Configurations
To restore a configuration run the following command:
cd %windir%\system32\inetsrv
appcmd list backups
appcmd restore backup <BACKUP NAME>
To change the number of restore points that IIS creates and the time interval between them you can edit the %windir%\system32\inetsrv\config\applicationHost.config file.
<configHistory maxHistories="30" period="00:00:15" />
There are four configurable settings (attributes) for the configHistory section:
Attribute | Default Setting | Definition |
---|---|---|
enabled | True | This value indicates whether configuration history is enabled or disabled |
path | %systemdrive%\inetpub\history | The path where history directories are created and stored |
maxHistories | 10 | The maximum number of directories retained |
period | 00:02:00 | The time between each check made for changes |
TIP: If IIS is not saving any backups check that the Windows Service is running and that there are no errors thrown by IIS-AppHstSvc in the Event Viewer.
Script to Cause History Creation
You can also use a VB script that will force the Application Host Help Service to generate a new safe point for your IIS server.
Option Explicit
' Global objects, variables
Dim objShell, argObj, oExec
Dim strDirectory, strFile, strCmd, strFullCmd, stdIn, i
set objShell = CreateObject("Wscript.Shell")
strDirectory = "%windir%\system32\inetsrv\"
strFile = "AppCmd.exe"
set ArgObj = Wscript.Arguments
' No args (default case), hard-code StdIn
If ArgObj.Count = 0 Then
stdIn = 17
i = 0 'initilize i
For i = 0 to stdIn
' Call Select Case to change Statement
strCmd = getStrCmd(i)
strFullCmd = strDirectory & strFile & " " & strCmd
Set oExec = objShell.Exec(strFullCmd)
Do While oExec.Status = 0
WScript.Sleep 100
Loop
If oExec.ExitCode <> 0 Then
' Something wrong with the IIS Installation
' Is AppCmd installed on the machine? \inetsrv directory?
msgBox "Executing AppCmd Command Failed. Please Try Again!"
wscript.Quit
End if
WScript.Sleep(2 * 1000)
Next
' Handle the case where we passed arguments to
' the script
Else
stdIn = ArgObj(0)
' Same code as above but handle arguments being passed.
i = 0 ' initialize i
For i = 0 to stdIn
' Call Select Case to change Statement
strCmd = getStrCmd(i)
strFullCmd = strDirectory & strFile & " " & strCmd
Set oExec = objShell.Exec(strFullCmd)
Do While oExec.Status = 0
WScript.Sleep 100
Loop
' Validate that AppCmd calls succeeded by checking Error code
If oExec.ExitCode <> 0 Then
' Something wrong with the IIS Installation
' Is AppCmd installed on the machine? \inetsrv directory?
msgBox "Executing AppCmd Command Failed. Please Try Again!"
wscript.Quit
End if
' Go to sleep for x period (default: 20)
WScript.Sleep(20 * 1000)
Next
' End the StdIn Input Tree
End if
' AppCMD Command Function
Function getStrCmd(MyIndex)
Select Case (MyIndex)
Case 0 ' set Server Runtime
getStrCmd = "set config /section:serverRuntime /enabled:false"
Case 1 ' set Default Document
getStrCmd = "set config /section:defaultDocument /enabled:true"
Case 2 'set httpRedirect
getStrCmd = "set config /section:httpRedirect /enabled:true"
Case 3 ' set Client Certificate Mapping Auth
getStrCmd = "set config /section:security/authentication/clientCertificateMappingAuthentication /enabled:true"
Case 4 ' set Directory Browse
getStrCmd = "set config /section:directoryBrowse /enabled:true"
Case 5 ' set httpRedirect
getStrCmd = "set config /section:httpRedirect /enabled:false"
Case 6 ' set anonymousAuth
getStrCmd = "set config /section:security/authentication/anonymousAuthentication /enabled:false"
Case 7 ' set basicAuth
getStrCmd = "set config /section:security/authentication/basicAuthentication /enabled:true"
Case 8 ' set digestAuth
getStrCmd = "set config /section:security/authentication/digestAuthentication /enabled:true"
Case 9 ' set client cert mapping auth
getStrCmd = "set config /section:security/authentication/clientCertificateMappingAuthentication /enabled:false"
Case 10 ' set windows auth
getStrCmd = "set config /section:security/authentication/windowsAuthentication /enabled:true"
Case 11 ' server runtime
getStrCmd = "set config /section:serverRuntime /enabled:true"
Case 12 ' set Server Runtime
getStrCmd = "set config /section:serverRuntime /enabled:false"
Case 13 ' set Server Runtime
getStrCmd = "set config /section:serverRuntime /enabled:true"
Case 14 ' set Server Runtime
getStrCmd = "set config /section:serverRuntime /enabled:true"
Case 15 ' set Server Runtime
getStrCmd = "set config /section:serverRuntime /enabled:true"
Case 16 ' set Server Runtime
getStrCmd = "set config /section:serverRuntime /enabled:true"
Case 17 ' set Server Runtime
getStrCmd = "set config /section:serverRuntime /enabled:true"
End select
End Function
Save the above script as ConfigHst.vbs and run it with:
cscript //nologo configHst.vbs