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ê conheça e gerencie cada maneira como 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 local padrão para o qual seu código pode fluir quando algo inesperado acontece.

Vamos usar um cenário do mundo real em 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 mais antigos do que um número especificado de dias. Precisamos construir um script que pesquise recursivamente uma pasta, encontre todos os arquivos mais antigos do que um certo número de dias e os remova.

A tarefa parece simples o suficiente, mas esta é a seção de tratamento de erros, então você sabe que algumas coisas vão dar 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 testando algumas coisas agora, não vamos salvar o script ainda. Diga temporariamente ao VS Code que você está prestes a escrever algum PowerShell.

    Pressione 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 criar 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 nesses subdiretórios, precisamos obtê-los também com Recurse.

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

    Como Get-ChildItem retorna cada arquivo com uma propriedade de objeto LastWriteTime, precisamos 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 então resolva a situação da data.

    ## (Get-ChildItem -Path C:\\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????}
    $Agora = Get-Date
    $Agora
    
  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 ?????}
    $Agora = Get-Date
    $UltimaEscrita = $Agora.AddDays(-30)
    $UltimaEscrita
    
  8. Pronto! Vamos juntar tudo até agora.

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

    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, precisamos adicionar a capacidade de remover esses arquivos mais antigos. Isso é trivial usando o cmdlet Remove-Item e o pipeline.

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

    $VerbosePreference = 'Continuar'
    
    $Agora = Get-Date
    $ÚltimaModificação = $Agora.AddDays(-30)
    $arquivosAntigos = (Get-ChildItem -Path C:\PastaEsquecidaAntiga -File -Recurse).Where{$_.LastWriteTime -le $ÚltimaModificação}
    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 esse código e ver o que acontece.

    Agora você pode ver através da 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 a Flexibilidade e Reutilização com Parâmetros

Você construiu seu script, mas ele ainda tem potencial para ser flexível e reutilizável. Como? Parâmetros nos permitirão especificar o diretório e a idade dos arquivos que queremos direcionar, 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 script da mesma maneira que os comandos do PowerShell para consistência e legibilidade.

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

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

    )

    $Agora = Get-Date
    $UltimaEscrita = $Agora.AddDays(-30)
    $arquivosAntigos = (Get-ChildItem -Path C:\PastaAntigaEsquecida -File -Recurse).Where{$_.LastWriteTime -le $UltimaEscrita}
    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, já que precisamos de um caminho e um número para o script funcionar. Além disso, especifique o tipo aqui como uma boa prática.

  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
    $UltimaEscrita = $Agora.AddDays(-$DaysOld)
    $arquivosAntigos = (Get-ChildItem -Path $FolderPath -File -Recurse).Where{$_.LastWriteTime -le $UltimaEscrita}
    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 temos que 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!

    Dando uma olhada na saída, encontramos um texto em vermelho. Ou você não tem permissões, ou o arquivo é somente leitura. Mas em quais arquivos houve 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 desejado, 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 a evitar a terminação do script e fornecendo insights detalhados sobre o que deu errado.

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

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