PowerShell定期FTP上传文件
我这里有这样一个需求:有一个数据库,每天使用SQL Server Agent自动生成备份文件,文件名为“<数据库名>_db_yyyyMMddHHmm.bak”。然后,这个数据库非常重要,需要把每天的备份上传一个远程的FTP服务器上去。
我们来分析一下这个问题的几个实现要点。
第一,要能识别出要上传的文件。我们知道SQL Server Agent在备份数据库的时候,是把近期所有的备份都放在同一个目录的,那么我们要做的就是在这个目录中找到今天的备份。然后我查了一下,我们SQL Server Agent的备份时间是下午18点,那么我们得把我们这个脚本的执行时间放到18点30分以后,以免我们程序执行时,备份还没有出来。另外,还有一个重要的问题是,虽然SQL Server Agent是在18:00分执行的,但是生成的文件最后HHmm却不一定都是1800,也有可能出现1801,甚至出现过1802的。所以,我们不能用文件名像什么来识别要上传的文件。然后又因为这个目录都是此数据库的备份,那我想直接把该目录下1天以内生成的.bak文件识别即可。
第二,调用FTP上传文件。之前考虑过使用ftp.exe这个cmd命令去做的,但因为服务器上都是使用被动模式的,这个ftp命令用不了。然后试过自己编写一个ftp客户端,但却总是在上传时有点问题。什么问题呢,就是上传小文件没问题,上传大文件就总是超时失败!这个问题最终没能解决得掉。后来换个思路一想,还不如直接调用一个第三方程序来做算了,于是想到了用FlashFXP。这个工具的命令还是挺容易的,直接在网上一搜索就有了。但是又出现一个问题,在命令行下直接能执行的命令,放到PowerShell中却不给力了。后来仔细研究了一下PowerShell中调用外部程序的多种方式,终于找到一个办法能让它跑起来。
第三,让程序每天自动执行。一开始想到的就是计划任务,但是很悲摧啊,计划任务中PowerShell执行失败了,FlashFXP都没有弹出来。算了,直接写个死循环吧,然后用Start-Sleep来做暂停延时。验证了一下,沉睡的时候占用CPU是0%,真是阿弥陀佛,善哉善哉!
完整的程序如下:
<#
文件:upload-db.ps1
用途:上传xxx的数据库到备份服务器
作者:splaybow.com
时间:2013-05-27
修改:2013-06-04
#>
while($true)
{
$execPath="D:\Progra~1\FlashFXP\flashfxp.exe"
$execArgs="-upload ftp://username:pass@xxx.xxx.xx.18 "
$execArgs=$execArgs+"-remotepath=`"/`" "
$files = Get-ChildItem D:\MSSQLBAK\dbbakDIR `
| ?{$_.CreationTime.AddDays(1) -gt [DateTime]::Today `
-and $_.CreationTime -lt [DateTime]::Today `
-and $_.PSIsContainer -eq $False `
-and $_.Name -like "*.bak.gz"} #这里之前已有程序把它压缩成gzip格式了,比较小一点,便于上传
foreach($file in $files)
{
$msg = '上传' + $file.FullName
Write-Output $msg
$var = $execArgs + "-localpath=`"" + $file.FullName + "`""
Start-Process -FilePath $execPath -ArgumentList $var
Write-Output '上传成功'
}
Write-Output "Sleep中,请不要关闭本窗口"
Start-Sleep -s 86400 #睡一天
}
对于FlashFXP的命令行的使用,大家可以上它的官网论坛查看。
要饭二维码
