การสร้างชื่อคุณสมบัติ PowerShell
เมื่อสัปดาห์ที่แล้วฉันได้เล่นกับโปรเจ็กต์ PowerShell ใหม่จาก Dave Carroll เพื่อใช้ Twitter จากพรอมต์ PowerShell โมดูลนี้เรียกว่า BluebirdPS และคุณสามารถติดตั้งได้จาก PowerShell Gallery โมดูลยังอยู่ในช่วงเริ่มต้นมากแต่ยังใช้งานได้ดีและน่าสนใจ เหตุผลที่คุณอาจพบว่าสิ่งนี้น่าสนใจไม่ได้อยู่ที่ Twitter มากนัก แต่เป็นเพราะ Dave ใช้ประโยชน์จาก Twitter API อย่างไร คุณอาจพบว่าตัวเองกำลังทำงานร่วมกับ API อื่นเพื่อสร้างเครื่องมือที่ใช้ PowerShell เมื่อคุณจัดการโปรเจ็กต์เหล่านี้ คุณจะต้องคิดถึง "ออบเจ็กต์ในไปป์ไลน์" เสมอ และส่วนหนึ่งของสิ่งนั้นหมายถึงการสร้างชื่อคุณสมบัติ PowerShell ที่เหมาะสม
ทำให้ผู้ใช้เป็นมิตร
เมื่อคุณสร้างเครื่องมือ PowerShell คุณต้องการให้เอาต์พุตใช้งานง่าย สำหรับผม นี่หมายถึงการมีชื่อทรัพย์สินที่ชัดเจน Dave มีคำสั่งในโมดูลเพื่อรับบัญชีผู้ใช้ Twitter นี่คือสิ่งที่เขียนไปยังไปป์ไลน์ในปัจจุบัน
เพื่อการสาธิต สมมติว่าคำสั่ง Get-TwitterUser คือโค้ดของคุณที่เรียกใช้ REST API และส่งคืนอ็อบเจ็กต์แบบกำหนดเองไปยังไปป์ไลน์
ชื่อคุณสมบัติส่วนใหญ่ชัดเจน แม้ว่าจะไม่เป็นมิตรกับ PowerShell มากนักก็ตาม คุณเรียกใช้คำสั่ง PowerShell ดั้งเดิมที่มีคุณสมบัติที่มีลักษณะเช่นนี้จำนวนกี่คำสั่ง มาแก้ไขปัญหานี้กัน
แปลง-PropertyName
ชื่อคุณสมบัติบางชื่อมีหลายคำโดยใช้ขีดล่างเป็นตัวคั่น นี่เป็นเรื่องปกติ แต่ฉันคิดว่า API บางตัวอาจสร้างคุณสมบัติเช่น default-profile ใน PowerShell ฉันขอยืนยันว่าชื่อคุณสมบัติที่ดีกว่าคือ DefaultProfile นี่เป็นวิธีหนึ่งในการเปลี่ยนแปลง
ก่อนอื่น ขอผมได้วัตถุตัวอย่างก่อน
$me = Get-TwitterUser -ScreenName jeffhicksฉันจะได้รับชื่อทรัพย์สินได้อย่างไร? PowerShell สร้างสิ่งที่เป็นนามธรรมมากมายภายใต้ประทุนเพื่อให้ใช้งานง่าย วัตถุที่แสดงโดย $me มีอีกเลเยอร์หนึ่ง
การรวบรวมคุณสมบัติมีประโยชน์ค่อนข้างมาก
หากต้องการ "กำหนด" ชื่อทรัพย์สินใหม่ ให้อธิบายกระบวนการในหัวของคุณหรือเขียนออกมา
- แบ่งชื่อบนตัวคั่น _
- สำหรับแต่ละองค์ประกอบในอาร์เรย์ให้ใช้ตัวอักษรตัวแรกเป็นตัวพิมพ์ใหญ่
- รวมอาร์เรย์กลับเป็นสตริงเดียวโดยไม่มีช่องว่าง
ฉันต้องการฟังก์ชัน PowerShell เพื่อให้งานนี้สำเร็จ อย่างที่คุณเห็นจากรายการของฉัน ฉันได้เขียนโค้ดหลักแล้ว
Function Convert-PropertyName {
Param(
[Parameter(Mandatory)]
[string]$Name,
#the character used as a delimiter in the native property name
[string]$Delimiter = "_"
)
#split on the underscore delimiter
$split = $name -split $Delimiter
#capitalize the first letter of each item in the array
for ($i=0;$i -lt $split.count;$i++) {
$split[$i] = "{0}{1}" -f $split[$i][0].ToString().ToUpper(),$split[$i].Substring(1)
}
#rejoin with no spaces and write the result to the pipeline
$split -join ""
}ฉันเขียนฟังก์ชันให้มีความยืดหยุ่นและไม่คิดว่าชื่อคุณสมบัติทั้งหมดจะใช้ขีดล่าง
การสร้างวัตถุ
เมื่อคำนึงถึงฟังก์ชันนี้แล้ว ฉันสามารถเขียนโค้ด PowerShell แบบง่ายๆ เพื่อสร้างออบเจ็กต์แบบกำหนดเองใหม่ได้
$me.psobject.properties | Foreach-object -Begin {
$newObj = [ordered]@{
PSTypeName = "BlueBirdUser"
}
} -process {
$newProp = Convert-PropertyName $_.Name
$newObj.Add($newProp,$_.value)
} -end {
#write the result as a custom object
[PSCustomObject]$newObj
}รหัสกำลังสร้าง hashtable ที่เรียงลำดับ จากนั้นเพิ่มรายการสำหรับชื่อคุณสมบัติที่แปลงแต่ละรายการและค่าที่เกี่ยวข้องจาก psobject ในตอนท้ายของ ForEach-Object ฉันจะเขียนวัตถุจริงลงในไปป์ไลน์
ฉันสามารถใช้โค้ดนี้และสร้างเครื่องมือรอบๆ โค้ด API หลักที่ตอนนี้เขียนออบเจ็กต์ PowerShell ที่ "ดีกว่า" ลงในไปป์ไลน์ ยังคงมีปัญหาที่อาจเกิดขึ้นกับมูลค่าทรัพย์สิน ตัวอย่างเช่น CreateAt เป็นสตริง ไม่ใช่ค่าวันที่และเวลา ซึ่งสามารถแก้ไขได้ในภายหลัง
อัปเดต TypeData
งานสุดท้ายที่คุณอาจต้องการดำเนินการคือปรับแต่งวิธีที่ PowerShell ใช้ออบเจ็กต์แบบกำหนดเองใหม่ของคุณ ตอนนี้โค้ดของฉันเขียนวัตถุที่มีคุณสมบัติทั้งหมด แม้ว่าสิ่งนั้นอาจมีประโยชน์ แต่ตามค่าเริ่มต้นแล้ว ผู้ใช้อาจต้องการดูคุณสมบัติบางส่วนเท่านั้น หรือคุณอาจต้องการปรับแต่งชื่อคุณสมบัติบางส่วนอย่างละเอียด ตัวอย่างเช่น ตอนนี้เอาต์พุตของฉันมีคุณสมบัติชื่อ StatusesCount ความหมายที่แท้จริงคือจำนวนทวีต การเปลี่ยนชื่อคุณสมบัตินั้นจะเป็นมิตรกับผู้ใช้มากกว่า
ทั้งหมดนี้เป็นจุดที่ Update-TypeData cmdlet เข้ามาในรูปภาพ ในการใช้ cmdlet นี้ ออบเจ็กต์ของคุณต้องมีชื่อประเภทที่กำหนดไว้และไม่ซ้ำกัน สิ่งนี้จะไม่ทำงานกับ pscustomobject ทั่วไป ในรหัสของฉัน คุณอาจสังเกตเห็นสิ่งนี้:
PSTypeName = "BlueBirdUser"ถ้าฉันรันโค้ดและไพพ์ไปที่ Get-Member ฉันจะเห็น TypeName ของ BlueBirdUser ซึ่งหมายความว่าฉันสามารถใช้ Update-TypeData ได้ ฉันเชื่อว่าคุณจะอ่านความช่วยเหลือและตัวอย่างฉบับเต็ม
ก่อนอื่น ฉันต้องการสร้างนามแฝงของคุณสมบัติบางส่วน PowerShell ทำสิ่งนี้ตลอดเวลาเพื่อคุณ
Update-TypeData -TypeName BlueBirdUser -MemberType AliasProperty -MemberName Followers -Value FollowersCount -force
Update-TypeData -TypeName BlueBirdUser -MemberType AliasProperty -MemberName Tweets -Value StatusesCount -Forceอีกขั้นตอนหนึ่งคือ ฉันต้องการกำหนดชุดคุณสมบัติเริ่มต้น เพื่อว่าเมื่อคำสั่งของฉันถูกรัน และวัตถุที่กำหนดเองเขียนลงในไปป์ไลน์ เว้นแต่ผู้ใช้จะขอสิ่งอื่นใด ก็จะแสดงชุดคุณสมบัติเริ่มต้น
Update-TypeData -TypeName BlueBirdUser -DefaultDisplayPropertySet "Name","ScreenName","ID","Location","Description","Followers","Tweets" -force
หากคุณกำลังสร้างโมดูล คุณอาจมี Convert-Property เป็นฟังก์ชันส่วนตัว และคำสั่งเช่นนี้เป็นฟังก์ชันสาธารณะ
Function Get-TwitterAccount {
[cmdletbinding()]
Param([string]$Username = "jeffhicks")
#Get-TwitterUser could be any REST API related code that creates an objecgt
$TwitterUser = Get-TwitterUser -ScreenName $UserName
$TwitterUser.psobject.properties | ForEach-Object -Begin {
$newObj = [ordered]@{
PSTypeName = "BlueBirdUser"
}
} -Process {
$newProp = Convert-PropertyName $_.Name
$newObj.Add($newProp, $_.value)
} -End {
#write the result as a custom object
[PSCustomObject]$newObj
}
}ตอนนี้ฉันมีเครื่องมือ PowerShell ที่เขียนออบเจ็กต์ที่เหมาะสมและมีโครงสร้างที่ดีลงในไปป์ไลน์ซึ่งฉันสามารถใช้ได้เหมือนกับคำสั่งอื่นๆ






