Created
December 8, 2022 07:34
-
-
Save JohnLBevan/5c014b601c9b71deaca5fb64483dd2a9 to your computer and use it in GitHub Desktop.
Code for finding whether any file transfers have occured on any IIS FTP sites in the last year (has parameters to allow this to be tweaked more, though I've not passed those all the way down as they were beyond my requirement).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Function Import-IISLog { | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Mandatory, ValueFromPipeline)] | |
[System.IO.FileInfo]$Path | |
, | |
[Parameter()] | |
[Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]$Encoding = [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]::Ascii | |
) | |
Begin { | |
$delim = ' ' | |
} | |
Process { | |
[string]$fn = $Path.FullName | |
[string[]]$headers = (Get-Content -Path $fn -Encoding $Encoding | Where-Object {$_ -like '#Fields*'} | Select -First 1) -split $delim | Select-Object -Skip 1 # although headers could change throughout the file, that seems unlikely... assume they're always the same | |
# for now ignore Software, Version, Date, and Fields metadata lines... if desired we could append those to our rows | |
# for now don't include info about our source file in the output... if desired we could restructure this function to return a more complex object with this in the header, or have it appended to each row... | |
Get-Content -Path $fn -Encoding $Encoding | Where-Object {$_ -notlike '#*'} | ConvertFrom-Csv -Delimiter $delim -Header $headers | |
} | |
} | |
Function ConvertTo-DateTime { | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Mandatory, ValueFromPipeline)] | |
[string]$InputObject | |
, | |
[Parameter()] | |
[string]$DateFormat = 'yyyy-MM-dd' | |
, | |
[Parameter()] | |
[System.Globalization.CultureInfo]$FormatProvider = [System.Globalization.CultureInfo]::InvariantCulture | |
, | |
[Parameter()] | |
[System.Globalization.DateTimeStyles]$DatetimeStyle = [System.Globalization.DateTimeStyles]::AllowWhiteSpaces -bor [System.Globalization.DateTimeStyles]::AssumeUniversal | |
) | |
Process { | |
$temp = [DateTime]::MinValue # this value isn't returned; TryParseExact just uses a ref where we only want an out | |
if ([DateTime]::TryParseExact($InputObject, $DateFormat, $FormatProvider, $DatetimeStyle,[ref]$temp)) { | |
$temp | |
} | |
} | |
} | |
Function Get-MostRecentIISLogDate { | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Mandatory, ValueFromPipeline)] | |
[System.IO.DirectoryInfo]$Path | |
, | |
[Parameter()] | |
[string]$Filter = '*.log' | |
, | |
[Parameter()] | |
[string[]]$MethodsOfInterest = @('APPE', 'RETR', 'STPR', 'STOU') # i.e. those commands which mean a file transfer's occurring | |
, | |
[Parameter()] | |
[DateTime]$CutoffDate = (Get-Date).AddYears(-1) # if there's been no activity in a year, we can safely treat it as no longer relevant (pass [DateTime]::MinValue for indefinite history) | |
) | |
Begin { | |
[string]$methodPropertyName = 'cs-method' # putting property names into variables in case we need to tweak things with logs in different languages... not sure | |
[string]$datePropertyName = 'date' # for now just checking on date; not time | |
} | |
Process { | |
Write-Verbose "Processing $($Path.FullName)" | |
$lastActivityDate = $CutoffDate | |
$logFiles = Get-ChildItem -Path $Path.FullName -Filter $Filter | Where-Object {$_.LastWriteTimeUtc -gt $lastActivityDate} | Sort-Object -Property LastWriteTimeUtc -Descending | |
foreach ($logFile in $logFiles) { | |
Write-Verbose "- $($logFile.Name)" | |
$foundDate = $logFile | | |
Import-IISLog | | |
Where-Object {$_.$methodPropertyName -in $methodsOfInterest} | | |
ForEach-Object {$_.$datePropertyName | ConvertTo-DateTime} | | |
Measure-Object -Maximum | | |
Select-Object -ExpandProperty Maximum | |
if ($null -ne $foundDate) { | |
if ($foundDate -gt $lastActivityDate) { | |
$lastActivityDate = $foundDate | |
} | |
break; | |
} | |
} | |
([PSCustomObject]@{Log = $Path.Name;LastActive=$lastActivityDate}) | |
} | |
} | |
Get-Item -Path 'C:\inetpub\logs\LogFiles\F*' | Where-Object {$_.Attributes -band [System.IO.FileAttributes]::Directory} | Get-MostRecentIISLogDate -Verbose | sort LastActive -Descending |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment