英文:
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['HostName'] = $vpnIP
$options['UserName'] = $User
$options['Password'] = $Password
try {
$sessionOptions = New-Object WinSCP.SessionOptions -Property $options
$session = New-Object WinSCP.Session
# Try Connect
$session.Open($sessionOptions)
}
catch {
Write-Error "Could not open WinSCP session: $($_.Exception.Message)"
throw
}
}
# Date 1 START
do {
$date = $null
$today = Read-Host -Prompt ('Enter START date (inclusive) (e.g. {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} Valid date - OK!' -f $date
}
catch {
'[X] {0} Invalid date!' -f $today
}
}
until ($date)
# Date 2 STOP
do {
$date1 = $null
Write-Host "Add +1 day" -ForegroundColor Red
$today1 = Read-Host -Prompt ('Enter END date (exclusive) (e.g. {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} Valid date - OK!' -f $date1
}
catch {
'[X] {0} Invalid date!' -f $today1
}
}
until ($date1)
# ----- Date END
$session = New-Object WinSCP.Session
$file = "*.log"
$localPath = "\temp_files"
$remotePath = "/C:/log", "/C:/Back_up"
try {
# Connect
$session.Open($sessionOptions)
# Check exists folder
foreach ($remotePath in $remotePath)
{
if ($session.FileExists($remotePath))
{
Write-Host "[OK] Folder '$remotePath' exist" -ForegroundColor Green
# Transfer file
Write-Host "[i] '$date' - '$date1' > '$inputID' downloading..." -ForegroundColor Cyan
$session.GetFilesToDirectory($remotePath, $localPath, "*.log>=$date<=$date1").Check();
}
else
{
Write-Host "[X] INFO: Folder: '$remotePath' doesn't exist" -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 = "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)
}
The code assumes that $date
and $date1
are actual DateTime
objects, not strings. So you need to remove the -Format "yyyy-MM-dd"
from the Get-Date
calls.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论