Windows PowerShell: Crie uma função melhor

As funções avançadas do Windows PowerShell 2.0 permitem que você emule cmdlets nativos com um script relativamente simples.

Don Jones

No Windows PowerShell 2.0, a Microsoft introduziu um novo tipo de função chamada uma "função avançada". Muitos dos colegas chamá-lo um "cmdlet script". A idéia com essas funções é que agora você pode usar a linguagem de script simplificada de Windows PowerShell para criar algo que pareça, o works, cheira muito bem e pareça quase exatamente um cmdlet nativo, real do Windows PowerShell.

Obviamente, nem todos vocês vão estar em uma posição para criar ferramentas reutilizáveis para si mesmo e seus colegas de trabalho. Entretanto, se você estiver criando ferramentas reutilizáveis, essas funções avançadas são a única maneira de ir. Na verdade, eu estou modificando courseware minha sala de aula para ensinar apenas esse tipo de função no momento.

Como a funções avançadas funcionam tanto como cmdlets reais, uma função feita corretamente pode ser mais fácil para que outros possam usar porque ele se "encaixa" com a maneira como o restante do shell funciona. Que estão sendo o caso, aqui um modelo que você pode usar mais rapidamente criar essas funções avançadas:

function Get-Something {
  <#
  .SYNOPSIS
  Describe the function here
  .DESCRIPTION
  Describe the function in more detail
  .EXAMPLE
  Give an example of how to use it
  .EXAMPLE
  Give another example of how to use it
  .PARAMETER computername
  The computer name to query. Just one.
  .PARAMETER logname
  The name of a file to write failed computer names to. Defaults to errors.txt.
  #>
  [CmdletBinding()]
  param
  (
    [Parameter(Mandatory=$True,
    ValueFromPipeline=$True,
    ValueFromPipelineByPropertyName=$True,
      HelpMessage='What computer name would you like to target?')]
    [Alias('host')]
    [ValidateLength(3,30)]
    [string[]]$computername,
        
    [string]$logname = 'errors.txt'
  )

  begin {
  write-verbose "Deleting $logname"
    del $logname -ErrorActionSilentlyContinue
  }

  process {

    write-verbose "Beginning process loop"

    foreach ($computer in $computername) {
      Write-Verbose "Processing $computer"
      # use $computer to target a single computer
    

      # create a hashtable with your output info
      $info = @{
        'info1'=$value1;
        'info2'=$value2;
        'info3'=$value3;
        'info4'=$value4
      }
      Write-Output (New-Object –TypenamePSObject –Prop $info)
    }
  }
}

Existem algumas coisas importantes a ser observado sobre esta função — muitos dos quais você precisará ajustar ao usar esse modelo:

  • O nome da função deve parecer com um nome de cmdlet, começando com um dos verbos Windows PowerShell comumente usados como "Obter" e terminando com um substantivo singular.
  • Preencha a ajuda com base no comentário. Forneça uma descrição de cada parâmetro, uma descrição da função geral e exemplos de como ele é usado. Execute about_comment_based_help de ajuda para obter mais informações sobre a escrita de Ajuda desta maneira.
  • O primeiro parâmetro, nome_do_computador $, é bastante complexo. Ele pode aceitar um ou mais valores no parâmetro ou do pipeline. Ele aceita apenas valores de 3 a 30 caracteres. Você pode usar –host em vez de – ComputerName ao executar a função. Este parâmetro é obrigatório. Se alguém executar a função sem fornecer um nome de computador, o shell solicitará que eles Insira uma ou mais.
  • O segundo parâmetro, $logname, é um parâmetro mais simples. Ele aceita apenas um valor de seqüência. Ele também tem um padrão.
  • O bloco de scripts BEGIN tenta excluir qualquer arquivo de log existente, para que cada execução da função possui um novo arquivo de log.
  • Dentro do bloco de script do processo, indiquei onde você usaria a variável $computer ter sua função de trabalhar com um único computador. Você não trabalhará diretamente com os computername $. Esse parâmetro pode conter um ou mais valores, para que o loop ForEach enumera-los e coloca apenas um de cada vez no computador de $ para você.
  • Tabela de hash de info $ deve conter seu formato de saída desejado. Considere isso como saída tabular. Criei colunas chamadas info1, info2, / Default e info4. Os valores para essas colunas são extraídos das variáveis $valorX. Este é apenas um exemplo. Eu ainda não realmente coloque nada essas variáveis neste modelo, portanto, você pode substituir a US $valor2 $ e assim por diante, com suas próprias informações.

Este modelo é bom para qualquer função avançada que precisa para obter informações, mas na verdade não fazer alterações de estado do sistema. Para as funções avançadas que alterará o estado do sistema, você precisa implementar alguns itens extras. Com isso em mente, aqui está um segundo modelo:

function Do-Something {
  <#
  .SYNOPSIS
  Describe the function here
  .DESCRIPTION
  Describe the function in more detail
  .EXAMPLE
  Give an example of how to use it
  .EXAMPLE
  Give another example of how to use it
  .PARAMETER computername
  The computer name to query. Just one.
  .PARAMETER logname
  The name of a file to write failed computer names to. Defaults to errors.txt.
  #>
  [CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='Low')]
  param
  (
    [Parameter(Mandatory=$True,
    ValueFromPipeline=$True,
    ValueFromPipelineByPropertyName=$True,
      HelpMessage='What computer name would you like to target?')]
    [Alias('host')]
    [ValidateLength(3,30)]
    [string[]]$computername,
        
    [string]$logname = 'errors.txt'
  )

  begin {
  write-verbose "Deleting $logname"
    del $logname -ErrorActionSilentlyContinue
  }

  process {

    write-verbose "Beginning process loop"

    foreach ($computer in $computername) {
      Write-Verbose "Processing $computer"
      if ($pscmdlet.ShouldProcess($computer)) {
        # use $computer here
      }
    }
  }
}

Neste modelo, você precisará modificar a configuração de "ConfirmImpact". Você precisa dar uma indicação relativa o perigo potencial de sua função avançada. Por exemplo, fazendo algo secundário como alterar o atributo de um arquivo somente leitura pode classificar um ConfirmImpact de "Baixa". Reiniciando o computador pode ser um ConfirmImpact de "Alta". Windows PowerShell usa essa configuração, juntamente com a variável de ConfirmPreference de $ interna do shell, para determinar se deve fornecer avisos "Tem certeza?" automaticamente quando você executa a função.

Observado onde você deve realmente executar sua ação, usando o computador $ para um único computador de destino. Que é encapsulado em uma construção "If", que usa o objeto de pscmdlet $ internos. Se essa função é executada com o – WhatIf ou – Confirm parâmetros (que oferecerá suporte), o objeto de pscmdlet $ cuidará de produzir a saída "e se" ou gerar os avisos de "Tem certeza?".

Ambos esses modelos também suportam o parâmetro –verbose e usar o Write-Verbose para gerar mensagens de status enquanto executa a função. Obviamente, nem toda função será necessário para computadores de destino. Às vezes, você desejará parâmetros para aceitar nomes de arquivos, nomes de usuário ou outras informações. Basta modificar as declarações de parâmetro apropriadamente.

Você pode encontrar mais informações sobre os atributos de parâmetro — como a validação, obrigatória, pipeline da entrada e assim por diante — executando help about_functions_advanced_parameter no shell. Divirta-se.

Don Jones

Don Jonesé um popular Windows PowerShell autor, instrutor e alto-falante. Seu livro mais recente é "Aprender Windows PowerShell em um mês de almoços" (Manning, 2011); visite MoreLunches.com para informações e livre complementar de conteúdo. Ele também está disponível para classes de treinamento no local (visite ConcentratedTech.com/training para obter mais informações).

Conteúdo relacionado