Powershell 监视本地文件夹中的更改并将其上载到SFTP服务器

Powershell 监视本地文件夹中的更改并将其上载到SFTP服务器,powershell,scripting,sftp,winscp,winscp-net,Powershell,Scripting,Sftp,Winscp,Winscp Net,这里的Linux用户正在尝试在PowerShell中编写脚本,以自动化从Windows服务器到远程服务器的SFTP传输。我大部分时间都在工作(尽管我还有一些测试要做)。我当前的问题是在脚本运行一次之后。我需要FileSystemWatcher在每次发现新文件创建时运行。我意识到这是因为退出,但当我删除该部分,用户进入目录时,它会循环遍历目录中的每个文件,并反复上传目录中的每个文件。我需要它做的是在进程中运行一次,然后保持活动状态以侦听另一个文件创建事件。我的问题可能是我在Windows中的编码工

这里的Linux用户正在尝试在PowerShell中编写脚本,以自动化从Windows服务器到远程服务器的SFTP传输。我大部分时间都在工作(尽管我还有一些测试要做)。我当前的问题是在脚本运行一次之后。我需要
FileSystemWatcher
在每次发现新文件创建时运行。我意识到这是因为退出,但当我删除该部分,用户进入目录时,它会循环遍历目录中的每个文件,并反复上传目录中的每个文件。我需要它做的是在进程中运行一次,然后保持活动状态以侦听另一个文件创建事件。我的问题可能是我在Windows中的编码工作有限,因此非常感谢您的帮助

是的,我意识到在处理我的文件和文件夹时,代码的重复是多余的。我很可能会使该部分成为一个函数,它根据给定的文件或文件夹接受参数

我张贴我的全部代码,以防它可以帮助别人以后

###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}

只需获取新文件的路径并使用将其映射到服务器路径,然后将文件上载到该路径即可

代码将简单得多。您需要做的就是确保在服务器上重新创建新文件夹

# 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 xxxxxxxxxxx...="
        }

        $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 }