การเข้าใจ 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 อาจดูน่ากลัวในตอนแรก แต่ด้วยการฝึกฝนและความเข้าใจที่ลึกซึ้งขึ้น คุณจะพบว่ามันกลายเป็นเรื่องธรรมชาติในเส้นทางการเขียนสคริปต์ของคุณ