|
| 1 | +--- |
| 2 | +description: How to identify and troubleshoot PowerShell startup issues, including performance problems and crashes. |
| 3 | +ms.date: 12/01/2025 |
| 4 | +title: Troubleshoot PowerShell startup issues |
| 5 | +--- |
| 6 | +# Troubleshoot PowerShell startup issues |
| 7 | + |
| 8 | +Sometimes, PowerShell can have problems before it's even ready to use. Startup issues can be |
| 9 | +difficult to troubleshoot, especially when you want to use PowerShell to help. There are three main |
| 10 | +phases of startup: |
| 11 | + |
| 12 | +1. Process creation |
| 13 | +1. PowerShell SessionState initialization |
| 14 | +1. Profile processing |
| 15 | + |
| 16 | +The most common problems include: |
| 17 | + |
| 18 | +- Long startup time or slow performance |
| 19 | +- Errors |
| 20 | +- Crashes |
| 21 | + |
| 22 | +## The steps of the startup sequence |
| 23 | + |
| 24 | +It's helpful to understand the steps PowerShell goes through during startup. This way, you can |
| 25 | +narrow down where the issue is happening. |
| 26 | + |
| 27 | +### Step 1: Process creation |
| 28 | + |
| 29 | +The process creation has a few steps: |
| 30 | + |
| 31 | +1. Create a Host window |
| 32 | + |
| 33 | + On Windows, the Host can be Windows Terminal, the Windows Console Host, Visual Studio Code, or |
| 34 | + any other hosting application. Problems that occur here are usually unrelated to PowerShell, but |
| 35 | + also extremely rare. |
| 36 | + |
| 37 | +1. Start the process host process |
| 38 | + |
| 39 | + Problems that occur here are usually caused by a corrupted executable or an issue in the |
| 40 | + operating system. |
| 41 | + |
| 42 | +1. Prepare .NET |
| 43 | + |
| 44 | + PowerShell is .NET-based and that needs to fully load. Depending on which PowerShell version you |
| 45 | + are trying to start, you either get the full, Windows-integrated .NET Framework with Windows |
| 46 | + PowerShell 5.1 or the newer .NET included in PowerShell 7. |
| 47 | + |
| 48 | + During first-time startup of PowerShell, PowerShell and .NET run optimization tasks. This |
| 49 | + optimization task is only run once, during the first startup after installation, upgrade, or if |
| 50 | + the cache is empty. Startup will take longer during this first-time optimization. Failure during |
| 51 | + optimization can create a corrupted cache. A corrupted PowerShell cache can cause issues with |
| 52 | + command discovery and module loading. |
| 53 | + |
| 54 | +### Step 2: PowerShell SessionState initialization |
| 55 | + |
| 56 | +Loading the PowerShell binaries and initializing the engine involves processing the PowerShell |
| 57 | +configuration and some cached data. |
| 58 | + |
| 59 | +1. Process configuration files: `powershell.config.json` and PSSession configuration files used by |
| 60 | + JEA and other remoting scenarios. These files may contain settings that can affect the language |
| 61 | + mode, available commands and modules, and some policy settings. |
| 62 | +1. Check Group Policies and Windows Security policies. Windows Group Policies can override settings |
| 63 | + in the `powershell.config.json`. Security Policies can enable features like WDAC (Windows |
| 64 | + Defender Application Control), which can also constrain the language mode available. |
| 65 | +1. Load the default modules (Microsoft.PowerShell.Core and PSReadLine) and any modules and |
| 66 | + assemblies defined in the PSSession configuration. |
| 67 | + |
| 68 | +For more information about PowerShell security features, see the following articles: |
| 69 | + |
| 70 | +- [PowerShell security features][01] |
| 71 | +- [about_Language_Modes][03] |
| 72 | + |
| 73 | +### Step 3: Profile processing |
| 74 | + |
| 75 | +Finally, PowerShell runs the available profile files. Profile scripts are run in the |
| 76 | +following order: |
| 77 | + |
| 78 | +1. All Hosts All Users |
| 79 | +1. Current Host All Users |
| 80 | +1. All Hosts Current User |
| 81 | +1. Current Host Current User |
| 82 | + |
| 83 | +> [!NOTE] |
| 84 | +> Profile scripts aren't run for remote sessions. |
| 85 | +
|
| 86 | +For more information about profiles, see [about_Profiles][04]. |
| 87 | + |
| 88 | +## Narrow the scope of the issue |
| 89 | + |
| 90 | +It's helpful to remove variables and narrow down the specific scope of where the issue happens. The |
| 91 | +easiest variable to eliminate is the profile. The profile often contains custom code, especially in |
| 92 | +the user-specific profile scripts. |
| 93 | + |
| 94 | +Try running PowerShell with the profile disabled: |
| 95 | + |
| 96 | +```powershell |
| 97 | +# PS 5.1: |
| 98 | +powershell -NoProfile |
| 99 | +
|
| 100 | +# PS 7.*: |
| 101 | +pwsh -NoProfile |
| 102 | +``` |
| 103 | + |
| 104 | +Next you should see if the problem is version-specific. Try running your profile in both Windows |
| 105 | +PowerShell 5.1 and PowerShell 7. Windows PowerShell and PowerShell 7 store the profile in different |
| 106 | +locations. Your profile may not be the same for both versions. Compare the files to understand the |
| 107 | +differences. You can try installing your PowerShell profile in Windows PowerShell 5.1. However, be |
| 108 | +aware that some PowerShell 7 commands and modules aren't compatible with Windows PowerShell 5.1. |
| 109 | + |
| 110 | +You can test your PowerShell 7 profile in Windows PowerShell 5.1 without overwriting your existing |
| 111 | +profile. |
| 112 | + |
| 113 | +1. Start Windows PowerShell 5.1 with the profile disabled. |
| 114 | +1. Manually dot-source your PowerShell 7 profile file into the Windows PowerShell 5.1 session. |
| 115 | + |
| 116 | + ```powershell |
| 117 | + . $env:USERPROFILE\Documents\PowerShell\Microsoft.PowerShell_profile.ps1 |
| 118 | + ``` |
| 119 | + |
| 120 | +1. Observe whether the issue occurs. |
| 121 | + |
| 122 | +If the issue persists, then you know problem is an environmental issue outside of the profile. |
| 123 | + |
| 124 | +Try running the profile on a different device. If the profile works correctly on another device, |
| 125 | +then you know the issue is specific to your original device. |
| 126 | + |
| 127 | +## Troubleshoot common environmental problems |
| 128 | + |
| 129 | +### Crashes during startup |
| 130 | + |
| 131 | +If the PowerShell console crashes during startup, especially early and with no feedback, you could |
| 132 | +have a corrupted process cache. This is a rare condition that you can resolve by clearing the |
| 133 | +cache. There are two cache locations that can be cleared: |
| 134 | + |
| 135 | +- User Cache: `$env:LOCALAPPDATA\Microsoft\Windows\Caches` |
| 136 | +- System Cache: `$env:windir\System32\Config\SystemProfile\AppData\Local\Microsoft\Windows\Caches` |
| 137 | + |
| 138 | +Delete the contents of the user cache folder first, then try starting PowerShell again. If the |
| 139 | +problem persists, delete the contents of the system cache and try again. |
| 140 | + |
| 141 | +You may also need to delete the PowerShell analysis cache. You can find the cache files in the |
| 142 | +following locations: |
| 143 | + |
| 144 | +- Windows PowerShell: |
| 145 | + `$env:windir\System32\Config\SystemProfile\AppData\Local\Microsoft\Windows\PowerShell` |
| 146 | +- PowerShell 7: `$env:LOCALAPPDATA\Microsoft\PowerShell` |
| 147 | + |
| 148 | +Delete only the following file patterns: |
| 149 | + |
| 150 | +- `ModuleAnalysisCache-*` |
| 151 | +- `StartupProfileData-*` |
| 152 | + |
| 153 | +The cached data is recreated the next time you start PowerShell. |
| 154 | + |
| 155 | +If the problem persists in Windows PowerShell 5.1, you may need to repair the .NET Framework |
| 156 | +installation. For more information, see [Repair the .NET Framework][02]. |
| 157 | + |
| 158 | +## Troubleshoot common profile problems |
| 159 | + |
| 160 | +This section describes some common problems that can occur during PowerShell startup, and how to |
| 161 | +troubleshoot them. |
| 162 | + |
| 163 | +### Profile takes too long to run |
| 164 | + |
| 165 | +First you must define what's _"too long."_ PowerShell is only doing what the scripts tell it to do. |
| 166 | +Check all profile paths. There may be multiple profile scripts being run. Review the code to |
| 167 | +understand it's trying to do. |
| 168 | + |
| 169 | +- Determine where the delay occurs |
| 170 | + |
| 171 | + If there are profile scripts for the **AllUsers** scope, you might not be able to edit those |
| 172 | + files. Work with your system administrator to review those files. For the **CurrentUser** scope |
| 173 | + profile scripts, edit those files to add timing messages to help you find where the delay occurs. |
| 174 | + For example, you can add the following line at various points in your profile script. |
| 175 | + |
| 176 | + ```powershell |
| 177 | + Write-Host "$(Get-Date -Format 'HH:mm:ss.fff') | Profile: Step X" |
| 178 | + ``` |
| 179 | + |
| 180 | +- Reduce dependencies |
| 181 | + |
| 182 | + Reduce the number of modules that need to be loaded to execute your profile. Run `Get-Module` |
| 183 | + after profile runs to see the modules that were loaded during startup. By default, PowerShell |
| 184 | + loads the Microsoft.PowerShell.Core and PSReadLine modules. Any additional modules were loaded |
| 185 | + by your profile scripts. |
| 186 | + |
| 187 | + Modules can be loaded explicitly by using `Import-Module` or implicitly by using commands defined |
| 188 | + in those modules. Consider whether you need a command or a module loaded during startup. |
| 189 | + |
| 190 | +- Avoid installing modules in a redirected folder |
| 191 | + |
| 192 | + In many situations on Windows, your `Documents` folder can be redirected to a network file share |
| 193 | + or to OneDrive. Network file access can be slow, especially if the network is congested or the |
| 194 | + server is under heavy load. Depending on how OneDrive is configured, it can also introduce delays |
| 195 | + or cause errors during profile exectution. |
| 196 | + |
| 197 | + You have a few options to mitigate this problem: |
| 198 | + |
| 199 | + - Don't redirect your `Documents` folder, but that might not be desired |
| 200 | + - Configure your `Modules` folder in OneDrive to _always_ be kept on disk. This prevents errors |
| 201 | + and delayed load times. |
| 202 | + - Install modules in the **AllUsers** scope, which is outside of the user profile folder. |
| 203 | + |
| 204 | +- Measure the actual performance |
| 205 | + |
| 206 | + If you don't know how long your profile takes to run, you can't determine whether it's too long. |
| 207 | + The `Measure-Command` cmdlet can show how long a command or script block takes to run. |
| 208 | + |
| 209 | + Steve Lee, the PowerShell Dev Manager, has a blog post that describes how to measure the |
| 210 | + performance of your profile. It includes instructions for establishing a baseline for performance, |
| 211 | + how to get detailed timing information, and ways to optimize your profile. |
| 212 | + |
| 213 | + See [Optimizing your $Profile][05]. |
| 214 | + |
| 215 | +### PowerShell 7 starts slowing in an isolated network |
| 216 | + |
| 217 | +In this scenario, your Windows computer is on a network that is not connected to the internet. For |
| 218 | +interactive PowerShell sessions, PowerShell loads the PSReadLine module automatically. PSReadLine is |
| 219 | +a signed module. PowerShell must verify the digital signature of the module. This verification can |
| 220 | +cause delays in a disconnected environment. To test this theory, start PowerShell 7 in |
| 221 | +_non-interactive_ mode: |
| 222 | + |
| 223 | +```powershell |
| 224 | +pwsh.exe -noninteractive |
| 225 | +``` |
| 226 | + |
| 227 | +If PowerShell starts quickly in non-interactive mode, then the problem is likely caused by |
| 228 | +Certificate Revocation List (CRL) checks. As part of the process of verifying a digital signature, |
| 229 | +The .NET runtime checks the CRL to ensure that the signing certificate is still valid. In a |
| 230 | +disconnected environment, you computer can't access the CRL on internet. The default timeout for CRL |
| 231 | +checks is 15 seconds. This means that every time PowerShell loads a signed module, it can take up to |
| 232 | +15 seconds to timeout. |
| 233 | + |
| 234 | +There are three possible workarounds for this problem: |
| 235 | + |
| 236 | +- Firewall or proxy exemption |
| 237 | + |
| 238 | + Allowing direct internet access for CRL checking prevents the problem. In an environment where you |
| 239 | + can control access to the internet access, you can configure your firewall or proxy to allow |
| 240 | + access to the CRL Urls. This is the easiest solution with the least impact. The firewall logs |
| 241 | + should show the Url that PowerShell attempted to reach. |
| 242 | + |
| 243 | +- Reduce CRL Timeout |
| 244 | + |
| 245 | + Reducing the CRL lookup timeout is possible, but doing so risks other lookups to fail, that can't |
| 246 | + complete in the time specified. For details about how to change the timeout, see [Manage Network |
| 247 | + Retrieval and Path Validation][04]. |
| 248 | + |
| 249 | +- Remove CRL checking |
| 250 | + |
| 251 | + The CRL checking settings are managed by Group Policy. For more information, see [Manage Trusted |
| 252 | + Publishers][03]. |
| 253 | + |
| 254 | + > [!WARNING] |
| 255 | + > It's possible to disable the CRL check however, it's not recommended. Disabling CRL checking |
| 256 | + > prevents you from actually revoking compromised certificates. |
| 257 | +
|
| 258 | +### ERROR: Cannot dot-source this command because it was defined in a different language mode |
| 259 | + |
| 260 | +PowerShell works with application control systems, such as AppLocker and Windows Defender |
| 261 | +Application Control (WDAC), by automatically running in **ConstrainedLanguage** mode. |
| 262 | +ConstrainedLanguage mode restricts some features that are potentially dangerous. However, there are |
| 263 | +times when you need **FullLanguage** mode to use certain commands or features. Scripts can run in |
| 264 | +**FullLanguage** mode when they're trusted by the policy. Trust can be indicated through file |
| 265 | +signing or other policy mechanisms configured in AppLocker or WDAC. |
| 266 | + |
| 267 | +When you start a PowerShell session that's managed under application control, you get the following |
| 268 | +error: |
| 269 | + |
| 270 | +``` |
| 271 | +Cannot dot-source this command because it was defined in a different language mode. To invoke this |
| 272 | +command without importing its contents, omit the '.' operator. |
| 273 | +``` |
| 274 | + |
| 275 | +Under application control, PowerShell is running in **ConstrainedLanguage** mode. This error occurs |
| 276 | +when and your profile script is _exempted_ or is _signed_ to run in **FullLanguage** mode. When |
| 277 | +PowerShell is running in **ConstrainedLanguage** mode, it can't dot-source code trusted to run in |
| 278 | +**FullLanguage** mode. |
| 279 | + |
| 280 | +To resolve the problem, you must remove the exemption or signature from the profile script. If you |
| 281 | +need code that must run in **FullLanguage** mode during your profile, move it into another script |
| 282 | +file that's exempted or signed. Call (don't dot-source) that script file from within your profile. |
| 283 | + |
| 284 | +For more information on this issue, see |
| 285 | +[PowerShell Constrained Language mode and the Dot-Source Operator][06]. |
| 286 | + |
| 287 | +## Further reading |
| 288 | + |
| 289 | +- [about_Language_Modes][03] |
| 290 | +- [Measure-Command][07] |
| 291 | + |
| 292 | +<!-- link references --> |
| 293 | +[01]: ../../security/security-features.md |
| 294 | +[02]: /dotnet/framework/install/repair |
| 295 | +[03]: /powershell/module/microsoft.powershell.core/about/about_language_modes |
| 296 | +[04]: /powershell/module/microsoft.powershell.core/about/about_profiles |
| 297 | +[05]: https://devblogs.microsoft.com/powershell/optimizing-your-profile/ |
| 298 | +[06]: https://devblogs.microsoft.com/powershell/powershell-constrained-language-mode-and-the-dot-source-operator/ |
| 299 | +[07]: xref:Microsoft.PowerShell.Utility.Measure-Command |
0 commit comments