Skip to content

IIS_Log_Collector_With_Search.ps1

File: iis/iis_scripts/IIS_Log_Collector_With_Search.ps1

<#
.SYNOPSIS
    IIS Log Collector - Gets logs from IIS site paths + additional configured paths
    Can also search logs instead of collecting them
#>

# ============================================
# CONFIGURATION SECTION
# ============================================
# Additional log root paths to check
$AdditionalLogRoots = @(
    "F:\inetpub"
)

# MODE: Set to "collect" or "search"
$Mode = "collect"  # Change to "search" to search logs instead of collecting

# SEARCH settings (only used if Mode = "search")
$SearchString = "your_search_string_here"
$CaseSensitive = $false

# Date range options - set ONE of these to $true
$CollectToday = $false
$CollectLast2Days = $false
$CollectLast7Days = $true
$CollectSpecificDays = $false  # If true, specify days below
$SpecificDays = @(9, 10, 11)   # Days of current month

# ============================================
# SCRIPT START
# ============================================

Import-Module WebAdministration -ErrorAction Stop

# Get current date info
$Today = Get-Date
$DateSuffix = $Today.ToString("yyyy-MM-dd")
$TempFolder = Join-Path $env:TEMP "IIS_Logs_$DateSuffix"

# Create output folders only if collecting
if ($Mode -eq "collect") {
    New-Item -ItemType Directory -Path $TempFolder -Force | Out-Null
}

Write-Host "`n=== IIS Website Information ===" -ForegroundColor Cyan
$Sites = Get-Website
foreach ($Site in $Sites) {
    Write-Host "ID: $($Site.Id) | Name: $($Site.Name) | Path: $($Site.physicalPath)" -ForegroundColor Yellow
}

# Determine date filter
$DatesToCollect = @()
if ($CollectToday) {
    $DatesToCollect = @($Today)
    Write-Host "`nCollecting: Today only" -ForegroundColor Green
}
elseif ($CollectLast2Days) {
    $DatesToCollect = @($Today, $Today.AddDays(-1))
    Write-Host "`nCollecting: Last 2 days" -ForegroundColor Green
}
elseif ($CollectLast7Days) {
    $DatesToCollect = -6..0 | ForEach-Object { $Today.AddDays($_) }
    Write-Host "`nCollecting: Last 7 days" -ForegroundColor Green
}
elseif ($CollectSpecificDays) {
    $CurrentYear = $Today.Year
    $CurrentMonth = $Today.Month
    $DatesToCollect = $SpecificDays | ForEach-Object { 
        Get-Date -Year $CurrentYear -Month $CurrentMonth -Day $_ 
    }
    Write-Host "`nCollecting: Days $($SpecificDays -join ', ') of current month" -ForegroundColor Green
}

# Convert dates to IIS log format (yyMMdd)
$DatePatterns = $DatesToCollect | ForEach-Object { $_.ToString("yyMMdd") }
Write-Host "Date patterns: $($DatePatterns -join ', ')" -ForegroundColor Gray

if ($Mode -eq "search") {
    Write-Host "`nMODE: Search" -ForegroundColor Cyan
    Write-Host "Searching for: $SearchString" -ForegroundColor Yellow
    Write-Host "Case sensitive: $CaseSensitive" -ForegroundColor Gray
} else {
    Write-Host "`nMODE: Collect" -ForegroundColor Cyan
}

Write-Host "`n=== Processing Sites ===" -ForegroundColor Cyan
$TotalLogsCopied = 0
$MatchesFound = @()

foreach ($Site in $Sites) {
    $SiteName = $Site.Name
    $SiteId = $Site.Id
    $SitePath = $Site.physicalPath
    Write-Host "`nProcessing: $SiteName (ID: $SiteId)" -ForegroundColor Yellow
    Write-Host "  Site Path: $SitePath" -ForegroundColor Gray

    # Build list of log paths to check
    $PathsToCheck = @()

    # 1. Search recursively for logs folder under the site's physical path (first one found only)
    if (Test-Path $SitePath) {
        Write-Host "  Searching for logs folder under site path..." -ForegroundColor Gray
        $LogFolder = Get-ChildItem -Path $SitePath -Directory -Recurse -Filter "logs" -ErrorAction SilentlyContinue | Select-Object -First 1
        if ($LogFolder) {
            $PathsToCheck += $LogFolder.FullName
            Write-Host "    Found: $($LogFolder.FullName)" -ForegroundColor Gray
        }
    }

    # 2. Check logs folder under each additional root
    foreach ($Root in $AdditionalLogRoots) {
        if (Test-Path $Root) {
            # Look for logs folder directly in root
            $PathsToCheck += Join-Path $Root "logs"

            # Also check standard IIS structure under root
            $PathsToCheck += Join-Path $Root "logs\LogFiles\W3SVC$SiteId"
        }
    }

    $LogsFound = @()

    foreach ($Path in $PathsToCheck) {
        if (Test-Path $Path) {
            Write-Host "  Checking: $Path" -ForegroundColor Gray

            # Get matching log files - filter by last modified date
            if ($CollectLast7Days) {
                $LogFiles = Get-ChildItem -Path $Path -File -ErrorAction SilentlyContinue | 
                    Where-Object { $_.LastWriteTime -ge $Today.AddDays(-6) }
            }
            elseif ($CollectLast2Days) {
                $LogFiles = Get-ChildItem -Path $Path -File -ErrorAction SilentlyContinue | 
                    Where-Object { $_.LastWriteTime -ge $Today.AddDays(-1) }
            }
            elseif ($CollectToday) {
                $LogFiles = Get-ChildItem -Path $Path -File -ErrorAction SilentlyContinue | 
                    Where-Object { $_.LastWriteTime.Date -eq $Today.Date }
            }
            elseif ($CollectSpecificDays) {
                $LogFiles = Get-ChildItem -Path $Path -File -ErrorAction SilentlyContinue | 
                    Where-Object { 
                        $FileDay = $_.LastWriteTime.Day
                        $SpecificDays -contains $FileDay
                    }
            }

            if ($LogFiles) {
                $LogsFound += $LogFiles
                Write-Host "    Found $($LogFiles.Count) log(s)" -ForegroundColor Green
            }
        }
    }

    if ($LogsFound.Count -eq 0) {
        Write-Host "  No logs found for specified dates" -ForegroundColor Red
        continue
    }

    if ($Mode -eq "search") {
        # Search mode
        foreach ($Log in $LogsFound) {
            Write-Host "    Searching: $($Log.Name)..." -ForegroundColor Gray -NoNewline

            if ($CaseSensitive) {
                $Matches = Select-String -Path $Log.FullName -Pattern $SearchString -CaseSensitive
            } else {
                $Matches = Select-String -Path $Log.FullName -Pattern $SearchString
            }

            if ($Matches) {
                Write-Host " FOUND ($($Matches.Count) matches)" -ForegroundColor Green
                $MatchesFound += @{
                    SiteName = $SiteName
                    FileName = $Log.Name
                    FilePath = $Log.FullName
                    MatchCount = $Matches.Count
                    Matches = $Matches
                }
            } else {
                Write-Host " No matches" -ForegroundColor DarkGray
            }
        }
    } else {
        # Collect mode - Copy and rename logs into site-specific folder
        $SiteFolder = Join-Path $TempFolder $SiteName
        New-Item -ItemType Directory -Path $SiteFolder -Force | Out-Null

        foreach ($Log in $LogsFound) {
            $NewName = "$($SiteName)_$($Log.Name)"
            $DestPath = Join-Path $SiteFolder $NewName
            Copy-Item -Path $Log.FullName -Destination $DestPath -Force
            Write-Host "    Copied: $($Log.Name) -> $NewName" -ForegroundColor Gray
            $TotalLogsCopied++
        }
    }
}

# Handle output based on mode
if ($Mode -eq "search") {
    Write-Host "`n=== Search Results ===" -ForegroundColor Cyan
    Write-Host "Files with matches: $($MatchesFound.Count)" -ForegroundColor Green

    if ($MatchesFound.Count -gt 0) {
        $OutputFile = Join-Path $env:USERPROFILE "Desktop\IIS_Search_Results_$DateSuffix.txt"

        foreach ($Match in $MatchesFound) {
            Add-Content -Path $OutputFile -Value "`n========================================"
            Add-Content -Path $OutputFile -Value "Site: $($Match.SiteName)"
            Add-Content -Path $OutputFile -Value "File: $($Match.FileName)"
            Add-Content -Path $OutputFile -Value "Path: $($Match.FilePath)"
            Add-Content -Path $OutputFile -Value "Matches: $($Match.MatchCount)"
            Add-Content -Path $OutputFile -Value "`nMatching lines:"
            $Match.Matches | ForEach-Object {
                Add-Content -Path $OutputFile -Value "Line $($_.LineNumber): $($_.Line)"
            }
        }

        Write-Host "`nSUCCESS!" -ForegroundColor Green
        Write-Host "Results saved: $OutputFile" -ForegroundColor Green
    } else {
        Write-Host "`nNo matches found" -ForegroundColor Red
    }
} else {
    Write-Host "`n=== Creating Archive ===" -ForegroundColor Cyan
    Write-Host "Total logs collected: $TotalLogsCopied" -ForegroundColor Green

    if ($TotalLogsCopied -gt 0) {
        $ZipPath = Join-Path $env:USERPROFILE "Desktop\IIS_Logs_$DateSuffix.zip"
        Compress-Archive -Path "$TempFolder\*" -DestinationPath $ZipPath -Force
        Remove-Item -Path $TempFolder -Recurse -Force

        Write-Host "`nSUCCESS!" -ForegroundColor Green
        Write-Host "Archive created: $ZipPath" -ForegroundColor Green
        Write-Host "Size: $([math]::Round((Get-Item $ZipPath).Length / 1MB, 2)) MB" -ForegroundColor Gray
    } else {
        Write-Host "`nNo logs collected - nothing to archive" -ForegroundColor Red
        Remove-Item -Path $TempFolder -Recurse -Force
    }
}

Write-Host "`n=== COMPLETE ===" -ForegroundColor Cyan