Script Powershell para sysadmin baixar backups regularmente do servidor para o computador

Recentemente, uma amiga minha se deparou com o problema de o provedor de VPS falir repentinamente sem aviso prévio. Infelizmente, por uma questão de preço baixo, ela escolheu um provedor de nicho - um que nem sequer oferecia download de dados. Pior ainda, ela nem tem o hábito de baixar backups regularmente. Da noite para o dia, o site dela desapareceu, juntamente com todos os dados nele contidos.

Chocado com isso, escrevi um script Powershell que baixará automaticamente backups do seu servidor para o seu computador local regularmente, sem a necessidade de comprar serviços adicionais de armazenamento de objetos ou gastar um centavo em outras coisas. Tudo o que você precisa é de um computador Windows que você usa regularmente (e que tenha bastante espaço em disco) e esteja conectado à Internet.

O script limpará automaticamente os backups de 5 dias atrás. Você pode definir o intervalo de backup automático e o tempo do backup mais antigo salvo localmente de acordo com suas necessidades.

$ssh_port = 22
$ssh_address = "username@your.site"

Write-Output "Starting Discourse backup download task..."
Write-Output '------------------------'
Write-Output "Fetching the latest backup file..."
Write-Output ''

while ($true) {

    $filename = ''

    while ($true) {
        try {
            Write-Output "> ssh -p $ssh_port $ssh_address 'cd /var/discourse/shared/standalone/backups/default/ && ls -t | head -n 1'"
            Write-Output ''
            $filename = ssh -p $ssh_port "$ssh_address" 'cd /var/discourse/shared/standalone/backups/default/ && ls -t | head -n 1'
            break
        }
        catch {
            $filename = ''

            Write-Output "Failed to fetch... Here is the log:"
            Write-Output '-------------'
            Write-Output $_

            $answer = Read-Host "Do you want to re-fetch? (y/N)"
            if ($answer -ne 'y') {
                break
            }
            Write-Output ''
        }
    }


    if ([String]::IsNullOrEmpty($filename)) {
        Write-Output "Error: Failed to fetch file name $filename"
        Write-Output ''
        $answer = Read-Host 'Retry?(y/N)'

        if ($answer -eq 'y') {

        }
        else {

            exit 1
        }

    }
    else {

        Write-Output "Latest backup: $filename"
        Write-Output ''

        $need_download = $true
        if (Test-Path ".\backups\$filename") {
            $answer = Read-Host ".\backups\$filename already exists. Do you want to download it again?(y/N)"
            Write-Output ''
            if ($answer -ne 'y') {
                $need_download = $false
            }
        }
        if ($need_download) {
            Write-Output "Start downloading..."
            Write-Output ''

            while ($true) {
                try {
                    Write-Output "scp -p $ssh_port ${ssh_address}:/var/discourse/shared/standalone/backups/default/$filename .\\backups\\"
                    Write-Output ''

                    scp -p $ssh_port "${ssh_address}:/var/discourse/shared/standalone/backups/default/$filename" .\\backups\

                    Write-Output "Download completed"
                    Write-Output ''

                    break
                }
                catch {

                    Write-Output "Download failed >_<... The following is the log:"
                    Write-Output ''

                    Write-Output $_

                    $answer = Read-Host "Download again? (y/N)"
                    Write-Output ''
                    if ($answer -ne 'y') {
                        break
                    }
                }
            }

        }

        Write-Output "Start trying to clean old backup files..."
        Write-Output ''

        $count = 0
        $backupfiles = Get-ChildItem -Path .\\backups\

        foreach ($file in $backupfiles) {
            if ($file.CreationTime -le (Get-Date).AddDays(-5)) {
                try {
                    Write-Output "Delete old backup file $file ..."
                    Write-Output ''
                    $file.Delete()
                    $count = $count + 1
                } catch {
                    Write-Output "An error occurred while deleting old backup file $file >_<"
                    Write-Output '-------------------'
                    Write-Output $_
                    Write-Output '-------------------'
                }
            }
        }

        if ($count -ge 0) {
            Write-Output "Cleaned $count old backup files"
            Write-Output ''
        }
        else {
            Write-Output 'No old backup files need to clean up'
            Write-Output ''
        }

        Pause

        exit 0


    }


}

Salve o script acima como scriptname.ps1 no caminho onde você deseja baixar o backup. Tente “Executar com Powershell”. Se for bem-sucedido, você poderá prosseguir para a próxima etapa.

Para agendar uma tarefa

  1. Pesquise por “Agendador de Tarefas”.
  2. Clique duas vezes em Adicionar Tarefa Agendada. O Assistente de Tarefa Agendada aparece.
  3. Clique em Avançar e, em seguida, clique em Procurar. A caixa de diálogo Selecionar Programa para Agendar aparece.
  4. Navegue até o script que você criou, clique nele e, em seguida, clique em Abrir. Você retorna ao Assistente de Tarefa Agendada.
  5. Forneça um nome para a tarefa, ou mantenha o padrão, que é o nome do arquivo, especifique a frequência com que o script deve ser executado e clique em Avançar.
  6. Especifique a hora e a data de início (se você especificou Diariamente, Semanalmente ou Mensalmente, etc.) e a recorrência, em seguida, clique em Avançar. Este item deve corresponder ao ciclo de backup automático do seu discourse.
  7. Digite o nome de usuário e a senha da conta que executará o script e clique em Avançar.
  8. Se você quiser configurar propriedades avançadas, selecione a caixa de seleção e clique em Concluir.
15 curtidas

Um bom lembrete de quão importante é ter backups remotos. Outro usuário do meta sofreu o mesmo problema há alguns meses.

Uma das minhas instâncias usa o recurso de backup S3 integrado, as outras usam Rclone e uma tarefa CRON para enviar backups para o Google Drive. Há um guia para isso: Use rclone to sync backups to Dropbox or Google Drive

Obrigado por compartilhar seu script Linca :+1:

3 curtidas

De fato, um lembrete muito bom. Eu sugeri (aqui) que a função de atualização pudesse verificar e alertar se os arquivos de backup tivessem tempos de último acesso muito distantes no passado. Nós atualizamos a cada dois ou três meses, então essa verificação não seria executada com muita frequência, e o momento de uma atualização é um bom momento para ter certeza de que há um backup seguro. Qualquer meio de copiar um arquivo de backup para outro lugar deve atualizar o timestamp de último acesso.

3 curtidas

Bom ponto, obrigado pelo script. Deixe-me compartilhar a versão do rsync :slight_smile: .

No exemplo abaixo, sql e anexos são sincronizados separadamente. Não há necessidade de incluir anexos no arquivo de backup. Também não há necessidade de excluir backups antigos.

Eu uso Chocolatey para instalar cwrsync. Após a instalação, basta adicionar algumas linhas ao final do arquivo cmd + criar um agendamento:

C:\ProgramData\chocolatey\lib\rsync\tools\cwrsync.cmd

Por exemplo:

rsync -rvm --delete --ignore-errors --ignore-existing --size-only --chmod=ugo=rwX -e "ssh -i /cygdrive/c/Users/user1/.ssh/id_rsa" login@host:/var/discourse/shared/standalone/backups/default/ /cygdrive/d/backup/forum/db/

rsync -rvm --delete --ignore-errors --ignore-existing --size-only --chmod=ugo=rwX -e "ssh -i /cygdrive/c/Users/user1/.ssh/id_rsa" login@host:/var/discourse/shared/standalone/uploads/ /cygdrive/d/backup/forum/uploads/

Observação 1: Use /cygdrive/c/ em vez de C:, leia o arquivo cmd para referência e sintaxe.

Observação 2: Você pode modificar o comando para usar senha em vez de chave ssh (formato PEM)

Observação 3: Se você não colocar uma barra após a pasta dump/, o rsync copiará a pasta, mas se você colocar, ele copiará apenas o conteúdo da pasta.

Observação 4: Se o chocolatey atualizar o cwrsync, ele cria um backup do cmd anterior na mesma pasta. Você precisa copiar seus comandos para o novo cmd manualmente para continuar os backups.

Importante: Defina a mesma regra no Agendador como o OP escreveu. A linha do agendador é:

C:\ProgramData\chocolatey\lib\rsync\tools\cwrsync.cmd >> d:\backup\cwrsync.txt 2>&1

Isso anexará a saída ao arquivo cwrsync.txt. É tudo.

3 curtidas

Eu tenho o hábito de configurar o rclone para copiar automaticamente os backups para um local remoto (um NAS auto-hospedado em casa) por causa do paranoia sobre esse tipo de coisa acontecer do nada. Este post serve muito bem como um lembrete de que não devemos colocar todos os ovos na mesma cesta.

5 curtidas

Enquanto isso, você também deve obter uma cópia de tudo em /var/discourse/containers.

4 curtidas

Boa ideia! Implantarei uma atualização

3 curtidas

Onde pesquisar por “Tarefas Agendadas”? (Novato pedindo ajuda, obrigado)

“Scheduled Tasks” é o Agendador de Tarefas, no Windows 10 e superior, basta pressionar a tecla do Windows e digitar para pesquisar

2 curtidas

Oi. Como recebo este erro?

Para quem estiver lendo isto, aqui estão instruções melhores/mais atualizadas, já que tive um pouco de dificuldade com as instruções do OP:

  1. Crie/Use uma pasta onde este script será armazenado. Em seguida, crie uma pasta chamada backup dentro dessa pasta.

  2. Copie/cole o script no Bloco de Notas. OBSERVAÇÃO: Se estiver usando um VPS, use o nome de usuário do seu VPS e o endereço IP público para a linha $ssh_address = \"username@your.site\". Salve como qualquernome.ps1 e não se esqueça de definir a caixa suspensa para "Todos os Arquivos", como mostrado abaixo.
    hhhh

  3. Pressione a Tecla Windows ⊞ e digite "Tarefas", depois clique em "Agendador de Tarefas".

  4. No lado direito, clique em "Criar Tarefa Básica".

  5. Dê qualquer nome/descrição.

  6. Escolha se você quer diário/semanal/anual/etc. Eu recomendo Diário.

  7. Defina a data e hora que você deseja fazer isso. Mantenha Recorrer em 1. Certifique-se de ir para as configurações de Administrador do seu site Discourse > Backups. Marque a caixa ao lado de backups automáticos ativados.
    Em seguida, defina a frequência de backup para o que você quiser. Eu recomendo 1, mas o ponto principal aqui é fazer com que isso corresponda às suas configurações do Agendador de Tarefas. Faça as datas de backup coincidirem. Exemplo: se você definiu o Agendador de Tarefas para fazer backup Diariamente, defina suas configurações de frequência de backup do Admin para 1.

  8. Deixe a configuração padrão em "iniciar um programa" e clique em Avançar.

  9. Clique em Procurar e encontre o script que você salvou. Clique em Avançar.

  10. Clique em Concluir.
    Se você quiser testar, clique com o botão direito no script e escolha "Executar com Powershell".

Observação: Se você receber "o sistema não consegue encontrar o arquivo especificado", digite sua senha como é mostrado no PowerShell e ele a encontrará de qualquer maneira.

1 curtida

Quando salvei o script PS (apenas editei meu nome de usuário e endereço IP na segunda linha), e cliquei com o botão direito > Executar com PowerShell, nada aconteceu.
Um flash acontece. E se eu já tiver um terminal aberto no meu win11, esse terminal é trazido para a frente. Nada mais. Apenas um flash.

Eu estava me perguntando, embora eu tenha dado meu nome de usuário e endereço IP ao script, como ele usaria minha chave SSH para fazer login e puxar o backup?

Obrigado.!

Eu tentei a solução do OP e a do 45thj5ej e nenhuma delas funcionou para mim. Ao executar o script com o Powershell, ele não encontra “/backups/” e nem o item filho. Também não consigo encontrar onde o OP menciona que você deve inserir seu nome de usuário e senha. Estou executando o Discourse em um VPS.