Error when running a powershell 7 script on a Windows host

I have a problem when trying to use powershell 7.x on a Windows host from Ansible. I can reproduce it at work (AAP 4.5.32) as well in my homelab (AWX 24.6.1)

In my lab I run Execution Environment quay.io / ansible / awx-ee:24.6.1, [latest] produces the same errors
pwsh 7.4 and 7.6 behave the same.

The error is “Failed to compile C# code:\r\nerror CS0041: Unexpected error writing debug information – ‘The version of Windows PDB writer is older than required: ‘diasymreader.dll’’”. Full log dumps below.

I searched the freshly new installed testmachines (Windows 2025) for diasymreader.dll and it’s only present in .\Microsoft.NET\Framework* folders for version 2.x and 4.x
The testmachines have only powershell 7 and vscode installed

I have this playbook:

---
- name: Test pwsh script execution
  hosts: all
  gather_facts: false

  tasks:
    - name: Run a Powershell script
      ansible.windows.win_powershell:
        script: |
          Write-Output "This is a Powershell script running on the target host."
          Write-Output "$($PSVersionTable.PSVersion.tostring())"
        executable: pwsh.exe
...

Below output from running the playbook on two hosts connecting through WinRM with pwsh 7.4 and 7.6. Despite the error the script is executed. Running with a PSRP connection gives the same result

ansible-playbook [core 2.15.12]
  config file = None
  configured module search path = ['/runner/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.9/site-packages/ansible
  ansible collection location = /runner/requirements_collections:/runner/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.9.19 (main, Jun 11 2024, 00:00:00) [GCC 11.4.1 20231218 (Red Hat 11.4.1-3)] (/usr/bin/python3)
  jinja version = 3.1.4
  libyaml = True
No config file found; using defaults
SSH password: 
setting up inventory plugins
Loading collection ansible.builtin from 
host_list declined parsing /runner/inventory/hosts as it did not pass its verify_file() method
Parsed /runner/inventory/hosts inventory source with script plugin
Loading collection ansible.windows from /usr/share/ansible/collections/ansible_collections/ansible/windows
Loading callback plugin default of type stdout, v2.0 from /usr/local/lib/python3.9/site-packages/ansible/plugins/callback/default.py
Loading callback plugin awx_display of type stdout, v2.0 from /usr/local/lib/python3.9/site-packages/ansible_runner/display_callback/callback/awx_display.py
Skipping callback 'awx_display', as we already have a stdout callback.
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: PwshTest.playbook.yml ************************************************
Positional arguments: playbooks/PwshTest.playbook.yml
verbosity: 4
remote_user: ansible@NUCLABS.NL
connection: smart
timeout: 10
ask_pass: True
become_method: sudo
tags: ('all',)
inventory: ('/runner/inventory/hosts',)
extra_vars: ('@/runner/env/extravars',)
forks: 5
1 plays in playbooks/PwshTest.playbook.yml

PLAY [Test pwsh script execution] **********************************************

TASK [Run a Powershell script] *************************************************
task path: /runner/project/playbooks/PwshTest.playbook.yml:8
Using module file /usr/share/ansible/collections/ansible_collections/ansible/windows/plugins/modules/win_powershell.ps1
Pipelining is enabled.
Using module file /usr/share/ansible/collections/ansible_collections/ansible/windows/plugins/modules/win_powershell.ps1
Pipelining is enabled.
<server1.nuclabs.nl> ESTABLISH WINRM CONNECTION FOR USER: ansible@NUCLABS.NL on PORT 5985 TO server1.nuclabs.nl
calling kinit with pexpect for principal ansible@NUCLABS.NL
<server2.nuclabs.nl> ESTABLISH WINRM CONNECTION FOR USER: ansible@NUCLABS.NL on PORT 5985 TO server2.nuclabs.nl
calling kinit with pexpect for principal ansible@NUCLABS.NL
EXEC (via pipeline wrapper)
EXEC (via pipeline wrapper)
changed: [server1.nuclabs.nl] => {
    "changed": true,
    "debug": [],
    "error": [
        {
            "category_info": {
                "activity": "",
                "category": "OperationStopped",
                "category_id": 14,
                "reason": "InvalidOperationException",
                "target_name": "",
                "target_type": ""
            },
            "error_details": null,
            "exception": {
                "help_link": null,
                "hresult": -2146233079,
                "inner_exception": null,
                "message": "Failed to compile C# code:\\r\\nerror CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: 'diasymreader.dll''",
                "source": null,
                "type": "System.InvalidOperationException"
            },
            "fully_qualified_error_id": "Failed to compile C# code:\\r\\nerror CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: 'diasymreader.dll''",
            "output": "Failed to compile C# code:\\r\\nerror CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: \\r\\n'diasymreader.dll''\\r\\nAt line:259 char:17\\r\\n+ ...             throw [InvalidOperationException]\\"Failed to compile C# co ...\\r\\n+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\r\\n    + CategoryInfo          : OperationStopped: (:) [], InvalidOperationException\\r\\n    + FullyQualifiedErrorId : Failed to compile C# code:\\r\\nerror CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: \\r\\n'diasymreader.dll''\\r\\n \\r\\n",
            "pipeline_iteration_info": [],
            "script_stack_trace": "at <ScriptBlock>, <No file>: line 259\\r\\nat <ScriptBlock>, <No file>: line 30",
            "target_object": null
        }
    ],
    "host_err": "",
    "host_out": "",
    "information": [],
    "invocation": {
        "module_args": {
            "arguments": null,
            "chdir": null,
            "creates": null,
            "depth": 2,
            "error_action": "continue",
            "executable": "pwsh.exe",
            "parameters": null,
            "removes": null,
            "script": "Write-Output \\"This is a Powershell script running on the target host.\\"\\nWrite-Output \\"The survey message is: $env:target_environment\\"\\nWrite-Output \\"$($PSVersionTable.PSVersion.tostring())\\"\\n",
            "sensitive_parameters": null
        }
    },
    "output": [
        "This is a Powershell script running on the target host.",
        "The survey message is: ",
        "7.4.7"
    ],
    "result": {},
    "verbose": [],
    "warning": []
}
changed: [server2.nuclabs.nl] => {
    "changed": true,
    "debug": [],
    "error": [
        {
            "category_info": {
                "activity": "",
                "category": "OperationStopped",
                "category_id": 14,
                "reason": "InvalidOperationException",
                "target_name": "",
                "target_type": ""
            },
            "error_details": null,
            "exception": {
                "help_link": null,
                "hresult": -2146233079,
                "inner_exception": null,
                "message": "Failed to compile C# code:\\r\\nerror CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: 'diasymreader.dll''",
                "source": null,
                "type": "System.InvalidOperationException"
            },
            "fully_qualified_error_id": "Failed to compile C# code:\\r\\nerror CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: 'diasymreader.dll''",
            "output": "Failed to compile C# code:\\r\\nerror CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: \\r\\n'diasymreader.dll''\\r\\nAt line:259 char:17\\r\\n+ ...             throw [InvalidOperationException]\\"Failed to compile C# co ...\\r\\n+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\r\\n    + CategoryInfo          : OperationStopped: (:) [], InvalidOperationException\\r\\n    + FullyQualifiedErrorId : Failed to compile C# code:\\r\\nerror CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: \\r\\n'diasymreader.dll''\\r\\n \\r\\n",
            "pipeline_iteration_info": [],
            "script_stack_trace": "at <ScriptBlock>, <No file>: line 259\\r\\nat <ScriptBlock>, <No file>: line 30",
            "target_object": null
        }
    ],
    "host_err": "",
    "host_out": "",
    "information": [],
    "invocation": {
        "module_args": {
            "arguments": null,
            "chdir": null,
            "creates": null,
            "depth": 2,
            "error_action": "continue",
            "executable": "pwsh.exe",
            "parameters": null,
            "removes": null,
            "script": "Write-Output \\"This is a Powershell script running on the target host.\\"\\nWrite-Output \\"The survey message is: $env:target_environment\\"\\nWrite-Output \\"$($PSVersionTable.PSVersion.tostring())\\"\\n",
            "sensitive_parameters": null
        }
    },
    "output": [
        "This is a Powershell script running on the target host.",
        "The survey message is: ",
        "7.6.1"
    ],
    "result": {},
    "verbose": [],
    "warning": []
}

PLAY RECAP *********************************************************************
server1.nuclabs.nl         : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
server2.nuclabs.nl         : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Below the output of the playbook running without the executable = pwsh.exe setting, but the extra_var ansible_psrp_configuration_name
The error is the same, but the script is not executed and the play is failed

{
  "ansible_connection": "psrp",
  "ansible_psrp_auth": "kerberos",
  "ansible_psrp_protocol": "http",
  "ansible_psrp_configuration_name": "powershell.7" 
}
ansible-playbook [core 2.15.12]
  config file = None
  configured module search path = ['/runner/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.9/site-packages/ansible
  ansible collection location = /runner/requirements_collections:/runner/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.9.19 (main, Jun 11 2024, 00:00:00) [GCC 11.4.1 20231218 (Red Hat 11.4.1-3)] (/usr/bin/python3)
  jinja version = 3.1.4
  libyaml = True
No config file found; using defaults
SSH password: 
setting up inventory plugins
Loading collection ansible.builtin from 
host_list declined parsing /runner/inventory/hosts as it did not pass its verify_file() method
Parsed /runner/inventory/hosts inventory source with script plugin
Loading collection ansible.windows from /usr/share/ansible/collections/ansible_collections/ansible/windows
Loading callback plugin default of type stdout, v2.0 from /usr/local/lib/python3.9/site-packages/ansible/plugins/callback/default.py
Loading callback plugin awx_display of type stdout, v2.0 from /usr/local/lib/python3.9/site-packages/ansible_runner/display_callback/callback/awx_display.py
Skipping callback 'awx_display', as we already have a stdout callback.
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: PwshTest.playbook.yml ************************************************
Positional arguments: playbooks/PwshTest.playbook.yml
verbosity: 4
remote_user: ansible@NUCLABS.NL
connection: smart
timeout: 10
ask_pass: True
become_method: sudo
tags: ('all',)
inventory: ('/runner/inventory/hosts',)
extra_vars: ('@/runner/env/extravars',)
forks: 5
1 plays in playbooks/PwshTest.playbook.yml

PLAY [Test pwsh script execution] **********************************************

TASK [Run a Powershell script] *************************************************
task path: /runner/project/playbooks/PwshTest.playbook.yml:8
Using module file /usr/share/ansible/collections/ansible_collections/ansible/windows/plugins/modules/win_powershell.ps1
Pipelining is enabled.
<server1.nuclabs.nl> ESTABLISH PSRP CONNECTION FOR USER: ansible@NUCLABS.NL ON PORT 5985 TO server1.nuclabs.nl
Using module file /usr/share/ansible/collections/ansible_collections/ansible/windows/plugins/modules/win_powershell.ps1
Pipelining is enabled.
<server2.nuclabs.nl> ESTABLISH PSRP CONNECTION FOR USER: ansible@NUCLABS.NL ON PORT 5985 TO server2.nuclabs.nl
PSRP: EXEC (via pipeline wrapper)
PSRP: EXEC (via pipeline wrapper)
The full traceback is:
Failed to compile C# code:\r
error CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: 'diasymreader.dll''
At line:262 char:17\r
+ …             throw [InvalidOperationException]"Failed to compile C# co …\r
+               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], InvalidOperationException
    + FullyQualifiedErrorId : Failed to compile C# code:\r
error CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: 'diasymreader.dll''\r
\r
ScriptStackTrace:\r
at Add-CSharpType, <No file>: line 262\r
at <ScriptBlock>, <No file>: line 19\r
at <ScriptBlock><End>, <No file>: line 143\r
at <ScriptBlock>, <No file>: line 11\r
fatal: [server2.nuclabs.nl]: FAILED! => {
    "changed": false,
    "msg": "internal error: failed to run exec_wrapper action module_powershell_wrapper: Failed to compile C# code:\\r\\nerror CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: 'diasymreader.dll''"
}
The full traceback is:
Failed to compile C# code:\r
error CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: 'diasymreader.dll''
At line:262 char:17\r
+ …             throw [InvalidOperationException]"Failed to compile C# co …\r
+               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], InvalidOperationException
    + FullyQualifiedErrorId : Failed to compile C# code:\r
error CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: 'diasymreader.dll''\r
\r
ScriptStackTrace:\r
at Add-CSharpType, <No file>: line 262\r
at <ScriptBlock>, <No file>: line 19\r
at <ScriptBlock><End>, <No file>: line 143\r
at <ScriptBlock>, <No file>: line 11\r
fatal: [server1.nuclabs.nl]: FAILED! => {
    "changed": false,
    "msg": "internal error: failed to run exec_wrapper action module_powershell_wrapper: Failed to compile C# code:\\r\\nerror CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: 'diasymreader.dll''"
}

PLAY RECAP *********************************************************************
server1.nuclabs.nl         : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
server2.nuclabs.nl         : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

Unfortunately I’m not sure why this particular error occurs but it sounds like maybe an env var may be causing the .NET compiler here to load an older diasymreader.dll causing this failure or that there is a slightly older .NET Framework version installed but I’m just guessing here.

Ultimately what is happening is the setup code for win_powershell calls Add-CSharpUtil to load some common code.

This is the at <ScriptBlock>, <No file>: line 30 in the script_stack_trace (it’s line 30 in the string).

Since Ansible 2.21 we’ve stopped trying to get the PDB stream based on generic PowerShell 7.x support so this might just start working if you were to try out that version but it’s not officially out yet.

Using ansible_psrp_configuration_name to set the PowerShell 7 configuration endpoint wasn’t officially supported but the error happens here before the module even starts which is why it’s a critical failure. The fact that this fails here even though it is not nested inside a powershell.exe process tells me it’s a host configuration that’s causing this underlying failure.

When testing this scenario on my own Windows 2025 target I run this win_powershell task to see what diasymreader.dll is being loaded in Ansible

- ansible.windows.win_powershell:
    script: |
      (Get-Process -Id $pid).Modules |
        Where-Object ModuleName -eq diasymreader.dll
    executable: pwsh.exe

The output on my test host is

- BaseAddress: "140725565718528"
  Company: Microsoft Corporation
  Container: null
  Description: Dia based SymReader
  EntryPointAddress: "140725565896256"
  FileName: C:\Windows\Microsoft.NET\FrameworkArm64\v4.0.30319\diasymreader.dll
  FileVersion: "14.8.9032.0 built by: NET481REL1"
  FileVersionInfo: |-
    File:             C:\Windows\Microsoft.NET\FrameworkArm64\v4.0.30319\diasymreader.dll
    InternalName:     diasymreader.dll
    OriginalFilename: diasymreader.dll
    FileVersion:      14.8.9032.0 built by: NET481REL1
    FileDescription:  Dia based SymReader
    Product:          Microsoft® .NET Framework
    ProductVersion:   14.8.9032.0
    Debug:            False
    Patched:          False
    PreRelease:       False
    PrivateBuild:     False
    SpecialBuild:     False
    Language:         English (United States)
  ModuleMemorySize: 1388544
  ModuleName: diasymreader.dll
  Product: Microsoft® .NET Framework
  ProductVersion: 14.8.9032.0
  Site: null
  Size: 1356

This shows I’m loading the diasymreader.dll from the .NET Framework location. It’ll be interesting to see if you are also loading it from the C:\Windows\Microsoft.NET\Framework*\v4*\diasymreader.dll path and what the version is. Do you have an env var that starts with MICROSOFT_DIASYMREADER_?

Yes, for some reason the Framework 2.0 version is loaded

{
            "BaseAddress": "140728236834816",
            "Company": "Microsoft Corporation",
            "Container": null,
            "Description": "Dia based SymReader",
            "EntryPointAddress": "140728236983680",
            "FileName": "C:\\\\Windows\\\\Microsoft.NET\\\\Framework64\\\\v2.0.50727\\\\diasymreader.dll",
            "FileVersion": "8.0.50727.9157 (WinRelRS6.050727-9100)",
            "FileVersionInfo": "File:             C:\\\\Windows\\\\Microsoft.NET\\\\Framework64\\\\v2.0.50727\\\\diasymreader.dll\\r\\nInternalName:     diasymreader.dll\\r\\nOriginalFilename: diasymreader.dll\\r\\nFileVersion:      8.0.50727.9157 (WinRelRS6.050727-9100)\\r\\nFileDescription:  Dia based SymReader\\r\\nProduct:          Microsoft® Visual Studio® 2005\\r\\nProductVersion:   8.0.50727.9157\\r\\nDebug:            False\\r\\nPatched:          False\\r\\nPreRelease:       True\\r\\nPrivateBuild:     True\\r\\nSpecialBuild:     False\\r\\nLanguage:         English (United States)\\r\\n",
            "ModuleMemorySize": 811008,
            "ModuleName": "diasymreader.dll",
            "Product": "Microsoft® Visual Studio® 2005",
            "ProductVersion": "8.0.50727.9157",
            "Site": null,
            "Size": 792
        }

There is no MICROSOFT_DIASYMREADER_* env var.

Good to know that specifying a powershell 7 config with ansible_psrp_configuration_name is not supported (yet)

Did some more testing now we know the problematic DLL comes from .NET Framework v2:

Machines with only v4 installed work fine
After removing v3, and thus v2 as well, it works fine.

So how bad is this behavior? Is it an error we can ignore, or could it lead to more problems?

Unfortunately we can’t remove older .NET Framework versions from all our machines.

That is certainly surprising but explains why the error is saying the writer is older than required. Do you see the same diasymreader.dll in C:\Windows\Microsoft.NET\Framework64\v4.*\diasymreader.dll?

The upcoming 2.21 release of Ansible will add official support for targeting PowerShell 7 interpreters both through ansible_pwsh_interpreter (and PSRP can set ansible_psrp_configuration_name to make it a bit more efficient at the same time). I still need to complete the docs for this though.

In this case you can mostly ignore it, it does mean that anything sent to stdout or stderr like [Console]::WriteLine("foo") in the PowerShell script specified won’t be captured but any other output is going to be fine. You can safely ignore this in 99% of the cases here.

If you see the diasymreader.dll in the v4* folder can you see if this also returns the v2 variant in a brand new pwsh process?

# This should not return anything
(Get-Process -Id $pid).Modules |
        Where-Object ModuleName -eq diasymreader.dll |
        Format-List *

# This is what the underlying library is loading
$c = New-Object -ComObject CorSymWriter_SxS

# The dll should now be loaded
(Get-Process -Id $pid).Modules |
        Where-Object ModuleName -eq diasymreader.dll |
        Format-List *

Are you able to test the above in pwsh directly on the server outside of Ansible and potentially through a win_command that replicates pwsh running through WinRM.

Output in a new pwsh session:

PowerShell 7.4.7

   A new PowerShell stable release is available: v7.6.1
   Upgrade now, or check out the release page at:
     https://aka.ms/PowerShell-Release?tag=v7.6.1

PS C:\Users\user1> # This should not return anything
PS C:\Users\user1> (Get-Process -Id $pid).Modules |
>>         Where-Object ModuleName -eq diasymreader.dll |
>>         Format-List *
PS C:\Users\user1>
PS C:\Users\user1> # This is what the underlying library is loading
PS C:\Users\user1> $c = New-Object -ComObject CorSymWriter_SxS
PS C:\Users\user1>
PS C:\Users\user1> # The dll should now be loaded
PS C:\Users\user1> (Get-Process -Id $pid).Modules |
>>         Where-Object ModuleName -eq diasymreader.dll |
>>         Format-List *

Size              : 792
Company           : Microsoft Corporation
FileVersion       : 8.0.50727.9157 (WinRelRS6.050727-9100)
ProductVersion    : 8.0.50727.9157
Description       : Dia based SymReader
Product           : Microsoft® Visual Studio® 2005
ModuleName        : diasymreader.dll
FileName          : C:\Windows\Microsoft.NET\Framework64\v2.0.50727\diasymreader.dll
BaseAddress       : 140719394324480
ModuleMemorySize  : 811008
EntryPointAddress : 140719394473344
FileVersionInfo   : File:             C:\Windows\Microsoft.NET\Framework64\v2.0.50727\diasymreader.dll
                    InternalName:     diasymreader.dll
                    OriginalFilename: diasymreader.dll
                    FileVersion:      8.0.50727.9157 (WinRelRS6.050727-9100)
                    FileDescription:  Dia based SymReader
                    Product:          Microsoft® Visual Studio® 2005
                    ProductVersion:   8.0.50727.9157
                    Debug:            False
                    Patched:          False
                    PreRelease:       True
                    PrivateBuild:     True
                    SpecialBuild:     False
                    Language:         English (United States)

Site              :
Container         :

CorSymWriter_SxS has CLSID 0AE2DEB0-F901-478b-BB9F-881EE8066788 and if I explore its properties I get this. The version numbers are the .NET Framework versions present on this machine. Not clear to me how this is translated to a .NET disk path btw

PS C:\Users\user1> gci 'registry::HKEY_CLASSES_ROOT\CLSID\{0AE2DEB0-F901-478b-BB9F-881EE8066788}' -Recurse

    Hive: HKEY_CLASSES_ROOT\CLSID\{0AE2DEB0-F901-478b-BB9F-881EE8066788}

Name                           Property
----                           --------
InprocServer32                 (default)      : C:\Windows\System32\mscoree.dll
                               ThreadingModel : Both

    Hive: HKEY_CLASSES_ROOT\CLSID\{0AE2DEB0-F901-478b-BB9F-881EE8066788}\InprocServer32

Name                           Property
----                           --------
2.0.50727                      (default)                : 2.0.50727
                               ImplementedInThisVersion :
4.0.30319                      (default)                : 4.0.30319
                               ImplementedInThisVersion :

    Hive: HKEY_CLASSES_ROOT\CLSID\{0AE2DEB0-F901-478b-BB9F-881EE8066788}

Name                           Property
----                           --------
ProgID                         (default) : CorSymWriter_SxS
Server                         (default) : diasymreader.dll

Output when run from a playbook with win_command:

{
  "changed": true,
  "invocation": {
    "module_args": {
      "removes": null,
      "_raw_params": "pwsh.exe -file C:\\Temp\\DiaSymReadertest.ps1",
      "chdir": null,
      "creates": null,
      "output_encoding_override": null,
      "cmd": null,
      "argv": null,
      "stdin": null
    }
  },
  "cmd": "pwsh.exe -file C:\\Temp\\DiaSymReadertest.ps1",
  "rc": 0,
  "stdout": "\r\n\u001b[32;1mSize              : \u001b[0m792\r\n\u001b[32;1mCompany           : \u001b[0mMicrosoft Corporation\r\n\u001b[32;1mFileVersion       : \u001b[0m8.0.50727.9157 (WinRelRS6.050727-9100)\r\n\u001b[32;1mProductVersion    : \u001b[0m8.0.50727.9157\r\n\u001b[32;1mDescription       : \u001b[0mDia based SymReader\r\n\u001b[32;1mProduct           : \u001b[0mMicrosoft® Visual Studio® 2005\r\n\u001b[32;1mModuleName        : \u001b[0mdiasymreader.dll\r\n\u001b[32;1mFileName          : \u001b[0mC:\\Windows\\Microsoft.NET\\Framework64\\v2.0.50727\\diasymreader.dll\r\n\u001b[32;1mBaseAddress       : \u001b[0m140719394324480\r\n\u001b[32;1mModuleMemorySize  : \u001b[0m811008\r\n\u001b[32;1mEntryPointAddress : \u001b[0m140719394473344\r\n\u001b[32;1mFileVersionInfo   : \u001b[0mFile:             C:\\Windows\\Microsoft.NET\\Framework64\\v2.0.50727\\diasymreader.dll\r\n                    InternalName:     diasymreader.dll\r\n                    OriginalFilename: diasymreader.dll\r\n                    FileVersion:      8.0.50727.9157 (WinRelRS6.050727-9100)\r\n                    FileDescription:  Dia based SymReader\r\n                    Product:          Microsoft® Visual Studio® 2005\r\n                    ProductVersion:   8.0.50727.9157\r\n                    Debug:            False\r\n                    Patched:          False\r\n                    PreRelease:       True\r\n                    PrivateBuild:     True\r\n                    SpecialBuild:     False\r\n                    Language:         English (United States)\r\n                    \r\n\u001b[32;1mSite              : \u001b[0m\r\n\u001b[32;1mContainer         : \u001b[0m\r\n\r\n",
  "stderr": "",
  "start": "2026-05-06 13:19:08.322066",
  "end": "2026-05-06 13:19:08.938309",
  "delta": "0:00:00.616242",
  "stdout_lines": [
    "",
    "\u001b[32;1mSize              : \u001b[0m792",
    "\u001b[32;1mCompany           : \u001b[0mMicrosoft Corporation",
    "\u001b[32;1mFileVersion       : \u001b[0m8.0.50727.9157 (WinRelRS6.050727-9100)",
    "\u001b[32;1mProductVersion    : \u001b[0m8.0.50727.9157",
    "\u001b[32;1mDescription       : \u001b[0mDia based SymReader",
    "\u001b[32;1mProduct           : \u001b[0mMicrosoft® Visual Studio® 2005",
    "\u001b[32;1mModuleName        : \u001b[0mdiasymreader.dll",
    "\u001b[32;1mFileName          : \u001b[0mC:\\Windows\\Microsoft.NET\\Framework64\\v2.0.50727\\diasymreader.dll",
    "\u001b[32;1mBaseAddress       : \u001b[0m140719394324480",
    "\u001b[32;1mModuleMemorySize  : \u001b[0m811008",
    "\u001b[32;1mEntryPointAddress : \u001b[0m140719394473344",
    "\u001b[32;1mFileVersionInfo   : \u001b[0mFile:             C:\\Windows\\Microsoft.NET\\Framework64\\v2.0.50727\\diasymreader.dll",
    "                    InternalName:     diasymreader.dll",
    "                    OriginalFilename: diasymreader.dll",
    "                    FileVersion:      8.0.50727.9157 (WinRelRS6.050727-9100)",
    "                    FileDescription:  Dia based SymReader",
    "                    Product:          Microsoft® Visual Studio® 2005",
    "                    ProductVersion:   8.0.50727.9157",
    "                    Debug:            False",
    "                    Patched:          False",
    "                    PreRelease:       True",
    "                    PrivateBuild:     True",
    "                    SpecialBuild:     False",
    "                    Language:         English (United States)",
    "                    ",
    "\u001b[32;1mSite              : \u001b[0m",
    "\u001b[32;1mContainer         : \u001b[0m",
    ""
  ],
  "stderr_lines": [],
  "_ansible_no_log": false
}

Thanks for that last bit of information. This is a weird one but from my understanding this is what is happening:

  • The C# compiler in PowerShell 7 is creating the COM object CorSymWriter_SxS
  • The COM registration for this will open the DLL mscoree.dll
  • This dll is basically loading the .NET Framework CLR and uses the subkeys version under InprocServer32 to determine the CLRs the COM server supports
  • Normally it would choose the CLR version already loaded but for PowerShell 7.x there is no Framework CLR
  • It seems like unless the main executable manifest (pwsh.exe's) specifies an explicit version or loading policy it’ll default to the v2 one when present for compatibility reasons (how ironic)
  • pwsh.exe doesn’t specify the loading policy so it chooses the 2.0 version which is incompatible with this PDB writer

Luckily there are a few things you can do here:

  1. Ignore the error as it only affects capturing stdout/stderr written in the scripts
  2. Upgrade to Ansible 2.21 when it is released as it doesn’t use this codepath anymore
  3. Uninstall the .NET 2.0/3.5 features so only v4.0.x is present and will be selected
  4. Set the env var COMPLUS_Version: v4.0 on the Ansible task to force it to choose the v4.0 components
  5. Create pwsh.exe.config (next to pwsh.exe) on the Windows host with the following
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" />
  </startup>
</configuration>

Hope this helps!

This sure helped. Suggestions 4 and 5 work like a charm. Thanks Jordan!

One last, slightly off-topic, question. Triggered by your remark not all forms of output will be logged when the wrong version of .net is addressed (and fails) I added a Write-Host statement to my test playbook and the log tells me that Write-Host is not found. Not that I am worried: thou shall not use write-host in non-interactive scripts. But just out of curiosity: is write-host removed by ansible here?

"exception": {
        "inner_exception": null,
        "message": "The term 'Write-Host:' is not recognized as a name of a cmdlet, function, script file, or executable program.\r\nCheck the spelling of the name, or if a path was included, verify that the path is correct and try again.",
        "source": "System.Management.Automation",
        "help_link": null,
        "type": "System.Management.Automation.CommandNotFoundException",
        "hresult": -2146233087
      }

That I cannot explain sorry, we aren’t restricting anything here and even doing a test locally seems to work fine with the Write-Host appearing under the host_out and as an information record as expected.

Looking at your error it is saying Write-Host: and not Write-Host. Did you have a stray colon when you tested it?

It was :face_with_bags_under_eyes: Easy to not see when combining yml and powershell including a class method call within 3 lines…
Thanks again!

tasks:
    - name: Run a Powershell script
      ansible.windows.win_powershell:
        script: |
          Write-Host: "Output from Write-Host"
          [Console]::WriteLine("Output from [Console]::WriteLine")
          Write-Output "This is a Powershell script running on the target host."