Created
December 6, 2025 04:56
-
-
Save CookieBox26/906e75e5c227c58043fa1aec6990656c to your computer and use it in GitHub Desktop.
WinSCP の .NET アセンブリを使用して FTPS ディレクトリ同期する PowerShell スクリプト
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <# | |
| PowerShell: WinSCP を使って FTPS (explicit) で同期するスクリプト | |
| #> | |
| param( | |
| [string] $accountName = "{FTPアカウント}", | |
| [string] $HostName = "{FTPサーバ名}", | |
| [string] $LocalPath = (Join-Path $PSScriptRoot "site"), | |
| [string] $RemotePath = "/home/{FTPアカウント}/www", | |
| [string] $LogFile = (Join-Path $PSScriptRoot "log.txt") | |
| ) | |
| # ----- WinSCP .NET アセンブリ読み込み ----- | |
| $assemblyPath = "C:\Program Files (x86)\WinSCP\WinSCPnet.dll" | |
| if (-not (Test-Path $AssemblyPath)) { throw "WinSCPnet.dll not found: $AssemblyPath" } | |
| Add-Type -Path $AssemblyPath | |
| # ----- Credential 入力 ----- | |
| $pass = Read-Host "Enter password for $accountName" -AsSecureString # パスワード入力を促す | |
| $cred = New-Object System.Management.Automation.PSCredential($accountName, $pass) | |
| # ----- セッションオプション設定 ----- | |
| $sessionOptions = New-Object WinSCP.SessionOptions -Property @{ | |
| Protocol = [WinSCP.Protocol]::Ftp | |
| HostName = $HostName | |
| UserName = $cred.UserName | |
| FtpSecure = [WinSCP.FtpSecure]::Explicit | |
| } | |
| # ----- 同期の設定 ----- | |
| $direction = [WinSCP.SynchronizationMode]::Remote # 同期の向き: ローカルからリモートに送る | |
| $remove = $false # 送り側にないファイルを削除するか: しない | |
| $mirror = $false # 送り側のタイムスタンプのほうが古いとき上書きするか: しない | |
| $to = New-Object WinSCP.TransferOptions | |
| $criteria = [WinSCP.SynchronizationCriteria]::Time | |
| $session = New-Object WinSCP.Session | |
| $session.SessionLogPath = $LogFile | |
| try { | |
| # パスワードを取り出して接続 | |
| $sessionOptions.Password = $cred.GetNetworkCredential().Password | |
| $session.Open($sessionOptions) | |
| $sessionOptions.Password = $null # 接続したら削除 | |
| $cred = $null # 接続したら削除 | |
| # --- 1) プレビュー --- | |
| $diffs = $session.CompareDirectories( | |
| $direction, $LocalPath, $RemotePath, $remove, $mirror, $criteria, $to | |
| ) | |
| if ($diffs.Count -eq 0) { Write-Host "No changes."; return } | |
| Write-Host "Planned changes:" | |
| foreach ($d in $diffs) { | |
| $path = if ($d.Local) { $d.Local.FileName } else { $d.Remote.FileName } | |
| Write-Host (" [{0}] {1}" -f $d.Action, $path) | |
| } | |
| # --- 2) 確認 --- | |
| $ans = Read-Host "Proceed with actual sync? [y/N]" | |
| if ($ans -notmatch '^(y|yes)$') { Write-Host "Aborted."; return } | |
| # --- 3) 同期 --- | |
| $result = $session.SynchronizeDirectories( | |
| $direction, $LocalPath, $RemotePath, $remove, $mirror, $criteria, $to | |
| ) | |
| $result.Check() | |
| Write-Host "Synchronized:" | |
| foreach ($u in $result.Uploads) { Write-Host (" [Upload] {0} -> {1}" -f $u.FileName, $u.Destination) } | |
| foreach ($d in $result.Downloads) { Write-Host (" [Download] {0} -> {1}" -f $d.FileName, $d.Destination) } | |
| foreach ($r in $result.Removals) { Write-Host (" [Remove] {0}" -f $r.FileName) } | |
| } catch { | |
| Write-Error $_.Exception.Message | |
| } finally { | |
| if ($session) { $session.Dispose() } | |
| Read-Host "Press Enter to exit" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment