During this process, I had a chance to build few automation modules in Powershell. I am going to share some snippets of the modules in upcoming posts which I found not so straight forward to build. So that it would be useful to someone who is trying perform the same task.
In this post I am going to cover the automated installation and configuration of IIS Advanced logging module.
Why Advanced Logging module?
Since all of our web servers are behind Elastic Load Balancers (ELB), the remote host address is always set to the internal IP address of the load balancer. ELB puts the actual client IP address is in the X-Forwarded-For request header. The stock standard IIS HTTP logging module doesn't have access to these custom headers therefore we chose to use Advanced Logging module to capture and log additional customer headers.
We only need Advanced Logging module for IIS 7, IIS 7.5 and IIS 8.0. In IIS 8.5 (i.e.: In Windows 2012 R2) the HTTP logging has native support to capture custom fields as part of stock standard HTTP logging.
It was pretty straight forward to install and configure manually but not so easy through Powershell because installation and configuration not fully supported through Powershell alone I had to use appcmd.exe as well.
We only need Advanced Logging module for IIS 7, IIS 7.5 and IIS 8.0. In IIS 8.5 (i.e.: In Windows 2012 R2) the HTTP logging has native support to capture custom fields as part of stock standard HTTP logging.
It was pretty straight forward to install and configure manually but not so easy through Powershell because installation and configuration not fully supported through Powershell alone I had to use appcmd.exe as well.
The Goal
- Install Advanced Logging module
- Create custom logging folder and assign permissions
- Disable stock standard IIS logging
- Add additional headers like X-Forwarded-For, X-Forwarded-Proto to the available logging fields
- Disable server level Advanced logging
- Enable Advanced logging
- Configure custom log directory at server level and default site level
- Configure Advanced Logging by site on the server
Lets dive into detail.....
1. Install Advanced Logging module
2. Create custom logging folder and assign permissionsmsiexec.exe /i C:\data\AdvancedLogging64.msi /passive /log C:\Data\advancedlogging.log Start-Sleep -Seconds 10
Give Read & Write access to IIS_IUSERS group (I found out about this in the hard way)
3. Disable stock standard IIS logging#grant permission to IIS_IUSERS group to the log directory $Command = "icacls C:\logs /grant BUILTIN\IIS_IUSRS:(OI)(CI)RXMW" cmd.exe /c $Command
Import-Module WebAdministration
# Disables http logging module
Set-WebConfigurationProperty -Filter system.webServer/httpLogging -PSPath machine/webroot/apphost -Name dontlog -Value true
4. Add additional headers like X-Forwarded-For, X-Forwarded-Proto to the available logging fields5. Disable default server level Advanced logging# Adds AWS ELB aware X-Forwarded-For logging field Add-WebConfiguration "system.webServer/advancedLogging/server/fields" -value @{id="X-Forwarded-For";sourceName="X-Forwarded-For";sourceType="RequestHeader";logHeaderName="X-Forwarded-For";category="Default";loggingDataType="TypeLPCSTR"} # Adds AWS ELB aware X-Forwarded-Proto logging field Add-WebConfiguration "system.webServer/advancedLogging/server/fields" -value @{id="X-Forwarded-Proto";sourceName="X-Forwarded-Proto";sourceType="RequestHeader";logHeaderName="X-Forwarded-Proto";category="Default";loggingDataType="TypeLPCSTR"}
6. Enable Advanced logging# Disables the default advanced logging config Set-WebConfigurationProperty -Filter "system.webServer/advancedLogging/server/logDefinitions/logDefinition[@baseFileName='%COMPUTERNAME%-Server']" -name enabled -value false
By default the Advanced Logging is disabled.
# Enable Advanced Logging
Set-WebConfigurationProperty -Filter system.webServer/advancedLogging/server -PSPath machine/webroot/apphost -Name enabled -Value true
7. Configure custom log directory at server level and default site level8. Configure Advanced Logging by site on the server# Set log directory at server level Set-WebConfigurationProperty -Filter system.applicationHost/advancedLogging/serverLogs -PSPath machine/webroot/apphost -Name directory -Value $logDirectory # Set log directory at site default level Set-WebConfigurationProperty -Filter system.applicationHost/sites/siteDefaults/advancedLogging -PSPath machine/webroot/apphost -Name directory -Value $logDirectory
function AdvancedLogging-GenerateAppCmdScriptToConfigureAndRun() { param([string] $site) #Get current powershell execution folder $currentLocation = Get-Location #Create an empty bat which will be populated with appcmd instructions $stream = [System.IO.StreamWriter] "$currentLocation\$site.bat" #Create site specific log definition $stream.WriteLine("C:\windows\system32\inetsrv\appcmd.exe set config `"$site`" -section:system.webServer/advancedLogging/server /+`"logDefinitions.[baseFileName='$site',enabled='True',logRollOption='Schedule',schedule='Daily',publishLogEvent='False']`" /commit:apphost") #Get all available fields for logging $availableFields = Get-WebConfiguration "system.webServer/advancedLogging/server/fields" #Add appcmd instruction to add all the selected fields above to be logged as part of the logging #The below section can be extended to filter out any unwanted fields foreach ($item in $availableFields.Collection) { $stream.WriteLine("C:\windows\system32\inetsrv\appcmd.exe set config `"$site`" -section:system.webServer/advancedLogging/server /+`"logDefinitions.[baseFileName='$site'].selectedFields.[id='$($item.id)',logHeaderName='$($item.logHeaderName)']`" /commit:apphost") } $stream.close() # execute the batch file create to configure the site specific Advanced Logging Start-Process -FilePath $currentLocation\$site.bat Start-Sleep -Seconds 10 }
#Call the above method by passing in the IIS site names AdvancedLogging-GenerateAppCmdScriptToConfigureAndRun 'foo.com'
And that’s it :).
I found following two posts to be helpful in building the above.
http://forums.iis.net/t/1193633.aspx?Configure+Advanced+Logging+through+powershell
http://forums.iis.net/t/1161699.aspx?IIS+Advanced+Logging+1+0+Feedback
Comments and suggestions are welcome.
3 comments:
Excellent article. Really helped with configuring some roll out scripts! The only thing you might want to add is that you need intiate the WebAdministration module for this to work by doing:
import-module WebAdministration
Hi, I am working on adding some custom log fields to my app servers (we have them sitting behind a load balancer and need the original client IP address to come in as a http header). I was able to add the fields in the IIS manager GUI without installing the advanced logging module, but I am having a hard time finding the commands needed to automate this process. See image below:
http://i61.tinypic.com/2zppa1y.png
This blog post is only relevant upto windows 2012. From windows 2012 r2 onwards, it has built in support for custom http headers as you mentioned. I still have to figure out how to automate for windows 2012 r2.
Post a Comment