Como Escrever Seu Primeiro Script PowerShell: Automação de Limpeza de Arquivos

Uma das metodologias de codificação mais importantes a seguir é garantir que você saiba e gerencie cada maneira que seu código pode “fluir”. Se você pensar no seu código como um fluxo, ele pode ramificar, retornar a vários pontos e encontrar muitas condições.

O tratamento de erros garante que você configure “redes” ou um lugar padrão para onde seu código pode fluir quando algo inesperado acontece.

Vamos usar um cenário do mundo real que você pode se encontrar, lidando com o tratamento de erros do PowerShell.

Construindo o Script Inicial para Limpeza de Arquivos

Precisamos limpar alguns arquivos antigos. Nosso servidor de arquivos existe há muito tempo e precisamos liberar espaço. A gerência decidiu remover todos os arquivos com mais de um número especificado de dias. Precisamos construir um script que busque recursivamente uma pasta, encontre todos os arquivos mais antigos que um certo número de dias e os remova.

A tarefa parece fácil, mas esta é a seção de tratamento de erros, então você sabe que algumas coisas darão errado!

Vamos começar a entender o tratamento de erros, construindo primeiro o script de demonstração do cenário sem tratamento de erros para demonstrar o problema que o tratamento de erros resolve.

  1. Primeiro, abra uma nova aba no VS Code.

    Como estamos apenas tentando algumas coisas agora, não vamos salvar o script ainda. Diga temporariamente ao VS Code que você está prestes a escrever algum PowerShell.

    Pule Ctrl-Shift-P, digite ‘lang’, selecione Escolher Modo de Linguagem, digite ‘power’ e escolha PowerShell. Agora o VS Code sabe que você estará escrevendo PowerShell.

  2. Em seguida, divida o problema em tarefas, resolvendo a mais óbvia primeiro.

    Neste caso, a tarefa consiste em um comando para ler arquivos em um diretório.

    Get-ChildItem -Path C:\OldForgottenFolder
    
  3. Get-ChildItem também retorna diretórios que não precisamos, então vamos limitar isso apenas a arquivos.

    Get-ChildItem -Path C:\OldForgottenFolder -File
    
  4. Se houver arquivos nessas subpastas, precisamos obtê-los também com Recurse.

    Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse
    
  5. Agora que temos o comando e os parâmetros, está retornando TODOS os arquivos. Precisamos apenas encontrar os que são mais antigos que um certo número de dias.

    Como Get-ChildItem retorna cada arquivo com uma propriedade de objeto LastWriteTime, devemos filtrar com base nessa propriedade. Usaremos o filtro Where para encontrar os arquivos com um LastWriteTime menor que uma data especificada.

    (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????}
    
  6. A data precisa ser dinâmica porque “antigo” hoje será diferente de “antigo” amanhã.

    Comente a linha anterior porque precisaremos dela em algum momento e depois resolva a situação da data.

    ## (Get-ChildItem -Path C:\\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????}
    $Now = Get-Date
    $Now
    
  7. Agora que temos a data de hoje, vamos encontrar um número específico de dias antes de hoje para descobrir a data. Vou colocar 30 aqui temporariamente, pois sei que alguns arquivos têm mais de cinco dias, para fazer um teste rudimentar.

    ## (Get-ChildItem -Path C:\\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????}
    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    $LastWrite
    
  8. Feito! Vamos juntar tudo até agora.

    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LastWrite}
    

    Agora temos um pequeno script que encontra todos os arquivos em um diretório que são mais antigos do que um número específico de dias.

  9. Em seguida, devemos adicionar a capacidade de remover esses arquivos mais antigos. Isso é trivial usando o cmdlet Remove-Item e o pipeline.

    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LastWrite} | Remove-Item
    
  10. Pronto! Mas espera, eu não tenho ideia de quais arquivos foram removidos. Também houve alguns erros que vamos resolver em alguns minutos. Vamos adicionar algumas funcionalidades básicas.

    $VerbosePreference = 'Continuar'
    
    $Agora = Get-Date
    $ÚltimaEscrita = $Agora.AddDays(-30)
    $arquivosAntigos = (Get-ChildItem -Path C:\PastaEsquecidaAntiga -File -Recurse).Where{$_.LastWriteTime -le $ÚltimaEscrita}
    foreach ($arquivo in $arquivosAntigos) {
        Remove-Item -Path $arquivo.FullName
        Write-Verbose -Message "Removido com sucesso [$($arquivo.FullName)]."
    }
    
  11. Você precisará incluir um loop como este para executar algum tipo de código para cada arquivo. Aqui não estamos usando o pipeline e, em vez disso, colocando todos os arquivos encontrados em uma variável arquivosAntigos, um array de objetos de arquivo. Em seguida, estamos executando Remove-Item em cada um como antes, mas desta vez incluindo uma mensagem detalhada informando qual arquivo está sendo removido.

  12. Vamos agora executar este código e ver o que acontece.

    Agora você pode ver pela mensagem detalhada que alguns arquivos foram removidos. O código que temos agora é o que precisamos para criar o script. Vamos agora criar um script real a partir disso na seção seguinte.

Maximizando Flexibilidade e Reutilização com Parâmetros

Você construiu seu script, mas ele ainda tem o potencial de ser flexível e reutilizável. Como? Parâmetros nos permitirão especificar o diretório e a idade dos arquivos que queremos atingir, tornando o script mais flexível.

  1. Antes de avançarmos muito, vamos salvar nosso trabalho. Chame-o de Remove-FileOlderThan.ps1.

    Note o formato verbo/substantivo com um hífen. Se possível, tente sempre criar nomes de scripts da mesma forma que os comandos do PowerShell para consistência e legibilidade.

  2. Primeiro, os scripts devem ser reutilizáveis. Chances são que você provavelmente vai querer usar este script em diferentes diretórios e diferentes idades. Precisamos introduzir alguns parâmetros. Para fazer isso, descobrimos o que vai mudar. O diretório e o número de dias. Entendido.

    param (
        [Parameter(Mandatory)]
        [string]$CaminhoPasta,
    [Parameter(Mandatory)]
    [int]$DiasAntigos
    

    )

    $Agora = Get-Date
    $ÚltimaEscrita = $Agora.AddDays(-30)
    $arquivosAntigos = (Get-ChildItem -Path C:\PastaVelhaEsquecida -File -Recurse).Where{$_.LastWriteTime -le $ÚltimaEscrita}
    foreach ($arquivo in $arquivosAntigos) {
    Remove-Item -Path $arquivo.FullName
    Write-Verbose -Message "Removido com sucesso [$($arquivo.FullName)]."
    }

    Adicione um bloco param no topo e defina cada parâmetro como obrigatório, pois precisamos de um caminho e um número para o script funcionar. Além disso, especifique o tipo aqui como uma prática recomendada.

  3. Substitua os itens estáticos que tínhamos no código anterior pelos valores dos parâmetros.

    param (
        [Parameter(Mandatory)]
        [string]$FolderPath,
    [Parameter(Mandatory)]
    [int]$DaysOld
    

    )

    $Agora = Get-Date
    $ÚltimaEscrita = $Agora.AddDays(-$DaysOld)
    $arquivosAntigos = (Get-ChildItem -Path $FolderPath -File -Recurse).Where{$_.LastWriteTime -le $ÚltimaEscrita}
    foreach ($arquivo in $arquivosAntigos) {
    Remove-Item -Path $arquivo.FullName
    Write-Verbose -Message "Removido com sucesso [$($arquivo.FullName)]."
    }

  4. Agora vamos executar o script e ver o que acontece.

    C:\Scripts\Remove-FileOlderThan.ps1 -FolderPath C:\OldForgottenFolder -DaysOld 30 -Verbose
    

    Você pode ver como precisamos especificar o caminho da pasta e o número de dias como parâmetros. Use o parâmetro Verbose para ver a linha Write-Verbose.

    O PowerShell executou o script exatamente como antes, mas agora temos um script parametrizado que podemos usar em qualquer diretório ou qualquer idade de arquivos!

    Ao olhar a saída, encontramos algum texto vermelho. Ou você não tem direitos, ou o arquivo é somente leitura. Mas em quais arquivos ocorreu a falha? E como garantir que esses arquivos também sejam removidos?

    Conclusão

    Neste tutorial, construímos um script para limpar arquivos antigos de um diretório, garantindo flexibilidade ao adicionar parâmetros. Embora o script funcione como pretendido, vimos que o tratamento de erros ainda não foi abordado, o que é crucial ao lidar com cenários do mundo real.

    À medida que avançamos, adicionar gerenciamento de erros nos permitirá lidar com problemas, como cmdlets gerando erros ou arquivos sendo inacessíveis, ajudando-nos a evitar a terminação do script e fornecendo informações detalhadas sobre o que deu errado.

    Fique ligado para a próxima demonstração! PowerShell 101: Erros Terminantes, Não Terminantes e Try/Catch.

Source:
https://adamtheautomator.com/powershell-file-cleanup-script/