2017-12-06 3 views
3

Linux 사용자는 Windows 서버에서 원격 서버로 SFTP 전송을 자동화하기 위해 PowerShell에서 스크립트를 작성하려고합니다. 나는 대부분을 위해 일하는 모든 것을 가지고있다. (나는 여전히 할 테스트가있다.) 현재 문제는 스크립트가 한 번 실행 된 후입니다. 새 파일 생성을 찾을 때마다 실행하려면 FileSystemWatcher이 필요합니다. 나는 이것이 exit 때문에 실현되지만 그 부분을 제거하고 사용자가 디렉토리에 떨어 뜨리면 디렉토리의 모든 파일을 반복하고 디렉토리의 모든 파일을 계속 업로드합니다. 내가해야 할 일은 프로세스를 한 번 실행 한 다음 다른 파일 생성 이벤트를 수신 대기 상태로 유지하는 것입니다. 내 문제는 Windows에서 코딩으로 제한된 작업 일 수 있으므로 어떤 도움도 받으실 수 있습니다!로컬 폴더의 변경 사항을보고 SFTP 서버에 업로드

그리고 네, 내 파일 대 내 폴더 처리에서 코드 중복이 중복된다는 것을 알고 있습니다. 나는 그 부분을 파일이나 폴더가 주어진 지에 따라 매개 변수를 받아들이는 함수로 만들 것이다.

나는 나중에

###Watches a directory for new files and fires off the batch file to push to Connexxion 

$folder = "C:\pathTo\watchfolder" 
$watcher = New-Object System.IO.FileSystemWatcher 
$watcher.Path = $folder 
$watcher.Filter = "*.csv" 
$watcher.IncludeSubdirectories = $true 
$watcher.EnableRaisingEvents = $true 

### LISTEN FOR CREATE 
Register-ObjectEvent $watcher Created -SourceIdentifier FileCreated -Action { 
$folderpath = $(split-path -LiteralPath $event.SourceEventArgs.FullPath) 
$filename = $event.SourceEventArgs.Name 
$filepath = (Join-Path $folderpath $filename.split("\")[-1]) 

Write-Host folderpath: $folderpath 
Write-Host filename: $filename 
Write-Host filepath: $filepath 

$remotePath = "/data/" 

If($filename.contains("\")){ 
    Write-Host "Here is directory" 
    try 
    { 
    #Set path to winscp 
    $assemblyPath = "C:\Program Files (x86)\WinSCP" 
    Add-Type -Path (Join-Path $assemblyPath "WinSCPnet.dll") 

    # Setup session options 
    $sessionOptions = New-Object WinSCP.SessionOptions -Property @{ 
     Protocol = [WinSCP.Protocol]::Sftp 
     HostName = "hostname" 
     UserName = "username" 
     Password = "passwd" 
     SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx" 
    } 

    $session = New-Object WinSCP.Session 

    try 
    { 
     # Connect 
     $session.Open($sessionOptions) 
     # Upload files, collect results 
     $transferOptions = New-Object WinSCP.TransferOptions 
     $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary 

     $transferResult = 
      $session.PutFiles($folderpath, $remotePath, $False, $transferOptions) 

     # Throw on any error 
     $transferResult.Check() 

     # Print results 
     foreach ($transfer in $transferResult.Transfers) 
     { 
      Write-Host "Upload of $($transfer.FileName) succeeded" 
     } 
    } 
    finally 
    { 
     # Disconnect, clean up 
     $session.Dispose() 
    } 

    exit 0 
    }#end of first try 
    catch 
    { 
    Write-Host "Error: $($_.Exception.Message)" 
    exit 1 
    } 
} 
Else{ 
    Write-Host "Here is a file" 
    try 
    { 
    #Set path to winscp 
    $assemblyPath = "C:\Program Files (x86)\WinSCP" 
    Add-Type -Path (Join-Path $assemblyPath "WinSCPnet.dll") 

    # Setup session options 
    $sessionOptions = New-Object WinSCP.SessionOptions -Property @{ 
     Protocol = [WinSCP.Protocol]::Sftp 
     HostName = "hostname" 
     UserName = "username" 
     Password = "passwd" 
     SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx" 
    } 

    $session = New-Object WinSCP.Session 

    try 
    { 
     # Connect 
     $session.Open($sessionOptions) 
     # Upload files, collect results 
     $transferOptions = New-Object WinSCP.TransferOptions 
     $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary 

     $transferResult = 
      $session.PutFiles($filepath, $remotePath, $False, $transferOptions) 

     # Throw on any error 
     $transferResult.Check() 

     # Print results 
     foreach ($transfer in $transferResult.Transfers) 
     { 
      Write-Host "Upload of $($transfer.FileName) succeeded" 
     } 
    } 
    finally 
    { 
     # Disconnect, clean up 
     $session.Dispose() 
    } 

    exit 0 
    }#end of first try 
    catch 
    { 
    Write-Host "Error: $($_.Exception.Message)" 
    exit 1 
    } 
    } 

}#end of action 
while ($true) {sleep 5} 
+0

원격 디렉토리 구조가 로컬 디렉토리 구조와 일치합니까? 또는 서버에 아직없는 새 하위 폴더가 로컬에 추가 될 수 있습니까? –

+0

예 새 하위 폴더가 로컬에 추가되어 생성 된 파일에 대한 작업 이벤트가 발생하고 원격 디렉토리로 푸시됩니다. 사용자가 여러 파일이있는 디렉토리를로드하면 스크립트는 찾은 모든 파일에 대해 전체 디렉토리를 반복합니다. 첫 번째 반복은 모든 파일을 업로드하기 때문에 불필요합니다. 나는 "출구"를 사용하여 그런 일이 일어나지 않도록하지만 출구에서 새 파일을 디렉토리에 놓으면 아무 일도 일어나지 않습니다. FileSystemWatcher가 더 이상 실행되지 않습니다. – pskz134

답변

0

그냥 새 파일의 경로를 가지고있는 사람에게 도움이 서버 경로에 매핑 할 RemotePath.TranslateLocalPathToRemote을 사용하고 업로드 할 수 있습니다 경우에 내 전체 코드를 게시하고 거기에 파일.

코드가 훨씬 간단합니다. 서버에서 새 폴더가 다시 만들어 지는지 확인하기 만하면됩니다.

### Watches a directory for new files and fires off the batch file to push to connection 

$remotePath = "/data" 
$localPath = "C:\pathTo\watchfolder" 
$watcher = New-Object System.IO.FileSystemWatcher 
$watcher.Path = $localPath 
$watcher.Filter = "*.csv" 
$watcher.IncludeSubdirectories = $True 
$watcher.EnableRaisingEvents = $True 

### LISTEN FOR CREATE 
Register-ObjectEvent $watcher Created -SourceIdentifier FileCreated -Action { 
    try 
    { 
     $localFilePath = $event.SourceEventArgs.FullPath 
     Write-Host "Local path: $localFilePath" 

     $assemblyPath = "C:\Program Files (x86)\WinSCP" 
     Add-Type -Path (Join-Path $assemblyPath "WinSCPnet.dll") 

     # Setup session options 
     $sessionOptions = New-Object WinSCP.SessionOptions -Property @{ 
      Protocol = [WinSCP.Protocol]::Sftp 
      HostName = "example.com" 
      UserName = "username" 
      Password = "password" 
      SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:..." 
     } 

     $session = New-Object WinSCP.Session 

     try 
     { 
      $remoteFilePath = 
       [WinSCP.RemotePath]::TranslateLocalPathToRemote(
        $localFilePath, $localPath, $remotePath) 
      Write-Host "Remote path: $remoteFilePath" 

      # Connect 
      $session.Open($sessionOptions) 

      # Check if corresponding remote directory exists, if not, create it 
      $i = $remoteFilePath.LastIndexOf("/") 
      $remoteDirPath = $remoteFilePath.SubString(0, $i) 
      if (($remoteDirPath.Length -gt 0) -and !$session.FileExists($remoteDirPath)) 
      { 
       Write-Host "New subdirectory, creating $remoteDirPath on server" 
       $session.CreateDirectory($remoteDirPath) 
      } 

      $session.PutFiles($localFilePath, $remoteFilePath).Check() 

      Write-Host "Upload of $localFilePath succeeded" 
     } 
     finally 
     { 
      # Disconnect, clean up 
      $session.Dispose() 
     } 

    } #end of first try 
    catch 
    { 
     Write-Host "Error: $($_.Exception.Message)" 
    } 
} #end of action 


while ($True) { sleep 5 } 
관련 문제