Upgrade/Load-NAVCumulativeUpdateHelper.ps1
<#
.Synopsis Loads a .Net assembly to easily find Microsoft Dynamics NAV downloads in the Microsoft Download Center. .DESCRIPTION Compiles C# in memory and gives you 2 static functions: static System.Collections.Generic.IEnumerable[MicrosoftDownload.NAVDownload] GetDownloadLocales(int productID) static System.Collections.Generic.IEnumerable[MicrosoftDownload.NAVDownload] GetDownloadDetail(int productID, string language) See examples for how to use them. The functions only work when you have a ProductID for Microsoft Dynamics NAV Download Center. The function "Get-NAVCumulativeUpdateFile" shows you how to get to the ProductID for Cumulative Updates. .EXAMPLE Load-NAVCumulativeUpdateHelper $Locales = [MicrosoftDownload.MicrosoftDownloadParser]::GetDownloadLocales(54317) $MyDownload = $Locales | out-gridview -PassThru | foreach { $_.DownloadUrl Start-BitsTransfer -Source $_.DownloadUrl -Destination C:\_Download\Filename.zip } .EXAMPLE Load-NAVCumulativeUpdateHelper $MyDownload = [MicrosoftDownload.MicrosoftDownloadParser]::GetDownloadDetail(54317, 'en-US') | Select-Object * .OUTPUT THe function gives you the ability to run two static functions: "GetDownloadLocales" and "GetDownloadDetail" #> function Load-NAVCumulativeUpdateHelper() { $cp = New-Object CodeDom.Compiler.CompilerParameters $cp.CompilerOptions = "/unsafe" $cp.WarningLevel = 4 $cp.TreatWarningsAsErrors = $true $cp.ReferencedAssemblies.Add('System.dll') | Out-Null $cp.ReferencedAssemblies.Add('System.Xml.dll') | Out-Null $cp.ReferencedAssemblies.Add('System.Xml.Linq.dll') | Out-Null $cp.ReferencedAssemblies.Add('System.Data.dll') | Out-Null $cp.ReferencedAssemblies.Add('System.Linq.dll') | Out-Null $cp.ReferencedAssemblies.Add('System.Net.dll') | Out-Null $cp.ReferencedAssemblies.Add('System.Net.Http.dll') | Out-Null $cp.ReferencedAssemblies.Add('System.Data.DataSetExtensions.dll') | Out-Null $cp.ReferencedAssemblies.Add('System.Collections.dll') | Out-Null $cp.ReferencedAssemblies.Add('System.Core.dll') | Out-Null Add-Type ` -CompilerParameters $cp ` -TypeDefinition @" namespace MicrosoftDownload { using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Xml.Linq; public static class MicrosoftDownloadParser { private const String urlTemplate = "https://www.microsoft.com/{0}/download/confirmation.aspx?id={1}"; private const String cdataStartTag = "<![CDATA[*/var " + "baseProductId"; private const String cdataEndTag = "/*]]>*/"; private const String downloadStartTag = "downloadData={"; private const String downloadEndTag = "}}"; private const String urlTag = "url:"; public static IEnumerable<NAVDownload> GetDownloadLocales(Int32 productID) { //**** Console.WriteLine(productID); var XMLDoc = XDocument.Load("https://www.microsoft.com/en-us/download/details.aspx?id=" + productID); IEnumerable<XElement> users = (from el in XMLDoc.Descendants() where (string)el.Attribute("name") == "newlocale" select el); foreach (var item in users.FirstOrDefault().Descendants()) foreach (var detail in GetDownloadDetail(productID, item.Attribute("value").Value)) yield return detail; } public static IEnumerable<NAVDownload> GetDownloadDetail(Int32 productID, String language) { Console.WriteLine("Loading " + language + " ... "); using (WebClient client = new WebClient()) { var pageData = client.DownloadString(String.Format(urlTemplate, language, productID)); var CData = FetchSubString(pageData, cdataStartTag, cdataEndTag); var downloadData = FetchSubString(CData, downloadStartTag, downloadEndTag); //**** Find Urls *** var xPos = downloadData.IndexOf(urlTag) + urlTag.Length + 1; while (xPos > -1) { var endPos = downloadData.IndexOf(@"""", xPos + 1); var url = downloadData.Substring(xPos, endPos - xPos); xPos = downloadData.IndexOf(urlTag, endPos); if (xPos >= 0) xPos += urlTag.Length + 1; var langCode = url.Substring(url.Length - 10, 2); yield return new NAVDownload(productID, language, langCode, url); } } } private static String FetchSubString(String source, String startTag, String endTag) { var startPos = source.IndexOf(startTag) + startTag.Length; return source.Substring(startPos, source.IndexOf(endTag, startPos) - startPos); } } public class NAVDownload { public Int32 ProductID { get; private set; } public String Locale { get; private set; } public String Code { get; private set; } public String DownloadUrl { get; private set; } public NAVDownload(Int32 productID, String locale, String code, String downloadUrl) { ProductID = productID; Locale = locale; Code = code; DownloadUrl = downloadUrl; } } } "@ } |