Мониторинг загруженных файлов на FTP-сервере с использованием сборки WinSCP .NET в PowerShell

#powershell #ftp #winscp #winscp-net

#powershell #ftp #winscp ( винскп ) #winscp-net #winscp

Вопрос:

Я пытаюсь написать скрипт PowerShell, который может отправлять электронное письмо, когда новый файл попадает на FTP (я не владелец FTP, поэтому я не могу выполнить задание cron).

Я получил сообщение об ошибке, потому что я использую Contains метод и после некоторых исследований Contains не работает через FTP.

Я не знаю другого способа выполнить эту работу. Кто — нибудь может помочь мне в моем невежестве здесь ?

Вот сценарий, который я написал :

 # Charger l'ensemble .NET de WinSCP
Add-Type -Path "WinSCPnet.dll"

# Configurer les options de session
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Ftp
    HostName = "xxxxxx"
    UserName = "xxxxxx"
    Password = "xxxxxx"
}

$sessionOptions.AddRawSettings("ProxyHost", "xxxxxx")
$sessionOptions.AddRawSettings("ProxyPort", "xxxxxx")
$sessionOptions.AddRawSettings("FtpProxyLogonType", "xxxxxx")

$session = New-Object WinSCP.Session

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

    # Votre code

    ### FONCTION ENVOI DE MAIL ###
    Function SendMail
    {
        $EXPEDITEUR = "xxxxxx"
        $DESTINATAIRE = "xxxxxx","xxxxxx"
        $SUJET = "xxxxxx"
        $SERVEUR_SMTP = "xxxxxx" 
        $CORPS_MAIL = "xxxxxx"
        #$PJ = 'c:scriptRapport.txt' # si Pièce jointe
        #$attachment = New-Object System.Net.Mail.Attachment($PJ) #Pour la Pièce jointe
        $Mail_Message = New-Object System.Net.Mail.MailMessage #on créé l'objet
        $Mail_Message.From = $EXPEDITEUR
        $Mail_Message.Subject = $SUJET
        $Mail_Message.Body = $CORPS_MAIL
        #$Mail_Message.Attachments.Add($PJ)
        $Mail_Adresses = $Mail_Message.To
        if ($DESTINATAIRE -is "System.Array") #Si plusieurs adresses
        {
            foreach ($Adr in $DESTINATAIRE) #on rajoute chaque adresse
            {
                $Mail_Adress = New-Object System.Net.Mail.MailAddress $Adr
                $Mail_Adresses.Add($Mail_Adress)
            }
        }
        else
        {
            $Mail_Adress = New-Object System.Net.Mail.MailAddress $DESTINATAIRE
            $Mail_Adresses.Add($Mail_Adress)
        }
        $SMTPClient = New-Object Net.Mail.SmtpClient($SERVEUR_SMTP, 25) #serveur SMTP et Port
        $SMTPClient.EnableSsl = $false #si SSL activé ou non - Importer le certificat avant?
        $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("xxxxxx", "xxxxxx"); #ICI Login et password du compte mail
        $SMTPClient.Send($Mail_Message) #l'envoi du mail
    }

    ### Déclaration variables ###
    $log="xxxxxx" #
    $dateverif = get-date -format "yyyy_MM_dd_-_HH_mm_ss"

    ### VERIFICATION DES COMMANDES EN ATTENTE ###
    $Date=(Get-Date).AddMinutes(-2)
    #$remotePath = "xxxxxx"
    #$H =Dir $remotePath
    #$path='xxxxxx'
    #$H=Dir $Path |
    $H=$session.Open
        Where-Object {! $_.PsIsContainer}|
        Group-Object -Property {$_.LastWriteTime -ge $date} -AsHashTable -AsString

    $oldOfs,$ofs=$ofs,' , '
    if ($H -eq $null) # Aucun fichier dans le répertoire à surveiller
    {
        echo "$dateverif Aucun fichier trouvé" >> $log
        exit 0
    }
    if ($H.Contains('True')) # Présence de fichiers de moins de 1 jour (1440 minutes)
    {
        Write-Warning "Nouveau rapport d'intervention TowerCast"
        "$($H.True)"
        echo "$dateverif NEW : Nouveau rapport d'intervention de Towercast" >> $log
        echo $H >>$log
        SendMail #Envoi du mail d'alerte
        exit 0
    }
    if ($H.Contains('False')) # Présence de fichiers de plus de 1 jour (1440 minutes)
    {
        Write-Warning "Pas de nouveau rapport"
        "$($H.False)"
        echo "$dateverif Aucun nouveau rapport" >> $log
        exit 0
    }
    $ofs=$oldOfs
}
finally
{
    $session.Dispose()
}
  

Заранее спасибо и хорошего дня

Ответ №1:

Вы хотите что-то вроде этого:

 $H = $session.ListDirectory($path) |
     Where-Object {! $_.IsDirectory} |
     Group-Object ...
  

Для другой реализации см. Пример WinSCP для
Отслеживание изменений на SFTP / FTP-сервере.

Ответ №2:

Я думаю, что из вашего существующего кода вы используете contains неправильно.

содержит используется для подтверждения, содержится ли соответствующее значение в массиве Ваш код пытается проверить, содержится ли строка «True» в виде файла, полученного в результате вашего предыдущего фильтрации файлов. Это не сработает.

Основываясь на вашем фильтре, вместо contains вы можете использовать count, это должно дать лучшие результаты:

 if (($H).Count -gt 0")
{
# There are at least 1 new file in your filter
}
else
{
# No new files in your filter
}
  

Позвольте мне предложить перейти к более простому модулю для подключения и воспроизведения файлов FTP:

Модуль FTP-клиентаPowerShell из галереи TechNet PowerShell выглядит очень дружелюбно.

Комментарии:

1. Спасибо @Klausen Я пытался заменить contains на count , но если для count установлено значение 0 , я всегда получаю электронное письмо, а если для него установлено значение 1 , я его никогда не получаю. Я думаю, что я неправильно реализовал count … Обновленная версия скрипта находится здесь: pastebin.com/MHCX1sjp

2. Что касается галереи TechNet PowerShell, я взглянул, но она не кажется мне более дружественной. Возможно, мне следует пойти дальше с этим. Но, насколько мне известно, я добьюсь успеха и с моим первым методом ^^

3. Я вижу, вы пробовали с числом в кавычках. Это позволяет Powershell обрабатывать его как текст: (($H). Количество -gt «0»). Вы должны использовать номер без них, чтобы он обрабатывался как число: (($ H). Количество — gt 0). Совет по устранению неполадок: после выполнения кода в консоли вы все еще можете перейти к терминальным переменным печати, используемым в сеансе, и т.д. Для устранения неполадок. Это должно помочь в устранении неполадок для любого созданного вами сценария Powershell.

4. @Klausen Вы неверно истолковываете, как .Contains() используется в примере. Это группируемая хэш-таблица, в которой $H['True'] будут перечислены элементы, соответствующие критериям ( $_.LastWriteTime -ge $date ), и $H['False'] будут перечислены те, которые не соответствуют.

5. @notjustme спасибо за замечание! Всегда рад узнать что-то новое. Возможно, я неправильно истолковал этот код. Я не нахожу это документированным. Не могли бы вы указать мне на какую-нибудь документацию, где я могу прочитать об этом, пожалуйста?