ในบทความนี้ เราจะเรียนรู้วิธีใช้ Invoke-Command cmdlet เพื่อเรียกใช้คำสั่ง PowerShell หรือสคริปต์จากระยะไกล คุณสามารถใช้ PowerShell เพื่อเรียกใช้คำสั่งจากระยะไกลบนคอมพิวเตอร์ตั้งแต่หนึ่งเครื่องขึ้นไปในเครือข่ายของคุณ Invoke-Command cmdlet กำลังใช้คุณสมบัติการจัดการระยะไกลจาก PowerShell Remoting . PowerShell Remoting ช่วยให้คุณสามารถเชื่อมต่อกับเซสชัน PowerShell จากระยะไกลบนคอมพิวเตอร์ผ่าน WinRM บริการ (Windows Remote Management) และ บริการเว็บสำหรับการจัดการ (WS-Management) โปรโตคอล บริการนี้ให้ความสามารถในการสร้างเซสชัน PowerShell ระยะไกลและเรียกใช้รหัสของคุณ
การกำหนดค่า WinRM สำหรับ PowerShell Remoting
PowerShell Remoting ใช้ HTTP (พอร์ต TCP/5985) หรือ HTTPS (พอร์ต TCP/5986) เพื่อสื่อสารระหว่างคอมพิวเตอร์ ตามค่าเริ่มต้น โปรโตคอล HTTP จะถูกใช้ แต่แม้กระทั่งการรับส่งข้อมูลนี้ก็ยังถูกเข้ารหัสโดยใช้ AES-56 (อย่างไรก็ตาม มีภัยคุกคามจากการโจมตีแบบคนกลาง) นอกจากนี้ยังสามารถใช้การตรวจสอบสิทธิ์ Kerberos หรือ NTLM ได้อีกด้วย
WinRM ต้องทำงานบนคอมพิวเตอร์ระยะไกลที่คุณจะเชื่อมต่อ ตรวจสอบสถานะบริการ WinRM:
Get-Service -Name "*WinRM*" | fl
หากบริการไม่ทำงาน ให้เริ่ม:
Enable-PSRemoting
WinRM has been updated to receive requests. WinRM service started. WinRM is already set up for remote management on this computer.
คำสั่งนี้จะเริ่มบริการ WinRM (และตั้งค่าให้เริ่มทำงานโดยอัตโนมัติ) ตั้งค่าเริ่มต้น winrm และเพิ่มกฎข้อยกเว้นให้กับ Windows Firewall Enable-PSRemoting –Force
คำสั่งเปิดใช้งาน WinRM โดยไม่ต้องแจ้งให้ผู้ใช้ทราบ
จากนั้นคุณสามารถเชื่อมต่อกับคอมพิวเตอร์จากระยะไกลโดยใช้ PowerShell Remoting
โปรดทราบว่า PowerShell Remoting จะไม่ทำงานตามค่าเริ่มต้น หากประเภทเครือข่ายของคุณตั้งค่าเป็น สาธารณะ . จากนั้นคำสั่งจะส่งคืนข้อผิดพลาดต่อไปนี้:Set-WSManQuickConfig : ... WinRM firewall exception will not work since one of the network connection types on this machine is set to Public. Change the network connection type to either Domain or Private and try again.
คุณต้องเปลี่ยนตำแหน่งเครือข่ายเป็นแบบส่วนตัวหรือใช้คำสั่งนี้:
Enable-PSRemoting –SkipNetworkProfileCheck.
เปิดใช้งานกฎไฟร์วอลล์ Windows Defender ที่อนุญาตให้เข้าถึง WinRM ในเครือข่ายสาธารณะ คุณสามารถเปิดใช้งานกฎไฟร์วอลล์โดยใช้ GPO หรือ PowerShell:
Set-NetFirewallRule -Name 'WINRM-HTTP-In-TCP' -RemoteAddress Any
ในการทดสอบการเชื่อมต่อกับคอมพิวเตอร์ระยะไกลผ่าน PowerShell Remoting ให้เรียกใช้คำสั่งต่อไปนี้:
Test-WsMan compname1
หากคุณไม่มีโดเมน Active Directory หรือเข้าถึงคอมพิวเตอร์ผ่าน PowerShell Remoting ด้วยที่อยู่ IP ในกรณีนี้ จะใช้โปรโตคอล NTLM สำหรับการตรวจสอบสิทธิ์ เมื่อใช้ NTLM ข้อผิดพลาดต่อไปนี้จะปรากฏขึ้นหากคุณพยายามเรียกใช้ Invoke-Command:
[192.168.1.201] Connecting to remote server 192.168.1.102 failed with the following error message: The WinRM client cannot process the request. Default authentication may be used with an IP address under the following conditions: thetransport is HTTPS or the destination is in the TrustedHosts list, and explicit credentials are provided. Use winrm.cmd to configure TrustedHosts. Note that computers in the TrustedHosts list might not be authenticated. + FullyQualifiedErrorId: CannotUseIPAddress,PSSessionStateBroken
หากต้องการให้การรับรองความถูกต้อง NTLM ทำงานอย่างถูกต้องบนคอมพิวเตอร์ที่คุณใช้เชื่อมต่อ ให้ทำบางสิ่งเพิ่มเติม:ออกใบรับรอง SSL สำหรับ WinRM หรือเพิ่มชื่อโฮสต์/ที่อยู่ IP ในรายการโฮสต์ที่เชื่อถือได้:
Set-Item wsman:\localhost\Client\TrustedHosts -value 192.168.1.201
หรือคุณสามารถอนุญาตการเชื่อมต่อกับคอมพิวเตอร์ทุกเครื่อง (ไม่แนะนำ เนื่องจากเป็นข้อเสียอย่างหนึ่งของ NTLM — ไม่รองรับการตรวจสอบความถูกต้องร่วมกัน)
Set-Item wsman:\localhost\Client\TrustedHosts -value *
ต้องใช้การตั้งค่าเดียวกันกับโฮสต์ระยะไกล
หากต้องการแสดงรายการโฮสต์ที่เชื่อถือได้ ให้เรียกใช้คำสั่ง:
Get-Item WSMan:\localhost\Client\TrustedHosts
หากต้องการใช้การเปลี่ยนแปลง ให้รีสตาร์ท WinRM:
Restart-Service WinRM
จะเรียกใช้คำสั่ง PowerShell จากระยะไกลโดยใช้คำสั่ง Invoke ได้อย่างไร
Invoke-Command cmdlet อนุญาตให้เรียกใช้คำสั่งบนคอมพิวเตอร์ระยะไกลตั้งแต่หนึ่งเครื่องขึ้นไป
ตัวอย่างเช่น หากต้องการเรียกใช้คำสั่งเดียวบนคอมพิวเตอร์ระยะไกล ให้ใช้สิ่งต่อไปนี้:
Invoke-Command -ComputerName dc01 -ScriptBlock {$PSVersionTable.PSVersion}
คำสั่งนี้จะแสดงเวอร์ชันของ PowerShell ที่ติดตั้งบนคอมพิวเตอร์ระยะไกล ซึ่งระบุชื่อไว้ใน -ComputerName
พารามิเตอร์. ป้อนคำสั่งที่จะเรียกใช้บนคอมพิวเตอร์ระยะไกลใน -ScriptBlock {[cmdlet]}
บล็อค
ตามค่าเริ่มต้น คำสั่งที่ส่งผ่าน Invoke-Command จะถูกดำเนินการในฐานะผู้ใช้ปัจจุบันบนคอมพิวเตอร์ระยะไกล หากคุณต้องการเรียกใช้ในฐานะผู้ใช้รายอื่น ให้ขอข้อมูลรับรองผู้ใช้และบันทึกลงในตัวแปร:
$cred = Get-Credential
Invoke-Command -ComputerName dc01 -Credential $cred -ScriptBlock {Get-NetAdapter}
คำสั่ง PowerShell นี้แสดงรายการอินเทอร์เฟซเครือข่ายบนคอมพิวเตอร์ระยะไกล:
คุณสามารถป้อนคำสั่งได้มากกว่าหนึ่งคำสั่งใน ScriptBlock โดยคั่นด้วยเครื่องหมายอัฒภาค ตัวอย่างเช่น คำสั่งต่อไปนี้จะแสดงเขตเวลาปัจจุบันและเปลี่ยนเป็นเขตเวลาอื่น:
Invoke-Command -Computername dc01 -ScriptBlock {Get-TimeZone| select DisplayName;Set-TimeZone -Name "Central Europe Standard Time”}
Invoke-Command ช่วยให้คุณเรียกใช้คำสั่งต่างๆ ได้ไม่เฉพาะแต่ยังเรียกใช้สคริปต์ PowerShell ได้อีกด้วย ในการทำเช่นนั้น ใช้อาร์กิวเมนต์ -FilePath (แทน –ScriptBlock) ในกรณีนี้ คุณระบุเส้นทางไปยังไฟล์สคริปต์ PS1 ในเครื่องบนคอมพิวเตอร์ของคุณ (คุณไม่จำเป็นต้องคัดลอกไฟล์สคริปต์ไปยังคอมพิวเตอร์เป้าหมายระยะไกล):
Invoke-Command -ComputerName DC01 -FilePath C:\PS\Scripts\CheckSMBversion.ps1
วิธีใช้ Invoke-Command เพื่อเรียกใช้คำสั่งบนคอมพิวเตอร์หลายเครื่องพร้อมกัน
คุณสามารถใช้ Invoke-Command เพื่อเรียกใช้คำสั่งบนคอมพิวเตอร์ระยะไกลหลายเครื่องพร้อมกันได้ (พร้อมกัน)
ในกรณีที่ง่ายที่สุด ชื่อของคอมพิวเตอร์ที่จะเรียกใช้คำสั่ง PowerShell จะถูกคั่นด้วยเครื่องหมายจุลภาค:
Invoke-Command server1, server2, server3 -ScriptBlock {get-date}
คุณสามารถวางรายการคอมพิวเตอร์ลงในตัวแปร (array):
$servers = @("server1","server2","server3")
Invoke-Command -ScriptBlock { get-date} -ComputerName $servers
หรือรับจากไฟล์ข้อความ:
Invoke-Command -ScriptBlock {Restart-Service spooler} -ComputerName(Get-Content c:\ps\servers.txt)
คุณยังสามารถรับรายการคอมพิวเตอร์ใน AD โดยใช้ Get-ADComputer cmdlet จาก AD สำหรับโมดูล PowerShell:
หากต้องการเรียกใช้คำสั่งในโฮสต์ Windows Server ทั้งหมดในโดเมน ให้ใช้รหัส PowerShell ต่อไปนี้:
$computers = (Get-ADComputer -Filter 'OperatingSystem -like "*Windows server*" -and Enabled -eq "true"').Name
Invoke-Command -ComputerName $computers -ScriptBlock {Get-Date} -ErrorAction SilentlyContinue
หากคอมพิวเตอร์ปิดอยู่หรือไม่พร้อมใช้งาน สคริปต์จะไม่หยุดทำงานเนื่องจากพารามิเตอร์ SilentlyContinue และจะยังทำงานบนคอมพิวเตอร์เครื่องอื่นต่อไป
เพื่อให้เข้าใจว่าคอมพิวเตอร์เป็นผลมาจากอะไร ให้ใช้ตัวแปรสภาพแวดล้อม PSComputerNamee
$results = Invoke-Command server1, server2, server3 -ScriptBlock {get-date}
$results | Select-Object PSComputerName, DateTime
เมื่อรันคำสั่งโดยใช้ Invoke-Command บนคอมพิวเตอร์หลายเครื่อง คำสั่งจะถูกรันพร้อมกัน Invoke-Command มีการจำกัดจำนวนสูงสุดของคอมพิวเตอร์ที่จะจัดการพร้อมกัน (PSSessions พร้อมกันในจำนวนที่จำกัด) ข้อจำกัดนี้ตั้งค่าไว้ใน ThrottleLimit พารามิเตอร์ (ค่าเริ่มต้นคือ 32) หากคุณต้องการเรียกใช้คำสั่งบนคอมพิวเตอร์มากกว่า 32 เครื่อง (เช่น 128) ให้ใช้ –ThrottleLimit 128
(อย่างไรก็ตาม คอมพิวเตอร์ของคุณจะมีโหลดที่สูงกว่าเพื่อสร้าง PSSessions จำนวนมาก)
ในการรันคำสั่งบนคอมพิวเตอร์ระยะไกลผ่าน Invoke-Command ในพื้นหลัง แอตทริบิวต์พิเศษ –AsJob
ถูกนำมาใช้. จากนั้นผลลัพธ์ของคำสั่งจะไม่ถูกส่งคืนไปยังคอนโซล เพื่อให้ได้ผลลัพธ์ ใช้ รับงาน cmdlet.