
ฉันสังเกตเห็นว่าบางครั้งคอนโซล PowerShell ใช้เวลานานในการเปิด ปัญหานี้เกิดขึ้นในคอมพิวเตอร์ที่แตกต่างกัน ในบางกรณีอาจใช้เวลาหลายนาทีเพื่อให้ PowerShell โหลด สิ่งนี้มีผลต่อการเปิดของเชลล์คำสั่งเอง (powershell.exe หรือ pwsh.exe) และเวลาดำเนินการของสคริปต์ Logon PowerShell ที่เปิดตัวผ่าน GPO หรือสคริปต์ในงานที่กำหนด โพสต์นี้อธิบายวิธีการระบุเหตุผลที่เป็นไปได้สำหรับการเริ่มต้น PowerShell ช้าและลดเวลาในการโหลด
นี่คือเหตุผลทั่วไปที่ PowerShell อาจใช้เวลานานในการโหลด:
-
ฟังก์ชั่นที่ผู้ใช้กำหนดไว้ในไฟล์โปรไฟล์ PowerShell จะถูกโหลดทุกครั้งที่กระบวนการ PowerShell.exe เริ่มต้นขึ้น
-
มีการติดตั้งโมดูล PS จำนวนมากและโหลดโดยอัตโนมัติ
-
โมดูล psreadline โหลดไฟล์ขนาดใหญ่ที่มีประวัติของคำสั่ง PowerShell
-
การชะลอตัวอย่างมีนัยสำคัญใน PowerShell และการโหลดโมดูลเกิดจากความขัดแย้งหรือการทุจริตในส่วนประกอบเฟรมเวิร์ก NET
CMDLET แบบวัดการวัดสามารถใช้ในการวัดเวลาโหลดของกระบวนการ PowerShell ใช้คำสั่งนี้เพื่อตรวจสอบเวลาโหลดของ PowerShell ในโหมดปกติ:
PowerShell-Noprofile-ExecutionPolicy Bypass (Measure-Command {PowerShell" Write-Host 1 "}). Totalseconds

คำสั่งจะแสดงระยะเวลาที่กระบวนการ PowerShell ใช้ในการโหลดและดำเนินการคำสั่งง่ายๆ
เมื่อ PowerShell เริ่มต้นมันอาจรายงานเวลาที่ใช้ในการโหลด
Loading personal and system profiles took XXX ms

อย่างที่คุณเห็นในตัวอย่างนี้กระบวนการ PowerShell ใช้เวลาโหลด 12 วินาที มันค่อนข้างมาก ข้อความนี้จะปรากฏขึ้นโดยอัตโนมัติหากเวลาโหลดของโปรไฟล์ PowerShell เกิน 500 ms
สิ่งนี้ชี้ให้เห็นว่าไฟล์โปรไฟล์ PowerShell กำลังดำเนินการรหัสช้าทุกครั้งที่กระบวนการเริ่มต้น
เปรียบเทียบความเร็วเริ่มต้นของกระบวนการ PowerShell เมื่อไม่ได้โหลดโปรไฟล์ ในการทำเช่นนี้ให้เรียกใช้กระบวนการเชลล์ด้วยตัวเลือกที่โนโปรเฟลี่:
powershell.exe-noprofile
หรือเพื่อเรียกใช้ PowerShell Core:
pwsh.exe-noprofile

อย่างที่คุณเห็น PowerShell เริ่มเร็วขึ้นมากเมื่อโปรไฟล์ไม่ได้โหลด โปรไฟล์ PowerShell เป็นไฟล์ PS1 ที่ใช้ในการกำหนดค่าสภาพแวดล้อมผู้ใช้ พวกเขายังอนุญาตให้ผู้ใช้เรียกใช้คำสั่งเฉพาะและโหลดฟังก์ชั่นหรือโมดูลที่กำหนดเอง
โดยค่าเริ่มต้นไฟล์โปรไฟล์ PowerShell จะไม่ถูกใช้ (ไม่มีการสร้างไฟล์โปรไฟล์) คำสั่งต่อไปนี้แสดงรายการไฟล์โปรไฟล์ทั้งหมดที่จะโหลดเมื่อกระบวนการ PowerShell เริ่มต้นขึ้น
$ profile | เลือก *

ตรวจสอบเนื้อหาของไฟล์โปรไฟล์ทั้งหมดสำหรับผู้ใช้ด้วยตนเองหรือใช้คำสั่งต่อไปนี้เพื่อแสดง:
`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-listavailable
แสดงรายการโมดูลบุคคลที่สามที่ติดตั้ง
get-installedModule

ตรวจสอบรายการเพื่อดูว่าคุณต้องการโมดูลทั้งหมดหรือไม่ ถอนการติดตั้งโมดูล PowerShell ที่ไม่ได้ใช้งาน:
`remove-mody-name burnttoast
ถอนการติดตั้ง-ชื่อชื่อการเผาไหม้-allversions-force `
ในการวิเคราะห์เวลาในการโหลดของแต่ละโมดูลให้ใช้คำสั่งต่อไปนี้:
`การวัด-คอมมิวนิส
หรือตรวจสอบเวลาโหลดของโมดูล PS ทั้งหมดเป็นกลุ่ม:
`$ modules = get-installedModule | เลือกชื่อ-exproperty ชื่อ unique
foreach ($ mod ใน $ modules) {
$ TIME = MEAMENT-COMMAND {Import Module $ mod-Force}
pscustomobject@{
โมดูล = $ mod
loadtimesec = $ time.totalseconds

ดูว่าโมดูลใดใช้เวลานานที่สุดในการโหลด
เพื่อป้องกันไม่ให้โมดูล PS ทั้งหมดโหลดโดยอัตโนมัติเพิ่มบรรทัดต่อไปนี้ในไฟล์โปรไฟล์:
`$ psmoduleautoLoadingPreference = ‘ไม่มี’
ในกรณีนี้คุณสามารถโหลดโมดูลที่ต้องการด้วยตนเองโดยใช้คำสั่งต่อไปนี้:
การนำเข้าโมดูล modulename
ตรวจสอบให้แน่ใจว่าได้เพิ่มโมดูลทั่วไปต่อไปนี้ในไฟล์โปรไฟล์ของคุณ:
`การนำเข้าโมดูล microsoft.powershell.utility
การนำเข้าโมดูล Microsoft.powershell.Management `
นอกจากนี้ยังมีปัญหาที่ทราบกันดีเมื่อโหลดโมดูลการจัดการโครงสร้างพื้นฐาน VMware PowerShell ซึ่งเป็นที่รู้จักกันในชื่อ VMware PowerCLI โมดูลอาจใช้เวลาหลายนาทีในการโหลดบนคอมพิวเตอร์ที่ไม่ได้เชื่อมต่อกับอินเทอร์เน็ต ปัญหาคือเมื่อโหลดโมดูลพยายามตรวจสอบรายการภายนอกของใบรับรองที่ถูกเพิกถอน (CRL, รายการการเพิกถอนใบรับรอง) เนื่องจากขาดการเชื่อมต่ออินเทอร์เน็ตกระบวนการนี้จึงหมดเวลา วิธีแก้ปัญหาคือการปิดใช้งานการตรวจสอบ CRL ใน Windows คุณสามารถปิดการตรวจสอบ CRL ผ่านรีจิสทรี:
reg เพิ่ม hklm \ system \ currentcontrolset \ services \ sstpsvc \ parameters/v nocerTrevocationCheck/t reg\_dword/d 0x00000001/f
หรือในแอปเพล็ตคุณสมบัติอินเทอร์เน็ต: inetcpl.cpl-> ขั้นสูง-> ยกเลิกการตรวจสอบตัวเลือกสำหรับการเพิกถอนใบรับรองผู้เผยแพร่ (เซิร์ฟเวอร์)

เหตุผลที่ PowerShell อาจใช้เวลานานในการเริ่มต้นมักจะเป็นซอฟต์แวร์ป้องกันไวรัสที่ติดตั้งบนคอมพิวเตอร์ คุณสามารถตรวจสอบ DLL และโมดูลภายนอกที่โหลดได้เมื่อกระบวนการ PowerShell เริ่มต้นขึ้น
-
เปิด
cmd.exeและเรียกใช้คำสั่ง:powershell.exe-c" การเขียน $ pid; start-leep-s 60 "` -
คำสั่งนี้ส่งคืนรหัสกระบวนการ (PID) ของกระบวนการ PowerShell.exe คัดลอก
PID
และวางลงในคำสั่งต่อไปนี้ในเซสชั่น PowerShell ใหม่:
`get-process | โดยที่ {$ _. id-eq } | เลือกโมดูล ExpandProperty ``
- คุณจะได้รับรายการ DLL ที่โหลดเมื่อกระบวนการ PowerShell เริ่มต้นขึ้น ตรวจสอบว่าห้องสมุดป้องกันไวรัสของคุณอยู่ในรายการหรือไม่ ถ้าเป็นเช่นนั้นให้ลองเพิ่ม pwsh.exe และ powerShell.exe กระบวนการลงในข้อยกเว้น Antivirus ของคุณ

ตัวอย่างเช่นคุณสามารถใช้คำสั่งด้านล่างเพื่อเพิ่มการยกเว้นใน Windows Defender Antivirus ในตัว:
add-mppreference-exclusionProcess" c: \ windows \ system32 \ windowspowershell \ v1.0 \ powershell.exe "," c: \ program files \ powershell \ 7 \ pwsh.exe "
หากคุณสงสัยว่าการเริ่มต้นที่ช้าของ PowerShell นั้นเกิดจากการทำงานของไลบรารี Slow.net Framework คุณสามารถรวบรวมแอสเซมบลีที่ใช้ทั้งหมดลงในรหัสเครื่องจักรดั้งเดิมโดยใช้เครื่องมือ ngen.exe (เครื่องกำเนิดภาพดั้งเดิม) สิ่งนี้จะปรับปรุงประสิทธิภาพของแอปพลิเคชัน NET อย่างมีนัยสำคัญรวมถึง PowerShell:
`$ env: path = runtime.interopservices.runtimeenvironment :: getRuntimedirectory ()
appdomain :: currentdomain.getAssemblies () | Foreach-Object {
$ path = $ _. ตำแหน่ง
ถ้า ($ path) {
$ name = split-path $ path-leaf
WRITE-HOST-FORUNGERCOLOR YELLOUL

เครื่องมือตรวจสอบกระบวนการคลาสสิกยังสามารถใช้ในการวิเคราะห์เวลาเริ่มต้น PowerShell (
https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx) เรียกใช้ procmon64.exe เปิดใช้งานตัวกรองในกระบวนการ powershell.exe เปิดเปลือก PS และระบุการดำเนินการที่ทำให้เกิดความล่าช้ามากที่สุด

ในตัวอย่างของฉันการอ่านไฟล์ประวัติคำสั่ง PowerShell ที่ดูแลโดยโมดูล PSReadline ใช้เวลาประมาณ 30 วินาที (c: \ users \ username \ AppData \ Roaming \ Microsoft \ Windows \ PowerShell \ psReadline \ consolehost\_history.txt) ปัญหาเกิดจากไฟล์ consolehost_history.txt เกินขนาด 2 GB การทำความสะอาดไฟล์ประวัติลดเวลาเริ่มต้นของ PowerShell อย่างมีนัยสำคัญ
*ลิงค์แหล่งที่มา:
สคริปต์ Logon PowerShell เปิดตัวผ่าน GPO, สคริปต์ในงานที่กำหนดเวลาประวัติของคำสั่ง PowerShell, PowerShell Core, Antivirus ผู้พิทักษ์ Windows ผู้พิทักษ์ Windows ในตัว ] ( https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx)
