การเข้าใจ System.DirectoryServices.ResultPropertyCollection
ใน PowerShell
เมื่อทำงานกับ PowerShell และการเรียกข้อมูลจาก Active Directory คุณอาจพบพฤติกรรมที่ทำให้สับสนเมื่อพยายามเข้าถึงคุณสมบัติจาก System.DirectoryServices.ResultPropertyCollection
ในโพสต์นี้ เราจะไขปัญหาที่เกิดขึ้นทั่วไปเมื่อดึงข้อมูลผ่าน DirectorySearcher
โดยเฉพาะเหตุผลที่ผลลัพธ์สองประเภทให้ผลที่คาดไม่ถึง ลองมาสำรวจปัญหา สาเหตุและวิธีที่คุณสามารถแก้ไขมันได้อย่างมีประสิทธิภาพ
ปัญหา
คุณได้ตั้งค่า PowerShell สคริปต์ที่ใช้คลาส DirectorySearcher
เพื่อค้นหาออบเจ็กต์คอมพิวเตอร์ใน Active Directory แต่คุณพบความแตกต่างในผลลัพธ์ของคุณ นี่คือตัวอย่างโค้ดที่ทำซ้ำได้อย่างง่าย:
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher.Filter = ("(objectclass=computer)")
$computers = $objSearcher.findall()
เมื่อคุณพยายามพิมพ์ชื่อคอมพิวเตอร์ คุณสังเกตเห็นผลลัพธ์สองประเภทดังต่อไปนี้:
$computers | %{
"Server name in quotes $_.properties.name"
"Server name not in quotes " + $_.properties.name
}
และจากนั้น:
$computers[0] | %{"$_.properties.name"; $_.properties.name}
ผลลัพธ์แสดงชื่อประเภทสำหรับคุณสมบัติเมื่อรวมอยู่ในเครื่องหมายคำพูด (System.DirectoryServices.SearchResult.properties.name
) แต่จะให้ค่าเมื่อไม่อยู่ในเครื่องหมายคำพูด การเข้าใจรายละเอียดนี้ถือเป็นกุญแจสำคัญในการทำความเข้าใจการเรียกคืนคุณสมบัติใน PowerShell
ทำไมผลลัพธ์ถึงแตกต่างกัน?
ความแตกต่างเกิดจากวิธีที่ PowerShell ประเมินตัวแปรและคุณสมบัติในสตริง เมื่อคุณรวม $_
ในสตริง PowerShell จะมองว่าเป็นวัตถุทั้งหมด:
-
บริบทที่มีเครื่องหมายคำพูด: เมื่อใช้
";"
ในสตริง เช่นใน"Server name in quotes $_.properties.name"
PowerShell จะไม่ ประเมินคุณสมบัติแต่สร้างการอ้างอิงถึงวิธีToString
ของวัตถุซึ่งในกรณีนี้จะต้องเป็นชื่อประเภทของคุณสมบัติ -
บริบทที่ไม่มีเครื่องหมายคำพูด: ในทางกลับกัน เมื่อคุณใช้มันโดยไม่ต้องใช้เครื่องหมายคำพูด เช่นใน
"Server name not in quotes " + $_.properties.name
PowerShell จะประเมินคุณสมบัติแรกแล้วทำการต่อเข้ากับสตริง ดังนั้นมันจึงดึงค่าจริงที่เก็บในคุณสมบัติมากกว่าชื่อประเภท
การแก้ไขผลลัพธ์
เพื่อดึงค่าของคุณสมบัติที่ตั้งใจไว้ขณะอยู่ในสตริงที่มีเครื่องหมายคำพูด คุณสามารถเรียกใช้การประเมินอย่างชัดเจนโดยใช้ไวยากรณ์ subexpression:
"Server name in quotes $($_.properties.name)"
การใช้ $()
นี้จะบอก PowerShell ให้ประเมินสิ่งที่อยู่ภายในก่อนที่จะดำเนินการกับส่วนที่เหลือของสตริง ส่งผลให้ได้ผลลัพธ์ที่ถูกต้องตามที่คาดหวัง
การสำรวจ Result Property Collection
จำไว้ว่าหมายเมื่อทำงานกับ ResultPropertyCollection
คุณกำลังจัดการกับคอลเลกชันของคุณสมบัติ คุณสามารถสำรวจโมเดลวัตถุโดยตรงจากบรรทัดคำสั่ง PowerShell ได้เสมอ ตัวอย่างเช่น การส่งออก $computers[0].properties
ไปยัง Get-Member
จะเปิดเผยข้อมูลเกี่ยวกับสมาชิกและคุณสมบัติที่มีอยู่:
$computers[0].properties | Get-Member
คุณสามารถเห็นคุณสมบัติ Values
ซึ่งใช้ดึง ICollection
ของค่าของคุณสมบัติ การสำรวจนี้ช่วยเพิ่มความเข้าใจของคุณและทำให้คุณนำทางผ่านคุณสมบัติได้อย่างมีประสิทธิภาพมากขึ้น
สรุป
เมื่อทำงานกับ PowerShell และ Active Directory’s System.DirectoryServices
เป็นเรื่องสำคัญในการเข้าใจว่าการประเมินสตริงนั้นกระทำต่อวัตถุและคุณสมบัติอย่างไร โดยการตระหนักถึงบริบทที่แตกต่างกันในขณะที่เข้าถึงคุณสมบัติเหล่านี้ คุณสามารถหลีกเลี่ยงความสับสนและดึงข้อมูลที่คุณต้องการในรูปแบบที่คุณคาดหวังได้
การนำทางผ่านการสร้าง PowerShell ที่ซับซ้อนเช่น ResultPropertyCollection
อาจดูน่ากลัวในตอนแรก แต่ด้วยการฝึกฝนและความเข้าใจที่ลึกซึ้งขึ้น คุณจะพบว่ามันกลายเป็นเรื่องธรรมชาติในเส้นทางการเขียนสคริปต์ของคุณ