Checkmk 2.5: win_exefiles parsing fails with German locale (mk_inventory.ps1)

Parsing of section win_exefiles fails on Checkmk 2.5.0p13 due to localized date separator in mk_inventory.ps1

CMK version:
Checkmk 2.5.0p13

OS version:
Checkmk server: Linux
Monitored hosts: Windows Server, German locale (de-DE)

Error message

After upgrading from Checkmk 2.4 to 2.5, the HW/SW inventory fails on most of our Windows hosts with:

Parsing of section win_exefiles failed

Running:

cmk --debug -vvn hostname

shows the following exception during HW/SW inventory processing:

ValueError: time data '12.31.2025 23:00:00' does not match format '%d.%m.%Y %H:%M:%S'

The traceback points to:

lib/python3/cmk/plugins/windows/agent_based/inventory_win_exefiles.py

and specifically to:

install_date = int(
    time.mktime(
        time.strptime(write_time, "%d.%m.%Y %H:%M:%S")
    )
)

The Windows agent and Checkmk server are both running version 2.5.0p13.

The debug output also shows that the persisted inventory section is being used:

Using persisted section 'win_exefiles'

Investigation

The affected Windows host is configured entirely for the German locale:

PS> Get-Culture | Format-List Name,DisplayName

Name        : de-DE
DisplayName : Deutsch (Deutschland)

PS> Get-WinSystemLocale

LCID Name  DisplayName
---- ----- -----------
1031 de-DE Deutsch (Deutschland)

PS> [System.Globalization.CultureInfo]::CurrentCulture.Name
de-DE

PS> [System.Globalization.CultureInfo]::CurrentCulture.DateTimeFormat.ShortDatePattern
dd.MM.yyyy

PS> Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Language' |
>> Select-Object Default, InstallLanguage

Default InstallLanguage
------- ---------------
0407    0407

Initially I suspected a Windows locale mismatch, but the issue appears to be reproducible directly with the new PowerShell-based mk_inventory.ps1.

The installed mk_inventory.ps1 formats LastWriteTime using:

Get-Date $_.LastWriteTime -Format 'M/d/yyyy HH:mm:ss'

On a German Windows installation this does not produce a literal /.

For example:

PS> Get-Date ([datetime]'2025-12-31 23:00:00') -Format 'M/d/yyyy HH:mm:ss'
12.31.2025 23:00:00

PS> (Get-Culture).DateTimeFormat.DateSeparator
.

The / in the .NET custom date/time format appears to be interpreted as the culture-specific date separator.

The same behavior can be reproduced with actual executable files:

C:\Windows\bfsvc.exe|7.15.2026 03:33:52|143360
C:\Windows\explorer.exe|9.9.2026 02:14:24|3191416
C:\Windows\notepad.exe|1.14.2026 19:34:56|360448

These values are clearly formatted as:

M.d.yyyy

rather than:

d.M.yyyy

Server-side parser

The win_exefiles parser included with Checkmk 2.5.0p13 contains:

# Since 1.2.6p1 the agent always provides a date format of "04/18/2003 18:06:32".
# Old agent versions provided localized date formats which lead to problems here
# when none of the implemented parsers matches.

install_date: int | None = None

if re.match(r"^\d{2}\.\d{2}\.20\d{2} \d{2}:\d{2}:\d{2}", write_time):
    install_date = int(
        time.mktime(
            time.strptime(write_time, "%d.%m.%Y %H:%M:%S")
        )
    )
elif re.match(
    r"^\d{1,2}/\d{1,2}/20\d{2} \d{1,2}:\d{2}:\d{2} (AM|PM)",
    write_time,
):
    install_date = int(
        time.mktime(
            time.strptime(write_time, "%m/%d/%Y %H:%M:%S %p")
        )
    )
elif re.match(
    r"^\d{1,2}/\d{1,2}/20\d{2} \d{1,2}:\d{2}:\d{2}",
    write_time,
):
    install_date = int(
        time.mktime(
            time.strptime(write_time, "%m/%d/%Y %H:%M:%S")
        )
    )

This seems to create the problematic combination.

For example, mk_inventory.ps1 generates:

12.31.2025 23:00:00

because the intended / separator is replaced by the German culture’s . separator.

The first parser condition then matches:

^\d{2}\.\d{2}\.20\d{2}

and Checkmk attempts to parse the value as:

%d.%m.%Y

Therefore:

12.31.2025

is interpreted as:

day   = 12
month = 31
year  = 2025

which results in the ValueError.

This can be reproduced independently of Checkmk with PowerShell:

Get-Date ([datetime]'2025-12-31 23:00:00') -Format 'M/d/yyyy HH:mm:ss'

on a de-DE Windows system.

Possible relation to the Checkmk 2.5 PowerShell inventory migration

I found Werk #10995, which states that win_exefiles should use a fixed date/time format instead of a localized one.

I also found Werk #17685 regarding the migration of the Windows HW/SW inventory from mk_inventory.vbs to mk_inventory.ps1 in Checkmk 2.5.

Therefore I am wondering whether this could be a regression introduced by the PowerShell migration.

Werk #19207 also concerns mk_inventory.ps1, but as far as I understand it addresses a different issue involving timestamp handling/output and should already be fixed in 2.5.0p13.

Expected behavior

The inventory plugin should emit a culture-independent date format which matches the format expected by inventory_win_exefiles.py.

For example, using InvariantCulture in PowerShell appears to avoid the culture-dependent date separator:

$_.LastWriteTime.ToString(
    "MM/dd/yyyy HH:mm:ss",
    [System.Globalization.CultureInfo]::InvariantCulture
)

This produces:

12/31/2025 23:00:00

which corresponds to the format documented in the existing Python parser.

Questions

Is this a known issue with mk_inventory.ps1 in Checkmk 2.5?

Has this already been fixed in a later 2.5 patch release or is there an associated Werk?

If not, would changing the PowerShell inventory output to use an invariant date format be the correct approach, or is there another recommended workaround?

I have not changed the Windows locale or patched the Checkmk agent/server yet, as I wanted to verify the intended fix first.

I was able to reproduce the issue and found a potential workaround.

The problem seems to be caused by this line in mk_inventory.ps1:

Write-Output ("$($_.FullName)|$(Get-Date $_.LastWriteTime -Format 'M/d/yyyy HH:mm:ss')|$($_.Length)||$fileVersion|")

In PowerShell/.NET, / in a custom date format uses the culture-specific date separator. On a German (de-DE) system this results in output like:

12.31.2025 23:00:00

The Checkmk win_exefiles parser interprets dotted dates as %d.%m.%Y, causing the parsing exception.

I changed the line to use InvariantCulture:

Write-Output ("$($_.FullName)|$($_.LastWriteTime.ToString('MM/dd/yyyy HH:mm:ss', [System.Globalization.CultureInfo]::InvariantCulture))|$($_.Length)||$fileVersion|")

This now produces e.g.:

12/31/2025 23:00:00

After forcing mk_inventory.ps1 to regenerate its data, Checkmk successfully processes the section:

win_exefiles: ok

So this looks like a viable workaround and potentially the required fix in mk_inventory.ps1.

Tested successfully with Checkmk 2.5.0p14 server and agent on Windows with de-DE locale.