如何将本地文件的年龄与FTP服务器上的文件进行比较,如果远程复制在PowerShell中更新,则下载

时间:2015-07-09 01:02:57

标签: windows powershell ftp

我正在编写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
    }

}

1 个答案:

答案 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的作者)