2017-12-06 17 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 } 
関連する問題