O que diabos está acontecendo com esse filtro AD no PowerShell?

9

Eu escrevi recentemente esta resposta e tropecei em algo interessante.

get-aduser -filter {-not (description -eq "auto")} | measure-object

e

get-aduser -filter {description -ne "auto"} | measure-object

retorna duas coisas muito diferentes quando executado com os mesmos dados, com o primeiro comando retornando o valor esperado. Aparentemente, à primeira vista, os usuários com um valor nulo no campo de descrição não são retornados como correspondências no segundo comando, embora NULL claramente não seja igual a "auto".

Algumas pessoas no chat olharam para isto e verificaram que não sou louco. O que está acontecendo aqui?

    
por MDMarra 10.01.2013 / 18:16

1 resposta

4

A principal diferença entre os dois é que o primeiro comando não envolve uma comparação direta de valores para obter todos os resultados, e o segundo comando o faz. O primeiro comando inclui resultados NULL e o segundo não (como o MDMarra já descobriu). Os dois comandos começam com este cmdlet:

get-aduser

Ao analisar o abaixo, lembre-se de que os resultados desse cmdlet incluem todos os usuários do AD, independentemente de qualquer outra coisa no parâmetro -filter após ele.

Agora vamos dividir as duas partes que são diferentes. O primeiro:

{-not (description -eq "auto")}

... significa

  1. "descobrir onde o atributo de descrição é igual a o texto string "auto". Para esta comparação funcionar, uma string precisa existir no campo de descrição do operador -eq para poder compará-lo para "auto". Valores NULL são eliminados desta comparação, uma vez que não é possível comparar um valor NULL com um valor de string.
  2. independentemente do parâmetro de filtro -eq me dá TUDO que NÃO é o resultado de (description -eq "auto") , que incluirá NULLs, porque o original cmdlet, get-aduser , inclui todos os usuários do AD. Ele não precisou comparar nada com o operador -not . Ele apenas deu a você tudo além dos resultados do filtro (description -eq "auto") .

No seu exemplo, suponha que você tenha 1 usuário AD com descrição igual a "auto", algumas centenas com algo diferente de "auto" e algumas centenas com descrições NULL. Percorrendo a lógica de comando, ele fará:

  1. Dê-me todos os usuários do AD (get-aduser) onde a descrição é igual a "auto" - resulta em 1 usuário
  2. Dê-me todos os usuários do AD que NÃO são o que você acabou de me dar - resultado é as poucas centenas com outra coisa E as poucas centenas que tem NULL.

Como não era necessário comparar nada com qualquer outra coisa usando o operador -not , o resultado incluiu os usuários da descrição NULOS que foram capturados no cmdlet get-aduser original.

O segundo comando:

{description -ne "auto"}

... significa

  1. "descobrir onde o atributo de descrição não é igual a a string exata" auto ". Novamente, para que essa comparação funcione, uma string precisa existir no campo de descrição do operador -ne para poder compará-lo para "auto". Valores NULL são eliminados desta comparação, uma vez que não é possível comparar um valor NULL com um valor de string.

No seu exemplo, suponha que você tenha 1 usuário AD com descrição igual a "auto", algumas centenas com algo diferente de "auto" e algumas centenas com descrições NULL. Percorrendo a lógica de comando, ele fará:

  1. Forneça a todos os usuários do AD onde a descrição não é igual a "auto" - resulta em algumas centenas de usuários com algo diferente de "auto" em sua descrição. Não puxa os usuários com descrições NULL porque não pode comparar um NULL a uma cadeia de texto.

De qualquer forma, toda a diferença entre os dois comandos é definitivamente não-intuitiva.

Usando este comando você deve ser capaz de capturar os NULLs com um "-e-" lá também assim:

{description -ne "auto" -and description -ne $NULL}

Eu não estou 100% na sintaxe, pois não posso testá-lo agora, e provavelmente há uma maneira melhor de fazê-lo do que isso também. Quando tudo está quebrado, é bastante anti-climático e precisei de muita digitação para explicar, mas eu me deparei com coisas estranhas como essa antes de usar os vários operadores e muitas tentativas e erros, já que eu nunca consigo me lembrar de todas as advertências. que vão junto com o uso de cada um.

Referência: link :

Comparison Operators

Use comparison operators (-eq, -ne, -gt, -lt, -le, -ge) to compare values and test conditions. For example, you can compare two string values to determine whether they are equal.

The comparison operators include the match operators (-match, -notmatch), which find patterns by using regular expressions; the replace operator (-replace), which uses regular expressions to change input values; the like operators (-like, -notlike), which find patterns using wildcard characters (*); and the containment operators (in, -notin, -contains, -notcontains), which determine whether a test value appears in a reference set.

They also include the bitwise operators (-bAND, -bOR, -bXOR, -bNOT) to manipulate the bit patterns in values.

For more information, see about_Comparison_Operators

Logical Operators

Use logical operators (-and, -or, -xor, -not, !) to connect conditional statements into a single complex conditional. For example, you can use a logical -and operator to create an object filter with two different conditions.

For more information, see about_Logical_Operators.

    
por 14.01.2013 / 22:27

Tags