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

การสร้างชื่อคุณสมบัติ 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 ที่เขียนออบเจ็กต์ที่เหมาะสมและมีโครงสร้างที่ดีลงในไปป์ไลน์ซึ่งฉันสามารถใช้ได้เหมือนกับคำสั่งอื่นๆ

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