如何通过PowerShell的FTP连接运行FTP服务器上的rename-files.ps1脚本?
Great question! Let's start with a key reality: standard FTP doesn’t support running server-side PowerShell scripts directly. FTP is built for transferring files, not executing commands on the server. But we can achieve your core goal—isolating existing XML files to avoid deleting new ones added mid-operation—with a few practical workarounds:
Option 1: Adjust Your FTP Logic (No Server Script Needed)
This is the most straightforward fix, and it avoids needing to deploy scripts on the server entirely. Instead of relying on a server-side rename, we’ll handle the isolation directly via FTP commands:
How it works:
- First, list all existing
.XMLfiles on the server (so we only target files that existed when we started, not new ones added later) - Rename each of those files to
.XML.copyto "lock" them in place - Download all the
.XML.copyfiles to your local directory - (Optional) Delete the
.XML.copyfiles from the server once confirmed downloaded
PowerShell Example (More Flexible Than Native FTP):
# Configure your FTP details $ftpServer = "ftp.site.com" $username = "yourUsername" $password = "yourPassword" $remoteFolder = "/Out" $localFolder = "E:\FTP\Site" # Step 1: Get list of current XML files on the server $ftpRequest = [System.Net.FtpWebRequest]::Create("ftp://$ftpServer$remoteFolder/") $ftpRequest.Credentials = New-Object System.Net.NetworkCredential($username, $password) $ftpRequest.Method = [System.Net.WebRequestMethods+Ftp]::ListDirectory $response = $ftpRequest.GetResponse() $reader = New-Object System.IO.StreamReader($response.GetResponseStream()) $existingXmlFiles = $reader.ReadToEnd().Split("`n") | Where-Object { $_ -match '\.XML$' -and ![string]::IsNullOrWhiteSpace($_) } $reader.Close() $response.Close() # Step 2: Rename each XML file to .XML.copy foreach ($file in $existingXmlFiles) { $renameRequest = [System.Net.FtpWebRequest]::Create("ftp://$ftpServer$remoteFolder/$file") $renameRequest.Credentials = New-Object System.Net.NetworkCredential($username, $password) $renameRequest.Method = [System.Net.WebRequestMethods+Ftp]::Rename $renameRequest.RenameTo = "$file.copy" $renameRequest.GetResponse().Close() } # Step 3: Download all .XML.copy files $webClient = New-Object System.Net.WebClient $webClient.Credentials = New-Object System.Net.NetworkCredential($username, $password) foreach ($file in $existingXmlFiles) { $remoteFilePath = "ftp://$ftpServer$remoteFolder/$file.copy" $localFilePath = Join-Path $localFolder "$file.copy" $webClient.DownloadFile($remoteFilePath, $localFilePath) } # Step 4: (Optional) Delete the .XML.copy files from the server foreach ($file in $existingXmlFiles) { $deleteRequest = [System.Net.FtpWebRequest]::Create("ftp://$ftpServer$remoteFolder/$file.copy") $deleteRequest.Credentials = New-Object System.Net.NetworkCredential($username, $password) $deleteRequest.Method = [System.Net.WebRequestMethods+Ftp]::DeleteFile $deleteRequest.GetResponse().Close() }
Option 2: Switch to a Protocol That Supports Remote Execution (SFTP/SSH)
If your server supports SFTP or SSH, you can first run your rename-files.ps1 script on the server via SSH, then transfer the files. This is cleaner if you already have SSH access enabled.
Example with Posh-SSH (PowerShell Module):
First, install the module if you haven’t:
Install-Module -Name Posh-SSH -Scope CurrentUser
Then run this script:
$server = "ftp.site.com" $cred = Get-Credential # Step 1: Connect via SSH and run the rename script $sshSession = New-SSHSession -ComputerName $server -Credential $cred Invoke-SSHCommand -SessionId $sshSession.SessionId -Command "powershell -File C:\path\to\rename-files.ps1" Remove-SSHSession -SessionId $sshSession.SessionId # Step 2: Download the renamed files via SFTP $sftpSession = New-SFTPSession -ComputerName $server -Credential $cred Get-SFTPItem -SessionId $sftpSession.SessionId -Path "/Out/*.XML.copy" -Destination $localFolder Remove-SFTPSession -SessionId $sftpSession.SessionId
Example with WinSCP (GUI + Command Line):
Create a script file ftp_workflow.txt:
# Use SFTP if your server supports it (SSH command execution works here) open sftp://username:password@ftp.site.com/ cd Out # Execute the server-side PowerShell script call powershell -File C:\path\to\rename-files.ps1 lcd "E:\FTP\Site" mget *.XML.copy mdel *.XML.copy exit
Run it via command line:
winscp.com /script=ftp_workflow.txt
Option 3: Trigger the Script via Server-Side Scheduled Task
If you can’t modify your client-side FTP script or don’t have SSH access, set up a scheduled task on the FTP server to run rename-files.ps1 at regular intervals. Then your original FTP script only needs to download .XML.copy files and delete them—no need to worry about new files being caught in the delete operation.
To recap:
- Use Option 1 if you need to stick with standard FTP
- Use Option 2 if your server supports SSH/SFTP (cleanest approach)
- Use Option 3 if you can’t adjust the client script
内容的提问来源于stack exchange,提问作者Prof. Jokert

