I'm in the process of writing a PowerShell script to help in the process of setting up new PC's for my work. This will hopefully be used by more than just me so I'm trying to think of everything.
I have offline installers (java, flash, reader, etc) saved on our FTP server that the script downloads if a local copy hasn't already been saved in the Apps directory that gets created. Periodically the files on the FTP server will get updated as new versions of the programs are released. I want the script to have an option of checking for newer versions of the installers in case someone likes to carry around the local copies and forgets to check the server every now and then. It also will need to work in Windows 7 without any need to import additional modules unless there's an easy way to do that on multiple PC's at a time. I know about the import command, but the experiences I've had needed me to copy the module files into multiple places on the PC before it'd work.
Right now I haven't had much luck finding any solutions. I've found code that checks for modified dates on local files, or files on a local server, but nothing that deals with FTP other than uploading\downloading files.
Here's the last thing I tried. I tried a combination of what I found for local files with FTP. Didn't work too well.
I'm new to PowerShell, but I've been pretty good at piecing this whole thing together so far. However, this idea is becoming troublesome.
Thank you for the help.
$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)
}
UPDATE:
Here's what I have after Martin's help. It kind of works. It downloads the file from FTP, but it's not comparing the remote and local correctly. The remote file returns 20150709140505 and the local file returns 07/09/2015 2:05:05 PM. How do I format one to look like the other before the comparison, and is "-gt" the correct comparison to use?
Thanks!
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
}
}
UPDATE 2:
Seems to be working! Here's the code. Thanks for the help!
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
}
}
You cannot use the
WebClient
class to check remote file timestamp.You can use the
FtpWebRequest
class with itsGetDateTimestamp
FTP "method" and parse the UTC timestamp string it returns. The format is specified by RFC 3659 to beYYYYMMDDHHMMSS[.sss]
.That would work only if the FTP server supports
MDTM
command that the method uses under the cover (most servers do, but not all).It would output something like:
Now you parse it, and compare against a UTC timestamp of a local file:
Or save yourself some time and use an FTP library/tool that can do this for you.
For example with WinSCP .NET assembly, you can synchronize whole remote folder with installers with a local copy with one call to the
Session.SynchronizeDirectories
. Or your can limit the synchronization to a single file only.To use the assembly, just extract a contents of .NET assembly package to your script folder. No other installation is needed.
The assembly supports not only the
MDTM
, but also other alternative methods to retrieve the timestamp.See also a related Powershell example that shows both the above code and other techniques.
(I'm the author of WinSCP)