Windows PowerShell Filtro à esquerda, formato à direita

Don Jones

Sumário

Filtrar esquerda — na fonte de
Formatar direita — e você está pronto com ele
Nos bastidores

Na lista de endereçamento Windows PowerShell MVP Most Valuable Professional (), nós recentemente foi discutir — e tentar documento — Windows PowerShell “ armadilhas. ” Você sabe o que queremos dizer: As pequenas coisas que don’t funcionam exatamente da maneira que você acha que fariam — e que realmente pode causar problemas quando aprender o shell.

Duas das armadilhas maiores envolvem filtros e formatação. Mencionei na lista que tentei ajudar a evitar problemas nessas áreas, lembre-se a "Filtrar à esquerda, direita Formatar." pessoal Ele me ocorreu que a frase pode ser uma boa base para uma coluna na utilização mais eficiente do Windows PowerShell — então, aqui estamos.

Filtrar esquerda — na fonte de

Uso livre do Active Directory (AD) cmdlets de gerenciamento da Quest (você pode encontrá-los em quest.com/powershell) muito e incentivar outras pessoas para usá-los, muito. Um cmdlet, Get-QADUser, foi projetado para recuperar os usuários do AD. Ver as pessoas a executar um comando como esse não é incomum que:

Get-QADUser | Where-Object { $_.Department -eq "Sales" } | Set-QADUser -department "Inside Sales"

Isso seria alterar todos cujo atributo Department AD está definido para vendas, para que o atributo foi definido para vendas interna. O problema é onde a filtragem está acontecendo. Será o primeiro cmdlet, Get-QADUser para recuperar cada usuário único de todo o domínio.

Felizmente, ele não irá recuperar todos os atributos de cada usuário por padrão, mas em um domínio grande, ele fará mais suficiente danos como o controlador de domínio ruim lutas (DC) para transmitir informações de conta de usuário para o computador cliente. Em seguida, seu cliente deve examinar cada conta, um de cada vez e descartar aqueles que não têm um atributo de departamento contendo o valor de vendas. Que um desperdício!

É por isso que eu gostaria de "Filtrar à esquerda." Sempre mover critérios de filtragem como muito para a esquerda da linha de comando ele como possible.In nesse caso, o cmdlet Get-QADUser próprio acontece com suporte à filtragem:

Get-QADUser -Department "Sales" | Set-QADUser -department "Inside Sales"

Não há nenhuma necessidade para o cmdlet Where-Object. Melhor ainda, usando essa sintaxe, Get-QADUser é transmitir os critérios de filtro para o controlador de domínio e o controlador de domínio é recuperar e transmitir apenas as contas que coincidirem com esse critério. Controladores de domínio são fantásticas na filtragem — eles fazem-lo dia inteiro, realmente — portanto, nós estiver colocando a filtragem no melhor local possível para execução rápida. O cliente não terá de lidar com quantos objetos provenientes de DC, portanto, o comando será executado mais rápido e eficiente.

Aqui está outro exemplo, usando a WMI (Instrumentação de gerenciamento do Windows):

Get-WmiObject CIM_DataFile -computerName Server2 | Where { $_.FileName -like "*.dll" }

Isso será contato do WMI no Server2, obter todas as instâncias da classe CIM_DataFile — que representa os arquivos no disco rígido — e filtrar aqueles que não são arquivos DLL. Assim você está à esquerda com uma lista de arquivos DLL no servidor. Mas isso vai levar tempo para executar — você está colocando todas as informações do arquivo do servidor ao seu computador. Novamente, ajuda a mover filtragem mais à esquerda e, nesse caso, é possível fazer isso:

Get-WmiObject CIM_DataFile -computerName Server2 -filter "FileName LIKE '*.dll'"

Você precisará usar sintaxe de filtro ligeiramente diferente porque essa sintaxe não está sendo executada pelo Windows PowerShell. Em vez disso, ele está sendo transmitido para WMI no computador remoto. Ainda levará tempo para executar, mas envolverá menos tráfego de rede e, basicamente, menos sobrecarga no Server2 e seu computador. Obter o hábito de leitura dos cmdlets(Ajuda Get-WmiObject, neste caso) arquivos de Ajuda para ver quais opções de filtragem oferece um cmdlet. Somente dependem Where-Object quando o Get-* cmdlet que você está usando não oferece suporte a filtragem que você precisa.

Formatar direita — e você está pronto com ele

Outro problema está relacionado a formatar-* cmdlets, como Format-Table e Format-List. Eu verá novatos executar algo assim:

Get-Process | Format-Table ID,VM,Name | Export-CSV c:\processes.csv

Ele não funcionará. AH, ele será executado, mas você não gostar dos resultados. E se você fizer um segundo para realmente ler esse comando, você deve estar imaginando exatamente o que você esperava que acontecesse assim mesmo. Você tiver chegado um monte de processos, formatado-los como uma tabela — e, em seguida, você deseja a tabela para se tornar um arquivo .csv alguma forma? Se o objetivo final é obter um arquivo .csv que contém apenas certas propriedades do objeto, você poderia executar isso:

Get-Process | Select-Object ID,VM,Name | Export-CSV c:\processes.csv

Se o objetivo é obter uma tabela formatada, coluna em um arquivo de texto, você faria isso:

Get-Process | Format-Table ID,VM,Name | Out-File c:\processes.txt

Mas não pode misturar e corresponder essas duas abordagens. Noções básicas sobre por que é isso requer algumas informações básicas sobre como funcionam esses cmdlets de formato, juntamente com como saída-* trabalho cmdlets.

Pipeline do Windows PowerShell — que é o que os comandos executam em - é codificado para terminar no Out-Default cmdlet. Esse cmdlet pouco mais de redirecionar objetos Out-Host, que é responsável por exibir a saída na tela.

Qualquer linha de comando — ou pipeline, para usar o termo correto — que não terminam em uma saída-* cmdlet, por padrão, terminará em Out-Default, que é o mesmo que informando que ele termina em Out-Host. O truque é que a saída-* cmdlets não sabe o que fazer com objetos — eles precisam desses objetos transformados em instruções de formatação. Portanto, quando Out-Host obtém objetos de processo, ele envia esses objetos para um formato-* cmdlets. Qual deles usa — tabela, Wide, personalizado ou lista — baseia-se um conjunto de regras que não conseguir cobrir nesta coluna. Mas ele envia os objetos para um deles e Format-* cmdlet leva os objetos e produz instruções de formatação. Saída-* cmdlets sabem como consumir essas instruções de formatação e eles usá-los para criar qualquer exibição é necessária.

Então, vamos colocar que em termos práticos: Há três ou quatro principal saída-* cmdlets que você irá encontrar e usar regularmente: Out-Host, Out-File, Out-Printer e Out-String.

Esses são projetados para consumir apenas instruções de formatação e execute as instruções para construir uma exibição de tela, um arquivo de texto, uma página de impressora ou uma seqüência de caracteres, respectivamente. A única maneira de obter essas instruções de formatação é executar objetos por meio de um formato-* cmdlet — e instruções de formatação são a única coisa Formatar-* cmdlets produzir. Então, quando você executar isso:

Get-Process | Format-Table ID,VM,Name |Export-CSV c:\processes.csv

o que vai para o arquivo .csv é as instruções de formatação produzidas pelo Format-Table — provavelmente não em todos os que você esperava. Depois de executar uma formatação-* cmdlet, os objetos originais serão perdidos e você está à esquerda com instruções de formatação. Eis aqui outra regra simples para você: Formate à direita. Em outras palavras, enviar o cmdlet formatação a extrema direita da linha de comando. A única coisa que pode vir após um formato-* cmdlet é um retorno de carro ou uma saída-* cmdlet. É por isso que isso é legal:

Get-Process | Format-Table ID,VM,Name | Out-File c:\processes.txt

Out-File sabe como ler as instruções de formatação e usá-los para criar um arquivo de texto. Isso também é legal:

Get-Process | Format-Table ID,VM,Name 

Aqui, depender Out-Default embutida, que redirecionará para Out-Host, que sabe como consumir instruções de formatação e criar uma exibição de texto na janela do host ou console. Manter a formatação como muito para a direita possível, seguido por nada ou por uma saída-* cmdlet e você estará bem.

Uma dica mais: Nada deve seguir uma saída-* cmdlet porque, com apenas uma exceção, nenhum deles emitir objetos para o pipeline. Não há nenhum sentido em ter nada execute uma saída-* cmdlet, porque nada virá dele.

Nos bastidores

Espero que eu já tiver ajudado você compreender por que essas armadilhas são a maneira como eles são. Mas, na pior das hipóteses, lembrar "Filtrar à esquerda, formato direita"e você poderá ficar longe do problema evitando as armadilhas inteiramente.

Muitas das sutilezas pouco do Windows PowerShell se tornam mais fácil entender uma vez que você realmente entenda como e por que o shell funciona da maneira ele faz. Demorando para saber o que está acontecendo nos bastidores — e aplicar esse conhecimento sempre que você está obtendo resultados inesperados no shell — rapidamente tornará um especialista do Windows PowerShell.

Don Jones é um da nação treinadores mais experientes do Windows PowerShell e gravadores. Blogs de he semanal Windows PowerShell dicas em ConcentratedTech.com; você também pode entre em contato com ele ou perguntas ele existe.