在 PowerShell 中使用 WinSCP .NET 程序集监视 FTP 服务器上上传的文件
Monitoring uploaded files on FTP server using WinSCP .NET assembly in PowerShell
我正在尝试编写 PowerShell 脚本,当新文件放在 FTP 上时可以发送电子邮件(我不是 FTP 的所有者,所以我不能做定时作业)。
我遇到了一个错误,因为我正在使用 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:\script\Rapport.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()
}
提前致谢,祝您愉快
根据您现有的代码,我认为您以错误的方式使用了 contains。
包含用于确认数组中是否包含匹配值
您的代码正在尝试检查“True”字符串是否作为文件包含在您之前对文件进行过滤的结果中。这行不通。
根据您的过滤器,您可以使用 count 而不是 contains,它应该会提供更好的结果:
if (($H).Count -gt 0")
{
# There are at least 1 new file in your filter
}
else
{
# No new files in your filter
}
让我建议移动到一个更简单的模块来连接和使用 FTP 文件:
PowerShell FTP Client Module 来自 TechNet PowerShell Gallery 看起来非常友好。
你想要这样的东西:
$H = $session.ListDirectory($path) |
Where-Object {! $_.IsDirectory} |
Group-Object ...
另一种实现方式,参见 WinSCP 示例
Watching for changes in SFTP/FTP server.
我正在尝试编写 PowerShell 脚本,当新文件放在 FTP 上时可以发送电子邮件(我不是 FTP 的所有者,所以我不能做定时作业)。
我遇到了一个错误,因为我正在使用 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:\script\Rapport.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()
}
提前致谢,祝您愉快
根据您现有的代码,我认为您以错误的方式使用了 contains。
包含用于确认数组中是否包含匹配值 您的代码正在尝试检查“True”字符串是否作为文件包含在您之前对文件进行过滤的结果中。这行不通。
根据您的过滤器,您可以使用 count 而不是 contains,它应该会提供更好的结果:
if (($H).Count -gt 0")
{
# There are at least 1 new file in your filter
}
else
{
# No new files in your filter
}
让我建议移动到一个更简单的模块来连接和使用 FTP 文件:
PowerShell FTP Client Module 来自 TechNet PowerShell Gallery 看起来非常友好。
你想要这样的东西:
$H = $session.ListDirectory($path) |
Where-Object {! $_.IsDirectory} |
Group-Object ...
另一种实现方式,参见 WinSCP 示例 Watching for changes in SFTP/FTP server.