WinSCP를 사용하여 PowerShell에서 어제 파일 다운로드


1

디자인 범위 : PowerShell 및 WinSCP .NET 어셈블리를 사용하여 파일 타임 스탬프를 사용하여 다운로드 할 파일을 식별함으로써 야간 다운로드를 자동화합니다. 연결되어있는 FTP 서버가 IIS이므로 현재 구성에서는 MLSD와 같은 모든 명령을 지원하지 않으므로 요청이있을 경우 변경하지 않습니다.

문제 : 한 달 또는 두 자리 월이있는 파일은 다른 문자열 길이를 반환합니다.이 문제를 해결하는 방법은 확실하지 않습니다. 내 코드는 이제 작동하지만 10 월에 작동을 멈 춥니 다.

예 : March은 03 / dd / yyyy 대신 3 / dd / yyyy를 표시합니다.

기타 참고 사항 : 처음에는 WinSCP.com을 사용하여 스크립팅을 시도했지만 날짜를 올바르게 지정하는 방법을 찾지 못했습니다.

예를 들어, 당신은 지정할 수 있습니다 *.zip>=1D또는 *.zip<=1D, 그러나 *.zip=1D*.zip==1D 현재 WinSCP에의 최신 릴리스에서 지원되지 않습니다.

암호:

$yesterday = [DateTime]::Today.AddDays(-1).ToString("M/dd/yyyy")
# OR I have to use ToString("MM/dd/yyyy") for months 10-12,
# but I need both formats to work.
#delete the temporary file
del .\FTPfiles.txt
# Load WinSCP .NET assembly
Add-Type -Path "C:\Program Files (x86)\WinSCP\WinSCPnet.dll"

# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Ftp
    HostName = "server.com"
    UserName = "joe"
    Password = "smith"
}

$session = New-Object WinSCP.Session

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

        $directory = $session.ListDirectory("/Folder")

        foreach ($fileInfo in $directory.Files)
        {
            Write-Output ("{1} {0}" -f
                $fileInfo.Name, $fileInfo.LastWriteTime) >> FTPfiles.txt
        }
        $fileList = get-content .\FTPfiles.txt | findstr $yesterday
        $stripped = $fileList -creplace '^.*Z12', 'Z12'


        # Download files
        $remotePath = "/Folder/"
        $transferOptions = New-Object WinSCP.TransferOptions
        $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary

        $lines = $stripped

        foreach ($line in $lines)
        {
            Write-Host ("Downloading {0} ..." -f $line)
            $session.GetFiles($remotePath+$line, "C:\Downloads\").Check()
        }

    }


catch [Exception]
{
    Write-Host ("Error: {0}" -f $_.Exception.Message)
    exit 1
}
finally
{
    # Disconnect, clean up
    $session.Dispose()
} 

$fileInfo in $directory.Files쓰기는 마지막으로 쓴 시간과은으로 파일 이름을 FTPfiles.txt지정한 폴더에서 FTP 서버에 포함 된 모든 파일에 대해. 이 텍스트 파일을 읽은 다음 어제 날짜에 발생한 쓰기 시간이있는 파일로 추가로 축소 한 다음 2 자리 대신 월에 1 자리를 사용하는 날짜 형식으로 인해 현재 9 개월 밖에 작동하지 않습니다 .

그 다음 파일은 파일 이름 앞의 날짜를 읽은 후 제거하여 파일 이름을 사용하여 다운로드를 반복합니다. 변환은 다음과 같습니다.

FROM:
3/14/2017 2:04:00 AM Z1234_20170314050001_1.zip
3/14/2017 3:04:00 AM Z1234_20170315060002_1.zip
3/14/2017 4:04:00 AM Z1234_20170316070001_1.zip
3/14/2017 5:04:00 AM Z1234_20170317080001_1.zip

TO:
Z1234_20170314050001_1.zip
Z1234_20170315060002_1.zip
Z1234_20170316070001_1.zip
Z1234_20170317080001_1.zip

그런 다음 스크립트는 그 파일 이름을 사용하여 전날의 필요한 파일을 다운로드합니다.


2
내가 문제 ATM을 보지 못한다. 형식 [DateTime]::Today.AddDays(-1).ToString("M/dd/yyyy")은 10 월에 두 자릿수 달로 확장 될 것이고, 하나의 M은 단지 선행 0을 의미하지 않는다.
LotPings

@LotPings 오른쪽입니다 : 예를 들어, [DateTime]::Today.AddDays(-120).ToString("M/dd/yyyy")반환 (CCA 사개월 전에 날짜) 11/15/2016두 자리 개월. BTW, 임시 파일을 만들고 외부 findstr.exe도구를 사용할 필요가 없습니다 . 당신은 $fileInfo.LastWriteTime 적절한 정규식과 -match연산자를 사용하여 PowerShell에서 직접 확인할 수 ...
JosefZ

@LotPings 올바른지, .NET 문자열 서식을 잘 처리 할 것입니다. [datetime]::Now.AddDays(200).ToString("M/dd/yyyy")(현재 10 월에 넣습니다. 항상 2 자리 숫자를 얻기 위해 문자열 형식 MM을 사용하십시오.
Austin T French

답변:


1

이 함수를 사용하여 지정된 날짜 범위를 매개 변수 StartDateEndDate

Function Download-Files 
{ 
    [CmdletBinding()] 
    Param 
    ( 
        [Parameter(Mandatory=$true)][Object]$Session, 
        [Parameter(Mandatory=$true)][String]$RemotePath, 
        [Parameter(Mandatory=$true)][String]$LocalPath, 
        [Parameter(Mandatory=$false)][String]$StartDate, 
        [Parameter(Mandatory=$false)][String]$EndDate 
    ) 

    If (-Not (Test-Path -Path $LocalPath -PathType Container)) { 
        New-Item -Path $LocalPath -ItemType Directory 
    } 

    Get-WinSCPChildItem -WinSCPSession $Session -Path $RemotePath | ForEach-Object { 
        If (-not($_.IsThisDirectory) -and -not($_.IsParentDirectory) -and $_.IsDirectory) { 
            Download-Files -Session $Session -RemotePath "$RemotePath\$($_.Name)\" -LocalPath "$LocalPath\$($_.Name)\" -StartDate $StartDate -EndDate $EndDate 
        } 

        If (-not($_.IsDirectory)) { 
            If ($_.LastWriteTime -ge $StartDate -and $_.LastWriteTime -le $EndDate) { 
                Receive-WinSCPItem -WinSCPSession $Session -Path "$RemotePath\$($_.Name)" -Destination $LocalPath 
            } 
        } 
    } 
}

WinSCP를 사용하여 PowerShell에서 최신 파일을 다운로드하는 방법 의 전체 코드 샘플을 다운로드 할 수 있습니다.


1

단일 WinSCP 파일 마스크에서 시간 상한 및 하한에 대한 키워드 todayyesterday키워드 를 사용할 수 있습니다 .

$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.FileMask = "*>=yesterday<today"
$session.GetFiles("/Folder/*",  "C:\Downloads\", $False, $transferOptions).Check()

WinSCP 5.15 이상이 필요합니다.


이전 버전의 WinSCP에서는 다음과 같이 PowerShell 코드에서 타임 스탬프를 생성 할 수 있습니다.
*>=2017-03-15<2017-03-16

(한밤중의 시간이 함축되어 있습니다. *=2017-03-15 도 아닙니다. 원하는 것, 그리고 사용하지 않는 이유도 구현되지 않았습니다)

PowerShell에서는 다음과 같이 구현할 수 있습니다.

$yesterday = (Get-Date).AddDays(-1)
$yesterday_timestamp = $yesterday.ToString("yyyy-MM-dd")
$today = Get-Date
$today_timestamp = $today.ToString("yyyy-MM-dd")

$transferOptions = New-Object WinSCP.TransferOptions
$file_mask = "*>=$yesterday_timestamp<$today_timestamp"
$transferOptions.FileMask = $file_mask

$session.GetFiles("/Folder/*",  "C:\Downloads\", $False, $transferOptions).Check()

PowerShell에서 타임 스탬프 서식 지정에 대한 WinSCP 기사를 참조하십시오 .

간단한 구현을 위해 WinSCP %TIMESTAMP%구문 을 사용할 수도 있지만 ,

$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.FileMask = "*>=%TIMESTAMP-1D#yyyy-mm-dd%<%TIMESTAMP#yyyy-mm-dd%"
$session.GetFiles("/Folder/*",  "C:\Downloads\", $False, $transferOptions).Check()

최신 파일 다운로드에 대한 WinSCP 기사를 참조하십시오 .


$ session.GetFiles ( "/ Folder / *"를 사용하면 하위 폴더도 반복적으로 다운로드됩니다.) 어떻게 폴더를 제외 할 수 있습니까?
Brad

* .zip을 필터링 할 수는 있지만, 재귀 적이 아닌 지정된 폴더에서 모든 것을 필요로 할 경우 어떻게합니까?
Brad

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.