使用我的脚本,我试图扫描一个目录,找到每天自动创建的子目录,其中包含目录名中的日期。一旦找到昨天的日期(因为我需要上传前一天),它会查找另一个子目录,然后查找包含“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文件,但我没有任何运气打破脚本。
答案 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
}