Severity: Info
Files:
setup/taskschd/ServyFailureEmail.ps1, lines 209 and 286
setup/taskschd/Get-ServyLastErrors.ps1, line 42
The watermark file (last-processed-email.dat) is written using a culture-invariant ISO 8601 round-trip format:
$timestampString = $newestTimestamp.ToString(\"o\")
[System.IO.File]::WriteAllText($timestampFile, $timestampString, [System.Text.Encoding]::UTF8)
But all three reads use [DateTime]::Parse(...) without a culture argument — and Parse is culture-sensitive in .NET:
# ServyFailureEmail.ps1:209
$lastProcessed = [DateTime]::Parse((Get-Content $timestampFile -ErrorAction Stop))
# ServyFailureEmail.ps1:286
$fileTimestamp = [DateTime]::Parse($currentFileContent)
# Get-ServyLastErrors.ps1:42
$LastProcessed = [DateTime]::Parse($LastProcessed)
ISO 8601 round-trip strings happen to parse correctly under most Latin-script locales, but the contract is brittle. On a host configured with a non-Gregorian system culture (e.g. fa-IR Persian, th-TH Thai Buddhist), Parse can throw or — worse — silently re-interpret the date, producing a wrong watermark. The wrong watermark leads to either alert flood (if it parses as something old) or alert silence (if it parses as something in the future).
Failures here also fall into a catch { } that resets state — alert correctness silently degrades.
Suggested fix:
Use the o-format-aware roundtrip parse, matching how the file is written:
$lastProcessed = [DateTime]::ParseExact(
(Get-Content $timestampFile -ErrorAction Stop),
'o',
[System.Globalization.CultureInfo]::InvariantCulture,
[System.Globalization.DateTimeStyles]::RoundtripKind
)
Or, if you want to stay tolerant of older formats while seeding new files invariant:
$lastProcessed = [DateTime]::Parse(
(Get-Content $timestampFile -ErrorAction Stop),
[System.Globalization.CultureInfo]::InvariantCulture,
[System.Globalization.DateTimeStyles]::RoundtripKind
)
Both forms are PS 2.0 / .NET 3.5 compatible.
Severity: Info
Files:
setup/taskschd/ServyFailureEmail.ps1, lines 209 and 286setup/taskschd/Get-ServyLastErrors.ps1, line 42The watermark file (
last-processed-email.dat) is written using a culture-invariant ISO 8601 round-trip format:But all three reads use
[DateTime]::Parse(...)without a culture argument — andParseis culture-sensitive in .NET:ISO 8601 round-trip strings happen to parse correctly under most Latin-script locales, but the contract is brittle. On a host configured with a non-Gregorian system culture (e.g.
fa-IRPersian,th-THThai Buddhist),Parsecan throw or — worse — silently re-interpret the date, producing a wrong watermark. The wrong watermark leads to either alert flood (if it parses as something old) or alert silence (if it parses as something in the future).Failures here also fall into a
catch { }that resets state — alert correctness silently degrades.Suggested fix:
Use the
o-format-aware roundtrip parse, matching how the file is written:Or, if you want to stay tolerant of older formats while seeding new files invariant:
Both forms are PS 2.0 / .NET 3.5 compatible.