Powershell 格式化 FTPS 列表输出以获取最新的文件戳

Powershell format FTPS list output to get newest file stamp

为了监控写入远程 FTPS 服务器的备份,我能够在 Powershell 中从服务器请求文件列表。 但是,我不确定如何处理输出以便从最新文件中获取时间戳。

也许有更好的方法,但这是我目前的代码,输出如下。

# Create an FTPWebRequest object to handle the connection to the FTP server
$sourceuri = "ftp://192.168.1.4/ROOT/CobianBackups"
$ftprequest = [System.Net.FtpWebRequest]::Create($sourceuri)

# Set the request's network credentials for an authenticated connection
$username = "admin" #Change username when done
$password = "xxx"
$ftprequest.Credentials = New-Object System.Net.NetworkCredential($username,$password)

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { return $true } #ignore unsigned SSL cert, UNSECURE! Get signed SSL
# Set FTPWebRequest method to ListDirectory
$ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::ListDirectoryDetails
$ftprequest.EnableSsl = $True
$ftprequest.UseBinary = $False
$ftprequest.UsePassive = $True
$ftprequest.KeepAlive = $False

$ftpresponse = $ftprequest.GetResponse()

#Write-Host $ftpresponse.StatusCode
#Write-Host $ftpresponse.StatusDescription


$reader = New-Object IO.StreamReader $ftpresponse.GetResponseStream() 
    $reader.ReadToEnd()
    $reader.Close()

echo $reader

输出:

-rw-rw-rw-   1 admin    users       137233604 Sep 30 13:41  OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-30 13;36;52 (Full).zip
-rw-rw-rw-   1 admin    users       138556255 Sep 30 19:48  OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-30 19;36;18 (Full).zip
-rw-rw-rw-   1 admin    users       139217601 Oct  1 00:12  OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-10-01 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       698303741 Sep  3 00:05 HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-03 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       699470009 Sep  4 00:06 HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-04 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       700639919 Sep  5 00:06 HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-05 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       698361150 Sep  6 00:06 HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-06 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       699553508 Sep  7 00:06 HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-07 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       700758345 Sep  8 00:06 HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-08 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       698512347 Sep  9 00:06 HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-09 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       699752013 Sep 10 00:06 HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-10 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       701003563 Sep 11 00:06 HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-11 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       698883380 Sep 12 00:06 HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-12 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       700251730 Sep 13 00:06 HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-13 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       701612056 Sep 14 00:08 HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-14 00;00;04 (Full).zip
-rwxrwxrwx   1 admin    users              79 Sep 14 00:15 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-14 00;14;59 (Full).zip
-rwxrwxrwx   1 admin    users       137231884 Sep 14 07:38 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-14 07;35;22 (Full).zip
-rwxrwxrwx   1 admin    users       138496696 Sep 14 14:59 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-14 14;55;24 (Full).zip
-rwxrwxrwx   1 admin    users       136790964 Sep 15 00:03 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-15 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       138052042 Sep 16 00:03 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-16 00;00;04 (Full).zip
-rwxrwxrwx   1 admin    users       139355293 Sep 17 00:03 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-17 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       137115162 Sep 18 00:03 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-18 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       138536791 Sep 19 00:03 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-19 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       139959405 Sep 20 00:04 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-20 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       137663847 Sep 21 00:03 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-21 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       138945285 Sep 22 00:03 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-22 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       140230350 Sep 23 00:03 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-23 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       137699171 Sep 24 00:03 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-24 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       138988930 Sep 25 00:03 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-25 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       140287732 Sep 26 00:03 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-26 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       137764807 Sep 27 00:04 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-27 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       139063256 Sep 28 00:03 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-28 00;00;03 (Full).zip
-rwxrwxrwx   1 admin    users       140365349 Sep 29 00:03 OpenVPN + HTDOCS + Apache conf+  exported databases backup to NAS01 2017-09-29 00;00;03 (Full).zip


CurrentEncoding BaseStream EndOfStream
--------------- ---------- -----------

可以使用一个或多个连续空格作为分隔符,这将导致日期位于第 6 列(月)、第 7 列(天)和第 8 列(时间),但我不确定该怎么做,我不要认为这将是最好的解决方案,因为它会在输出更改后立即中断。

有什么想法吗?我真的只需要最新文件的日期时间戳,这样我就可以计算自上次备份以来的时间。获取数组中的输出会更好,因为我将来可以将该脚本用于其他目的。

希望你能帮助我。

-贾森

尝试String.Split method

$reader.Split([char[]]"`n") |
ForEach-Object {, $_.Split([char[]]$null, [StringSplitOptions]::RemoveEmptyEntries)} |
ForEach-Object {"$($_[5..7])"}

可以通过正则表达式实现更多控制

$reader |
Select-String '\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec|Sep)\s(\d\d)\s(\d\d:\d\d)\s' -AllMatches |
ForEach-Object {$_.Matches} |
ForEach-Object {, ($_.Groups[1..3] | Select-Object -ExpandProperty Value)} |
ForEach-Object {$_[0] + ' ' + $_[1] + ' ' + $_[2]}

编辑: Andrei Odegov 使用新的正则表达式更新了他们的解决方案,因此我想提供基于该解决方案的变体而不是我之前的答案。

一旦您 $dirlist 似乎您正在采取可能不需要的额外步骤来实现您的目标。请尝试以下操作:

# Create an FTPWebRequest object to handle the connection to the FTP server
clear
$sourceuri = "ftp://192.168.1.4/ROOT/CobianBackups"
$ftprequest = [System.Net.FtpWebRequest]::Create($sourceuri)

# Set the request's network credentials for an authenticated connection
$username = "admin" #Change username when done
$password = "xxx"
$ftprequest.Credentials = New-Object System.Net.NetworkCredential($username,$password)

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { return $true } #ignore unsigned SSL cert, UNSECURE! Get signed SSL
# Set FTPWebRequest method to ListDirectory
$ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::ListDirectoryDetails
$ftprequest.EnableSsl = $True
$ftprequest.UseBinary = $False
$ftprequest.UsePassive = $True
$ftprequest.KeepAlive = $False

Remove-Variable ftpresponse
$ftpresponse = $ftprequest.GetResponse()
#Write-Host $ftpresponse.StatusCode
#Write-Host $ftpresponse.StatusDescription

Remove-Variable reader
$reader = New-Object IO.StreamReader $ftpresponse.GetResponseStream() 
    $dirlist = $reader.ReadToEnd()
    $reader.Close()

echo "raw output:"
$dirlist

$dateArray = $dirlist | Select-String -Pattern "((?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec|Sep)\s(s|\d)\d\s\d{2}:\d{2})" | % {$_.Matches} |  % {[datetime]::parseexact($_.Value, 'MMM dd HH:mm', $null)} | Sort-Object

echo "DateTime Sorted:"
$dateArray

echo "Last file:"
$dateArray[-1]

Select-String 的结果可以在管道中转换为 [DateTime],并在同一管道中使用 Sort-Object 进行排序,默认情况下按升序排序。

一旦到达最后一个文件,$array[-1] 将 return 数组中的最后一项,无需获取长度即可实现此目的。

在摆弄 Select 之后,我放弃并尝试了另一种方法。 (我一直收到关于正则表达式不正确的错误。)

使用 Andrei Odegov 的代码片段,我拆分了 $dirlist 并从文件名中选择了日期和时间,而不是实际的修改日期。为此,我删除了一些较旧的备份,以便所有文件在第 19 个和第 20 个对象上都有日期和时间。此日期包括年份,当存在超过一年的文件时可能会避免出现问题。

然后我把这些日期处理成$dateArray,然后排序,最后得到了一个不错的结果!

下面是最终代码,因为这个脚本的目的是获取自上次备份到我的 PRTG 网络监视器以来的时间(以分钟为单位),我也包含了该代码。

# Create an FTPWebRequest object to handle the connection to the FTP server
clear
$sourceuri = "ftp://192.168.1.4/ROOT/CobianBackups" #Full path to folder
$ftprequest = [System.Net.FtpWebRequest]::Create($sourceuri)

# Set the request's network credentials for an authenticated connection
$username = "username"
$password = "password"
$ftprequest.Credentials = New-Object System.Net.NetworkCredential($username,$password)

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { return $true } #ignore unsigned SSL cert, UNSECURE! Get signed SSL
# Set FTPWebRequest method to ListDirectory
$ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::ListDirectoryDetails
$ftprequest.EnableSsl = $True
$ftprequest.UseBinary = $False
$ftprequest.UsePassive = $True
$ftprequest.KeepAlive = $False

Remove-Variable ftpresponse
$ftpresponse = $ftprequest.GetResponse()
#Write-Host $ftpresponse.StatusCode
#Write-Host $ftpresponse.StatusDescription

Remove-Variable reader
$reader = New-Object IO.StreamReader $ftpresponse.GetResponseStream() 
    $dirlist = $reader.ReadToEnd()
    $reader.Close()

Remove-Variable rawdates
$rawdates = $dirlist.Split([char[]]"`n") |
ForEach-Object {, $_.Split([char[]]$null, [StringSplitOptions]::RemoveEmptyEntries)} |
ForEach-Object {"$($_[19..20])"}


Remove-Variable dateArray
foreach ($element in $rawdates){
$date = [datetime]::parseexact($element, 'yyyy-MM-dd HH;mm;ss', $null)
[DateTime[]]$dateArray += $date
}

[Array]::Sort($dateArray)

$dateArray[-1]
$DateNow = Get-Date
$DateDif = $DateNow - $dateArray[-1]
$DateDif.TotalMinutes

#Final output to PRTG (write-host VALUE:MESSAGE)
write-host $DateDif.TotalMinutes: Last backup executed at $dateArray[-1] which is ($DateDif.Days) days, ($DateDif.Hours) hours, ($DateDif.Minutes) minutes ago

感谢大家的贡献!

-贾森