检查 WinSCP 是否在两个日期之间的每一天下载了文件。

huangapple go评论62阅读模式
英文:

Check if WinSCP downloaded files for every day between two dates

问题

我有这个脚本来收集两个日期之间的日志文件。通常我在远程机器上每天都有创建日志,但是否有可能显示存在或不存在的文件呢?

例如,如果我尝试在两个日期25.06 - 30.06之间下载文件,而在远程机器上没有来自28.06的日志,就在控制台中打印出来。

25.06,26.06,27.06,29.06,30.06 日志下载成功
[!] 警告 28.06 远程机器上的日志不存在!

# 设置会话选项
$options = @{
    Protocol = [WinSCP.Protocol]::Sftp
    HostName = $entry.IP
    UserName = $User
    Password = $Password
    GiveUpSecurityAndAcceptAnySshHostKey = $true
}

try {
    # 使用第一个密码设置会话选项
    $sessionOptions = New-Object WinSCP.SessionOptions -Property $options
    $session = New-Object WinSCP.Session
    # 尝试连接
    $session.Open($sessionOptions)
} 
catch {
    # 使用第二个设置设置会话选项
    $options['HostName'] = $vpnIP
    $options['UserName'] = $User
    $options['Password'] = $Password
    try {
        $sessionOptions = New-Object WinSCP.SessionOptions -Property $options
        $session = New-Object WinSCP.Session
        # 尝试连接
        $session.Open($sessionOptions)
    }
    catch {
        Write-Error "无法打开 WinSCP 会话: $($_.Exception.Message)"
        throw
    }
}

# 日期1 起始
do {
    $date = $null
    $today = Read-Host -Prompt ('输入起始日期(包括在内)(例如 {0})[yyyy.MM.dd]' -f (Get-Date -Format "yyyy.MM.dd"))

    try {
        $date = Get-Date -Date $today -Format "yyyy-MM-dd" -ErrorAction Stop
        '[OK] {0} 有效日期 - OK!' -f $date
    }
    catch {
        '[X] {0} 无效日期!' -f $today
    }
}
until ($date)

# 日期2 停止

do {
    $date1 = $null
    Write-Host "添加 +1 天" -ForegroundColor Red
    $today1 = Read-Host -Prompt ('输入结束日期(不包括在内)(例如 {0})[yyyy.MM.dd]' -f (Get-Date -Format "yyyy.MM.dd"))

    try {
        $date1 = Get-Date -Date $today1 -Format "yyyy-MM-dd" -ErrorAction Stop
        '[OK] {0} 有效日期 - OK!' -f $date1
    }
    catch {
        '[X] {0} 无效日期!' -f $today1
    }
}
until ($date1)

# ----- 日期结束

$session = New-Object WinSCP.Session

$file = "*.log"
$localPath = "\temp_files" 
$remotePath = "/C:/log", "/C:/Back_up"

try {
    # 连接
    $session.Open($sessionOptions)

    # 检查文件夹是否存在
    foreach ($remotePath in $remotePath)
    {
        if ($session.FileExists($remotePath))
        {
            Write-Host "[OK] 文件夹 '$remotePath' 存在" -ForegroundColor Green

            # 传输文件
            Write-Host "[i] '$date' - '$date1' > '$inputID' 正在下载..." -ForegroundColor Cyan

            $session.GetFilesToDirectory($remotePath, $localPath, "*.log>=$date<=$date1").Check();
        }
        else
        {
            Write-Host "[X] INFO: 文件夹: '$remotePath' 不存在" -ForegroundColor Red
        }
    }
}
finally {
    $session.Dispose()
}

谢谢。

英文:

I have this script to collect logs file between two dates. Normally I have logs created for everyday on remote machine but is there any possibility to show what file exist or not?

For example If I try to download file between two dates 25.06 - 30.06 and on remote machine doesn't exist log from 28.06 print in console.

> 25.06,26.06,27.06,29.06,30.06 log downloaded successfully
> [!] warning 28.06 log doesn't exist on remote machine!

# Set up session options
$options = @{
Protocol = [WinSCP.Protocol]::Sftp
HostName = $entry.IP
UserName = $User
Password = $Password
GiveUpSecurityAndAcceptAnySshHostKey = $true
}
try {
# Set up session options using first password
$sessionOptions = New-Object WinSCP.SessionOptions -Property $options
$session = New-Object WinSCP.Session
# Try Connect
$session.Open($sessionOptions)
} 
catch {
# Set up session options using second settings
$options[&#39;HostName&#39;] = $vpnIP
$options[&#39;UserName&#39;] = $User
$options[&#39;Password&#39;] = $Password
try {
$sessionOptions = New-Object WinSCP.SessionOptions -Property $options
$session = New-Object WinSCP.Session
# Try Connect
$session.Open($sessionOptions)
}
catch {
Write-Error &quot;Could not open WinSCP session: $($_.Exception.Message)&quot;
throw
}
}
# Date 1 START
do {
$date = $null
$today = Read-Host -Prompt (&#39;Enter START date (inclusive) (e.g. {0}) [yyyy.MM.dd]&#39; -f (Get-Date -Format &quot;yyyy.MM.dd&quot;))
try {
$date = Get-Date -Date $today -Format &quot;yyyy-MM-dd&quot; -ErrorAction Stop
&#39;[OK] {0} Valid date - OK!&#39; -f $date
}
catch {
&#39;[X] {0} Invalid date!&#39; -f $today
}
}
until ($date)
# Date 2 STOP
do {
$date1 = $null
Write-Host &quot;Add +1 day&quot; -ForegroundColor Red
$today1 = Read-Host -Prompt (&#39;Enter END date (exclusive) (e.g. {0}) [yyyy.MM.dd]&#39; -f (Get-Date -Format &quot;yyyy.MM.dd&quot;))
try {
$date1 = Get-Date -Date $today1 -Format &quot;yyyy-MM-dd&quot; -ErrorAction Stop
&#39;[OK] {0} Valid date - OK!&#39; -f $date1
}
catch {
&#39;[X] {0} Invalid date!&#39; -f $today1
}
}
until ($date1)
# ----- Date END
$session = New-Object WinSCP.Session
$file = &quot;*.log&quot;
$localPath = &quot;\temp_files&quot; 
$remotePath = &quot;/C:/log&quot;, &quot;/C:/Back_up&quot;
try {
# Connect
$session.Open($sessionOptions)
# Check exists folder
foreach ($remotePath in $remotePath)
{
if ($session.FileExists($remotePath))
{
Write-Host &quot;[OK] Folder &#39;$remotePath&#39; exist&quot; -ForegroundColor Green
# Transfer file
Write-Host &quot;[i] &#39;$date&#39; - &#39;$date1&#39; &gt; &#39;$inputID&#39; downloading...&quot; -ForegroundColor Cyan
$session.GetFilesToDirectory($remotePath, $localPath, &quot;*.log&gt;=$date&lt;=$date1&quot;).Check();
}
else
{
Write-Host &quot;[X] INFO: Folder: &#39;$remotePath&#39; doesn&#39;t exist&quot; -ForegroundColor Red
}
}
}
finally {
$session.Dispose()
}

Thank you.

答案1

得分: 2

你可以分析Session.GetFilesToDirectory返回的传输文件列表,以找出在范围内的所有日期是否有下载(你已经知道了)。但在我看来,更简单的方法是逐日进行,分别下载每天的日志并简单地检查是否下载了任何日志。

$d = $date
while ($d -le $date1)
{
    $f = "yyyy-MM-dd"
    $start = $d.ToString($f)
    $end = $d.AddDays(1).ToString($f)
    $mask = "*.log>=$start<$end"
    Write-Host "Downloading logs for $start..."

    $transferResult = $session.GetFilesToDirectory($remotePath, $localPath, $mask)
    $transferResult.Check()

    $c = $transferResult.Transfers.Count
    if ($c -gt 0)
    {
        Write-Host "$c logs for $start were downloaded"
    }
    else
    {
        Write-Host "NO logs for $start were downloaded"
    }

    $d = $d.AddDays(1)
}

这段代码假设$date$date1是实际的DateTime对象,而不是字符串。因此,你需要从Get-Date调用中移除-Format "yyyy-MM-dd"

英文:

You can analyze the list of transferred files returned by Session.GetFilesToDirectory to find out if there any download for all days in the range (you know that already).

But imo, way easier would be to go day-by-day, downloading respective day logs separately and simply checking, if any log was downloaded at all.

$d = $date
while ($d -le $date1)
{
$f = &quot;yyyy-MM-dd&quot;
$start = $d.ToString($f)
$end = $d.AddDays(1).ToString($f)
$mask = &quot;*.log&gt;=$start&lt;$end&quot;
Write-Host &quot;Downloading logs for $start...&quot;
$transferResult = $session.GetFilesToDirectory($remotePath, $localPath, $mask)
$transferResult.Check()
$c = $transferResult.Transfers.Count
if ($c -gt 0)
{
Write-Host &quot;$c logs for $start were downloaded&quot;
}
else
{
Write-Host &quot;NO logs for $start were downloaded&quot;
}
$d = $d.AddDays(1)
}

The code assumes that $date and $date1 are actual DateTime objects, not strings. So you need to remove the -Format &quot;yyyy-MM-dd&quot; from the Get-Date calls.

huangapple
  • 本文由 发表于 2023年7月23日 16:02:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76747210.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定