我正在编写PowerShell脚本,以帮助我为我的工作设置新PC。希望这不仅仅是我使用,所以我想要考虑所有事情。
如果本地副本尚未保存在创建的Apps目录中,我的FTP服务器上保存了脱机安装程序(java,flash,reader等)。随着程序的新版本的发布,FTP服务器上的文件将定期更新。我希望脚本可以选择检查安装程序的更新版本,以防有人喜欢随身携带本地副本并忘记偶尔检查服务器。它还需要在Windows 7中工作,而无需导入额外的模块,除非有一种简单的方法可以在多台PC上同时执行此操作。我知道import命令,但是我需要的经验是在模块工作之前将模块文件复制到PC上的多个位置。
现在我没有找到任何解决方案。我找到了检查本地文件或本地服务器上的文件的修改日期的代码,但除了上传\下载文件之外,没有任何其他内容涉及FTP。
这是我尝试过的最后一件事。我尝试了我发现的本地文件与FTP的组合。做得不好。
我是PowerShell的新手,但到目前为止,我一直非常擅长将这一切拼凑在一起。但是,这个想法变得很麻烦。
感谢您的帮助。
$ftpsite = "ftp://ftpsite.com/folder/"
$firefox = (Get-Item $dir\Apps\install_firefox.exe).LastWriteTime.toString("MM/dd/yyyy")
if ($firefoxftp = (Get-ChildItem $ftpsite/install_firefox.exe | Where{$_.LastWriteTime -gt $firefox})) {
$File = "$dir\Apps\install_firefox.exe"
$ftp = "ftp://ftpsite.com/folder/install_firefox.exe"
$webclient = New-Object System.Net.WebClient
$uri = New-Object System.Uri($ftp)
$webclient.DownloadFile($uri, $File)
}
更新:
这是马丁帮助后的情况。它有点工作。它从FTP下载文件,但它没有正确比较远程和本地。远程文件返回20150709140505,本地文件返回07/09/2015 2:05:05 PM。在比较之前如何将一个格式化为另一个,并且“-gt”是否使用正确的比较?
谢谢!
function update {
$ftprequest = [System.Net.FtpWebRequest]::Create("ftp://ftpsite.com/Script_Apps/install_firefox.exe")
$ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::GetDateTimestamp
$response = $ftprequest.GetResponse().StatusDescription
$tokens = $response.Split(" ")
$code = $tokens[0]
$localfile = (Get-Item "$dir\Apps\install_firefox.exe").LastWriteTimeUtc
if ($tokens -gt $localfile) {
write-host "Updating Firefox Installer..."
$File = "$dir\Apps\install_firefox.exe"
$ftp = "ftp://ftpsite.com/Script_Apps/install_firefox.exe"
$webclient = New-Object System.Net.WebClient
$uri = New-Object System.Uri($ftp)
$webclient.DownloadFile($uri, $File)
"Updated Firefox" >> $global:logfile
mainmenu
}
else {
Write-Host "Local Copy is Newer."
sleep 3
mainmenu
}
}
更新2:
好像在起作用!这是代码。谢谢你的帮助!
function update {
$ftprequest = [System.Net.FtpWebRequest]::Create("ftp://ftpserver.com/Script_Apps/install_firefox.exe")
$ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::GetDateTimestamp
$response = $ftprequest.GetResponse().StatusDescription
$tokens = $response.Split(" ")
$code = $tokens[0]
$localtime = (Get-Item "$dir\Apps\install_firefox.exe").LastWriteTimeUtc
if ($code -eq 213) {
$tokens = $tokens[1]
$localtime = "{0:yyyymmddHHmmss}" -f [datetime]$localtime
}
if ($tokens -gt $localtime) {
write-host "Updating Firefox Installer..."
$File = "$dir\Apps\install_firefox.exe"
$ftp = "ftp://ftpserver.com/Script_Apps/install_firefox.exe"
$webclient = New-Object System.Net.WebClient
$uri = New-Object System.Uri($ftp)
$webclient.DownloadFile($uri, $File)
"Updated Firefox" >> $global:logfile
mainmenu
}
else {
Write-Host "Local Copy is Newer."
sleep 3
mainmenu
}
}
答案 0 :(得分:2)
您不能使用WebClient
类来检查远程文件时间戳。
您可以将FtpWebRequest
class与其GetDateTimestamp
FTP "method"一起使用,并解析它返回的UTC时间戳字符串。该格式由RFC 3659指定为YYYYMMDDHHMMSS[.sss]
。
只有当FTP服务器支持该方法在封面下使用的MDTM
命令(大多数服务器都可以,但不是全部)时,这才有效。
$ftprequest = [System.Net.FtpWebRequest]::Create("ftp://ftpsite.com/folder/install_firefox.exe")
$ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::GetDateTimestamp
$response = $ftprequest.GetResponse().StatusDescription
$tokens = $response.Split(" ")
$code = $tokens[0]
if ($code -eq 213)
{
Write-Host "Timestamp is" $tokens[1]
}
else
{
Write-Host "Error" $response
}
它会输出如下内容:
Timestamp is 20150709065036
现在解析它,并与本地文件的UTC时间戳进行比较:
(Get-Item "install_firefox.exe").LastWriteTimeUtc
或节省一些时间并使用可以为您执行此操作的FTP库/工具。
例如,对于WinSCP .NET assembly,您可以将整个远程文件夹与安装程序与本地副本同步,同时调用Session.SynchronizeDirectories
。或者您可以将同步限制为单个文件。
# Load WinSCP .NET assembly
Add-Type -Path "WinSCPnet.dll"
# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions
$sessionOptions.Protocol = [WinSCP.Protocol]::Ftp
$sessionOptions.HostName = "ftpsite.com"
$session = New-Object WinSCP.Session
# Connect
$session.Open($sessionOptions)
$transferOptions = New-Object WinSCP.TransferOptions
# Synchronize only this one file.
# If you remove the file mask, all files in the folder are synchronized:
$transferOptions.FileMask = "install_firefox.exe"
$session.SynchronizeDirectories(
[WinSCP.SynchronizationMode]::Local, "$dir\Apps", "/folder",
$False, $False, [WinSCP.SynchronizationCriteria]::Time,
$transferOptions).Check()
要使用程序集,只需将.NET assembly package的内容解压缩到脚本文件夹即可。无需其他安装。
程序集不仅支持MDTM
,还支持其他检索时间戳的替代方法。
另请参阅显示上述代码和其他技术的related Powershell example。
(我是WinSCP的作者)