I’d like to show you a simple way to find any related information in IIS logs with PowerShell. Yeah, I know there are some tool which are useful to parse IIS logs, but I like scripting and playing with PowerShell.
I wrote a small script which can collect between start and end time IIS logs from a Web server and merge them into a CSV file which is useful to gain information or create small report based on parameters.
How the script works?
There are three parameter in order Name, StartTime and EndTime
. Name represent the WebSite name which can be found to list all websites in a web server using Get-WebSite
cmdlet. For the cmdlet you have to import WebAdministration
module. Keep in mind since PowerShell 3.0, installed modules are automatically imported when you use any commands if $PSModuleAutoLoadingPreference
preference variable is set to All
. About preference variables.
Based on website name the script set the $LogFolder
variable to the IIS log folder which contains related events for.
$LogFolder = Get-Website | ?{$_.Name -eq $Name} | Select @{N="LogFile";E={$_.LogFile.Directory + "\W3SVC" + $_.Id}}
Then collect log files from the folder, which are true for the Where-Object
condition.
$LogFile = Get-ChildItem $LogFolder.LogFile | ?{$_.CreationTime -lt $EndTime -and $_.LastwriteTime -gt $StartTime}
Collect all rows from log files which contains the “Fields: ” text. We need heads for the .csv file.
$Heads = Get-Content $LogFile.FullName[0] | ?{$_ -match "#Fields: "}
Formad first line of $Heads
and take it into a temporary file. I tried to avoid temporary file, but I could not solve import into CSV from variable.
$Heads[0] | %{$_ -replace "#Fields: ","" -replace "-","_" -replace "\(","" -replace "\)",""} | Out-File .\tempiislog.tmp
Append all events into the temporary file.
$LogFile | %{Get-Content $_.FullName} | ?{$_ -notlike "#*"} | Out-File .\tempiislog.tmp -Append
In the end select only rows from temp file which are exactly match for the criteria (date and time) and export into .csv file.
Import-Csv -Delimiter " " -Path .\tempiislog.tmp |
?{[datetime]($_.Date +" "+$_.Time) -gt $StartTime -and [datetime]($_.Date +" "+$_.Time) -lt $EndTime} |
Export-Csv -Path ("MergedIISLogs_{0:MMddyyHHmm}-" -f $StartTime + "{0:MMddyyHHmm}.log" -f $EndTime) -Delimiter ";"
Merged IIS log files can be found next to your script as MergedIISLogs_MMddyyHHmm-MMddyyHHmm.log
in CSV format.
How can you search in IIS logs?
For example you can find all related entries where status code is “302” which is a redirection.
Import-Csv -Delimiter ";" -Path .\MergedIISLogs_xxxxxxxxxx-xxxxxxxxxx.log | Where-Object {$_.sc_status -match "302"}
Or you can find the slowest uri.
$maximum = (Import-Csv -Delimiter ";" -Path .\MergedIISLogs_xxxxxxxxxx-xxxxxxxxxx.log |
Measure-Object -Property time_taken -Maximum).maximum
Import-Csv -Delimiter ";" -Path .\MergedIISLogs_xxxxxxxxxx-xxxxxxxxxx.log | ?{$_.time_taken -eq $maximum}