用PowerShell自动化安全FTP的最佳方法是什么?

问题描述 投票:27回答:9

我想使用PowerShell自动下载数据库备份文件的FTP。 文件名包括日期,所以我不能每天都运行同一个FTP脚本。 有没有一种干净的方法可以在PowerShell中内置或使用.NET框架来实现这个功能?

我想使用一个安全的FTP会话。

.net powershell ftp ftps
9个回答
24
投票

经过一些实验,我想出了这个方法,在PowerShell中自动完成一个安全的FTP下载。 这个脚本运行在 公共测试FTP服务器 由Chilkat软件管理。 因此,你可以复制和粘贴这段代码,它将运行,而无需修改。

$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行是与下载文件的目的最相关的。


6
投票

取自 此处

$source = "ftp://ftp.microsoft.com/ResKit/win2000/dureg.zip"
$target = "c:\temp\dureg.zip"
$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile($source, $target)

对我有用


3
投票

就PowerShell而言,n软件。NetCmdlets 包中包含了FTP cmdlets(包括对两种安全FTP类型的支持),你可以很容易地使用它们来完成这个任务。


1
投票

JAMS Job Scheduler提供了一些cmdlets,可以让这个任务变得简单。它有各种用于安全会话的FTP cmdlets,以及用于将自然日期转换为.Net日期对象的日期cmdlets,比如 "Last day of month"。

JAMS任务调度器小工具:


1
投票

最被@Eric投票的自问自答正在工作,但它。

  • 缓冲区只有1KB,效率低下
  • 不必要的复杂的重新实施,什么可以很容易和更有效地完成与 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上传文件.


0
投票

这并不像我希望的那样简单。据我所知,有三种选择。

1) .Net - 你可以在PS中使用.Net框架来完成这个任务,但它涉及到原始的套接字操作,我不想在脚本中做。如果我要走这条路,那么我会把所有的ftp垃圾打包到C#中的DLL中,然后使用powerhell中的DLL。

2) 操纵文件 - 如果你知道每天需要获取的文件名的模式,那么你可以用PS打开你的ftp脚本,在脚本中改变文件名。然后运行脚本。

3)将文本管到FTP上--最后一个选项是使用powershell将信息管进和管出你的FTP会话。请看 此处.


0
投票

像这样的东西可以工作。

$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
}

看看这个 Powershell:压缩备份和FTP传输。


-1
投票

我已经成功使用Indy Project .NET库来做FTP。而且......唉,看来托管的.NET构建已经不可用了。


-1
投票

$realdate = (Get-Date).ToString("yyyyMMdd")

$path = "D:\samplefolderstructure\filename" + $realdate + ".msi"

ftps -f $path -s:D:\FTP.txt

ftp.txt是我们保存所有连接信息到ftp服务器的方式。ftps是我们使用的客户端,所以可能需要改变一些东西。但是,这应该可以帮助你了解这个想法。

© www.soinside.com 2019 - 2024. All rights reserved.