PowerShell HashTable - ทุกสิ่งที่คุณจำเป็นต้องรู้
Hashtables ใน PowerShell สามารถใช้เพื่อจัดเก็บข้อมูลในลักษณะที่มีโครงสร้าง ซึ่งทำได้โดยใช้คู่คีย์/ค่าที่ช่วยให้คุณสามารถดึงข้อมูลที่จำเป็นจากแฮชเทเบิลได้อย่างง่ายดาย คุณสามารถเปรียบเทียบแฮชเทเบิลใน PowerShell กับอาเรย์ที่เชื่อมโยงได้หากต้องการ
Hashtables ถูกใช้ค่อนข้างบ่อยใน PowerShell เนื่องจากเป็นวิธีที่ดีในการจัดเก็บและประมวลผลข้อมูล ข้อดีของ hashtable คือคีย์และค่าสามารถเป็นอ็อบเจกต์ประเภทใดก็ได้ ดังนั้นคุณจึงไม่ได้จำกัดอยู่เพียงจำนวนเต็มและสตริง แต่คุณสามารถสร้างแฮชเทเบิลแบบซ้อนได้ เป็นต้น
ในบทความนี้ เราจะดูแฮชเทเบิลและวิธีใช้ในสคริปต์ PowerShell ของคุณ
Hashtable กับอาร์เรย์
ก่อนที่เราจะดู hashtables ก่อนอื่นเรามาอธิบายความแตกต่างระหว่าง hashtables และ array กันก่อน นี่เป็นคำถามที่มักถูกถาม และผู้คนมักจะสับสนระหว่างทั้งสอง
อาร์เรย์คือรายการค่าที่จัดทำดัชนีไว้ ดัชนีจะถูกสร้างขึ้นโดยอัตโนมัติเมื่อคุณเพิ่มค่าให้กับอาร์เรย์ ดังนั้นคุณไม่สามารถควบคุมตำแหน่งที่คุณจัดเก็บข้อมูลในอาร์เรย์ได้
$array = @('apple','raspberry','kiwi')
เราสามารถเข้าถึงรายการในอาร์เรย์ได้โดยการวนซ้ำหรือเข้าถึงรายการตามหมายเลขดัชนี:
$array | Foreach { Write-Host $_ }
# Result
apple
raspberry
kiwi
# Or by index number
write-host $array[1]
# Result
raspberryเรายังสามารถเพิ่มหรืออัปเดตค่าในอาร์เรย์ได้ แต่เราไม่สามารถเปลี่ยนแปลงหรือกำหนดหมายเลขดัชนีของรายการได้:
# Replace the raspberry with melon
$array[1] = 'melon'
# Add a fruit to the array
$array += 'banana'แฮชเทเบิล
ดังที่เราได้เห็นแล้วว่าอาร์เรย์เป็นเพียงรายการ (คอลเลกชัน) ของรายการ ซึ่งเราสามารถเพิ่ม แก้ไข หรือลบออกจากรายการได้ ดัชนีจะถูกสร้างขึ้นโดยอัตโนมัติเมื่อคุณเพิ่มรายการลงไป ในทางตรงกันข้าม ด้วย PowerShell HashTable เราจะต้องกำหนดดัชนี (คีย์) ของค่าที่เราต้องการเพิ่ม
ในการสร้างแฮชเทเบิล เราใช้ {} แทน ():
# Creating a hashtable
$serverIps= @{}
# Or creating a pre-populate hashtable
$serverIps= @{
'la-srv-lab02' = '192.168.10.2'
'la-srv-db01' = '192.168.10.100'
}ในการเพิ่มที่อยู่ IP ของเซิร์ฟเวอร์ลงในแฮชเทเบิล เราจะต้องกำหนดคีย์ เราไม่สามารถทำเพียงแค่ $hashtable.add('value') ได้ เนื่องจาก hashtable จะไม่สร้างดัชนีโดยอัตโนมัติ
$key = 'la-srv-lab01'
$value = '192.168.10.1'
$serverIps.add($key,$value)
# Or simply
$serverIps.add('la-srv-lab03','192.168.10.3')
# Result:
$serverips
Name Value
---- -----
la-srv-lab03 192.168.10.3
la-srv-lab01 192.168.10.1คีย์ในกรณีนี้คือชื่อเซิร์ฟเวอร์และค่าที่อยู่ IP ของเซิร์ฟเวอร์ หากเราต้องการที่อยู่ IP ของเซิร์ฟเวอร์ lab03 เราก็สามารถดำเนินการดังต่อไปนี้:
การดึงข้อมูลจาก Hashtable
ในการดึงข้อมูลจากแฮชเทเบิลใน PowerShell เราสามารถระบุคีย์ ซึ่งจะส่งคืนค่าของคีย์:
$serverIps['la-srv-lab03']
# Result
192.168.10.3อีกทางเลือกหนึ่งคือการวนซ้ำผ่านแฮชเทเบิล แต่วิธีนี้ทำงานแตกต่างออกไปเล็กน้อยเมื่อเปรียบเทียบกับอาเรย์ หากเราเพียงแค่ไพพ์ foreach ไว้ด้านหลัง hashtable คุณจะสังเกตได้ว่ามันจะส่งคืนเฉพาะวัตถุ hashtable เท่านั้น:
$serverIps | foreach {write-host $_}
System.Collections.Hashtableหากต้องการรับเฉพาะค่าจาก hashtable เราสามารถใช้คุณสมบัติ .value:
# Return only the values
$serverIps.values
# Or pipe them in a foreach to ping the servers for example:
$serverIps.values | foreach {ping $_}เมื่อทำงานกับแฮชเทเบิล คุณอาจต้องการดึงข้อมูลเป็นคู่คีย์/ค่าด้วย สำหรับสิ่งนี้ เราสามารถใช้ฟังก์ชัน GetEnumerator:
$serverIps.GetEnumerator() | ForEach-Object {
$result = '{0} IP address is {1}' -f $_.key, $_.value
write-host $result
}
# Result
la-srv-lab03 IP address is 192.168.10.3
la-srv-lab01 IP address is 192.168.10.1กำลังอัปเดตค่า
การอัปเดตค่าใน hashtable สามารถทำได้โดยใช้คีย์เพื่อเลือกคู่คีย์/ค่าที่ถูกต้อง:
$serverIps['la-srv-lab03'] = '192.168.10.5'หากคุณต้องการอัปเดตหลายค่าใน hashtable คุณไม่สามารถใช้ ForEach loop เพื่อวนซ้ำผ่าน hashtable ได้ ตัวอย่างเช่น สิ่งนี้จะไม่ทำงาน:
$serverIps.Keys | ForEach-Object {
$serverIps[$_] = '192.168.10.20'
}ก่อนอื่นคุณจะต้องโคลนคีย์ก่อนจึงจะสามารถอัปเดตค่าได้:
$serverIps.Keys.Clone() | ForEach-Object {
$serverIps[$_] = '192.168.10.20'
}การลบคีย์หรือค่า
หากต้องการลบคู่คีย์/ค่าออกจาก hashtable โดยสมบูรณ์ คุณสามารถใช้ฟังก์ชัน .remove คุณจะต้องระบุรหัสที่คุณต้องการลบ:
$serverIps.Remove('la-srv-lab03')นอกจากนี้ยังสามารถลบเฉพาะค่าออกจากคีย์ได้:
$serverIps['la-srv-lab03'] = $nullหากต้องการล้าง hashtable โดยสมบูรณ์ คุณมีสองตัวเลือก คุณสามารถสร้างอินสแตนซ์ hashtable ใหม่หรือใช้ฟังก์ชัน clear อย่างหลังเป็นที่ต้องการเพราะจะทำให้โค้ดของคุณอ่านง่ายขึ้น
# Recreate the hashtable instance
$serverIps = @{}
# Better option for readability, use the clear function
$serverIps.clear()สาดแฮชเทเบิล
cmdlet บางตัวใน PowerShell ต้องการคุณสมบัติมากมายที่โดยทั่วไปแล้วเราทุกคนเขียนไว้ในบรรทัดเดียว ซึ่งอาจทำให้สคริปต์ PowerShell ของคุณอ่านยากขึ้น เนื่องจากคุณอาจต้องเลื่อนในแนวนอนเพื่อดูคำสั่งทั้งหมด
ตัวอย่างเช่น เมื่อคุณต้องการส่งอีเมลจาก PowerShell คุณจะต้องมีพารามิเตอร์เป็นบรรทัดยาว
Send-MailMessage -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เพื่อให้อ่านง่ายขึ้น เราสามารถใช้แฮชเทเบิลและทำเครื่องหมายไว้ Splatting จะแทนที่พารามิเตอร์และค่าทั้งหมดด้วยตัวแปรตัวเดียว โปรดทราบว่าเราใช้สัญลักษณ์ @ เพื่อระบุตัวแปรแทน $
$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
}
# Note the @ infront of mail, instead of $
Send-MailMessage @mailอย่างที่คุณเห็น การสาดจะทำให้โค้ดของคุณอ่านและบำรุงรักษาได้ง่ายขึ้น แทนที่จะต้องใช้พารามิเตอร์เป็นแถวยาวๆ
การสร้างวัตถุจาก Hashtables
Hashtables มีประโยชน์มากเมื่อคุณต้องการจัดโครงสร้างข้อมูลสำหรับออบเจ็กต์เดียวหรือสำหรับการแบ่งแยก แต่สิ่งเหล่านี้ไม่ใช่ออบเจ็กต์ที่แท้จริง Hashtables มีเพียงสองคอลัมน์ คีย์ และค่าเท่านั้น ดังนั้นเราจึงสามารถสร้างแฮชเทเบิลที่มีข้อกำหนดเฉพาะของเซิร์ฟเวอร์เดียว แต่เมื่อเราต้องการจัดเก็บข้อมูลเกี่ยวกับเซิร์ฟเวอร์หลายเครื่อง เราก็พบกับข้อจำกัด (เช่น เราไม่สามารถนำชื่อคอลัมน์กลับมาใช้ซ้ำได้)
ดังนั้นวิธีที่ดีกว่าในการจัดโครงสร้างข้อมูลของคุณเมื่อคุณมีหลายรายการคือการใช้ออบเจ็กต์ วิธีที่ง่ายที่สุดในการสร้างออบเจ็กต์ใน PowerShell คือการแปลงแฮชเทเบิลเป็นออบเจ็กต์ PowerShell แบบกำหนดเอง เราทำสิ่งนี้โดยเพิ่ม [pscustomobject] ไว้หน้าแฮชเทเบิล
ยกตัวอย่างต่อไปนี้ อันดับแรกเราสร้างแฮชเทเบิลที่มีข้อกำหนดเฉพาะของเซิร์ฟเวอร์:
$servers = @{
'name' = 'la-srv-db01'
'ip' = '192.168.10.100'
'model' = 'Hp DL380 G10'
'memory' = '96Gb'
}
# Result
Name Value
---- -----
memory 96Gb
ip 192.168.10.100
name la-srv-db01
model Hp DL380 G10อย่างที่คุณเห็น เรามีเพียงสองคอลัมน์ ชื่อ และค่าเท่านั้น แฮชเทเบิลแสดงถึงเซิร์ฟเวอร์เดียวและเราไม่สามารถใช้มันเพื่อสร้างรายการเซิร์ฟเวอร์ได้
อย่างไรก็ตาม หากเราแปลงแฮชเทเบิลเป็นออบเจ็กต์ PowerShell แบบกำหนดเอง เราจะได้ตารางจริงซึ่งเรามีหลายคอลัมน์
$servers = [pscustomobject]@{
'name' = 'la-srv-db01'
'ip' = '192.168.10.100'
'model' = 'Hp DL380 G10'
'memory' = '96Gb'
}
# Result
name ip model memory
---- -- ----- ------
la-srv-db01 192.168.10.100 Hp DL380 G10 96Gb ตอนนี้เราสามารถเพิ่มเซิร์ฟเวอร์อื่นให้กับ pscustomobject ได้เช่นกัน:
function servers {
[pscustomobject]@{
'name' = 'la-srv-db01'
'ip' = '192.168.10.100'
'model' = 'Hp DL380 G10'
'memory' = '96Gb'
}
[pscustomobject]@{
'name' = 'la-srv-lab03'
'ip' = '192.168.10.3'
'model' = 'Hp DL180 G9'
'memory' = '32Gb'
}
}
servers
# Result
name ip model memory
---- -- ----- ------
la-srv-db01 192.168.10.100 Hp DL380 G10 96Gb
la-srv-lab03 192.168.10.3 Hp DL180 G9 32Gbการส่งออก Hashtable เป็น CSV
เมื่อคุณส่งออกแฮชเทเบิลเป็น CSV คุณจะสังเกตเห็นว่าตามค่าเริ่มต้นคีย์และค่าไม่ได้ถูกส่งออก ผลลัพธ์จะมีข้อมูลเกี่ยวกับออบเจ็กต์แฮชเท่านั้น ไม่ใช่ข้อมูลภายในแฮชเทเบิล
หากต้องการส่งออกเนื้อหาของแฮชเทเบิล คุณจะต้องใช้วิธี GetEnumerator เช่นเดียวกับที่เราทำกับการดูเนื้อหาของแฮชเทเบิ้ล เราต้องการเพียงคีย์และค่าจากแฮชเทเบิล ดังนั้นคุณจะต้องเพิ่มการเลือกให้กับคำสั่งด้วย
$serverIps= @{
'la-srv-lab02' = '192.168.10.2'
'la-srv-db01' = '192.168.10.100'
'la-srv-lab03' = '192.168.10.3'
}
$serverIps.GetEnumerator() | Select Key, Value | Export-CSV -path c:\temp\hash.csv -Noห่อขึ้น
Hashtables ใน PowerShell เป็นวิธีที่ยอดเยี่ยมในการจัดโครงสร้างข้อมูลหรือใช้ร่วมกับการแบ่งส่วน อย่างไรก็ตาม โปรดทราบว่ามีไว้เพื่อใช้สำหรับสินค้าชิ้นเดียวเท่านั้น เราไม่สามารถสร้างคอลัมน์ที่กำหนดเองหรือจัดเก็บหลายแถวด้วยคีย์เดียวกันได้ เพื่อสิ่งนั้น คุณจำเป็นต้องใช้ PowerShell Objects แบบกำหนดเองจริงๆ
ฉันหวังว่าบทความนี้จะมีประโยชน์ หากคุณมีคำถามใด ๆ เพียงแสดงความคิดเห็นด้านล่าง
หากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ PowerShell ตรวจสอบให้แน่ใจว่าคุณได้อ่านคำสั่ง PowerShell 10 อันดับแรกที่คุณต้องรู้ด้วย
