此处的 Linux 用户尝试在 PowerShell 中编写脚本以自动将 SFTP 从 Windows 服务器传输到远程服务器。我大部分时间都在工作(尽管我还有一些测试要做)。我当前的问题是脚本运行一次后。我需要 FileSystemWatcher
在每次发现新文件创建时运行。我意识到这是因为 exit
但当我删除该部分并且用户进入目录时,它会遍历目录中的每个文件并一遍又一遍地上传目录中的每个文件。我需要它做的是运行一次该过程,然后保持事件状态以监听另一个文件创建事件。我的问题可能是我在 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}
最佳答案
只需获取新文件的路径并使用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 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 }
关于powershell - 观察本地文件夹的变化并将它们上传到 SFTP 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47682702/