Yesterday, I blogged about the availability of the first Cumulative Update of NAV 2017. In that post, I talked about the fact that Microsoft recently changed the place where to download them.
This also means the way of automating the download had to be changed. In fact, the PowerShell function that was part of my repository (and built by Kamil originally), didn’t work anymore. I didn’t really know how to get around this – but luckily, I have a really clever colleague (well, I do have more than one ;-)) that did find a way in .Net. And we managed to transfer the logic to PowerShell .. (literally “transfer”, not rewrite … you’ll see what I mean ;-)).
I’m not going to tell you “how” it works – you can find out in the code. I’ll just show you what we created, and how it works.
Load-NAVCumulativeUpdateHelper
The main functionality is in C# .. and you can make it available by loading and compiling it by simply calling “Load-NAVCumulativeUpdateHelper”. In C#, you’re just that more flexible – and since we’re working in HTML, and figuring stuff out in HTML, it’s just much nicer to do so in C#. And .. the fact that this is the preferred environment of my colleague might have a reason in that as well ;-).
The PowerShell function is loading (compiling) two functions in memory and make them available to me:
static System.Collections.Generic.IEnumerable[MicrosoftDownload.NAVDownload] GetDownloadLocales(int productID) static System.Collections.Generic.IEnumerable[MicrosoftDownload.NAVDownload] GetDownloadDetail(int productID, string language)
Let me show you some examples on how to use them.
This example, is going to show you a gridview of all download URLs in a gridview, and when you select one and press ok, it starts the download. It uses the “GetDownloadLocales” to get all the languages one-by-one:
Load-NAVCumulativeUpdateHelper $Locales = [MicrosoftDownload.MicrosoftDownloadParser]::GetDownloadLocales(54317) $MyDownload = $Locales | out-gridview -PassThru | foreach { $_.DownloadUrl Start-BitsTransfer -Source $_.DownloadUrl -Destination C:\_Download\Filename.zip }
The other function “GetDownloadDetail”, you need to specify the Locale (like “en-US”), which can be used to speed up the process (no need to generate and navigate to all the URLs of all the “Locales”), like:
Load-NAVCumulativeUpdateHelper $MyDownload = [MicrosoftDownload.MicrosoftDownloadParser]::GetDownloadDetail(54317, 'en-US') | Select-Object * $MyDownload
You also see that the functions need a ProductID. Well, that’s how Download Center works .. If you have the ID, you know what to download .. and to get to that ProductID, let’s look into the next function.
This function is based on the good old function that Kamil Sacek once wrote – based on the ideas of my colleague. It is going to look at the Microsoft Dynamics NAV Team Blog to figure out the link to the Download Center – and yes – to figure out the ProductID. And obviously, going to use the Helper above to be able to start the download(s). It’s still limited to only search for the latest Cumulative Update. I’m working on a solution (probably a new function) to start the download from a specific blog article, or KB article.
The function above can simply be used in this way (and here are some more examples) which will simply start the download to the specified folder:
Get-NAVCumulativeUpdateFile -versions 2017 -CountryCode W1 -DownloadFolder C:\_Download
The function also creates a JSON with specifics about the download. Not because it’s necessary .. just because we can ;-).
Do I need the complete module to be able to do this?
No. You basically only need these two functions. So go ahead and automate! :-). The result is a much more stable way to automate these downloads, simply because Download Center doesn’t require you to run through a complicated login process ..
22 comments
3 pings
Skip to comment form
Good job!!
Author
Thanks 🙂
Actually you could do without instancing an Internet Explorer COM object in “Get-NAVCumulativeUpdateFile”. Just download the plain HTML page and parse through it using RegEx. It is much easier to REALLY automate it and have it run in an non-interactive session (we are actually doing it using a JobQueue Codeunit)
Author
Thanks for the suggestion! Something needs to change indeed – must get much more stable :-/
Hi,
Didn’t an older version allow me to download a dedicated CU Version?
Due to the latest “mess from MS” with 2017 Cu2 or 2016CU15 or … the script will of course fail as it won’t be able to download CU2 at all … I was about to use and test this scripts which i can’t right now… [get file, unzip, unblock files, create platform hotfixfolder – all in one script]
However, would be nice to allow the CU Version to be part [again?] of the parameters and used like the following:
$blogurl = $feed.SelectNodes(“/rss/channel/item[./category=’NAV $version’ and ./category=’Cumulative Updates’ and ./title=’Cumulative Update $CUVersion for Microsoft Dynamics NAV $version has been released’]”).link | Select-Object -First 1
Br and a nice Weekend,
Kris
Author
You are right. It’s still on my list to do. but please, don’t hold yourself to create issues on GitHub 😉
When I use Get-NAVCumulativeUpdateFile and set version to 2015, it get’s the wrong build (41779) I guess because it appears on https://blogs.msdn.microsoft.com/nav/2017/02/08/cumulative-update-28-for-microsoft-dynamics-nav-2015-has-been-released/ before the real buildnumber. It does download the correct file though. Maybe it would be better to fetch the buildnumber from the KB article, but I guess that could also go wrong if Microsoft decides to put multiple KB numbers on the blog post? 🙂
Awesome job….
Cheers,
Just a small addition to eliminate an issue I found with 2013/ 2013 R2 blog page not supplying the “Build No.”
Insert this line into the Get-NAVCumulativeUpdateFile after the line “112”-> $Build = $ie.Document.body.inner……
if ($Build.length -gt 5) {$Build = ‘xxxxx’}
This would be great but right now it is not working for me:
PS >Get-NAVCumulativeUpdateFile -versions 2017 -CountryCode W1 -DownloadFolder C:\TMP
Processing parameters W1 2017
Searching for RSS item
Reading blog page https://blogs.msdn.microsoft.com/nav/2017/03/06/cumulative-update-04-for-microsoft-dynamics-nav-2017-has-been-released/
Searching KB Url
Microsoft Download Center link
Found Product ID 54802
Loading NAVCumulativeUpdateHelper
An error occurred while enumerating through a collection: Object reference not set to an instance of an object..
At C:\Program Files\WindowsPowerShell\Modules\Cloud.Ready.Software.NAV\1.0.0.2\Upgrade\Get-NAVCumulativeUpdateFile.ps1:97 char:21
+ … $DownloadLinks = [MicrosoftDownload.MicrosoftDownloadPars …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (MicrosoftDownlo…oadLocales>d__2:d__2) [], RuntimeException
+ FullyQualifiedErrorId : BadEnumeration
Author
Works like a charm here (just tested it).
Sure you have the last version of the function? I noticed your “version”-parameter is wrong (should be “version” not “versions”)
Author
Latest version is always on github:
https://github.com/waldo1001/Cloud.Ready.Software.PowerShell/blob/master/PSModules/Cloud.Ready.Software.NAV/Upgrade/Get-NAVCumulativeUpdateFile.ps1
Hi Waldo and thanks for the post.
When I am trying your first example I am getting the following error. Could you please let me know what could be wrong?
An error occurred while enumerating through a collection: The remote server returned an error: (404) Not Found..
At C:\Tools\test.ps1:3 char:1
+ $MyDownload = $Locales | out-gridview -PassThru | foreach {$_.Downloa …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (MicrosoftDownlo…oadLocales>d__2:d__2) [], RuntimeExcep
tion
+ FullyQualifiedErrorId : BadEnumeration
Thanks in advance.
Author
Sorry for the late reply – is this still the case?
Hi, yes I just tried again and I am getting the same error.
Author
I just tried this:
Get-NAVCumulativeUpdateFile -version 2017 -CountryCode W1 -DownloadFolder C:\_Downloads
on a new pc, and it works.
So:
– did you update the modules to the latest version?
– do you have internet connection? (the error states a 404)
– can you access “https://blogs.msdn.microsoft.com/nav/2017/05/08/cumulative-update-06-for-microsoft-dynamics-nav-2017-has-been-released/” with that user on that machine?
Hi waldo,
Thanks for your reply.
Get-NAVCumulativeUpdateFile works for me too. I’m getting the error when I’m trying to run your first example:
Load-NAVCumulativeUpdateHelper
$Locales = [MicrosoftDownload.MicrosoftDownloadParser]::GetDownloadLocales(54317)
$MyDownload = $Locales | out-gridview -PassThru | foreach {
$_.DownloadUrl
Start-BitsTransfer -Source $_.DownloadUrl -Destination C:\_Download\Filename.zip
}
It seems that the call to [MicrosoftDownload.MicrosoftDownloadParser]::GetDownloadLocales(54317) returns the 404 error.
The answer to all your questions is yes.
Hi Eric
Does this still work? I probably gess not because Microsoft changed the locations.
Regards René
Author
I’m afraid not, René 🙂
Hi – a bit late maybe but I commit some changes to the gitrepo … for me the tool most of the time works now again 🙂
I’m not 100% aware on how long the rss feed URL will do it’s job – but I guess we will notice 😀
Author
Update is online, thanks, Kristof!
Hi I just submitted a pull request for a rewrite of this function. Be interested in your feedback.
[…] I described it here: http://www.waldo.be/2016/12/09/automate-downloads-of-cumulative-updates/. […]
[…] I described it here: http://www.waldo.be/2016/12/09/automate-downloads-of-cumulative-updates/. […]
[…] Mirror post […]