修正:PowerShellコンソールとスクリプトのスロースタートアップ

PowerShellコンソールが開くのに長い時間がかかることがあることに気付きました。この問題は、異なるコンピューターで発生します。場合によっては、PowerShellがロードに数分かかる場合があります。これは、コマンドシェル自体(PowerShell.exeまたはPwsh.exe)の開設と、GPOまたはスケジュールされたタスクでスクリプトを介して起動されたログオンPowerShellスクリプトの実行時間に影響します。この投稿では、PowerShellのスタートアップが遅くなり、読み込み時間を短縮する潜在的な理由を特定する方法について説明します。
PowerShellがロードに長い時間がかかる可能性がある一般的な理由は次のとおりです。
- PowerShellプロセスのプロセスが開始されるたびに、PowerShellプロファイルファイルのユーザー定義の機能がロードされます
*かなりの数のPSモジュールがインストールされ、自動的にロードされます
-
Psreadlineモジュールは、PowerShellコマンドの履歴を含む巨大なファイルをロードします
-
PowerShellおよびモジュールの負荷の大幅な減速は、紛争または腐敗によるcorruption.NETフレームワークコンポーネントによって引き起こされます。
測定コマンドCMDLETを使用して、PowerShellプロセスの負荷時間を測定できます。このコマンドを使用して、通常モードでPowerShellの負荷時間を確認します。
Powershell-noprofile-executionpolicyバイパス(測定コマンド{powershell" write-host 1 "}).totalseconds

コマンドは、PowerShellプロセスが単純なコマンドをロードおよび実行するのにかかった時間を表示します。
PowerShellが開始すると、ロードにかかった時間を報告する場合があります。
Loading personal and system profiles took XXX ms

この例でわかるように、PowerShellプロセスはロードに12秒かかりました。それはかなりたくさんです。このメッセージは、PowerShellプロファイルの負荷時間が500ミリ秒を超える場合、自動的に表示されます。
これは、PowerShellプロファイルファイルがプロセスが開始されるたびに遅いコードを実行していることを示唆しています。
プロファイルがロードされていないときに、PowerShellプロセスのスタートアップ速度を比較します。これを行うには、シェルプロセスをNoprofileオプションで実行します。
powershell.exe-noprofile
またはPowerShellコアを実行するには:
pwsh.exe-noprofile

ご覧のとおり、PowerShellはプロファイルがロードされていない場合にはるかに速くスタートしました。 PowerShellプロファイルは、ユーザー環境の構成に使用されるPS1ファイルです。また、ユーザーが特定のコマンドを実行し、カスタム関数またはモジュールをロードすることもできます。
デフォルトでは、PowerShellプロファイルファイルは使用されません(プロファイルファイルは作成されていません)。次のコマンドには、PowerShellプロセスが開始されたときにロードされるすべてのプロファイルファイルのリストが表示されます。
$プロファイル| [ *

ユーザーのすべてのプロファイルファイルの内容を手動で確認するか、次のコマンドを使用して表示します。
`get-content $ profile.allusersallhosts
get-content $ profile.alluserscurrenthost
get-content $ profile.currentuserallhosts
get-content $ profile.currentusercurrenthost `
私の場合、いくつかのコマンドがmicrosoft.powershell_profile.ps1ユーザーファイルに追加されます。プロファイルファイルを確認して、すべてのコマンドと機能が必要であることを確認してください。可能であれば、不必要なコマンドを削除し、コードを最適化します。 
インストールされた多数のモジュールは、PowerShellのスタートアップが遅い別の理由になる可能性があります。 PowerShellは、次のフォルダーからモジュールを自動的にロードします。
C:\Users\%username%\Documents\WindowsPowerShell\ModulesC:\Program Files\WindowsPowerShell\ModulesC:\Windows\system32\WindowsPowerShell\v1.0\Modules
それらのリストは次のように表示できます。
$ env:psmodulepath-split ';'

セッションにロードされたPSモジュールをリストします。
get-module-listavable
インストールされているサードパーティモジュールをリストします。
get-instaledModule

リストを確認して、すべてのモジュールが必要かどうかを確認してください。未使用のPowerShellモジュールをアンインストールします。
`remody-module-name burnttoast
Uninstall-Module-Name Burnttoast-Allversions-Force `
各モジュールの読み込み時間を分析するには、次のコマンドを使用します。
Measure-Command {Import-Module modulename-force}
または、すべてのPSモジュールの負荷時間をバルクで確認します。
`$ modules = get-installedModule | Select-Object-ExpandProperty name-unique
foreach($ mod in $ module){
$ time = measure-command {import-module $ mod-force}
pscustomobject@{
モジュール= $ mod
LoadTimesec = $ time.totalseconds
}
} `

どのモジュールがロードに最も長いかを確認してください。
すべてのPSモジュールが自動的にロードされないようにするには、次の行をプロファイルファイルに追加します。
$ psmoduleautoloadingpreference = 'none'
この場合、次のコマンドを使用して、必要なモジュールを手動でロードできます。
Import-Module moduleName
次の共通モジュールをプロファイルファイルに追加してください。
`Import-Module Microsoft.PowerShell.Utility
Import-Module Microsoft.Powershell.Management `
また、VMware PowerCliとしても知られるVMwareインフラストラクチャ管理PowerShellモジュールをロードする場合、既知の問題もあります。モジュールは、インターネットに接続されていないコンピューターに数分かかる場合があります。問題は、ロードするときに、モジュールが取り消された証明書の外部リスト(CRL、証明書の取り消しリスト)を確認しようとすることです。インターネット接続が不足しているため、このプロセスはタイムアウトしました。解決策は、WindowsでCRLチェックを無効にすることです。レジストリを介してCRLチェックを無効にすることができます。
reg add hklm \ system \ currentControlset \ services \ sstpsvc \ parameters/v nocertrevocationcheck/t reg\_dword/d 0x00000001/f
またはインターネットプロパティでアプレット: inetcpl.cpl
-
advanced
-
untick publisher(server)証明書の取り消しのオプションチェック。

PowerShellが開始に時間がかかる理由は、多くの場合、コンピューターにインストールされているウイルス対策ソフトウェアです。 PowerShellプロセスが開始されたときに、どの外部DLLとモジュールがロードされるかを確認できます。
1。 cmd.exeを開き、コマンドを実行します: powershell.exe-c" write-host $ pid; start-sleep-s 60 "
2.このコマンドは、実行中のPowerShell.exeプロセスのプロセスID(PID)を返します。コピーします
pid
新しいPowerShellセッションで次のコマンドに貼り付けます。
get-process |ここで{$ \_。id-eq } | Select-ExpandPropertyモジュール
- PowerShellプロセスが開始されたときにロードされたDLLのリストを受け取ります。アンチウイルスライブラリがリストされているかどうかを確認してください。その場合は、Pwsh.exeとPowershell.exeをウイルス対策の例外に追加してみてください。

たとえば、以下のコマンドを使用して、組み込みのWindows Defender Antivirusに除外を追加できます。
add-mppreference-exclusionProcess" c:\ windows \ system32 \ windowspowershell \ v1.0 \ powershell.exe "、" c:\ program files \ powershell \ 7 \ pwsh.exe "
PowerShellのスロースタートアップがSlow.NETフレームワークライブラリ操作によって引き起こされると思われる場合は、 ngen.exeツール(ネイティブ画像ジェネレーター)を使用して、すべての使用されたアセンブリをネイティブマシンコードにコンパイルできます。これにより、PowerShellを含む.NETアプリケーションのパフォーマンスが大幅に向上します。
`$ env:path = runtime.interopservices.runtimeenvironment :: getruntimedirectory()
appdomain :: currentDomain.getAssemblies()| foreach-object {
$ path = $ _。場所
if($ path){
$ name = split-path $ path-leaf
write-host-foregroundcolor yellow “ rnrunning ngen.exe on ‘$ name’ “ngen.exe $ path/nologoをインストールします
}
} `

クラシックプロセスモニターツールを使用して、PowerShellの起動時間を分析することもできます。 (
https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx)。 procmon64.exeを実行し、powershell.exeプロセスでフィルターを有効にし、PSシェルを開き、最大の遅延を引き起こした操作を特定します。

私の例では、Psreadlineモジュールによって維持されているPowerShellコマンド履歴ファイルを読むには、約30秒かかりました。 ( c:\ users \ username \ appdata \ roaming \ microsoft \ windows \ powershell \ psreadline \ csolehost\_history.txt)。この問題は、ConsoleHost_history.txtファイルが2 GBを超えるサイズを超えることによって引き起こされました。履歴ファイルのクリーニングは、PowerShellのスタートアップ時間を大幅に短縮しました。
*÷ソースリンク:
GPOを介して起動されたログオンPowerShellスクリプト、スケジュールされたタスクのスクリプト、PowerShellコマンドの歴史、PowerShell Core、組み込みのWindows Defender Antivirus、 https://technet.microsoft.com/en-us/sysinternals/processmonor.aspxxxxxxxxxxxx、
