{"id":753,"date":"2018-04-19T10:04:05","date_gmt":"2018-04-19T10:04:05","guid":{"rendered":"http:\/\/giraffeit.com\/?p=753"},"modified":"2018-04-19T10:09:35","modified_gmt":"2018-04-19T10:09:35","slug":"powershell-winscp","status":"publish","type":"post","link":"https:\/\/giraffeit.com\/index.php\/2018\/04\/19\/powershell-winscp\/","title":{"rendered":"Powershell : WinSCP"},"content":{"rendered":"<p>WinSCP has a series of inbuilt libraries to help keep a remote site synchronised with a local site.<\/p>\n<p>You will need WinSCP (obviously) and winscp.ino as well as WINSCPnet.dll.<\/p>\n<p>I adapted the code a little more than listed here, but the premise is the same.<\/p>\n<pre class=\"lang:ps decode:true \" >function Sync\r\n{\r\nparam (\r\n# Use Generate URL function to obtain a value for -sessionUrl parameter.\r\n$sessionUrl = \"sftp:\/\/somewhereelse-;fingerprint=ssh-rsa-long ssh key@notherecom\",\r\n[Parameter(Mandatory)]\r\n$localPath,\r\n[Parameter(Mandatory)]\r\n$remotePath,\r\n[Switch]\r\n$delete = $False,\r\n[Switch]\r\n$beep = $False,\r\n[Switch]\r\n$continueOnError = $False,\r\n$sessionLogPath = $Null,\r\n$interval = 30,\r\n[Switch]\r\n$pause = $False\r\n)\r\n\r\ntry\r\n{\r\n# Load WinSCP .NET assembly\r\n$assemblyPath = if ($env:WINSCP_PATH) { $env:WINSCP_PATH } else { $PSScriptRoot }\r\nAdd-Type -Path (Join-Path $assemblyPath \"WinSCPnet.dll\")\r\n\r\n# Setup session options\r\n$sessionOptions = New-Object WinSCP.SessionOptions\r\n$sessionOptions.ParseUrl($sessionUrl)\r\n\r\n$session = New-Object WinSCP.Session\r\n\r\n# Optimization\r\n# (do not waste time enumerating files, if you do not need to scan for deleted files)\r\nif ($delete)\r\n{\r\n$localFiles = Get-ChildItem -Recurse -Path $localPath\r\n}\r\n\r\ntry\r\n{\r\n$session.SessionLogPath = $sessionLogPath\r\n\r\nWrite-Host \"Connecting...\"\r\n$session.Open($sessionOptions)\r\n\r\nwhile ($True)\r\n{\r\nWrite-Host \"Synchronizing changes...\"\r\n$result = $session.SynchronizeDirectories([WinSCP.SynchronizationMode]::Local, $localPath, $remotePath, $delete)\r\n\r\n$changed = $False\r\n\r\nif (!$result.IsSuccess)\r\n{\r\nif ($continueOnError)\r\n{\r\nWrite-Host (\"Error: {0}\" -f $result.Failures[0].Message)\r\n$changed = $True\r\n}\r\nelse\r\n{\r\n$result.Check()\r\n}\r\n}\r\n\r\n# Print updated files\r\nforeach ($download in $result.Downloads)\r\n{\r\nWrite-Host (\"{0} &lt;= {1}\" -f $download.Destination, $download.FileName)\r\n$changed = $True\r\n}\r\n\r\nif ($delete)\r\n{\r\n# scan for removed local files (the $result does not include them)\r\n$localFiles2 = Get-ChildItem -Recurse -Path $localPath\r\n$changes = Compare-Object -DifferenceObject $localFiles2 -ReferenceObject $localFiles\r\n\r\n$removedFiles =\r\n$changes |\r\nWhere-Object -FilterScript { $_.SideIndicator -eq \"&lt;=\" } |\r\nSelect-Object -ExpandProperty InputObject\r\n\r\n# Print removed local files\r\nforeach ($removedFile in $removedFiles)\r\n{\r\nWrite-Host (\"{0} deleted\" -f $removedFile)\r\n$changed = $True\r\n}\r\n\r\n$localFiles = $localFiles2\r\n}\r\n\r\nif ($changed)\r\n{\r\nif ($beep)\r\n{\r\n[System.Console]::Beep()\r\n}\r\n}\r\nelse\r\n{\r\nWrite-Host \"No change.\"\r\n}\r\n\r\nWrite-Host \"Waiting for $interval seconds, press Ctrl+C to abort...\"\r\n$wait = [int]$interval\r\n# Wait for 1 second in a loop, to make the waiting breakable\r\nwhile ($wait -gt 0)\r\n{\r\nStart-Sleep -Seconds 1\r\n$wait--\r\n}\r\n\r\nWrite-Host\r\n}\r\n}\r\nfinally\r\n{\r\nWrite-Host \"Disconnecting...\"\r\n# Disconnect, clean up\r\n$session.Dispose()\r\n}\r\n}\r\ncatch [Exception]\r\n{\r\nWrite-Host (\"Error: {0}\" -f $_.Exception.Message)\r\n}\r\n\r\n# Pause if -pause switch was used\r\nif ($pause)\r\n{\r\nWrite-Host \"Press any key to exit...\"\r\n[System.Console]::ReadKey() | Out-Null\r\n}\r\n\r\n# Never exits cleanly\r\n#exit 1\r\n\r\n}\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>WinSCP has a series of inbuilt libraries to help keep a remote site synchronised with a local site. You will need WinSCP (obviously) and winscp.ino as well as WINSCPnet.dll. I adapted the code a little more than listed here, but the premise is the same. function Sync { param ( # Use Generate URL function &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/giraffeit.com\/index.php\/2018\/04\/19\/powershell-winscp\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Powershell : WinSCP&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[14],"class_list":["post-753","post","type-post","status-publish","format-standard","hentry","category-bog","tag-powershell"],"_links":{"self":[{"href":"https:\/\/giraffeit.com\/index.php\/wp-json\/wp\/v2\/posts\/753","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/giraffeit.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/giraffeit.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/giraffeit.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/giraffeit.com\/index.php\/wp-json\/wp\/v2\/comments?post=753"}],"version-history":[{"count":3,"href":"https:\/\/giraffeit.com\/index.php\/wp-json\/wp\/v2\/posts\/753\/revisions"}],"predecessor-version":[{"id":756,"href":"https:\/\/giraffeit.com\/index.php\/wp-json\/wp\/v2\/posts\/753\/revisions\/756"}],"wp:attachment":[{"href":"https:\/\/giraffeit.com\/index.php\/wp-json\/wp\/v2\/media?parent=753"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/giraffeit.com\/index.php\/wp-json\/wp\/v2\/categories?post=753"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/giraffeit.com\/index.php\/wp-json\/wp\/v2\/tags?post=753"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}