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:[email protected] " $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的命令行的使用,大家可以上它的官网论坛查看。