我想使用 PowerShell 自动下载数据库备份文件。文件名包含日期,所以我不能每天都运行相同的 FTP 脚本。是否有一种内置于 PowerShell 或使用 .NET 框架的干净方法来执行此操作?
我想使用安全的 FTP 会话。
我想使用 PowerShell 自动下载数据库备份文件。文件名包含日期,所以我不能每天都运行相同的 FTP 脚本。是否有一种内置于 PowerShell 或使用 .NET 框架的干净方法来执行此操作?
我想使用安全的 FTP 会话。
经过一些实验后,我想出了这种在 PowerShell 中自动进行安全 FTP 下载的方法。该脚本在由 Chilkat Software 管理的公共测试 FTP 服务器上运行。因此,您可以复制并粘贴此代码,它无需修改即可运行。
$sourceuri = "ftp://ftp.secureftp-test.com/hamlet.zip"
$targetpath = "C:\hamlet.zip"
$username = "test"
$password = "test"
# Create a FTPWebRequest object to handle the connection to the ftp server
$ftprequest = [System.Net.FtpWebRequest]::create($sourceuri)
# set the request's network credentials for an authenticated connection
$ftprequest.Credentials =
New-Object System.Net.NetworkCredential($username,$password)
$ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
$ftprequest.UseBinary = $true
$ftprequest.KeepAlive = $false
# send the ftp request to the server
$ftpresponse = $ftprequest.GetResponse()
# get a download stream from the server response
$responsestream = $ftpresponse.GetResponseStream()
# create the target file on the local system and the download buffer
$targetfile = New-Object IO.FileStream ($targetpath,[IO.FileMode]::Create)
[byte[]]$readbuffer = New-Object byte[] 1024
# loop through the download stream and send the data to the target file
do{
$readlength = $responsestream.Read($readbuffer,0,1024)
$targetfile.Write($readbuffer,0,$readlength)
}
while ($readlength -ne 0)
$targetfile.close()
我在这些链接中找到了很多有用的信息
如果要使用 SSL 连接,则需要添加该行
$ftprequest.EnableSsl = $true
在调用 GetResponse() 之前添加到脚本。有时您可能需要处理过期的服务器安全证书(就像我不幸的那样)。PowerShell 代码库中有一个页面,其中包含执行此操作的代码片段。前 28 行与下载文件最相关。
取自这里:
$source = "ftp://ftp.microsoft.com/ResKit/win2000/dureg.zip"
$target = "c:\temp\dureg.zip"
$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile($source, $target)
这个对我有用。
就 PowerShell 而言,/n Software NetCmdlets包包括 FTP cmdlet(包括对两种安全 FTP 类型的支持),您可以很容易地为此使用它们。
JAMS Job Scheduler 提供了一些 cmdlet,可以简化此任务。它有多种用于安全会话的 FTP cmdlet 以及用于将自然日期转换为 .NET 日期对象的日期 cmdlet,例如“一个月的最后一天”:
@Eric 投票最多的自我回答是有效的,但它是:
Stream.CopyTo
:$fileUrl = "ftp://ftp.example.com/remote/path/file.zip"
$localFilePath = "C:\local\path\file.zip"
$downloadRequest = [Net.WebRequest]::Create($fileUrl)
$downloadRequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
$downloadRequest.Credentials =
New-Object System.Net.NetworkCredential("username", "password")
# Enable secure FTPS (FTP over TLS/SSL)
$downloadRequest.EnableSsl = $True
$sourceStream = $downloadRequest.GetResponse().GetResponseStream()
$targetStream = [System.IO.File]::Create($localFilePath)
$sourceStream.CopyTo($targetStream);
$sourceStream.Dispose()
$targetStream.Dispose()
如需上传,请参阅使用 PowerShell 通过 FTP 上传文件。
这并不像我希望的那么简单。我知道有三个选项。
.NET - 您可以使用 .NET 框架在 PowerShell 中执行此操作,但它涉及我不想在脚本中执行的原始套接字操作。如果我要走这条路,那么我会将所有 FTP 垃圾打包到 C# 中的 DLL 中,然后使用 PowerShell 中的 DLL。
操作文件 - 如果您知道每天需要获取的文件名称的模式,那么您可以使用 PowerShell 打开您的 FTP 脚本并更改脚本中的文件名。然后运行脚本。
将文本通过管道传输到 FTP - 最后一个选项是使用 PowerShell 将信息通过管道传输到 FTP 会话中。见这里。
像这样的东西可以工作:
$bkdir = "E:\BackupsPWS" #backups location directory
$7Zip = 'C:\"Program Files"\7-Zip\7z.exe' #compression utility
$files_to_transfer = New-Object System.Collections.ArrayList #list of zipped files to be transferred over FTP
$ftp_uri="myftpserver"
$user="myftpusername"
$pass="myftppassword"
# Find .bak files not zipped yet, zip them, add them to the list to be transferrd
get-childitem -path $bkdir | Sort-Object length |
where { $_.extension -match ".(bak)" -and
-not (test-path ($_.fullname -replace "(bak)", "7z")) } |
foreach {
$zipfilename = ($_.fullname -replace "bak", "7z")
Invoke-Expression "$7Zip a $zipfilename $($_.FullName)"
$files_to_transfer.Add($zipfilename)
}
# Find .bak files, if they've been zipped, delete the .bak file
get-childitem -path $bkdir |
where { $_.extension -match ".(bak)" -and
(test-path ($_.fullname -replace "(bak)", "7z")) } |
foreach { del $_.fullname }
# Transfer each zipped file over FTP
foreach ($file in $files_to_transfer)
{
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass) # FTP credentials
$ftp_urix = $ftp_uri + "/" + $file.Substring($bkdir.Length + 1) # ftp address where to transfer the file
$uri=[system.URI] $ftp_urix
$webclient.UploadFile($uri, $file) #transfer the file
}
我已成功使用 Indy Project .NET 库进行 FTP。而且......呃,看起来托管的 .NET 版本不再可用。
$realdate = (Get-Date).ToString("yyyyMMdd")
$path = "D:\samplefolderstructure\filename" + $realdate + ".msi"
ftps -f $path -s:D:\FTP.txt
ftp.txt 是我们将所有连接信息保存到 FTP 服务器的方式。ftps
显然是我们使用的客户端,因此您可能需要更改一些内容。但是,这应该可以帮助您了解这个想法。