PowerShell の起動が遅いというのはよくある悩みの種です。特に、ターミナルウィンドウを開くだけでも途方もない時間がかかるような環境ではなおさらです。原因は、プロファイルファイルが大量のカスタム関数やモジュールを読み込もうとしていることや、特定のモジュールの初期化が遅いことなど様々です。これらの原因によって、スクリプトの実行やログオンスクリプトがひどく遅くなることがあります。また、Windows は物事を過度に複雑にしがちなので、こうした速度低下は明確な原因もなく、様々なマシンで突然発生し、人々を困惑させています。朗報です。PowerShell の起動を高速化できる調整やチェック機能が数多くあります。ちょっとしたチェックのために起動する場合でも、スケジュールされたタスクでスクリプトを実行する場合でも、PowerShell の起動を高速化できます。
PowerShell の起動が遅い場合の修正方法
方法1:起動時間を測定して読み込みが遅い部分を特定する
これは、遅延の原因がプロファイル、モジュール、あるいはその他の何かなのかを明確に把握するのに役立ちます。基準値がなければ、何を調整すればよいかわかりません。Measure -Commandを使用すると、PowerShell の起動と簡単なコマンドの実行にかかる時間を確認できるため、異なる構成での起動速度を比較できます。
PowerShell ウィンドウでこれを実行します。
powershell -noprofile -ExecutionPolicy Bypass ( Measure-Command { powershell "Write-Host 1" } ).TotalSeconds
これは、PowerShellを起動してプロファイルを読み込まずに簡単なコマンドを実行するのにかかる時間を測定します。設定によっては、読み込み時間が10秒を超える場合があります。これは長すぎると言わざるを得ません。そのような場合は、起動プロファイルをプロファイリングすることで、遅いコマンドや、全体の処理を遅くする重いモジュールを特定できます。
方法2: プロファイルをスキップしてベースラインを確認する
プロファイルは時に厄介な存在となり、遅いコマンドが含まれていたり、大きなモジュールを読み込んだりすることがあります。PowerShellを-noprofileオプションで起動すると、これらのプロファイルは完全にスキップされ、通常は大幅に高速化されます。これは、プロファイルが速度低下の原因となっているかを確認したり、より高速な起動状態を準備したりするのに役立ちます。
走る:
powershell.exe -noprofile
または PowerShell Core の場合:
pwsh.exe -noProfile
これで速度が大幅に向上した場合は、プロファイルファイルのプロファイリングが次のステップです。どのプロファイルファイルがロードされるように設定されているかを確認してください。
$profile | select *
次に、これらのファイルを手動で確認し、重いコマンドや不要なモジュールの読み込みがないか確認してください。ユーザープロファイルスクリプトが数十個のモジュールを読み込もうとしたり、時間のかかるコマンドを実行しようとしたりすることが時々あり、これはシステムにとって好ましくありません。これらのスクリプトを削除または最適化することで、起動時間を大幅に短縮できます。
方法3: モジュールを制限してPowerShell環境を最適化する
PowerShell の自動モジュール読み込み機能は、多くのモジュールが残っていると動作を遅くすることがあります。インストールされ読み込まれているモジュールを確認するには、次のコマンドを実行してください。
$Env:PSModulePath -split ';'
これはモジュールが保存されているパスを示しています。利用可能なモジュールと実際にロードされているものを確認するには、以下を試してください。
Get-Module -ListAvailable
次に、サードパーティのモジュールを含む、インストールされているすべてのモジュールを確認します。
Get-InstalledModule
使用しないモジュールがある場合はアンインストールします。
Remove-Module -Name ModuleName; Uninstall-Module -Name ModuleName -AllVersions -Force
プロのヒント: 各モジュールを明示的にインポートして時間を計測することで、読み込みにかかる時間を確認することもできます。
Measure-Command { Import-Module ModuleName -Force }
さらに良いことに、インストールされているすべてのモジュールをすばやく分析するには、次の操作を実行します。
$modules = Get-InstalledModule | Select-Object -ExpandProperty Name -Unique foreach ($mod in $modules) { $time = Measure-Command { Import-Module $mod -Force } [PSCustomObject]@{ Module = $mod LoadTimeSec = $time. TotalSeconds } }
1~2秒以上かかるモジュールは、起動時に無効にすることをお勧めします。モジュールの自動読み込みを防ぐには、プロファイルに次の行を追加してください。
$PSModuleAutoLoadingPreference = 'None'
必要に応じて、次のコマンドでモジュールを手動でロードできます。
Import-Module ModuleName
これにより、特にセッションごとに必要ではない大量のモジュールを扱っている場合に、起動がスリムになります。
方法 4: 既知の遅いモジュールに対処する (VMware PowerCLI など)
一部のモジュール、特にVMware PowerCLIは、マシンが外部証明書を検証できない場合(オフラインの場合やファイアウォールがCRLチェックをブロックしている場合など)、数分間ハングすることがあります。WindowsでCRLチェックを無効にすると、以下の問題が解決する場合があります。
reg add HKLM\SYSTEM\CurrentControlSet\Services\SstpSvc\Parameters /v NoCertRevocationCheck /t REG_DWORD /d 0x00000001 /f
または、Internet Explorerの「オプション」の「詳細設定」で証明書失効チェックをオフにしてください。Windowsは当然のことながら、必要以上に複雑な設定をしています。
方法5: ウイルス対策ソフトの干渉をチェックする
これはちょっと厄介な問題です。ウイルス対策アプリ、特にエンタープライズグレードや一部のセキュリティスイートは、起動時にDLLをスキャンしたりプロセスを集中的に監視したりする傾向があり、PowerShellの起動速度が低下します。これをテストするには、PowerShellの起動時に読み込まれるモジュールをキャプチャすることで簡単に確認できます。
- cmd.exeを開いて実行します:
powershell.exe -c "Write-Host $PID;Start-Sleep -s 60" - 表示されている ^PID^ をコピーし、新しい PowerShell ウィンドウで実行します。
Get-Process | where {$_. Id -eq <YOUR_PID>} | select -ExpandProperty modules - ウイルス対策またはセキュリティ DLL を探します。存在する場合は、ウイルス対策設定で PowerShell 実行可能ファイルをホワイトリストに登録してみてください。
Windows Defender の場合、次の方法で除外を追加できます。
Add-MpPreference -ExclusionProcess "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", "C:\Program Files\PowerShell\7\pwsh.exe"
そうすれば、ウイルス対策ソフトが起動時間に影響することがなくなるはずです。
方法 6:.NET Framework と PowerShell のネイティブ イメージ生成 (NGen) に取り組む
.NETライブラリの呼び出し速度が遅いことが原因の場合は、アセンブリに対してngen.exe(ネイティブイメージジェネレーター)を実行できます。これにより、アセンブリがネイティブコードにプリコンパイルされ、読み込み時間が短縮されます。少し手間がかかりますが、どうしても必要な場合は試してみる価値があります。
$env:PATH = [Runtime. InteropServices. RuntimeEnvironment]::GetRuntimeDirectory() [AppDomain]::CurrentDomain. GetAssemblies() | ForEach-Object { $path = $_. Location if ($path) { $name = Split-Path $path -Leaf Write-Host "Running ngen on '$name'" -ForegroundColor Yellow & ngen install $path /nologo } }
注:管理者権限で実行し、事前にバックアップを作成してください。万能ではありませんが、一部のシステムでは起動時間が大幅に短縮されます。
そして、他に何も効果がない場合は…
ここでSysinternalsのProcess Monitorが役立ちます。powershell.exeにフィルターを設定して、起動を遅くしている原因を確認できます。DLLやレジストリ呼び出しがハングしているかもしれませんし、ネットワークチェックが遅いことに気づいているかもしれません。PowerShellの履歴ファイル(環境によっては容量が非常に大きくなることがあります)をクリーンアップすると改善する場合もあります。AppDataConsoleHost_history.txtフォルダ内のファイルを削除してください。
全体的に見て、必ずしも一つの原因とは限りません。プロファイル、モジュール、あるいはウイルス対策ソフトが原因の場合もあります。しかし、これらのチェックと最適化を実行することで、通常はかなりの効果が得られます。Windowsは当然のことながら、必要以上に複雑にする必要があるからです。
まとめ
- 起動時間を測定して
Measure-Commandボトルネックを見つけます。 - プロファイルをスキップしてベースライン パフォーマンスを確認します。
- ロードされたモジュールを確認して削減します。
- PowerCLI などのモジュールの読み込みが遅い場合は、CRL チェックを無効にします。
- ウイルス対策ソフトウェアで PowerShell をホワイトリストに登録すると、遅延を回避できます。
- 必要に応じて、ngen.exe を使用して. NET アセンブリをプリコンパイルすることを検討してください。
- 詳細な起動分析を行うには、プロセス モニターを使用します。
まとめ
これらのヒントが少しでもスピードアップに役立つことを願っています。PowerShell の速度低下の原因を突き止めるのは少し面倒ですが、コツをつかめば大抵は解決できます。多くの場合、プロファイルやモジュールが原因となっています。ただし、設定によってはこれらすべてが混在している場合もあることを覚えておいてください。幸運を祈ります。そして、この記事が誰かの起動時間の短縮に役立つことを祈っています!