How to Fix Slow Startup Times for PowerShell Console and Scripts

I have observed that the PowerShell console can be slow to open across various computers, sometimes taking several minutes. This slow start impacts not only the command shell (powershell.exe or pwsh.exe) but also the execution of logon PowerShell scripts via Group Policy Objects (GPO) or scheduled tasks. In this piece, we will explore possible causes for the sluggish startup and methods to reduce loading time.

Common Causes for Slow PowerShell Startup

  1. User-defined Functions: Functions defined in PowerShell profile files are reloaded every time the PowerShell process starts.
  2. Excessive PS Modules: A large number of installed modules that load automatically can delay startup.
  3. PSReadLine History: The PSReadLine module may attempt to load an overly large history file.
  4. .NET Framework Issues: Conflicts or corruption in .NET Framework components can introduce significant delays.

Measuring PowerShell Load Time

The Measure-Command cmdlet provides insight into how long it takes for PowerShell to load. Execute the following command to check load time:

powershell -noprofile -ExecutionPolicy Bypass ( Measure-Command { powershell "Write-Host 1" } ).TotalSeconds

If the load time exceeds 500 ms, PowerShell will log:

Loading personal and system profiles took XXX ms

For example, a startup time of 12 seconds signals slow executing code in profile files, indicating a possible problem.

Checking Profile Files

To compare startup speeds, you can run PowerShell without loading profiles using the options -noprofile for PowerShell or -noProfile for PowerShell Core.

To list all profile files used during the startup, run the command:

$profile | select *

You can also check the contents of the profile files using:

Get-Content $PROFILE.AllUsersAllHostsGet-Content $PROFILE.AllUsersCurrentHostGet-Content $PROFILE.CurrentUserAllHostsGet-Content $PROFILE.CurrentUserCurrentHost

Review these files for unnecessary commands or functions and optimize where possible.

Managing PS Modules

Examine the installed modules, as a large collection could impede startup speed. List available modules with:

Get-Module -ListAvailable

To remove unused modules, employ:

Remove-Module -Name ModuleNameUninstall-Module -Name ModuleName -AllVersions -Force

Analyze the loading time of each module using:

Measure-Command { Import-Module ModuleName -Force }

Consider preventing automatic loading of all PS modules by adding:

$PSModuleAutoLoadingPreference = 'None'

Addressing Other Possible Issues

  1. VMware PowerCLI Delays: If you are using the VMware Infrastructure Management module, it might delay loading due to CRL checks. You can disable CRL checking through the registry or in the Internet Properties applet.

  2. Antivirus Software: Sometimes, antivirus software may delay the startup. To check which DLLs are loaded during startup, run:

powershell.exe -c "Write-Host $PID;Start-Sleep -s 60"

Then, in a new PowerShell session, use:

Get-Process | where {$_.Id -eq <YOUR_PID>} | select -ExpandProperty modules

If your antivirus library is present, add exclusions for the PowerShell processes.

  1. Accelerate .NET Framework Operations: Improve .NET Framework performance by compiling assemblies into native machine code using ngen.exe. Use the following command:
$env:PATH = [Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory()[AppDomain]::CurrentDomain.GetAssemblies() | ForEach-Object {    $path = $_.Location    if ($path) {        $name = Split-Path $path -Leaf        Write-Host -ForegroundColor Yellow "`r`nRunning ngen.exe on '$name'"        ngen.exe install $path /nologo    }}
  1. Process Monitor: Finally, consider using Process Monitor to identify any operations causing significant delays when starting PowerShell.

By employing these strategies, you can address the common issues related to slow PowerShell startup and enhance its performance.


Posted

in

by

Tags: