ค้นหาเว็บไซต์

การใช้ PowerShell Invoke-Command เพื่อเรียกใช้สคริปต์บนคอมพิวเตอร์ระยะไกล


ในบทความนี้ เราจะเรียนรู้วิธีใช้ cmdlet เรียกใช้คำสั่ง เพื่อเรียกใช้คำสั่งหรือสคริปต์ PowerShell จากระยะไกล คุณสามารถใช้ PowerShell เพื่อเรียกใช้คำสั่งจากระยะไกลบนคอมพิวเตอร์ตั้งแต่หนึ่งเครื่องขึ้นไปในเครือข่ายของคุณ Invoke-Command cmdlet กำลังใช้คุณลักษณะการจัดการระยะไกลจาก PowerShell Remoting PowerShell Remoting ช่วยให้คุณสามารถเชื่อมต่อระยะไกลกับเซสชัน PowerShell บนคอมพิวเตอร์ผ่านบริการ WinRM (Windows Remote Management) และโปรโตคอล Web Services for 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

คุณยังสามารถเปิดใช้งานและกำหนดค่า WinRM โดยใช้ Group Policies

วิธีเรียกใช้คำสั่ง PowerShell จากระยะไกลโดยใช้ Invoke-Command

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}

คุณสามารถวางรายการคอมพิวเตอร์ลงในตัวแปร (อาร์เรย์):

$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 รับ-งาน

บทความที่เกี่ยวข้อง