IIS Log Management PowerShell Scripts
Each function can be used independently, but some call others as noted below
STANDALONE: Get IIS log file locations
function Get-IISLogPaths {
Import-Module WebAdministration
Get-Website | ForEach-Object {
$logPath = (Get-ItemProperty "IIS:\Sites\$($_.Name)" -Name logFile.directory).Value
$logPath = $logPath -replace '%SystemDrive%', $env:SystemDrive
[PSCustomObject]@{
SiteName = $_.Name
LogPath = "$logPath\W3SVC$($_.ID)"
Status = $_.State
}
}
}
QUICK START: Get the default website log path
function Get-DefaultLogPath {
return "C:\inetpub\logs\LogFiles\W3SVC1"
}
REQUIRES LOG PATH: Parse W3C log files (you must provide the path)
function Parse-IISLogs {
param(
[Parameter(Mandatory=$true)]
[string]$LogPath, # Example: "C:\inetpub\logs\LogFiles\W3SVC1"
[datetime]$StartDate = (Get-Date).AddDays(-1),
[datetime]$EndDate = (Get-Date),
[string]$StatusCode = "*"
)
Get-ChildItem "$LogPath\*.log" | Where-Object {
$_.LastWriteTime -ge $StartDate -and $_.LastWriteTime -le $EndDate
} | ForEach-Object {
$content = Get-Content $_.FullName
$fields = ($content | Where-Object { $_ -like "#Fields:*" } | Select-Object -First 1) -replace "#Fields: ", "" -split " "
$content | Where-Object {
$_ -notlike "#*" -and $_ -ne ""
} | ForEach-Object {
$values = $_ -split " "
$logEntry = [ordered]@{}
for ($i = 0; $i -lt $fields.Length; $i++) {
$logEntry[$fields[$i]] = $values[$i]
}
if ($logEntry['sc-status'] -like $StatusCode) {
[PSCustomObject]$logEntry
}
}
}
}
SIMPLE STANDALONE: Get today's logs from default location
function Get-TodaysLogs {
$logPath = "C:\inetpub\logs\LogFiles\W3SVC1"
$today = Get-Date -Format "yyMMdd"
$logFile = Get-ChildItem "$logPath\ex$today.log" -ErrorAction SilentlyContinue
if ($logFile) {
Get-Content $logFile.FullName | Where-Object { $_ -notlike "#*" -and $_ -ne "" } | Select-Object -Last 20
} else {
Write-Host "No log file found for today at $logPath" -ForegroundColor Yellow
}
}
3. Get today's error logs (4xx, 5xx status codes)
function Get-IISErrors {
param([string]$SiteName = "Default Web Site")
$site = Get-Website -Name $SiteName
$logPath = (Get-ItemProperty "IIS:\Sites\$SiteName" -Name logFile.directory).Value
$logPath = $logPath -replace '%SystemDrive%', $env:SystemDrive
$fullPath = "$logPath\W3SVC$($site.ID)"
Parse-IISLogs -LogPath $fullPath -StatusCode "[45]*" |
Group-Object 'sc-status' |
Sort-Object Count -Descending |
Select-Object Name, Count, @{Name='URLs'; Expression={($_.Group | Select-Object -First 5 'cs-uri-stem').('cs-uri-stem')}}
}
4. Monitor real-time IIS logs
function Watch-IISLogs {
param(
[string]$SiteName = "Default Web Site",
[int]$TailLines = 10
)
$site = Get-Website -Name $SiteName
$logPath = (Get-ItemProperty "IIS:\Sites\$SiteName" -Name logFile.directory).Value
$logPath = $logPath -replace '%SystemDrive%', $env:SystemDrive
$logFile = Get-ChildItem "$logPath\W3SVC$($site.ID)" -Filter "*.log" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
Get-Content $logFile.FullName -Tail $TailLines -Wait
}
5. Configure W3C logging format
function Set-IISLogFormat {
param(
[string]$SiteName = "Default Web Site",
[string[]]$Fields = @('date', 'time', 'c-ip', 'cs-username', 'cs-method', 'cs-uri-stem', 'cs-uri-query', 'sc-status', 'sc-bytes', 'cs-bytes', 'time-taken', 'cs(User-Agent)', 'cs(Referer)')
)
Import-Module WebAdministration
Set-WebConfigurationProperty -Filter "system.webServer/httpLogging" -PSPath "IIS:\Sites\$SiteName" -Name "selectiveLogging" -Value "LogAll"
# Set log fields
$logFields = $Fields -join ','
Set-WebConfigurationProperty -Filter "system.webServer/httpLogging" -PSPath "IIS:\Sites\$SiteName" -Name "logExtFileFlags" -Value $logFields
}
6. Analyze top IPs and URLs
function Get-IISTopStats {
param(
[string]$SiteName = "Default Web Site",
[int]$TopCount = 10
)
$site = Get-Website -Name $SiteName
$logPath = (Get-ItemProperty "IIS:\Sites\$SiteName" -Name logFile.directory).Value
$logPath = $logPath -replace '%SystemDrive%', $env:SystemDrive
$fullPath = "$logPath\W3SVC$($site.ID)"
$logs = Parse-IISLogs -LogPath $fullPath
Write-Host "Top $TopCount IPs:" -ForegroundColor Green
$logs | Group-Object 'c-ip' | Sort-Object Count -Descending | Select-Object -First $TopCount Name, Count
Write-Host "`nTop $TopCount URLs:" -ForegroundColor Green
$logs | Group-Object 'cs-uri-stem' | Sort-Object Count -Descending | Select-Object -First $TopCount Name, Count
Write-Host "`nTop $TopCount User Agents:" -ForegroundColor Green
$logs | Group-Object 'cs(User-Agent)' | Sort-Object Count -Descending | Select-Object -First $TopCount Name, Count
}
Usage Examples:
SIMPLE - Just see today's logs:
Get-TodaysLogs
FIND LOG PATHS - If you don't know where logs are:
Get-IISLogPaths
PARSE SPECIFIC PATH - HERE'S HOW YOU ADD THE PATH:
Parse-IISLogs -LogPath "C:\inetpub\logs\LogFiles\W3SVC1"
OR if your logs are on F drive:
Parse-IISLogs -LogPath "F:\inetpub\logs\LogFiles\W3SVC1"
REAL EXAMPLES OF HOW TO TYPE THE COMMANDS:
1. Copy and paste this exact line in PowerShell:
Parse-IISLogs -LogPath "C:\inetpub\logs\LogFiles\W3SVC1"
2. Or if you want only errors:
Parse-IISLogs -LogPath "C:\inetpub\logs\LogFiles\W3SVC1" -StatusCode "4*"
3. Or just today's logs:
Parse-IISLogs -LogPath "C:\inetpub\logs\LogFiles\W3SVC1" -StartDate (Get-Date).Date
The path goes AFTER -LogPath and in quotes!
Last updated: 2025-08-26 20:00 UTC