使用PowerShell的WinSCP XML日志确认多个文件上载

时间:2016-07-18 15:20:17

标签: powershell winscp

使用我的脚本,我试图扫描一个目录,找到每天自动创建的子目录,其中包含目录名中的日期。一旦找到昨天的日期(因为我需要上传前一天),它会查找另一个子目录,然后查找包含“JONES”的任何文件。找到这些文件后,它会执行foreach循环以使用winscp.com上传它们。

我的问题是我正在尝试使用winscp创建的.xml日志发送给用户以确认上传。问题是.xml文件仅包含上载的最后一个文件。

这是我的剧本:

# Set yesterday's date (since uploads will happen at 2am)
$YDate = (Get-Date).AddDays(-1).ToString('MM-dd-yyyy')

# Find Directory w/ Yesterday's Date in name
$YesterdayFolder = Get-ChildItem -Path "\\Path\to\server" | Where-Object {$_.FullName.contains($YDate)}

If ($YesterdayFolder) {

    #we specify the directory where all files that we want to upload are contained 
    $Dir= $YesterdayFolder

    #list every sql server trace file
    $FilesToUpload = Get-ChildItem -Path (Join-Path $YesterdayFolder.FullName "Report") | Where-Object {$_.Name.StartsWith("JONES","CurrentCultureIgnoreCase")}

    foreach($item in ($FilesToUpload))
    { 
          $PutCommand = '& "C:\Program Files (x86)\WinSCP\winscp.com" /command "open ftp://USERNAME:PASSWORD@ftps.hostname.com:21/dropoff/ -explicitssl" "put """"' + $Item.FullName + '""""" "exit"' 
          Invoke-Expression $PutCommand         
    } 
} Else {
    #Something Else will go here
}

我觉得我的$PutCommand行都包含在ForEach循环中,每次连接/退出时它都会覆盖xml文件,但我没有任何运气打破脚本。

1 个答案:

答案 0 :(得分:2)

您正在为每个文件反复运行WinSCP。每次运行都会覆盖上一次运行的日志。

仅调用WinSCP一次。它会更好,因为你避免重新连接每个文件。

$FilesToUpload = Get-ChildItem -Path (Join-Path $YesterdayFolder.FullName "Report") |
    Where-Object {$_.Name.StartsWith("JONES","CurrentCultureIgnoreCase")}

$PutCommand = '& "C:\Program Files (x86)\WinSCP\winscp.com" /command "open ftp://USERNAME:PASSWORD@ftps.hostname.com:21/dropoff/ -explicitssl" '

foreach($item in ($FilesToUpload))
{ 
      $PutCommand += '"put """"' + $Item.FullName + '""""" '
} 
$PutCommand += '"exit"'

Invoke-Expression $PutCommand 

虽然你真正需要做的就是检查WinSCP退出代码。如果它是0,一切都很好。无需将XML日志作为证明。

更好的是,使用WinSCP .NET assembly from PowerShell script,而不是从命令行驱动WinSCP。它会为您执行所有错误检查(如果出现任何问题,您会收到异常)。并且你避免了所有令人讨厌的命令行(比如在凭证和文件名中转义特殊符号)。

try
{
    # Load WinSCP .NET assembly
    Add-Type -Path "WinSCPnet.dll"

    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
        Protocol = [WinSCP.Protocol]::Ftp
        FtpSecure = [WinSCP.FtpSecure]::Explicit
        TlsHostCertificateFingerprint = "xx:xx:xx:xx:xx:xx..."
        HostName = "ftps.hostname.com"
        UserName = "username"
        Password = "password"
    }

    $session = New-Object WinSCP.Session

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

        # Upload files
        foreach ($item in ($FilesToUpload))
        {
            $session.PutFiles($Item.FullName, "/dropoff/").Check()
            Write-Host "Upload of $($Item.FullName) succeeded"
        }
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }

    exit 0
}
catch [Exception]
{
    Write-Host "Error: $($_.Exception.Message)"
    exit 1
}