Entendendo a System.DirectoryServices.ResultPropertyCollection no PowerShell

Ao trabalhar com PowerShell e consultar o Active Directory, você pode encontrar um comportamento perplexo ao tentar acessar propriedades da System.DirectoryServices.ResultPropertyCollection. Neste post, vamos desvendar um problema comum encontrado ao buscar informações através de um DirectorySearcher—especificamente, por que duas saídas diferentes oferecem resultados inesperados. Vamos explorar o problema, sua raiz e como você pode resolvê-lo de maneira eficaz.

O Problema

Você configurou um script PowerShell que utiliza a classe DirectorySearcher para encontrar objetos de computador no Active Directory, mas está enfrentando discrepâncias na sua saída. Aqui está uma replicação simplificada do seu código:

$objSearcher = New-Object System.DirectoryServices.DirectorySearcher  
$objSearcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry  
$objSearcher.Filter = ("(objectclass=computer)")  
$computers = $objSearcher.findall()  

Quando você tenta imprimir os nomes dos computadores, observa as seguintes duas saídas:

$computers | %{
    "Nome do servidor entre aspas $_.properties.name" 
    "Nome do servidor sem aspas " + $_.properties.name 
}

E então:

$computers[0] | %{"$_.properties.name"; $_.properties.name}

O resultado mostra um nome de tipo para a propriedade quando incluído entre aspas (System.DirectoryServices.SearchResult.properties.name), mas um valor quando não. Compreender essa nuance é fundamental para dominar a recuperação de propriedades no PowerShell.

Por Que As Saídas Diferem?

A discrepância surge de como o PowerShell avalia variáveis e propriedades em strings. Quando você inclui $_ em uma string, o PowerShell vê isso como um objeto completo:

  • Contexto de Citação: Ao usar ";" na string, como em "Nome do servidor entre aspas $_.properties.name", o PowerShell não avalia a propriedade, mas faz referência ao método ToString do objeto, que, neste caso, padrão é o nome do tipo da propriedade.

  • Contexto Sem Citação: Por outro lado, quando você o usa sem aspas, como em "Nome do servidor sem aspas " + $_.properties.name, o PowerShell avalia a propriedade primeiro e depois a concatena à string. Assim, ele recupera o valor real armazenado na propriedade em vez do nome do tipo.

Corrigindo a Saída

Para recuperar o valor da propriedade pretendido enquanto dentro de uma string entre aspas, você pode invocar explicitamente a avaliação usando a sintaxe de subexpressão:

"Nome do servidor entre aspas $($_.properties.name)"  

Este uso de $() diz ao PowerShell para avaliar o que está dentro antes de prosseguir com o restante da string, resultando na saída correta que você esperava.

Explorando a Coleção de Propriedades de Resultado

Lembre-se, ao trabalhar com ResultPropertyCollection, você está lidando com uma coleção de propriedades. Você pode sempre explorar o modelo de objeto diretamente a partir da linha de comando do PowerShell. Por exemplo, canalizando $computers[0].properties para Get-Member revela informações sobre membros e propriedades disponíveis:

$computers[0].properties | Get-Member

Você pode observar a propriedade Values, que recupera um ICollection dos valores da propriedade. Essa exploração aprimora sua compreensão e permite que você navegue pelas propriedades de maneira mais eficaz.

Conclusão

Ao trabalhar com PowerShell e as System.DirectoryServices do Active Directory, é crucial entender como a avaliação de strings age sobre objetos e suas propriedades. Ao reconhecer os diferentes contextos nos quais essas propriedades são acessadas, você pode evitar confusões e recuperar as informações de que precisa no formato que espera.

Navegar em construções complexas do PowerShell como ResultPropertyCollection pode parecer assustador no início, mas com prática e uma compreensão mais profunda, você descobrirá que se torna algo natural em sua jornada de scripting.