Windows PowerShell O que não script

Don Jones

Conteúdo

Não sobrecarregar variáveis
Nomes de variáveis significativos
Simplificar comparações
Não quebrar o seu script
O loop de loop
Não ser até silencioso
Mostre-me as scripts

Uma oferta (que ainda significa) feitas recentemente para os leitores do meu ConcentratedTech.comblog: envie seus scripts do Windows PowerShell e eu será revisá-las e oferecem alguma sugestão preciso melhorá-los. A idéia realmente veio de uma pesquisa meu co-bloggers e executei — um leitor sugerido que isso seria fornecem uma maneira excelente, mundo real para pessoas melhorar suas habilidades de scripts. Sobre últimos meses, observei algumas tendências como localizar me fazer várias sugestões determinados repetidamente. Portanto, eu tenha compilado uma lista para compartilhar com você aqui.

Deixe-me primeiro estado, no entanto, que qualquer script que obtém o trabalho feito (com êxito e sem danos Acessórios, do curso) é um script boa. Algumas coisas que eu estou sugerindo podem parecer nitpicky e algumas delas são certamente. No entanto, cada uma das minhas sugestões tem algumas vantagens distintas, que tentarei para destacar como vou.

Não levar ofensa se está realmente fazendo algumas das "incorretas práticas" eu destaque. Sei que um lote de pessoas que esse script no Windows PowerShell começou scripts com o VBScript e alguns dessas "práticas incorreto" são realmente muito comuns no mundo do VBScript. Esta é uma ótima oportunidade, em seguida, para saber como VBScript e Windows PowerShell são um pouco diferente e como escrever scripts que usam o exclusivo vantagens que do Windows PowerShell tem a oferecer.

Com que disse, aqui estão meus sugestões de comuns seis superior feitas sobre últimos meses.

Não sobrecarregar variáveis

Certamente, variáveis são úteis, mas vamos não obter executadas imediatamente. Eu tiver sido vendo muita esse tipo de script:

$varfile = "c:\names.txt"
$varexists = Test-Path $varfile
if ($varexists –eq $false) {
  Write-Output "The file $varfile does not exist"
  break
}
$varnames = Get-Content $varfile

Existem algumas práticas que gostaria de ver alterados em um exemplo desta. Primeiro e foremost, há pouca necessidade de usar todas essas informações em variáveis. É possível reescrever isso com menos variáveis. Por que se preocupar? Bem, o shell pode não se preocupar com como muitas variáveis que você usar, mas sou um grande, grande fã de fazer scripts como legível possível para que alguém possa ler o script em papel ou em um editor de scripts e ser capaz de descobrir o que o script está fazendo. Mais variáveis que você incluir, o mais alguém tenha que controlar em sua cabeça — e o menos provável que ele será capaz descobrir qual é o script até. Se eu não consegue descobrir o script em papel, estou menos probabilidade de ser capaz de depurar o script se há um problema. Portanto, eu comece reescrevendo neste exemplo, da seguinte maneira:

$varfile = "c:\names.txt"
If ((Test-Path $varfile) –eq $false) {
Write-Output "The file $varfile does not   exist"
  break
}
$varnames = Get-Content $varfile

Tudo o que Estou fazendo realmente é eliminando a variável de varexists $ e diretamente utilizando a saída de Test-Path. Dessa forma, não preciso examinar se construir, consulte varexists $ e, em seguida, voltar e descobrir quais varexists $ deve para conter. É menos para mim controlar na minha cabeça. Observe que deixei $ varfile; isso é porque Estamos usando essas informações três vezes — se você estiver reutilizar informações várias vezes, vale a pena colocar em uma variável.

Nomes de variáveis significativos

Continuar com o exemplo anterior, sempre se lembrar que nomes de variáveis devem ajudar Lembre-se o que há dentro de uma variável. Você não precisará usar prefixos de nome como "var" porque o caractere $ informa é uma variável. Na verdade, nome prefixos como "str" para seqüências de caracteres ou "int" para números inteiros está desatualizado ("é então 1993" é o que eu dizer quando eu estou ensinando classes). Basta use nomes de variáveis simples. Eis o exemplo reconfigurado:

$filename = "c:\names.txt"
If ((Test-Path $filename) –eq $false) {
Write-Output "The file $filename does not exist"
  break
}
$computernames = Get-Content $filename

Simplificar comparações

Não sou um fã de operadores de comparação no Windows PowerShell — aquelas como –gt, - lt, - eq e assim por diante. Minha falta de fondness provavelmente é proveniente de minha experiência longa com o VBScript, onde eu poderia usar operadores familiarizados, como >, < e =. Muitos de vocês provavelmente reconhecem esses operadores da escola grau matemática lições, e portanto exigem menos análise mental quando você lê-las. Sempre que possível, em seguida, eu gostaria evitar o uso de um operador. E qualquer condição onde você procurar algo para ser True ou False é uma oportunidade para livrar-se de um operador:

$filename = "c:\names.txt"
If (-not (Test-Path $filename)) {
Write-Output "The file $filename does not exist"
  break
}
$computernames = Get-Content $filename

Como o cmdlet Test-Path retorna VERDADEIRO ou FALSO, há não precise comparar para True ou False. Tudo dentro se constrói parênteses precisa boil para baixo como True ou False. Normalmente, você usaria uma comparação para atingir que, mas se tudo o que é aí é já gerar True ou False, você poderá usar que informações diretamente.

Eu deve observar que o operador –not é que realmente gosto. É mais como inglês comuns que o equivalente a! = operador usado por vários idiomas.

Além disso, devem comentar parênteses que estou colocando em torno de Test-Path e seu parâmetro de entrada, $ nome do arquivo. Comecei a incluindo comandos entre parênteses, pois ajuda a me entendê-los visualmente como uma única unidade. Windows PowerShell usa espaços, em vez de algum outro caractere para separar coisas como comandos, nomes de parâmetros e valores de parâmetro. Incluindo a seqüência de comando inteira entre parênteses me ajuda a vê-lo todos juntos, sem forçar eu realmente examinar os espaços e determinar onde o comando inicia e pára.

Não quebrar o seu script

A última sugestão que tenho para este exemplo em execução é a maneira que sua lógica é criada. Se o arquivo não existir, eu interromper a saída do script. Se o arquivo existe, eu nunca execute a instrução break e portanto, o script continuará. Sempre que possível, eu gostaria de evitar o uso quebra para sair de um script. Eu poderia reescrever o exemplo a — novamente — da seguinte maneira:

$filename = "c:\names.txt"
If (Test-Path $filename) {
$computernames = Get-Content $filename
  # do whatever we planned to do
} else {
Write-Output "The file $filename does not exist"
}

Dessa forma, eu já simplificado a lógica de se construir. Eu também eliminou a necessidade de usar a instrução break, que reduz a confusão sobre o que o script está fazendo. Estou a primeira a admitir que essa sugestão é absolutamente um nitpick, mas Acho que boas práticas de codificação ajudam a tornar os scripts melhor e isso é definitivamente uma prática melhor que desistindo check-out de um script no meio do caminho. Esse tipo de construção é mais fácil depurar e é muito mais fácil siga do papel se você estiver observando um script e tentando descobrir o que ele faz.

O loop de loop

Vários scripts que revisado necessário para ler as informações de um arquivo de texto e o loop através de cada linha do arquivo. Por exemplo, convém entrar em contato com uma série de computadores, para que você pode listar seus nomes, um nome por linha, em um arquivo de texto. Eis uma construção comuns que já vi:

$line = 0
$names = get-content c:\names.txt
while ($line –lt $names.length) {
  # do something with $names[$line]
  $line++
}

Isso carrega o arquivo na variável $ nomes e, em seguida, enumera manualmente a através da coleção como se fosse uma matriz. A variável de linha $ controla de qual linha Estou trabalhando com. Ele funciona bem — mas Estou fazendo um pouco mais de trabalho que preciso fazer, e eu estou fazendo o código um pouco mais difícil para alguém ler mais tarde. A construção ForEach no Windows PowerShell é um pouco mais apropriada para enumeração de coleções. (Tecnicamente, Get-Content retorna uma coleção, não uma matriz). Tente o seguinte:

Foreach ($name in (Get-Content c:\names.txt))
{
  # do something with $name
}

Há poucas vantagens aqui. Acompanhando minha sugestão anterior, eu estou colocar a chamada para Get-Content para a direita dentro de construção, como acredito que torna um pouco mais clara como para o que está acontecendo. ForEach irá enumerar através da coleção inteira, independentemente de quanto tempo é. Cada vez, ele irá levar o próximo item na coleção e coloca esse item na variável $ nome. Portanto, o nome da variável representa o que ele contém — um nome de computador. E que torna mais fácil ler e execute o script.

Windows PowerShell Q & A

Q Existe uma maneira de definir um alias personalizado permanente no Windows PowerShell?

A se você já tiver criado um novo alias, você provavelmente percebeu que ele desaparece quando você fechar o shell. Por exemplo, isso cria um novo d alias, que é um atalho para o comando Get-ChildItem:

Novo alias d Get-ChildItem

Mas quando eu fechar o shell, o alias será perdido. O truque é criar um perfil de Windows PowerShell. Na pasta documentos, crie uma nova pasta chamada WindowsPowerShell. Dentro dessa pasta, crie um arquivo de texto chamado profile.ps1. Nesse arquivo de texto, coloque os comandos que você deseja executar automaticamente cada vez que inicia o shell — incluindo uma nova definição de alias. O perfil garante que os comandos executados sempre que você iniciar o shell, criar um alias "permanente" que está sempre disponível no Windows PowerShell.

Não preciso se preocupar sobre qual linha estou trabalhando com ou manter uma variável de linha $ para controlar que — a construção ForEach faz isso para mim. Eliminar três linhas de código torna o código um pouco mais sucinta e requer que você controlar as coisas menos de cabeça quando você estiver tentando descobrir o que faz o script.

Não ser até silencioso

A um prática que desejo realmente nip in a bud é a prática de supressão de erros do shell em um script inteiro. Digamos que você estiver observando um script que inclui esse direito de linha na parte superior:

$ErrorActionPreference = "SilentlyContinue"

Pare imediatamente.

Isso não faz erros desaparecer, mas ele suprimi-los. Sim, certamente há vezes quando você irá prever e deseja desconsiderar um determinado erro, como quando você estiver usando (WMI) para se conectar a máquinas remotas que possivelmente não estão disponíveis. Mas nunca há um motivo para ignorar erros globalmente. Mensagens de erro são úteis e aponte para problemas que você pode corrigir algumas vezes.

Se você quiser ignorar erros para um determinado cmdlet, você pode fazer isso adicionando o parâmetro de "SilentlyContinue" – EA para esse cmdlet. Se desejar ignorar erros de vários comandos em uma linha, adicione o parâmetro – EA para cada ou adicionar a linha de ErrorActionPreference $ imediatamente antes dos comandos e após os comandos, adicionar:

$ErrorActionPreference = "Continue"

Isso define o tratamento de erros em normal.

Pessoalmente, não gosto de desativar o erros em todos os, a menos que eu estou tratamento me esses erros. Por exemplo:

Trap {
  # output error to a log file or something
}
Get-WmiObject Win32_Service –computerName $remote –EA Stop

Este exemplo breve mostra como o parâmetro de "Stop" – EA irá gerar exceções true em vez de apenas mensagens de erro, dando a você uma oportunidade para interceptá-los e manipulá-las por conta própria. Você pode registrá-los em um arquivo, exibir uma mensagem de erro amigável ou fazer algo para esse efeito.

Mostre-me as scripts

Como eu disse, algumas delas foram um nitpicky bits — mas todos eles oferecem vantagens distintas que vale a pena consideração. Eu convidá-lo para compartilhar seus próprios scripts do Windows PowerShell. Eu examinar algumas cada mês e postar minhas sugestões no ConcentratedTech.com. Fique à vontade consultar algumas de minhas sugestões anteriores e talvez até mesmo enviar seus próprios scripts para revisão. Espero ouvir você!

Don Jones é co-fundador da Concentrated Technology. Você pode ler dicas sobre o Windows PowerShell e outros tópicos IT, bem como entrar em contato com Don, seu blog em ConcentratedTech.com.