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

สคริปต์ PowerShell - สุดยอดคู่มือในการเริ่มต้น


ทำให้งานประจำวันเป็นแบบอัตโนมัติ แยกข้อมูลจากระบบ หรือจัดการ Microsoft 365 สคริปต์ PowerShell ทำให้งานประจำวันของคุณง่ายขึ้นมาก เมื่อคุณทำงานด้านไอที คุณจะไม่สามารถใช้งาน PowerShell ได้

PowerShell คืออินเทอร์เฟซบรรทัดคำสั่งขั้นสูง (CLI) และภาษาสคริปต์ที่สามารถใช้ได้กับ Windows, Linux และ macOS ด้วยความช่วยเหลือของ cmdlets เราสามารถทำงานต่างๆ เช่น ดึงข้อมูลผู้ใช้จาก Active Directory หรือทดสอบการเชื่อมต่อเครือข่ายของเซิร์ฟเวอร์ เราสามารถรวมงานและกระบวนการเหล่านี้เป็นสคริปต์ที่เราสามารถเรียกใช้บนคอมพิวเตอร์หลายเครื่องได้อย่างรวดเร็วหรือกำหนดเวลาเป็นงานรายวันได้

ในบทความนี้ ฉันจะอธิบายว่าคุณสามารถสร้างสคริปต์ PowerShell ของคุณเองได้อย่างไร เครื่องมือใดที่คุณสามารถใช้ได้ วิธีจัดรูปแบบสคริปต์ และเคล็ดลับทั่วไปในการเริ่มต้น ในตอนท้ายของบทความ คุณจะพบเทมเพลตที่คุณสามารถใช้สำหรับสคริปต์ของคุณได้

ตัวแก้ไข PowerShell

คนส่วนใหญ่ที่เริ่มเขียนสคริปต์ PowerShell จะใช้เครื่องมือแผ่นจดบันทึกง่ายๆ เช่น Notepad++ มันใช้งานได้กับสคริปต์ขนาดเล็ก แต่ตัวแก้ไขที่ดีทำให้การเขียนสคริปต์ PowerShell ง่ายขึ้นมาก พวกมันมาพร้อมกับการเน้นไวยากรณ์ ฟังก์ชันเติมข้อความอัตโนมัติ การตรวจจับข้อผิดพลาด ฯลฯ และสิ่งที่ฉันชอบที่สุดคือคุณสามารถสร้างโปรเจ็กต์ ซึ่งช่วยให้คุณสลับระหว่างไฟล์ได้อย่างรวดเร็วและจัดระเบียบไฟล์ของคุณ

สำหรับ PowerShell หนึ่งในโปรแกรมแก้ไขฟรีที่ดีที่สุดที่จะเริ่มต้นด้วยคือ Visual Studio Code โปรแกรมแก้ไขจาก Microsoft นี้ใช้งานได้ฟรีและสามารถใช้ได้กับ Windows, Linux และ macOS หากต้องการใช้ตัวแก้ไขกับ PowerShell คุณจะต้องติดตั้งปลั๊กอิน (ส่วนขยาย)

  1. ขั้นแรก ติดตั้ง Visual Studio Code โดยใช้โปรแกรมติดตั้ง เพียงคลิกถัดไปบนทุกหน้าจอ
  2. คลิกที่ส่วนขยาย
  3. ค้นหา PowerShell
  4. ติดตั้ง ส่วนขยาย PowerShell จาก Microsoft

ในการสร้างสคริปต์ PowerShell แรกของเรา เราจะต้องสร้างไฟล์ใหม่ เพื่อจัดระเบียบ เราจะสร้างโฟลเดอร์ใหม่ “สคริปต์” ที่เราจะจัดเก็บไฟล์ของเรา ในรหัส Visual Studio:

  1. เปิด นักสำรวจ
  2. เลือก เปิดโฟลเดอร์
  3. สร้างสคริปต์โฟลเดอร์ใหม่ใน OneDrive ของคุณ เป็นต้น
  4. คลิก เลือกโฟลเดอร์

คุณจะได้รับข้อความแจ้งหากคุณเชื่อถือไฟล์ในโฟลเดอร์นี้ ตรวจสอบให้แน่ใจว่าคุณได้ทำเครื่องหมายที่ “เชื่อถือผู้เขียนของไฟล์ทั้งหมดในโฟลเดอร์หลัก” แล้วคลิก ใช่ ฉันเชื่อถือผู้เขียน

หากต้องการสร้างไฟล์ใหม่ ให้คลิกขวาที่ตัวแก้ไข (หรือคลิกที่ไอคอนไฟล์ใหม่) และสร้างสคริปต์ PowerShell แรกของคุณ คุณยังสามารถสร้างโฟลเดอร์ย่อยเพื่อจัดระเบียบสคริปต์ของคุณได้

การเรียกใช้สคริปต์ PowerShell

ก่อนที่เราจะเริ่มเขียนสคริปต์ PowerShell เราควรทราบว่าคุณสามารถเรียกใช้หรือทดสอบสคริปต์ของคุณได้อย่างไร ปัญหาทั่วไปประการหนึ่งเมื่อคุณพยายามเรียกใช้สคริปต์คือข้อผิดพลาด “การเรียกใช้สคริปต์ถูกปิดใช้งานบนระบบนี้” เพื่อแก้ปัญหานี้ เราจะต้องเปลี่ยนการอนุญาตการดำเนินการบนคอมพิวเตอร์ Windows 10 หรือ 11 ของคุณ

เปิด PowerShell และพิมพ์คำสั่งด้านล่างเพื่อเปลี่ยนนโยบายการดำเนินการ อ่านเพิ่มเติมเกี่ยวกับนโยบายการดำเนินการ PowerShell ในบทความนี้

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

# Verify the setting with
Get-ExecutionPolicy

ด้วยการกำหนดนโยบายการดำเนินการ เราสามารถเรียกใช้สคริปต์ของเราได้โดยไม่มีข้อผิดพลาดในการอนุญาต ขณะนี้มีหลายตัวเลือกในการเรียกใช้สคริปต์ PowerShell โปรดอ่านรายละเอียดเพิ่มเติมในบทความนี้ แต่สำหรับคำแนะนำนี้ เราจะเน้นไปที่สองตัวเลือกต่อไปนี้:

  • การใช้เทอร์มินัลในตัวใน Visual Studio Code
  • เรียกใช้สคริปต์ใน PowerShell

การใช้โค้ด Visual Studio

ข้อดีอย่างหนึ่งเมื่อใช้ Visual Studio Code เป็นตัวแก้ไขสคริปต์ PowerShell ของคุณก็คือ คุณสามารถทดสอบและรันสคริปต์ของคุณในเทอร์มินัลในตัวได้ คุณสามารถเรียกใช้สคริปต์ทั้งหมดได้โดยการกด F5 หรือเรียกใช้การเลือกบรรทัดโดยกด F8

การใช้ PowerShell

อีกวิธีหนึ่งคือการใช้ PowerShell เพื่อเรียกใช้สคริปต์ของคุณ เปิด Windows PowerShell หรือ Windows Terminal (คลิกขวาที่ Start) และนำทางไปยังโฟลเดอร์ที่บันทึกสคริปต์ของคุณ พิมพ์ชื่อไฟล์สคริปต์ของคุณแล้วกด Enter

พื้นฐาน

การใช้ Cmdlets ใน PowerShell

ในพรอมต์คำสั่ง เรามีคำสั่งซึ่งเป็นฟังก์ชัน (คำสั่ง) ในตัวที่ดำเนินงาน ตัวอย่างเช่น ถ้าคุณพิมพ์ hostname ใน command prompt มันจะแสดงชื่อคอมพิวเตอร์ของคุณ หรือคำสั่ง dir จะแสดงรายการเนื้อหาของไดเร็กทอรีปัจจุบัน

ใน PowerShell เรามี command-lets (cmdlets) คุณสามารถจดจำ cmdlet ได้โดยการตั้งชื่อเนื่องจากมีคู่ กริยา-คำนาม แบบแผนการตั้งชื่อนี้ช่วยให้คุณเข้าใจว่า cmdlet เฉพาะทำอะไร

บันทึก

ในตัวอย่างด้านล่าง ฉันกำลังใช้ cmdlets จากโมดูล Active Directory ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้งโมดูลแล้วหากคุณต้องการทำตามขั้นตอนต่างๆ เรียกใช้คำสั่งต่อไปนี้เพื่อติดตั้งโมดูล:

Add-WindowsCapability -online -Name “Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 ”

ตัวอย่างเช่น Get-ComputerInfo cmdlet รับข้อมูลคอมพิวเตอร์ทั้งหมดจากคอมพิวเตอร์ของคุณ หากต้องการแสดงเนื้อหาของโฟลเดอร์ เราสามารถใช้ Get-ChildItem ได้ เป็นต้น

นอกจาก cmdlets ในตัวแล้ว คุณยังสามารถติดตั้งโมดูลใน PowerShell ได้อีกด้วย โมดูลเหล่านี้สามารถใช้เพื่อทำงานกับ Exchange Online หรือ Azure AD ได้ แต่ละโมดูลมาพร้อมกับ cmdlets ของตัวเองสำหรับงานเฉพาะ

แผ่นโกง PowerShell

ตรวจสอบให้แน่ใจว่าคุณชำระเงินและดาวน์โหลด PowerShell Cheat Sheet ด้วย

กริยาของ PowerShell

คำกริยาที่ได้รับอนุมัติจำนวนมากที่คุณสามารถใช้ได้เมื่อคุณสร้างคำสั่งหรือฟังก์ชัน PowerShell ของคุณเอง แต่คำกริยาที่พบบ่อยที่สุดที่คุณจะพบคือ:

VerbActionExample
AddAdds or appends are resources to another itemAdd-MailboxPermission
ClearRemoves all resources from a container, but doesn’t
delete the container
Clear-Host
ConnectMakes a connection to another systemConnect-AzureAD
DisconnectBreak the connection with the other systemDisconnect-AzureAD
GetRetrieves data from a resourceGet-ChildItem
NewCreates a new resourceNew-Mailbox
RemoveRemove a resource from a containerRemove-Mailbox
SetReplaces data in an existing resourceSet-Mailbox
SelectSelects a resource in a containerSelect-Object

ตัวแปร

เมื่อเขียนสคริปต์ คุณมักจะต้องจัดเก็บข้อมูลชั่วคราว เพื่อให้คุณสามารถนำมาใช้ในสคริปต์ของคุณได้ในภายหลัง สำหรับสิ่งนี้เราใช้ตัวแปร ใน PowerShell เราไม่จำเป็นต้องเริ่มต้นตัวแปร เราสามารถสร้างได้เมื่อจำเป็น ตัวแปรไม่เพียงแต่สามารถจัดเก็บข้อมูล เช่น สตริง และจำนวนเต็ม แต่ยังรวมถึงผลลัพธ์ที่สมบูรณ์ของ cmdlets อีกด้วย

เริ่มต้นด้วยตัวอย่างง่ายๆ เราใช้ Get-Computer cmdlet จากเมื่อก่อน cmdlet ส่งคืนชื่อคอมพิวเตอร์ของคุณ:

บันทึก

เนื้อหาที่อยู่หลัง # ในสคริปต์ PowerShell คือความคิดเห็น ความคิดเห็นใช้เพื่ออธิบายว่าฟังก์ชันทำหน้าที่อะไร และทำให้โค้ดของคุณสามารถใช้งานได้มากขึ้น
hostname

# Result
LazyBook

เราไม่ต้องการแสดงเพียงชื่อคอมพิวเตอร์ แต่เราต้องการรวมชื่อคอมพิวเตอร์ไว้ในสตริงที่ดีแทน ในกรณีนี้ ก่อนอื่นเราสามารถจัดเก็บผลลัพธ์ของ Get-Computername cmdlet ลงในตัวแปร ซึ่งเราจะเรียกว่า ชื่อคอมพิวเตอร์ จากนั้นรวมตัวแปรนี้ไว้ในสตริง:

# Store computer name inside the variable
$computername = hostname

# Include the variable inside the string
Write-Host "The name of your computer is $computername"

# Result
The name of your computer is LazyBook

ตัวดำเนินการเปรียบเทียบและเงื่อนไข If-Else

ใน PowerShell เราสามารถใช้ตัวดำเนินการเปรียบเทียบเพื่อเปรียบเทียบหรือค้นหาค่าที่ตรงกัน ตามค่าเริ่มต้น ตัวดำเนินการจะคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ แต่คุณสามารถใส่เครื่องหมาย c ก่อนตัวดำเนินการเพื่อทำให้คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ได้ ตัวอย่างเช่น:

'lazyadmin' -eq 'LazyAdmin'
# Result
True

'lazyadmin' -ceq 'LazyAdmin'
# Result
False

ตัวดำเนินการที่เราสามารถใช้ใน PowerShell คือ:

OperatorCounter-Part operatorDescription
-eq-neEqual or not equal
-gt-ltGreater or less than
-geGreat than or equal to
-leLess than or equal to
-Like-NotLikeMatch a string using * wildcard or not
-Match-NotMatchMatches or not the specified regular expression
-Contains-NotContainsCollection contains a specified value or not
-In-NotInSpecified value in collection or not
-ReplaceReplace specified value

เราสามารถใช้โอเปอเรเตอร์เหล่านี้ร่วมกับคำสั่ง If-Else เช่น หากข้อความช่วยให้เราสามารถตรวจสอบว่าการเปรียบเทียบใดเป็นจริงหรือไม่ ขึ้นอยู่กับผลลัพธ์ที่เราสามารถรันโค้ดบางส่วนหรือข้ามไปยังส่วนอื่นได้

มาดูตัวอย่างชื่อคอมพิวเตอร์กันอีกครั้ง เราได้เก็บชื่อคอมพิวเตอร์ไว้ในตัวแปร ตอนนี้เรามาตรวจสอบว่าชื่อคอมพิวเตอร์คือแล็ปท็อปของฉันหรือไม่:

$computername = hostname

# Check if the computer name equal LazyBook
if ($computername -eq 'LazyBook') {
  Write-Host "This computer is from LazyAdmin"
}else{
  Write-host "This is someone else's computer"
}

ชื่อคอมพิวเตอร์ของเราขึ้นต้นด้วย LT สำหรับแล็ปท็อปและพีซีสำหรับเดสก์ท็อป ดังนั้นเราจึงสามารถระบุได้ว่าอุปกรณ์นั้นเป็นแล็ปท็อปหรือไม่ตามชื่อคอมพิวเตอร์ สำหรับสิ่งนี้ เราจะใช้คำสั่ง if พร้อมด้วยตัวดำเนินการ -like ตัวดำเนินการ like ยอมรับ wildcard ดังนั้นเราจึงสามารถตรวจสอบได้ว่าสตริงขึ้นต้นด้วย "LT" ในกรณีนี้หรือไม่

$computername = hostname

# Or better is
$computername = $env:COMPUTERNAME

# Check if the computer name start with Lazy
if ($computername -like 'Lazy*') {
  Write-Host "This is a laptop"
}else{
  Write-host "This is something else"
}

ส่งต่อผลลัพธ์ที่แท้จริงด้วย Pipelining

นอกจากตัวแปรแล้ว ยังมีวิธีอื่นในการส่งข้อมูลผ่านไปยัง cmdlet อื่นใน PowerShell ซึ่งใช้ตัวดำเนินการไปป์ไลน์ | . ตัวดำเนินการไปป์ไลน์จะส่งผลลัพธ์ของคำสั่งไปยังคำสั่งถัดไป ตัวอย่างที่พบบ่อยที่สุดของ piping คือการจัดรูปแบบหรือการเลือกผลลัพธ์ของ cmdlet

ลองใช้ตัวอย่างต่อไปนี้ cmdlet Get-NetIPAddress ส่งคืนการกำหนดค่าที่อยู่ IP ของอินเทอร์เฟซเครือข่ายทั้งหมดของคุณ โดยค่าเริ่มต้น จะส่งกลับผลลัพธ์ในรูปแบบรายการ

Get-NetIPAddress

เพื่อให้ผลลัพธ์อ่านง่ายขึ้น เราสามารถจัดรูปแบบผลลัพธ์ลงในแท็บเล็ตหรือเลือกเฉพาะคุณสมบัติที่เราต้องการ เราทำเช่นนี้โดยการวาง cmdlet format-table (ft) ไว้ด้านหลังหรือ cmdlet select-object (select):

Get-NetIPAddress | FT

# Or select the fields
Get-NetIPAddress | Select InterfaceAlias, IPAddress, PrefixOrigin

นี่เป็นตัวอย่างง่ายๆ ของ piping cmdlets แต่ลองมาดูการใช้ piping cmdlets ขั้นสูงกว่านี้กันดีกว่า เราจะรวบรวมกล่องจดหมายของผู้ใช้ทั้งหมด จากแต่ละกล่องจดหมาย เราจะค้นหาสถิติกล่องจดหมาย เลือกเฉพาะฟิลด์ที่เราต้องการ และส่งออกผลลัพธ์เป็นไฟล์ CSV หากไม่มีตัวดำเนินการไปป์ เราจะต้องเขียนโค้ดที่คล้ายกับสิ่งนี้:

บันทึก

Get-EXOMailbox cmdlet เป็นส่วนหนึ่งของโมดูล Exchange Online ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้งแล้วหากคุณต้องการทำตามขั้นตอนด้านล่าง
$mailboxes = Get-EXOMailbox -RecipientTypeDetails UserMailbox

$mailboxes.ForEach({
  $Mailboxstats = Get-EXOMailboxStatistics -Identity $_.Identity
  $fields = Select-Object -InputObject $Mailboxstats -Property DisplayName,ItemCount,TotalItemSize
  Export-CSV -InputObject $fields -Path c:\temp\file.csv -Append
})

แต่ด้วย piping ใน PowerShell เราสามารถทำสิ่งต่อไปนี้ได้:

Get-EXOMailbox -RecipientTypeDetails UserMailbox | Get-EXOMailboxStatistics | Select DisplayName, ItemCount, TotalItemSize | Export-CSV c:\temp\filename.csv

การจัดเก็บข้อมูลในอาร์เรย์และแฮชเทเบิล

อาร์เรย์และแฮชเทเบิลสามารถใช้เพื่อจัดเก็บข้อมูลได้ Hashtables ใช้หลักการของค่าคีย์ซึ่งคุณต้องกำหนดคีย์ก่อนจึงจะสามารถจัดเก็บค่าได้ อาร์เรย์ใช้ดัชนีที่สร้างขึ้นโดยอัตโนมัติเพื่อจัดเก็บค่า

ในการสร้างอาร์เรย์ เราสามารถกำหนดค่าหลายค่าให้กับตัวแปร โดยแยกแต่ละค่าด้วยค่าร่วม ตัวอย่างเช่น:

# Create an array of fruits
$array = 'apple','raspberry','kiwi'

อีกทางเลือกหนึ่งคือการเริ่มต้นอาร์เรย์ก่อนและเพิ่มค่าให้กับอาร์เรย์ในภายหลัง ในการสร้างอาร์เรย์ว่าง เราจะใช้สัญลักษณ์ @ ตามด้วยวงเล็บ:

# Create an empty array
$fruits = @()

# Add content to the array
$fruits += "apple"

Hashtables ยังเป็นที่รู้จักกันในนาม associative arrays ซึ่งจะใช้เมื่อคุณต้องการจัดเก็บข้อมูลในลักษณะที่มีโครงสร้างมากขึ้น แทนที่จะเป็นดัชนีที่เป็นตัวเลข ดัชนีจะขึ้นอยู่กับคู่คีย์-ค่า ซึ่งคุณต้องกำหนดคีย์ด้วยตนเอง หากต้องการสร้างแฮชเทเบิลว่าง คุณจะต้องใช้วงเล็บปีกกาและสัญลักษณ์ @:

# Create empty hashtable
$hashTable = @{}

ตัวอย่างเช่น คุณสามารถใช้แฮชเทเบิลเพื่อจัดเก็บที่อยู่ IP ของเซิร์ฟเวอร์

$serverIps= @{
  'la-srv-lab02' = '192.168.10.2'
  'la-srv-db01' = '192.168.10.100'
}

# Result
Name                           Value
----                           -----
la-srv-lab02                   192.168.10.2
la-srv-db01                    192.168.10.100

หรือเป็นไฟล์ปรับแต่งภายในสคริปต์ของคุณ:

$mail = @{
  SmtpServer  = 'smtp.contoso.com'
  To          = 'johndoe@lazyadmin.nl'
  From        = 'info@contoso.com'
  Subject     = 'super long subject goes here'
  Body        = 'Test email from PowerShell'
  Priority    = High
}

การวนซ้ำข้อมูลด้วย Foreach และ Do-While

การวนซ้ำข้อมูลเป็นหนึ่งในงานทั่วไปในภาษาสคริปต์ใดๆ ForEach loops ช่วยให้คุณสามารถดูแต่ละรายการในคอลเลกชันและดำเนินการบางอย่างกับรายการนั้นได้ ตัวอย่างเช่น เราใช้อาร์เรย์ของผลไม้และเขียนแต่ละรายการ (ผลไม้) ลงในคอนโซล:

$fruits = @('apple','pear','banana','lemon','lime','mango')

# Foreach block
Foreach ($fruit in $fruits) {
    Write-Host $fruit;
}

# Shorthand
$fruits.foreach( {
    Write-Host $_;
})

ในตัวอย่างข้างต้น เราใช้เฉพาะอาร์เรย์ธรรมดาเท่านั้น แต่คุณสามารถใช้ ForEach กับอ็อบเจ็กต์ได้ ภายในบล็อก ForEach คุณสามารถเข้าถึงแต่ละคุณสมบัติของออบเจ็กต์ได้ ตัวอย่างเช่น หากเราได้รับกล่องจดหมายทั้งหมด เราก็จะสามารถเข้าถึงชื่อที่แสดงได้ดังนี้:

$mailboxes = Get-EXOMailbox -RecipientTypeDetails UserMailbox

$mailboxes.ForEach({ 
  # Write the displayname of each mailbox
  Write-host $_.DisplayName
})

นอกจากลูป ForEach แล้ว เรายังสามารถใช้ลูป While และ Do-While ได้อีกด้วย การวนซ้ำ while จะทำงานเมื่อตรงตามเงื่อนไขเท่านั้น Do-While จะทำงานหนึ่งครั้งเสมอและตราบใดที่เงื่อนไขเป็นจริง

# Do While loop
Do {
    Write-Host "Online"
    Start-Sleep 5
}
While (Test-Connection -ComputerName 8.8.8.8 -Quiet -Count 1)

Write-Host "Offline"

# While loop
$i = 0;
$path = "C:\temp"

While ($i -lt 10) {
    # Do Something
    $newFile = "$path\while_test_file_" + $i + ".txt";
    New-Item $newFile
    $i++;
}

เรียนรู้เพิ่มเติมเกี่ยวกับ For loops คำสั่ง ForEach และ Do While loops ในบทความนี้

จับข้อผิดพลาดด้วย Try-Catch

บล็อก Try-catch ใช้เพื่อจัดการกับข้อผิดพลาดในวิธีที่เหมาะสม โดยปกติเมื่อฟังก์ชันไม่ทำงานหรือพบข้อผิดพลาด สคริปต์จะหยุดและโยนข้อผิดพลาด บางครั้งนี่เป็นเรื่องปกติ แต่ในโอกาสอื่นๆ คุณอาจต้องการแสดงข้อผิดพลาดที่สามารถอ่านได้มากขึ้นหรือดำเนินการต่อ

ตัวอย่างเช่น เมื่อคุณอัปเดตผู้ใช้หลายรายใน Active Directory โดยใช้ ForEach loop เมื่อบัญชีผู้ใช้บัญชีใดบัญชีหนึ่งไม่มีอยู่ สคริปต์จะเกิดข้อผิดพลาดและหยุดทำงาน แต่วิธีแก้ปัญหาที่ดีกว่าคือถ้าสคริปต์แสดงชื่อผู้ใช้ที่ไม่ได้อัปเดตและดำเนินการต่อกับชื่อถัดไป นี่คือที่มาของบล็อก Try-Catch

จากตัวอย่างข้างต้น บล็อกโค้ดต่อไปนี้จะพยายามค้นหาและอัปเดตผู้ใช้ Azure AD หากเกิดข้อผิดพลาดในบล็อก Try ส่วน Catch จะแสดงข้อผิดพลาด

$users.ForEach{
  Try{
    # Find the user to update
    $ADUser = Get-AzureAdUser -SearchString $_.name
    
    # Update the job title
    Set-AzureAdUser -ObjectId $ADUser.ObjectId -JobTitle $_.jobtitle
  }
  Catch{
    Write-Host ("Failed to update " + $($_.name)) -ForegroundColor Red
  }
}

นี่คือการใช้งานขั้นพื้นฐานของบล็อก try-catch คุณยังสามารถใช้ catch block หลายบล็อกในคำสั่ง Try เดียว เพื่อให้คุณตรวจจับข้อผิดพลาดต่างๆ ได้ อ่านเพิ่มเติมเกี่ยวกับบล็อก Try-Catch ในบทความเชิงลึกนี้

การสร้างสคริปต์ PowerShell

ตอนนี้คุณควรมีความเข้าใจโดยย่อเกี่ยวกับเครื่องมือใดที่คุณสามารถใช้ได้ใน PowerShell เพื่อสร้างสคริปต์ มาดูกันว่าเรารวมสิ่งนี้เข้ากับสคริปต์ PowerShell ที่แท้จริงได้อย่างไร สำหรับตัวอย่างด้านล่าง เราจะสร้างสคริปต์ขนาดเล็กที่สร้างไฟล์ทดสอบในโฟลเดอร์ที่กำหนด

ด้านล่างนี้คุณจะพบหลักการพื้นฐานของสคริปต์ เรามีเส้นทางที่ฮาร์ดโค้ดในสคริปต์ อาร์เรย์ที่มีตัวเลข 1 ถึง 10 และลูป ForEach ด้วยตัวอย่างด้านล่าง เราจะปรับปรุงสคริปต์นี้เป็นสคริปต์ PowerShell ที่แท้จริง

$path = "C:\temp"

1..10 | ForEach-Object {
    $newFile = "$path\test_file_$_.txt";
    New-Item $newFile
}

การจัดทำเอกสารและความคิดเห็น

เมื่อสร้างสคริปต์ PowerShell เป็นความคิดที่ดีเสมอที่จะเพิ่มเอกสารประกอบให้กับสคริปต์ของคุณ เอกสารประกอบจะถูกวางไว้ที่ด้านบนของสคริปต์ของคุณในบล็อกความคิดเห็น และอธิบายการทำงานของสคริปต์ ตัวอย่างสองสามตัวอย่างเกี่ยวกับวิธีใช้สคริปต์ และบล็อกบันทึกย่อที่มีผู้เขียน เวอร์ชัน วันที่ ฯลฯ

ดังนั้นสำหรับสคริปต์ไฟล์ทดสอบของเรา เราสามารถเพิ่มคำอธิบายต่อไปนี้ที่ตอนต้นของไฟล์:

<#
  .SYNOPSIS
  Create test files in given directory

  .DESCRIPTION
  The script generates an x amount of text file based test file in the given folder. The files don't
  contain any content.

  .EXAMPLE
  CreateTestFiles.ps1 -path c:\temp -amount 50

  Create 50 files in c:\temp
  
  .NOTES
  Version:        1.0
  Author:         R. Mens - LazyAdmin.nl
  Creation Date:  04 oct 2022
  Modified Date:  
  Purpose/Change: Init
  Link:           https://lazyadmin.nl/powershell/powershell-scripting
#>

หากตอนนี้คุณรันคำสั่ง Get-Help ตามด้วยชื่อสคริปต์ใน PowerShell คุณจะได้รับคำอธิบายของสคริปต์ของคุณ:

อ่านเพิ่มเติมเกี่ยวกับความคิดเห็นและเอกสารประกอบใน PowerShell Best Practice Guide

พารามิเตอร์ Cmdlet

เมื่อใช้ PowerShell cmdlets คุณอาจสังเกตเห็นว่าส่วนใหญ่มาพร้อมกับพารามิเตอร์ที่เราสามารถตั้งค่าได้ ตัวอย่างเช่น เมื่อคุณต้องการรับกล่องจดหมายจาก Exchange Online คุณสามารถระบุชื่อผู้ใช้ด้วยพารามิเตอร์ -Identity เราสามารถทำได้เช่นเดียวกันในสคริปต์ PowerShell ของเราเองโดยการกำหนดแอตทริบิวต์พารามิเตอร์

ในตัวอย่างข้างต้น เราได้ฮาร์ดโค้ดตัวแปรพาธ หากคุณต้องการสร้างไฟล์ทดสอบในไดเร็กทอรีอื่น คุณจะต้องเปลี่ยนสคริปต์ ตัวเลือกที่ดีกว่าคือถ้าคุณสามารถกำหนดเส้นทางจากบรรทัดคำสั่งได้ ดังนั้นเราจะสร้างบล็อกพารามิเตอร์ โดยมีเส้นทางพารามิเตอร์:

param(
  [Parameter()]
  [string]$path
)

# Create files
1..10 | ForEach-Object {
    $newFile = "$path\test_file_$_.txt";
    New-Item $newFile
}

เราคาดว่าเส้นทางจะเป็นสตริง ตัวเลือกอื่นๆ เช่น สวิตช์ที่คุณสามารถเลือกค่าหรือจำนวนเต็มได้ หากคุณเปิด PowerShell และพิมพ์ชื่อไฟล์สคริปต์ คุณสามารถเพิ่มพารามิเตอร์ -path ได้ด้วย:

แต่จะเกิดอะไรขึ้นถ้าผู้ใช้สคริปต์ไม่ได้กำหนดเส้นทาง? ในกรณีนี้ เส้นทางเป็นสิ่งจำเป็น หากไม่มีเส้นทางดังกล่าว ไฟล์ทดสอบจะถูกสร้างขึ้นในตำแหน่งรากของสคริปต์ เพื่อให้บังคับ เราจะเพิ่มคุณสมบัติพารามิเตอร์ บังคับ และตั้งค่าเป็นจริง อีกทางเลือกหนึ่งคือการตั้งค่าเริ่มต้น:

param(
  [Parameter(
    Mandatory = $true,
    HelpMessage = "Enter path were test files should be created"
  )]
  [string]$path,

  [Parameter(
    HelpMessage = "How many files should be created"
  )]
  [int]$amount = 10
)

อ่าน-Host

สคริปต์ของเรากำลังจะสร้างไฟล์ข้อความในโฟลเดอร์ที่กำหนด หากผู้ใช้พิมพ์ผิด อาจเป็นไปได้ว่าสคริปต์จะสร้างไฟล์ 1,000 ไฟล์ แทนที่จะเป็น 100 ไฟล์ ดังนั้นก่อนที่เราจะสร้างไฟล์ อาจเป็นความคิดที่ดีที่จะขอคำยืนยัน สำหรับสิ่งนี้ เราจะใช้ cmdlet Read-Host

Read-Host ใช้เพื่อแจ้งให้ผู้ใช้ป้อนข้อมูล ซึ่งอาจเป็นสตริงหรือรหัสผ่านเป็นต้น ผลลัพธ์ของอินพุตสามารถตรวจสอบได้ด้วยการเปรียบเทียบง่ายๆ ในกรณีนี้ ขั้นแรกเราจะเขียนคอนโซลด้วยค่าที่ผู้ใช้กำหนดไว้ผ่านพารามิเตอร์ จากนั้นถามว่าผู้ใช้ต้องการดำเนินการต่อหรือไม่:

# Ask for confirmation
Write-host "Creating $amount test files in $path" -ForegroundColor Cyan
$reply = Read-Host -Prompt "Is this correct? [Y] Yes [N] No "

# Check the reply and create the files:
if ( $reply -match "[yY]" ) { 
    # Create files
    1..10 | ForEach-Object {
      $newFile = "$path\test_file_$_.txt";
      New-Item $newFile
    }
}

ฟังก์ชั่น

ฟังก์ชันเป็นวิธีที่ดีเยี่ยมในการจัดระเบียบและนำโค้ดบางส่วนกลับมาใช้ใหม่ภายในสคริปต์ของคุณ ฟังก์ชันควรทำงานเดียว คุณสามารถดูตัวอย่างที่ดีได้ในสคริปต์รายงานขนาด OneDrive นี้ ฟังก์ชัน ConvertTo-Gb รับค่าและแปลงเป็นกิกะไบต์และส่งกลับผลลัพธ์ หากคุณเลื่อนสคริปต์ลงไปเล็กน้อย คุณจะเห็นว่าฟังก์ชัน Get-OneDriveStats รวบรวม OneDrive ทั้งหมดและประมวลผลแต่ละรายการ ภายในลูป ForEach ฉันจะแปลงค่าโดยใช้ฟังก์ชัน ConvertTo-GB

โครงสร้างของฟังก์ชันโดยพื้นฐานแล้วจะเป็นสคริปต์ขนาดเล็ก เราเริ่มต้นด้วยคำอธิบายสั้น ๆ เรื่องย่อ หากเราต้องส่งค่าไปยังสคริปต์ เราจะใช้พารามิเตอร์ คุณอาจสังเกตเห็นว่าบางฟังก์ชันมีบล็อกโค้ด 3 บล็อก ได้แก่ เริ่มต้น ประมวลผล และสิ้นสุด บล็อกกระบวนการจะถูกดำเนินการสำหรับค่าทั้งหมดที่คุณส่งไปยังฟังก์ชัน และบล็อกเริ่มต้นและสิ้นสุดเพียงครั้งเดียวเท่านั้น ตอนนี้ต้องบอกเลยว่าไม่ได้ใช้ start และ end บ่อยนัก

ดังนั้นเราจะสร้างฟังก์ชันง่ายๆ สำหรับสคริปต์ไฟล์ทดสอบของเรา ฉันได้เพิ่มพารามิเตอร์ Path ในฟังก์ชันด้วย ไม่จำเป็นจริงๆ เพราะฟังก์ชันยังสามารถเข้าถึงพารามิเตอร์ที่เราตั้งค่าไว้ตอนต้นของสคริปต์ได้ด้วย (นี่เป็นมากกว่าเพื่อแสดงให้เห็นถึงความเป็นไปได้)

Function New-TestFiles{
  <#
    .SYNOPSIS
        Create test files
  #>
  param(
    [Parameter(Mandatory = $true)]
    [string]$path
  )
  1..$amount | ForEach-Object {
    $newFile = "$path\test_file_$_.txt";
    New-Item $newFile
  }
}

ตอนนี้เราสามารถใช้ฟังก์ชันในสคริปต์ของเราได้ดังนี้:

if ( $reply -match "[yY]" ) { 
    New-TestFiles -path $path
}

เบรกพอยท์

การพิมพ์ผิด คำพูดที่ถูกลืม หรือข้อผิดพลาดเล็กๆ น้อยๆ เกิดขึ้นได้อย่างง่ายดายเมื่อสร้างสคริปต์ PowerShell นั่นคือเหตุผลว่าทำไมการทดสอบสคริปต์ของคุณอย่างต่อเนื่องเมื่อคุณเขียนจึงเป็นเรื่องสำคัญ แต่ถึงอย่างนั้นบางครั้งการค้นหาสาเหตุของข้อผิดพลาดในสคริปต์ของคุณก็อาจเป็นเรื่องยาก

เพื่อช่วยคุณค้นหาข้อผิดพลาดในสคริปต์ของคุณ คุณสามารถใช้เบรกพอยท์ได้ หากคุณใช้โค้ด Visual Studio คุณสามารถใช้ฟังก์ชัน เรียกใช้และดีบักในตัว ได้ ซึ่งช่วยให้คุณสามารถตั้งค่าเบรกพอยต์บรรทัดและรันสคริปต์ของคุณทีละบรรทัด

ในโค้ด Visual Studio เราสามารถตั้งค่าเบรกพอยต์ได้โดยการคลิกที่จุดสีแดงก่อนหมายเลขบรรทัด ในภาพหน้าจอด้านล่าง ฉันได้ตั้งค่าเบรกพอยต์ (1) บน cmdlet New-Item ที่บรรทัด 46 เมื่อเราคลิกที่ Run (2) สคริปต์จะถูกดำเนินการและหยุดที่จุดพักที่บรรทัด 46 ในขณะนี้ เราจะเห็นตัวแปรทางด้านซ้าย (3) สิ่งนี้บอกเราว่าลูป ForEach-Object อยู่ที่รายการแรก และไฟล์ใหม่จะถูกสร้างขึ้นใน c:\temp\files โดยมี name test_file_1 .txt

ด้วยปุ่มที่ด้านบน (5) เราสามารถไปยังขั้นตอนถัดไป ข้ามขั้นตอน ฯลฯ

การใช้เบรกพอยต์ใน PowerShell

ตัวเลือกอื่นในการดีบักสคริปต์ PowerShell ของคุณคือการใช้ cmdlet Set-PSBreakpoint ในคอนโซล cmdlet นี้ช่วยให้คุณสามารถตั้งค่าเบรกพอยต์สำหรับสคริปต์ใด ๆ ที่คุณต้องการเรียกใช้ใน PowerShell ด้วย cmdlet เราสามารถตั้งค่าเบรกพอยท์บนหมายเลขบรรทัด การดำเนินการ หรือตัวแปรได้ ดังนั้นเรามาตั้งค่าเบรกพอยต์แบบเดียวกับที่เราทำใน Visual Studio Code:

# Set the breakpoint on line 46 for the script CreateTestFiles.ps1
Set-PSBreakPoint -Script .\CreateTestFiles.ps1 -Line 46

เมื่อเรารันสคริปต์ มันจะหยุดที่บรรทัด 46:

สคริปต์หยุดทำงานแต่ไม่แสดงอะไรเลย ดังนั้นเราจะเริ่มต้นด้วยการแสดงโค้ดรอบๆ เบรกพอยต์ของเรา เพียงพิมพ์ตัวอักษร L ในคอนโซล:

เครื่องหมายดอกจันบนบรรทัดที่ 46 ระบุจุดพักที่เราตั้งไว้ หากเราต้องการทราบว่าตัวแปรพาธคืออะไร หรือชื่อไฟล์ใหม่ เราสามารถพิมพ์ชื่อตัวแปรในคอนโซลแล้วกด Enter:

เราสามารถดูเบรกพอยต์ทั้งหมดที่เราตั้งค่าไว้ด้วย cmdlet Get-PSBreakpoint และลบออกด้วย Remove-PSBreakpoint การรวมทั้งสองอย่างเข้าด้วยกันจะลบเบรกพอยต์ทั้งหมด:

Get-PSBreakPoint | Remove-PSBreakpoint

ห่อขึ้น

เมื่อสร้างสคริปต์ PowerShell ให้เริ่มต้นจากเล็กๆ น้อยๆ และทดสอบสคริปต์ของคุณบ่อยๆ นอกจากนี้ ตรวจสอบให้แน่ใจว่าคุณได้เพิ่มความคิดเห็นลงในโค้ดของคุณตามที่จำเป็น ตอนนี้อาจชัดเจนแล้วว่าโค้ดเหล่านั้นคืออะไร แต่ถ้าคุณต้องการแก้ไขสคริปต์ในอีกหนึ่งปีต่อมา บางครั้งอาจเป็นปริศนาในการพิจารณาว่าสคริปต์ทำอะไรและทำงานอย่างไร

หากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ PowerShell หนังสือด้านล่างนี้ก็น่าอ่านจริงๆ นี่เป็นหนึ่งในสินค้าขายดีเมื่อพูดถึงการเรียนรู้ PowerShell:

  • พลังค์, ทราวิส (ผู้เขียน)
  • ภาษาอังกฤษ (ภาษาสิ่งพิมพ์)
  • 360 หน้า - 26/04/2022 (วันที่ตีพิมพ์) - Manning (ผู้จัดพิมพ์)

ในตัวอย่างด้านบน เราสร้างสคริปต์เล็กๆ ที่สร้างไฟล์ทดสอบ คุณจะพบสคริปต์ฉบับสมบูรณ์ด้านล่าง ดังที่ได้กล่าวไปแล้ว มันอาจเกินกำลังไปหน่อยสำหรับงานง่ายๆ เช่นนี้ แต่มันช่วยให้คุณมีแนวคิดในการสร้างสคริปต์ของคุณได้อย่างไร

<#
  .SYNOPSIS
  Create test files in given directory

  .DESCRIPTION
  The script generates an x amount (by default 10) of text file based test file in the 
  given folder. The files don't contain any content.

  .EXAMPLE
  CreateTestFiles.ps1 -path c:\temp -amount 50

  Create 50 files in c:\temp

  .NOTES
  Version:        1.0
  Author:         R. Mens - LazyAdmin.nl
  Creation Date:  04 oct 2022
  Modified Date:  
  Purpose/Change: Init
  Link:           https://lazyadmin.nl/powershell/powershell-scripting
#>

param(
  [Parameter(
    Mandatory = $true,
    HelpMessage = "Enter path were test files should be created"
  )]
  [string]$path,

  [Parameter(
    HelpMessage = "How many files should be created"
  )]
  [int]$amount = 10
)

Function New-TestFiles{
  <#
    .SYNOPSIS
        Create test files
  #>
  param(
    [Parameter(Mandatory = $true)]
    [string]$path
  )
  1..$amount | ForEach-Object {
    $newFile = "$path\test_file_$_.txt";
    New-Item $newFile
  }
}

# Ask for confirmation
Write-host "Creating $amount test files in $path" -ForegroundColor Cyan
$reply = Read-Host -Prompt "Is this correct? [Y] Yes [N] No "

if ( $reply -match "[yY]" ) { 
    New-TestFiles -path $path
}

ฉันหวังว่าบทความนี้จะมีประโยชน์ หากคุณมีคำถามใด ๆ เพียงแสดงความคิดเห็นด้านล่าง และกรุณาแบ่งปันถ้าคุณชอบมัน!

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