Skip to content

Windows Defender has started to slowdown method calls in PowerShell dramatically #19431

@User1785604260

Description

@User1785604260

Prerequisites

Steps to reproduce

Run the following test.ps1 file with the latest Windows Defender signature version (e.g. 1.385.1608.0 at time of filing).

for ($i = 0; $i -lt 40000; $i++) {
    $path = "C:\"
    $fileName = [System.IO.Path]::GetFileName($path)
    $fileExtension = [System.IO.Path]::GetExtension($path)
    
    $parent = $path.TrimEnd("\")
    $parent = [System.IO.Path]::GetDirectoryName($parent)
}

This script will take ~40ms with realtime protection turned off, vs ~8000ms with realtime protection turned on. The test script executes quickly with realtime protection turned on in PowerShell 5, however.

(Note: to address some pushback I received on reddit, yes, this is nonsense code doing nonsense work. The whole point is to demonstrate that just calling methods at all is taking a huge penalty all of the sudden.)

Furthermore, if I use my own infrastructure for timing code and execute the following:

Invoke-Timed { [void]"".IndexOf("") } -Count 10000

I see 60 microseconds for each call with realtime protection turned on, vs 1 microsecond with realtime protection turned off. That same [void]"".IndexOf("") body can be placed into the for loop of the test.ps1 file to see the slowdown without my timing infrastructure.

It appears that the latest Windows Defender is significantly impacting method calls in PowerShell 7.

For a full repro, to make sure this isn't just something wrong with my install:

  • Perform a fresh windows install of Windows 11 Pro 22H2 from Win11_22H2_English_x64v1.iso, with windows11.0-kb5023778-x64_204c2f5ab1eb71d80eb470b5af079dd8e56c20e7.msu already slipstreamed in
  • Install windows using a local account (so none of my MS account settings are being brought in)
  • Execute Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force -Verbose
  • Grab the latest winget: ms-windows-store://pdp/?productId=9NBLGGH4NNS1
  • Install powershell 7.3.3: winget install -e Microsoft.PowerShell -a x64 --accept-package-agreements --accept-source-agreements
  • Observe that Windows Defender signature version is 1.321.69.0
  • Run the test.ps1 file in PowerShell 5 and 7
  • $stopwatch = [System.Diagnostics.Stopwatch]::StartNew(); powershell.exe -NoProfile -File "test.ps1"; Write-Host "Elapsed: $($stopwatch.ElapsedMilliseconds.ToString("N0"))ms"
  • $stopwatch = [System.Diagnostics.Stopwatch]::StartNew(); pwsh.exe -NoProfile -File "test.ps1"; Write-Host "Elapsed: $($stopwatch.ElapsedMilliseconds.ToString("N0"))ms"
  • Open Windows Defender and check for protection updates
  • Observe that the signature version updates to e.g. 1.385.1608.0
  • Wait for threat protection service to restart
  • Re-execute the test.ps1 file in PowerShell 5 and 7
  • Observe that the script remains fast in PowerShell 5, but dramatically slows down in 7
  • Turn real-time protection off
  • Observe that the fast script execution time is restored in 7

The issue appears to have started somewhere around signature version 1.385.1310.0, around March 27, 2023.

(Edit: reddit links removed. I couldn't get anyone to try my repro test.ps1 code out, so they were of limited value. I'm still not sure if this issue is affecting anyone but me. It's been confirmed below that I'm not the only one seeing this.)

While I understand this is probably an issue external to PowerShell 7, I thought the team should be aware and there's no Windows Defender GitHub repo for me to file an issue against.

Expected behavior

Method calls like [void]"".IndexOf("") are fast, on the order of 1 microsecond, with Windows Defender realtime protection turned on.

Actual behavior

Method calls like [void]"".IndexOf("") are slow, on the order of 60 microseconds, with Windows Defender realtime protection turned on.

Error details

No response

Environment data

Name                           Value
----                           -----
PSVersion                      7.3.3
PSEdition                      Core
GitCommitId                    7.3.3
OS                             Microsoft Windows 10.0.22621
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

No response

(Note: Latest signature version where I'm still seeing this: 1.389.2214.0)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-BugIssue has been identified as a bug in the productResolution-ExternalThe issue is caused by external component(s).WG-Engine-Performancecore PowerShell engine, interpreter, and runtime performance

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions