Skip to content

Instantly share code, notes, and snippets.

@JohnLBevan
Created December 8, 2022 07:34
Show Gist options
  • Save JohnLBevan/5c014b601c9b71deaca5fb64483dd2a9 to your computer and use it in GitHub Desktop.
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).
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