Скопируйте файлы на FTP и заархивируйте с сегодняшней датой

Мне нужно создать сценарий, который выполняет следующие действия:

  1. Копирует все файлы в папке на FTP-сайт.
  2. Если копирование прошло успешно, переместите файлы в архив.
  3. В архиве должна быть только что созданная папка с сегодняшней датой (чтобы мы знали, когда они были отправлены).

Я пытался каннибализировать другие сценарии, чтобы что-то работало, но я ничего не добился, поэтому мне нужна помощь. Я работал над этим часами.

Я использую WinSCP DLL только потому, что мой другой (рабочий) скрипт использует SFTP, который в нем нуждается. Я знаю, что обычный FTP этого не делает, но я не смог найти легко переносимого кода, поэтому вместо этого попытался его изменить.

Итак, вот код, который у меня есть, который даже не запускается, не говоря уже о правильном запуске, может ли кто-нибудь помочь мне разобраться? Извините, это немного беспорядок.

param (
    $localPath = "c:\test\source",
    $remotePath = "/upload",
    $folder = ($_.CreationTime | Get-Date -Format yyyyMMdd)
    # not sure this works but don't see how to point the destination
    # to the newly created folder
    $backupPath = "c:\test\destination\$folder"  
)

try
{
    # Load WinSCP .NET assembly
    Add-Type -Path "C:\Windows\System32\WindowsPowerShell\v1.0\WinSCPnet.dll"

    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
        Protocol = [WinSCP.Protocol]::ftp
        HostName = "xxxxxxxx"
        UserName = "xxxxxxxx"
        Password = "xxxxxxxx"
    }

    $session = New-Object WinSCP.Session

    try
    {
        # Connect
        $session.Open($sessionOptions)

        # Upload files, collect results
        $transferResult = $session.PutFiles($localPath, $remotePath)

        # Iterate over every transfer
        foreach ($transfer in $transferResult.Transfers)
        {
            # Success or error?
            if ($transfer.Error -eq $Null)
            {
                # If today's folder doesn't exist, create it
                if (!(Test-Path $BackupPath))
                {
                    New-Item -ItemType Directory -Force -Path $BackupPath
                }

                Write-Host ("Upload of {0} succeeded, moving to Uploaded folder" -f
                    $transfer.FileName)
                # Upload succeeded, move source file to backup
                Move-Item $transfer.FileName $backupPath
            }
            else
            {
                Write-Host ("Upload of {0} failed: {1}" -f
                    $transfer.FileName, $transfer.Error.Message)
            }
        }
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }

    exit 0
}
catch [Exception]
{
    Write-Host ("Error: {0}" -f $_.Exception.Message)
    exit 1
}

Вот и код. Я счастлив использовать встроенный PowerShell для FTP, чтобы упростить его, я просто хочу, чтобы он работал.


person SysAdminUK    schedule 24.11.2017    source источник


Ответы (1)


Я не уверен, что вас беспокоит с кодом. Выглядит неплохо, за исключением синтаксической ошибки при установке $folder:

Почему вы даже пытаетесь использовать $_.CreationTime в качестве отметки времени папки? Просто используйте текущую дату:

$folder = (Get-Date -Format "yyyyMMdd")

См. Форматирование временных меток в PowerShell в документации WinSCP.

Также не вижу смысла выставлять $folder и $backupPath в блоке params. Переместите его после блока params. Если вы все равно хотите этого, вы должны пропустить запятую после $folder назначения.


В остальном ваш код должен работать.

Вы не можете упростить его, используя встроенные функции FTP в PowerShell (или, скорее, .NET), поскольку он не имеет таких мощных команд, как сборка WinSCP .NET.


Я бы написал код как:

$localPath = "C:\source\local\path\*"
$remotePath = "/dest/remote/path/"
$folder = (Get-Date -Format "yyyyMMdd")
$backupPath = "C:\local\backup\path\$folder"

# If today's folder doesn't exist, create it
if (!(Test-Path $BackupPath))
{
    New-Item -ItemType Directory -Force -Path $BackupPath | Out-Null
}

try
{
    # Load WinSCP .NET assembly
    Add-Type -Path "WinSCPnet.dll"

    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
        Protocol = [WinSCP.Protocol]::ftp
        HostName = "ftp.example.com"
        UserName = "username"
        Password = "password"
    }

    $session = New-Object WinSCP.Session

    try
    {
        # Connect
        $session.Open($sessionOptions)

        # Upload files, collect results
        $transferResult = $session.PutFiles($localPath, $remotePath)

        # Iterate over every transfer
        foreach ($transfer in $transferResult.Transfers)
        {
            # Success or error?
            if ($transfer.Error -eq $Null)
            {
                Write-Host ("Upload of $($transfer.FileName) succeeded, " +
                    "moving to backup")
                # Upload succeeded, move source file to backup
                Move-Item $transfer.FileName $backupPath
            }
            else
            {
                Write-Host ("Upload of $($transfer.FileName) failed: " +
                    "$($transfer.Error.Message)")
            }
        }
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }

    exit 0
}
catch [Exception]
{
    Write-Host "Error: $($_.Exception.Message)"
    exit 1
}

На основе перемещения локальных файлов в другое место после успешной загрузки.

person Martin Prikryl    schedule 24.11.2017
comment
Получил работу после добавления журнала, чтобы увидеть, где что-то пошло не так. Спасибо за помощь! (была проблема с разрешением, мешавшая работе последнего шага) - person SysAdminUK; 30.11.2017