Linux user here trying to write a script in PowerShell to automate SFTP transfers from a Windows server to a remote server. I have everything working for the most part (though I still have some testing to do). My current issue is after the script runs one time it is done. I need the FileSystemWatcher
to run every time it finds a new file creation. I realize this is because of the exit
but when I remove that portion and a user drops in a directory it loops through every file in the directory and uploads every file in the directory over and over. What I need it to do is run through the process once and then remain active to listen for another file creation event. My issue may be my limited workings with coding in Windows so any help is appreciated!
And yes I realize the duplication of code in the handling of my files vs my folders is redundant. I will most likely make that portion a function that accepts parameters depending on if it is given a file or folder.
I am posting my entire code in case it can help someone later
###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}