alexsusanu@docs:IIS Log Management PowerShell Scripts $
alexsusanu@docs
:~$ cat IIS Log Management PowerShell Scripts.md

HomeLIMS → IIS Log Management PowerShell Scripts

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