AL/Get-AllSymbol.ps1
<# .Synopsis Downloads Symbols for apps .Description Downloads Symbols from container for app, dependency apps, and optionally test app .Parameter SourcePath Path to the current project .Parameter ContainerName If blank, the container name will be retrieved from settings.json .Parameter includeTestSymbols Add this switch to get the test app symbols as well .Example Get-AllSymbol -SourcePath "C:\Temp" -ContainerName "container" -includeTestSymbols #> function Get-AllSymbol { Param( [Parameter(Mandatory=$false)] [string]$SourcePath = (Get-Location), [Parameter(Mandatory=$false)] [string]$ContainerName = (Get-ContainerFromLaunchJson), # optionally download the test symbols [Parameter(Mandatory=$false)] [switch] $includeTestSymbols ) $PackagesPath = Join-Path $SourcePath '.alpackages' if (!(Test-Path $PackagesPath)) { New-EmptyDirectory $PackagesPath } # prepare a list of apps to download [Version]$PlatformVersion = [Version]::Parse((Get-AppKeyValue -SourcePath $SourcePath -KeyName 'platform')) $appsToDownload = [System.Collections.ArrayList]@() $serviceTier = 'BC' if ($PlatformVersion.Major -ge 15) { $Dependencies = Get-AppKeyValue -SourcePath $SourcePath -KeyName 'dependencies' foreach ($Dependency in $Dependencies) { $appsToDownload.Add([PSCustomObject]@{ Publisher = $Dependency.Publisher Name = $Dependency.name Version = $Dependency.Version fileName = "" }) | Out-Null } if ((Get-AppKeyValue -SourcePath $SourcePath -KeyName "Application") -ne "") { $applicationInfo = Get-BcContainerAppInfo -containerName $ContainerName -tenant "default" -tenantSpecificProperties | Where-Object {$_.Name -eq "Application"} $appsToDownload.Add([PSCustomObject]@{ Publisher = $applicationInfo.Publisher Name = $applicationInfo.name Version = $applicationInfo.Version fileName = "" }) | Out-Null } $applicationInfo = Get-BcContainerAppInfo -containerName $ContainerName -SymbolsOnly foreach ($app in $applicationInfo) { $appsToDownload.Add([PSCustomObject]@{ Publisher = $app.Publisher Name = $app.Name Version = $app.Version fileName = "" }) | Out-Null } } else { $appsToDownload.Add([PSCustomObject]@{ Publisher = 'Microsoft' Name = 'Application' Version = (Get-AppKeyValue -SourcePath $SourcePath -KeyName 'application') fileName = "" }) | Out-Null $appsToDownload.Add([PSCustomObject]@{ Publisher = 'Microsoft' Name = 'System' Version = (Get-AppKeyValue -SourcePath $SourcePath -KeyName 'platform') fileName = "" }) | Out-Null if ($includeTestSymbols.IsPresent) { $appsToDownload.Add([PSCustomObject]@{ Publisher = 'Microsoft' Name = 'Test' Version = (Get-AppKeyValue -SourcePath $SourcePath -KeyName 'test') fileName = "" }) | Out-Null } $serviceTier = 'NAV' } $appsDownloaded = [System.Collections.ArrayList]@() $appsNewDownloaded = [System.Collections.ArrayList]@() $Headers = New-Header while ($appsToDownload.Count -ne 0) { $appsNewDownloaded.Clear() # now download all apps foreach($app in $appsToDownload) { $version = [version]$app.Version $existingFile = Get-Item (Join-Path $PackagesPath ('{0}_{1}_{2}.{3}.*.*.app' -f $app.Publisher, $app.Name, $version.Major, $version.Minor).Replace(":", "_").Replace("__", "_")) -ErrorAction SilentlyContinue if ($null -eq $existingFile) { $Uri = 'http://{0}:7049/{1}/dev/packages?publisher={2}&appName={3}&versionText=' -f $ContainerName, $serviceTier, $app.Publisher, $app.Name if ($PlatformVersion.Major -ge 15) { $Uri = '{0}&tenant=default' -f $Uri } Write-Output "Downloading $($app.Publisher) - $($app.Name)" try { $file = Invoke-WebRequest -Uri $Uri -Headers $Headers -OutFile (Join-Path $PackagesPath ('{0}_{1}_{2}.app' -f $app.Publisher, $app.Name, $app.Version).Replace(":", "_").Replace("__", "_")) -PassThru } catch { $appinfo = Get-BcContainerAppInfo -containerName $containerName -tenant default -tenantSpecificProperties | Where-Object {$_.Name -like ("*{0}*" -f $app.Name)} if ($null -ne $appinfo) { $Uri = 'http://{0}:7049/{1}/dev/packages?publisher={2}&appName={3}&versionText=' -f $ContainerName, $serviceTier, $appinfo.Publisher, $appinfo.Name if ($PlatformVersion.Major -ge 15) { $Uri = '{0}&tenant=default' -f $Uri } $file = Invoke-WebRequest -Uri $Uri -Headers $Headers -OutFile (Join-Path $PackagesPath ('{0}_{1}_{2}.app' -f $appinfo.Publisher, $appinfo.Name, $appinfo.Version).Replace(":", "_").Replace("__", "_")) -PassThru $app.Name = $appinfo.Name $app.Version = $appinfo.Version } } if ($file.Headers."Content-Disposition".Contains('"')) { $fileName = $file.Headers."Content-Disposition".Split('"')[1] } else { $fileName = $file.Headers."Content-Disposition".Split(';')[1].Split('=')[1] } if ($fileName -ne ('{0}_{1}_{2}.app' -f $app.Publisher, $app.Name, $app.Version).Replace(":", "_").Replace("__", "_")) { if (Test-Path (Join-Path $PackagesPath $fileName)) { Remove-Item (Join-Path $PackagesPath $fileName) -Force } Rename-Item (Join-Path $PackagesPath ('{0}_{1}_{2}.app' -f $app.Publisher, $app.Name, $app.Version).Replace(":", "_").Replace("__", "_")) $fileName -Force $app.Version = [version]($fileName.Split("_")[-1].Split(".")[0..3] -join ".") } $app.fileName = $fileName } else { $fileName = Split-Path $existingFile -Leaf $app.fileName = $fileName try { $app.Version = [version]($fileName.Split("_")[-1].Split(".")[0..3] -join ".") } catch { $existingInfo = Get-AppInfoFromContainer -containerName $ContainerName -appFile $existingFile $app.Version = [version]$existingInfo.Version } } $appsDownloaded.Add($app) | Out-Null $appsNewDownloaded.Add($app) | Out-Null } # now go through all apps and check for dependencies $appsToDownload.Clear() foreach ($app in $appsNewDownloaded) { # unpack app $appFolder = New-TempDirectory try { Extract-AppFileToFolder -appFilename (Join-Path $PackagesPath $app.fileName) -appFolder $appFolder -generateAppJson | Out-Null # loop through dependencies and add apps to $appJson = Get-Content -Path (Join-Path $appFolder 'app.json') | ConvertFrom-Json } catch { $appJson = Get-AppInfoFromContainer -containerName $ContainerName -appFile (Join-Path $PackagesPath $app.fileName) } if ($null -ne $appJson.dependencies) { foreach($dep in $appJson.dependencies) { $found = $appsDownloaded | Where-Object {$_.Publisher -eq $dep.Publisher -and $_.Name -eq $dep.name -and $_.Version -ge $dep.Version} $version = [version]$dep.Version $existingFile = Get-Item (Join-Path $PackagesPath ('{0}_{1}_{2}.*.*.*.app' -f $dep.Publisher, $dep.Name, $version.Major)) -ErrorAction SilentlyContinue if ($null -ne $existingFile) { $existingFileParts = $existingFile.FullName.Split(".") if (($existingFileParts[1] -lt $version.Minor) -or ($existingFileParts[1] -eq $version.Minor -and $existingFileParts[2] -lt $version.Build) -or ($existingFileParts[1] -eq $version.Minor -and $existingFileParts[2] -eq $version.Build -and $existingFileParts[3] -lt $version.Revision)) { $existingFile = $null } } if ($null -eq $found -and $null -eq $existingFile) { $appsToDownload.Add([PSCustomObject]@{ Publisher = $dep.Publisher Name = $dep.name Version = $dep.Version fileName = "" }) | Out-Null } } } # cleanup Remove-Item -Path $appFolder -Recurse -Force } } Write-Output "downloaded all symbols" } function New-Header { [CmdletBinding(SupportsShouldProcess, ConfirmImpact="low")] [OutputType([System.Collections.Hashtable])] Param () if ($PSCmdlet.ShouldProcess("Authorization", "Adding authorization headers to ")) { $ba = '{0}:{1}' -f (Get-Secret -vaultName "NAV-X" -secretName "Username"), (Get-Secret -vaultName "NAV-X" -secretName "Password") $ba = [System.Text.Encoding]::UTF8.GetBytes($ba) $ba = [System.Convert]::ToBase64String($ba) $h = @{Authorization=("Basic {0}" -f $ba);'Accept-Encoding'='gzip,deflate'} $h } } Export-ModuleMember -Function Get-AllSymbol |