O que é
Este artigo fornece um guia completo sobre as melhores práticas de scripting em PowerShell, com foco na estrutura do código, formatação de saída, tratamento de erros, otimização de desempenho e medidas de segurança.
Por que seguir
Seguir as melhores práticas no scripting em PowerShell garante que seus scripts sejam legíveis, fáceis de manter, seguros e performáticos. Isso reduz a dívida técnica, melhora a colaboração e minimiza riscos em ambientes de produção.
Como aplicar
Design de Ferramentas e Controladores
Decida se você está criando uma ‘Ferramenta’ ou um ‘Controlador’
- Ferramenta: Funções/módulos reutilizáveis.
- Controlador: Automatiza uma tarefa específica, não projetado para reutilização.
Torne seu código modular
- Use funções e módulos de script para maximizar a reutilização.
Use convenções padrão de nomenclatura
- Siga o formato Verbo-Substantivo utilizando verbos aprovados pelo PowerShell (
Get-Verb
).
Padronize os nomes dos parâmetros
- Utilize nomes como
$ComputerName
ao invés de prefixos personalizados.
Ferramentas devem retornar dados brutos
- Forneça dados minimamente processados para maior flexibilidade.
Controladores devem retornar dados formatados
- Formate a saída para relatórios amigáveis ao usuário.
Exemplo
function Get-DiskInfo {
param ([string]$ComputerName)
Get-WmiObject Win32_LogicalDisk -ComputerName $ComputerName
}
Evite reinventar a roda
Use cmdlets nativos como Test-Connection
em vez de criar funções personalizadas.
# Recomendado
Test-Connection $ComputerName -Quiet
Escrevendo Blocos de Parâmetros
Sempre escreva a ajuda
Inclua ajuda baseada em comentários com .SYNOPSIS
, .DESCRIPTION
e pelo menos um .EXAMPLE
.
function Test-Help {
<#
.SYNOPSIS
Demonstra documentação de ajuda adequada.
.EXAMPLE
Test-Help -MandatoryParameter "Exemplo"
Executa a função Test-Help com um parâmetro obrigatório.
#>
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[Alias("MP")]
[String]$MandatoryParameter
)
}
Use [CmdletBinding()]
Habilita parâmetros comuns como -Verbose
, -Debug
, -ErrorAction
.
Suporte -WhatIf e -Confirm
Para comandos que alteram o estado, utilize SupportsShouldProcess
.
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = "Medium")]
param ([switch]$Force)
Tipagem forte dos parâmetros
Defina sempre os tipos para validação e clareza.
param (
[string]$Name,
[int]$Count
)
Use [switch] corretamente
- O padrão é
$false
. - Utilize como booleano, evitando lógica de três estados.
Formatação de Saída
Evite Write-Host quando não necessário
Prefira Write-Verbose
, Write-Debug
ou Write-Output
conforme o contexto.
Use Write-Progress para atualizações de progresso
Write-Progress -Activity "Processando" -Status "50% Concluído" -PercentComplete 50
Use arquivos de formatação para objetos personalizados
Defina arquivos .format.ps1xml
ao invés de formatação inline.
Retorne apenas um tipo de objeto por vez
Utilize [OutputType()]
e evite tipos mistos.
Melhores Práticas de Tratamento de Erros
Use -ErrorAction Stop com cmdlets
Forçe erros para serem tratados com try-catch
.
try {
Get-Item "C:\CaminhoInvalido" -ErrorAction Stop
} catch {
Write-Warning "Item não encontrado."
}
Use $ErrorActionPreference para operações não-cmdlet
Ajuste temporariamente para 'Stop'
em operações arriscadas.
Evite flags e $? para tratamento de erros
Prefira blocos estruturados com try-catch
.
Copie $Error[0] ou $_ imediatamente dentro do catch
catch {
$errorDetails = $_
Write-Error "Ocorreu um erro: $($errorDetails.Exception.Message)"
}
Otimização de Desempenho
PERF-01 Meça o desempenho quando necessário
Use Measure-Command
para comparar abordagens.
Measure-Command {
foreach ($item in $data) { Process-Item $item }
}
PERF-02 Equilibre desempenho e legibilidade
- Para pequenos conjuntos de dados, priorize a legibilidade.
- Para grandes volumes, considere streaming e técnicas com .NET.
Mais legível:
$content = Get-Content -Path file.txt
foreach ($line in $content) {
Do-Something -Input $line
}
Otimizado para desempenho:
Get-Content -Path file.txt | ForEach-Object {
Do-Something -Input $_
}
Alta performance com .NET:
$sr = New-Object System.IO.StreamReader "file.txt"
while ($sr.Peek() -ge 0) {
$line = $sr.ReadLine()
Do-Something -Input $line
}
PERF-03 Prefira recursos da linguagem ao invés de cmdlets
- Construções da linguagem (
foreach
) > Métodos .NET > Scripts > Cmdlets/Pipeline. - Sempre meça antes de otimizar.
Melhores Práticas de Segurança
Sempre use PSCredential para credenciais
Evite senhas em texto simples. Use parâmetros [Credential()]
.
param (
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential
)
Ao passar para APIs:
$Insecure.SetPassword($Credential.GetNetworkCredential().Password)
Use SecureString para dados sensíveis
Solicite de forma segura e armazene criptografado.
$Secure = Read-Host -Prompt "Digite dados seguros" -AsSecureString
Converter para texto simples de forma segura:
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Secure)
$PlainText = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR)
Armazene credenciais com segurança
Use Export-CliXml
.
Get-Credential | Export-CliXml -Path C:\secure\cred.xml
$Credential = Import-CliXml -Path C:\secure\cred.xml
Armazene strings criptografadas
ConvertFrom-SecureString -SecureString $Secure | Out-File -Path "${Env:AppData}\secure.bin"
$Secure = Get-Content -Path "${Env:AppData}\secure.bin" | ConvertTo-SecureString
Conclusão
Seguindo estas melhores práticas de PowerShell em design, documentação, saída, tratamento de erros, desempenho e segurança, você criará scripts robustos, eficientes e fáceis de manter. Busque sempre o equilíbrio entre legibilidade, performance e segurança para entregar soluções de automação de alta qualidade.