Загружать файлы из массива с SFTP-сервера с помощью WinSCP в PowerShell, только если файлы существуют

У меня есть этот код PowerShell.

У меня небольшая проблема:

  • Я скачиваю два удаленных файла Device.log и Saveinfo.dat; Не все машины имеют одновременно device.log и saveinfo.dat. На некоторых машинах есть только device.log, и когда я пробую на машинах, на которых только device.log, скрипт терпит неудачу. Что я могу сделать?

  • Если на машине есть оба файловых архива вместе, и если на машине есть только device.log архив, только этот файл (device.log).

Спасибо

Add-Type -Path "C:\Program Files (x86)\WinSCP\WinSCPnet.dll"
 
$db = import-csv -Path "C:\Program Files (x86)\WinSCP\db.csv"
 
$inputID = Read-Host -Prompt "ID"
 
$entry = $db -match $inputID

Write-Host "IP:" $entry.IP

    $User = "user"
    $Password = "password"
    $Command = "C:\SaveBVInfo.exe"

    $secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
    $Credentials = New-Object System.Management.Automation.PSCredential($User, $secpasswd)

Get-SSHTrustedHost | Remove-SSHTrustedHost

$SessionID = New-SSHSession -ComputerName $entry.IP -Credential $Credentials -AcceptKey:$true

Invoke-SSHCommand -Index $sessionid.sessionid -Command $Command

# Set up session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Sftp
    HostName = $entry.IP
    UserName = "$User"
    Password = "$Password"
    GiveUpSecurityAndAcceptAnySshHostKey = "true"
}
 
$session = New-Object WinSCP.Session

$file = "Device.log", "SaveBVInfo.dat"
$localPath = "E:\loguri\Log\Arhive\*"
$remotePath = "/C:/Program Files/Common Files/logs/Device.log", "/C:/Program Files/Pc/SaveBVInfo.dat"
 
try {

    # Connect
    $session.Open($sessionOptions)

    # Check files exists
 
        if ($session.FileExists($remotePath))
        {
            Write-Host "File $remotePath exists"
            # Transfer files

            $session.GetFiles($remotePath, $localPath).Check()
 
            exit 0
        }
        else
        {
            Write-Host "File $remotePath does not exist"
            exit 1
        }
}
finally {
    $session.Dispose()
}
foreach ($file in "E:\loguri\Log\Arhive\Device.log", "E:\loguri\Log\Arhive\SaveBVInfo.dat") {
    Compress-Archive $file -DestinationPath "E:\Arhive\$inputID.zip" -Update
    Remove-Item $file -Force
}

person Bogdan    schedule 29.01.2021    source источник


Ответы (2)


Вы не можете передавать массивы PowerShell в методы .NET, которые не принимают массивы.

Вы должны обрабатывать свои файлы в цикле:

$remotePaths = "/C:/Program Files/Common Files/logs/Device.log", "/C:/Program Files/Pc/SaveBVInfo.dat"
foreach ($remotePath in $remotePaths)
{
    if ($session.FileExists($remotePath))
    {
        Write-Host "File $remotePath exists"
        # Transfer files

        $session.GetFiles($remotePath, $localPath).Check()
    }
    else
    {
        Write-Host "File $remotePath does not exist"
    }
}
person Martin Prikryl    schedule 01.02.2021

Где сценарий терпит неудачу? Я вижу два места, где вы предполагаете, что файлы существуют. Перед тем, как позвонить $session.GetFiles(), вы обязательно должны сначала позвонить $session.FileExists(), чтобы убедиться, что он там. См. https://winscp.net/eng/docs/script_checking_file_existence

Во-вторых, ваш Test-Path будет истинным, если присутствует какой-либо файл, но затем вы добавляете оба в архив независимо от того, был ли там только один. Проверьте каждый файл и затем добавьте его.

foreach ($file in "E:\Arhive\Device.log", "E:\Arhive\Saveinfo.dat") {
    if (Test-Path $file) {
        Compress-Archive $file -DestinationPath "E:\Arhive\$inputID.zip" -Update
        Remove-Item $file
     }
}
person Mark Elvers    schedule 29.01.2021
comment
Привет, Марк, прежде всего еще раз спасибо за вашу помощь. Я редактирую свой вопрос обновленными скриптами, но что-то идет не так ... - person Bogdan; 31.01.2021
comment
Привет, где что-то пошло не так? Ваш блок try никогда никуда не приведет, потому что оба ваших пути имеют exit. Попробуйте удалить exit 0 в случае, если файл существует, и переместите exit 1 в блок finally. - person Mark Elvers; 31.01.2021
comment
Я исправляю эту проблему. (Сценарий Мартина) Независимо от того, что ваш Compress-Archive работает очень хорошо, но если у меня есть только Device.log для архива, архив сценария в порядке, но код возврата Saveinfo.dat отсутствует или что-то в этом роде. Могу ли я исправить эту незначительную проблему? (ненавижу красный) :)) (Примерно так, если Saveinfo.dat не существует, пожалуйста, за исключением его без кода ошибки вывода) Еще раз спасибо за вашу помощь. - person Bogdan; 01.02.2021
comment
Я добавил Test-Path в цикл, который должен избавиться от красного. - person Mark Elvers; 01.02.2021
comment
Отлично, теперь все работает очень хорошо. Еще раз спасибо, Марк. - person Bogdan; 01.02.2021