Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> ระบบ >> Windows Server

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

ในบทความนี้เราจะเรียนรู้วิธีใช้ Cmdlet Invoke-Command เพื่อรัน PowerShell Commands หรือ Scripts แบบ Remote คุณสามารถใช้ PowerShell เพื่อรันคำสั่ง Remote บนคอมพิวเตอร์หนึ่งหรือหลายเครื่องใน Network ของคุณ Cmdlet Invoke-Command ใช้ Remote Management Features จาก PowerShell Remoting PowerShell Remoting อนุญาตให้คุณเชื่อมต่อ Remote PowerShell Sessions บนคอมพิวเตอร์ผ่าน Service WinRM (Windows Remote Management) และโปรโตคอล Web Services for Management (WS-Management) Service นี้ให้ความสามารถในการสร้าง Remote PowerShell Sessions และรันโค้ดของคุณ

การตั้งค่า WinRM สำหรับ PowerShell Remoting

PowerShell Remoting ใช้ HTTP (Port TCP/5985) หรือ HTTPS (Port TCP/5986) เพื่อสื่อสารระหว่างคอมพิวเตอร์ โดย Default ใช้ HTTP Protocol แม้ Traffic นี้จะถูก Encrypted ด้วย AES-56 (อย่างไรก็ตาม มีภัยคุกคาม Man-in-the-middle Types) การยืนยันตัวตน Kerberos หรือ NTLM อาจถูกใช้ได้เช่นกัน

WinRM ต้องทำงานบน Remote Computers ที่คุณจะเชื่อมต่อ ตรวจสอบสถานะ WinRM Service:

Get-Service -Name "*WinRM*" | fl

หาก Service ไม่ทำงาน ให้เริ่มมัน:

Enable-PSRemoting

WinRM has been updated to receive requests. WinRM service started. WinRM is already set up for remote management on this computer.

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

คำสั่งนี้จะ Start WinRM Service (และตั้งค่าให้ Start อัตโนมัติ) ตั้งค่า Default WinRM Settings และเพิ่ม Exception Rules ไปยัง Windows Firewall คำสั่ง Enable-PSRemoting –Force เปิดใช้งาน WinRM โดยไม่ Prompt User

จากนั้นคุณสามารถเชื่อมต่อกับคอมพิวเตอร์ Remote โดยใช้ PowerShell Remoting ได้

โปรดทราบว่า PowerShell Remoting จะไม่ทำงานโดย Default หาก Network Type ของคุณตั้งค่าเป็น Public คำสั่งจะคืนค่า Error ดังนี้:

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.

คุณต้องเปลี่ยน Network Location เป็น Private หรือใช้คำสั่งนี้:

Enable-PSRemoting –SkipNetworkProfileCheck.

นอกจากนี้ ให้ Enable Windows Defender Firewall Rule ที่อนุญาตการเข้าถึง WinRM ใน Public Networks คุณสามารถ Enable Firewall Rule โดยใช้ GPO หรือ PowerShell:

Set-NetFirewallRule -Name 'WINRM-HTTP-In-TCP' -RemoteAddress Any

เพื่อทดสอบการเชื่อมต่อกับ Remote Computer ผ่าน PowerShell Remoting ให้รันคำสั่งต่อไปนี้:

Test-WsMan compname1

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

หากคุณไม่มี Active Directory Domain หรือคุณเข้าถึงคอมพิวเตอร์ผ่าน PowerShell Remoting ด้วย IP Addresses ในกรณีนี้ NTLM Protocol จะถูกใช้สำหรับ Authentication เมื่อใช้ NTLM Error ต่อไปนี้จะปรากฏหากคุณพยายามรัน 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: the transport 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

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

เพื่อให้ NTLM Authentication ทำงานถูกต้องบนคอมพิวเตอร์ที่คุณใช้เชื่อมต่อ ทำเพิ่มเติมดังนี้: ออก SSL Certificate สำหรับ WinRM หรือเพิ่ม Host Name/IP Address ไปยัง Trusted Hosts List:

Set-Item wsman:\localhost\Client\TrustedHosts -value 192.168.1.201

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

หรือคุณสามารถอนุญาตการเชื่อมต่อกับคอมพิวเตอร์ทั้งหมดได้ (ไม่แนะนำ เพราะเป็นหนึ่งในข้อเสียของ NTLM — ไม่รองรับ Mutual Authentication)

Set-Item wsman:\localhost\Client\TrustedHosts -value *

การตั้งค่าเดียวกันต้องถูกนำไปใช้บน Remote Hosts ด้วย

เพื่อแสดงรายการ Trusted Hosts ให้รันคำสั่ง:

Get-Item WSMan:\localhost\Client\TrustedHosts

เพื่อ Apply Changes ให้ Restart WinRM:

Restart-Service WinRM

คุณยังสามารถ Enable และ Configure WinRM โดยใช้ Group Policies ได้

วิธีรัน PowerShell Commands แบบ Remote โดยใช้ Invoke-Command

Cmdlet Invoke-Command อนุญาตให้รันคำสั่งบน Remote Computers หนึ่งหรือหลายเครื่อง

ตัวอย่างเช่น เพื่อรันคำสั่งเดี่ยวบน Remote Computer ให้ใช้ดังนี้:

Invoke-Command -ComputerName dc01 -ScriptBlock {$PSVersionTable.PSVersion}

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

คำสั่งนี้จะแสดง PowerShell Version ที่ติดตั้งบน Remote Computer ซึ่งชื่อถูกระบุในพารามิเตอร์ -ComputerName ใส่คำสั่งที่จะรันบน Remote Computer ใน Block -ScriptBlock {[cmdlet]}

โดย Default คำสั่งที่ส่งผ่าน Invoke-Command จะถูก Execute ในฐานะ Current User บน Remote Computer หากคุณต้องการรันในฐานะ User อื่น ให้ Request User Credentials และบันทึกลงใน Variable:

$cred = Get-Credential
Invoke-Command -ComputerName dc01 -Credential $cred -ScriptBlock {Get-NetAdapter}

คำสั่ง PowerShell นี้แสดงรายการ Network Interfaces บน Remote Computer:

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

คุณสามารถใส่คำสั่งมากกว่าหนึ่งคำสั่งใน ScriptBlock ได้ โดยคั่นด้วย Semicolons ตัวอย่างเช่น คำสั่งต่อไปนี้จะแสดง Time Zone ปัจจุบันและเปลี่ยนเป็นอีก Time Zone หนึ่ง:

Invoke-Command -Computername dc01 -ScriptBlock {Get-TimeZone| select DisplayName;Set-TimeZone -Name "Central Europe Standard Time”}

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

Invoke-Command อนุญาตให้รันไม่ได้แค่คำสั่งเดี่ยว แต่ยังรัน PowerShell Scripts ได้ ในการทำเช่นนั้น ใช้ Argument -FilePath (แทน –ScriptBlock) ในกรณีนี้ คุณระบุ Path ไปยัง Local PS1 Script File บนคอมพิวเตอร์ของคุณ (คุณไม่ต้อง Copy Script File ไปยัง Target Remote Computer):

Invoke-Command -ComputerName DC01 -FilePath C:\PS\Scripts\CheckSMBversion.ps1

วิธีใช้ Invoke-Command เพื่อรันคำสั่งบนหลายคอมพิวเตอร์พร้อมกัน

คุณสามารถใช้ Invoke-Command เพื่อรันคำสั่งบน Remote Computers หลายเครื่องแบบ Parallel (พร้อมกัน)

ในกรณีง่ายที่สุด ชื่อคอมพิวเตอร์ที่จะรัน PowerShell Commands จะคั่นด้วย Commas:

Invoke-Command server1, server2, server3 -ScriptBlock {get-date}

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

คุณสามารถวางรายการคอมพิวเตอร์ลงใน Variable (Array) ได้:

$servers = @("server1","server2","server3")
Invoke-Command -ScriptBlock { get-date} -ComputerName $servers

หรือรับจาก Text File:

Invoke-Command -ScriptBlock {Restart-Service spooler} -ComputerName(Get-Content c:\ps\servers.txt)

คุณยังสามารถรับรายการคอมพิวเตอร์ใน AD โดยใช้ Get-ADComputer Cmdlet จาก AD for PowerShell Module:

เพื่อรันคำสั่งใน Windows Server Hosts ทั้งหมดใน Domain ให้ใช้ PowerShell Code ต่อไปนี้:

$computers = (Get-ADComputer -Filter 'OperatingSystem -like "*Windows server*" -and Enabled -eq "true"').Name
Invoke-Command -ComputerName $computers -ScriptBlock {Get-Date} -ErrorAction SilentlyContinue

หาก Computer ปิดอยู่หรือ Unavailable Script จะไม่หยุดเนื่องจาก Parameter SilentlyContinue และจะยังคงรันบนคอมพิวเตอร์อื่นๆ ต่อไป

เพื่อเข้าใจว่าผลลัพธ์มาจาก Computer ไหน ให้ใช้ Environment Variable PSComputerNamee

$results = Invoke-Command server1, server2, server3 -ScriptBlock {get-date}
$results | Select-Object PSComputerName, DateTime

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

เมื่อรันคำสั่งโดยใช้ Invoke-Command บนหลายคอมพิวเตอร์ มันจะรันพร้อมกัน Invoke-Command มีข้อจำกัดใน Maximum Number ของ Computers ที่จะจัดการพร้อมกัน (Limited Number ของ Simultaneous PSSessions) ข้อจำกัดนี้ตั้งค่าใน Parameter ThrottleLimit (Default Value คือ 32) หากคุณต้องการรันคำสั่งบนมากกว่า 32 Computers (128 ตัวอย่าง) ให้ใช้ –ThrottleLimit 128 (อย่างไรก็ตาม คอมพิวเตอร์ของคุณจะมี Load สูงขึ้นเพื่อสร้าง PSSessions จำนวนมาก)

เพื่อรันคำสั่งบน Remote Computers ผ่าน Invoke-Command ใน Background ใช้ Attribute พิเศษ –AsJob จากนั้น Result ของคำสั่งจะไม่ถูก Return ไปที่ Console เพื่อรับ Results ให้ใช้ Cmdlet Receive-Job