Security change on December 1, 2026: TLS 1.2 will become the minimum standard for 365 business Print Agent. Details and system requirements
365 business development
PowerShell Module

Feeds module

Module: businessdev.ALbuild.Feeds  •  Tier: Free / Licensed  •  Cmdlets: 14

The Feeds module is home to ALbuild's headline capability: a real transitive dependency resolver across NuGet v3 feeds, Azure DevOps Universal Packages, GitHub Releases and Microsoft's public feeds. It also creates and publishes NuGet packages and promotes them to Azure DevOps feed views. See the Dependency resolver deep dive.

Licensing

This module spans both free and licensed tiers. Dependency resolution and packaging are free of license; see Licensing & tiers for the features that require a license.

Cmdlets in this module

CmdletDescription
ConvertFrom-BcRemoteUrlDerives the Azure DevOps organization and project from a git remote URL.
Find-BcPackageFinds the available versions of an AL app across feeds.
Get-BcDependencyReconciliationReconciles an app's manifest dependencies against what a container already has and what the configured feeds can provide.
Get-BcFeedReturns the registered feed providers.
Get-BcPackageVersionThe published versions of one or more package ids on a feed.
Get-BcUniversalPackageDownloads a named package from an Azure DevOps Universal feed into a folder.
Invoke-BcPackagePromotionPromotes a published NuGet package version to a view on an Azure DevOps Artifacts feed.
New-BcNuGetPackageCreates a NuGet package (.nupkg) that contains a Business Central .app.
Publish-BcPackagePushes a NuGet package (.nupkg) to a NuGet v3 feed.
Register-BcFeedRegisters a NuGet package feed for dependency resolution.
Resolve-BcDependenciesResolves an AL project's dependencies across feeds and writes them to .alpackages.
Resolve-BcDependencyCeilingPicks the BC version that dependency resolution should cap against, from the available sources.
Resolve-BcExternalDependency
Select-BcArtifactForDependenciesPicks the newest Business Central artifact whose build every project's dependencies still resolve against - stepping back through minor versions when an ISV has not yet shipped packages for the latest BC (dependency-aware selection with downgrade-on-conflict).

ConvertFrom-BcRemoteUrl

Derives the Azure DevOps organization and project from a git remote URL.

The org/project a project-scoped Universal feed needs used to be parsed with a single regex that only matched the HTTPS remote format (dev.azure.com/{org}/{project}/_git/...). Azure Pipelines checks out exactly that way, so the pipeline worked; an SSH-based checkout (our agents / any SSH clone) uses the SSH v3 form (git@ssh.dev.azure.com/{org}/{project}/{repo}), which the HTTPS regex does NOT match - the project came back empty, the Universal download ran org-scoped, the project-scoped feed was not found, and the failure surfaced much later as AL1024 on publish.

This function recognizes every common Azure DevOps remote format so org/project resolve the same regardless of how the repo was cloned:

  • HTTPS https://[user@]dev.azure.com/{org}/{project}/_git/{repo}
  • Legacy HTTPS https://{org}.visualstudio.com/{project}/_git/{repo}
  • SSH v3 [user@]ssh.dev.azure.com/{org}/{project}/{repo}
  • SSH host-alias <alias>/{org}/{project}/{repo} (a ~/.ssh/config Host alias)

Returns empty strings for both when nothing is recognized (e.g. a non-Azure-DevOps remote), so the caller can fall back to org-scoped behaviour without a hard failure.

Syntax

PowerShellCode
ConvertFrom-BcRemoteUrl [-RemoteUrl <String>]

Parameters

ParameterTypeRequiredDescription
-RemoteUrlStringNoThe output of git remote get-url origin (or any git remote URL).

Output

PSCustomObject with Organization (a full https://dev.azure.com/&#123;org}/ URL, or '') and Project (the URL-decoded project name, or ''). The project name is URL-encoded in every remote format (e.g. 'Dynamics%20365%20...') and is decoded here.


Find-BcPackage

Finds the available versions of an AL app across feeds.

Syntax

PowerShellCode
Find-BcPackage -AppId <String> [-Name <String>] [-Publisher <String>] [-Feeds <Object[]>]

Parameters

ParameterTypeRequiredDescription
-AppIdStringYesThe AL app id (GUID).
-NameStringNoThe app name (used for the package id scheme).
-PublisherStringNoThe app publisher (used for the package id scheme).
-FeedsObject[]NoFeed providers. Defaults to the registered feeds (Get-BcFeed).

Output

PSCustomObject with Feed, PackageId, Version.

Examples

Example 1

PowerShellCode
Find-BcPackage -AppId '437dbf0e-84ff-417a-965d-ed2bb9650972' -Name 'Base Application' -Publisher 'Microsoft'

Get-BcDependencyReconciliation

Reconciles an app's manifest dependencies against what a container already has and what the configured feeds can provide.

Read-only (installs nothing). For each dependency (from app.json 'dependencies'), reports whether it is already satisfied by an app installed in the container, otherwise whether a configured feed can provide a compatible version, otherwise that it is missing. Microsoft first-party apps ship with the artifact, so they normally show up as satisfied by the container.

Feeds are taken from -Feeds, else the currently registered feeds (Get-BcFeed) -- register them first with Register-BcFeed / Register-BcFeed -FromProjectConfig.

Syntax

PowerShellCode
Get-BcDependencyReconciliation -ContainerName <String> -Dependencies <Object[]> [-Feeds <Object[]>]

Parameters

ParameterTypeRequiredDescription
-ContainerNameStringYesThe container to reconcile against.
-DependenciesObject[]YesThe app.json 'dependencies' entries: objects with id (GUID), optional name/publisher, and version (the minimum required version).
-FeedsObject[]NoFeed definitions to search (default: all currently registered feeds).

Output

PSCustomObject: containerName, feedsSearched, summary { total, satisfied, availableFromFeed, missing }, satisfied[], availableFromFeed[], missing[].


Get-BcFeed

Returns the registered feed providers.

Syntax

PowerShellCode
Get-BcFeed [-Name <String>]

Parameters

ParameterTypeRequiredDescription
-NameStringNoOptional name to return a single feed.

Output

The registered feed provider object(s).

Examples

Example 1

PowerShellCode
Get-BcFeed

Get-BcPackageVersion

The published versions of one or more package ids on a feed.

A plain listing, for the times when the question is "what is already on the feed" rather than "resolve a dependency". The runtime factory asks it to decide what it still has to build: idempotency keyed on blob storage alone lets blob and feed drift apart, because the checkpoint uploads to blob first and pushes to the feed second, and a failed push is warned about rather than fatal.

THE EMPTY-RESULT TRAP The provider's version lookup swallows every error and returns nothing, so "this package has no versions" and "the feed could not be asked" look identical from the outside. Reading the second as the first would tell the factory that nothing is published and send it off to rebuild the whole matrix - hundreds of containers.

So the feed is proven reachable and authorised FIRST, on its own, and a failure there throws. After that an empty version list genuinely means the package is absent, and callers can trust it. A caller that would rather degrade than rebuild should catch the exception and fall back.

Syntax

PowerShellCode
Get-BcPackageVersion -Feed <Object> -PackageId <String[]>

Parameters

ParameterTypeRequiredDescription
-FeedObjectYesA feed from Register-BcFeed or Get-BcFeed.
-PackageIdString[]YesOne or more package ids. Ids are matched case-insensitively by the feed, as NuGet requires.

Output

PSCustomObject[] with PackageId and Versions (string[], empty when the package is absent).

Examples

Example 1

PowerShellCode
$feed = Register-BcFeed -Name rt -Kind runtime -Url $url -Token $token Get-BcPackageVersion -Feed $feed -PackageId '365businessdevelopment.365businessbanking.runtime-18-3-513-27128'

Example 2

PowerShellCode
# What is already on the feed, as the factory asks it. Get-BcPackageVersion -Feed $feed -PackageId $ids | ForEach-Object { foreach ($v in $_.Versions) { "$appId/$v" } }

Get-BcUniversalPackage

Downloads a named package from an Azure DevOps Universal feed into a folder.

Azure DevOps Universal feeds address packages by name and version (unlike NuGet symbol feeds, which the dependency resolver queries by app id). This cmdlet downloads such a named package - e.g. shared symbol bundles or a configuration package - into -OutputFolder. It is the native replacement for the V1 DownloadArtifactsUniversalFeed / DownloadDependenciesUniversalFeed / DownloadConfigPackageUniversalFeed tasks.

Download uses the Azure CLI 'az artifacts universal download' (the supported Universal Packages client). The Azure CLI with the azure-devops extension must be available; the call is routed through Invoke-ALbuildProcess so it is captured and testable. Authenticate either by a prior 'az login' or by passing -AccessToken (a PAT), which is exported as AZURE_DEVOPS_EXT_PAT for the download only.

Syntax

PowerShellCode
Get-BcUniversalPackage -Organization <String> -Feed <String> -Name <String> [-Version <String>] -OutputFolder <String> [-Project <String>] [-AccessToken <String>] [-AzExecutable <String>]

Parameters

ParameterTypeRequiredDescription
-OrganizationStringYesThe Azure DevOps organization - a full URL (https://dev.azure.com/org) or a bare org name.
-FeedStringYesThe feed name.
-NameStringYesThe Universal package name.
-VersionStringNoThe package version, or '' for the latest. Default ''. Default: '*'.
-OutputFolderStringYesThe folder to download the package contents into (created if missing).
-ProjectStringNoProject name for a project-scoped feed. Omit for an organization-scoped feed.
-AccessTokenStringNoA personal access token used for authentication (exported as AZURE_DEVOPS_EXT_PAT).
-AzExecutableStringNoThe Azure CLI executable. Default 'az'. Default: 'az'.

Output

PSCustomObject: Name, Version, OutputFolder, Files.

Examples

Example 1

PowerShellCode
Get-BcUniversalPackage -Organization 'https://dev.azure.com/contoso' -Feed 'D365BC' ` -Name 'shared-symbols' -Version '*' -OutputFolder '.\.alpackages'

Invoke-BcPackagePromotion

Promotes a published NuGet package version to a view on an Azure DevOps Artifacts feed.

Azure DevOps Artifacts feeds expose 'views' (e.g. @Prerelease, @Release). Promoting a package version to a view lets partners consume it from a view-scoped feed URL (.../_packaging/<feed>@Prerelease/nuget/v3/index.json), which is how ALbuild distributes prerelease (dev) and release (master) app packages from one feed.

The view assignment is a one-shot PATCH against the Azure DevOps Packaging REST API (it is not part of the NuGet protocol). The feed's v3 index URL is parsed to derive the organisation, optional project and feed name. Promotion is OPT-IN: when -View is not supplied the cmdlet is a no-op and returns $true, so callers can pass the parameter through unconditionally.

Syntax

PowerShellCode
Invoke-BcPackagePromotion -Url <String> [-View <String>] -ApiKey <String> [-PackagePath <String>] -PackageId <String> -Version <String>

Parameters

ParameterTypeRequiredDescription
-UrlStringYesThe feed's NuGet v3 service index URL (.../nuget/v3/index.json) on an Azure DevOps Artifacts host (pkgs.dev.azure.com or *.pkgs.visualstudio.com).
-ViewStringNoTarget view name, e.g. 'Prerelease' or 'Release' (any custom view name is accepted). When empty or omitted, no promotion is performed.
-ApiKeyStringYesThe Azure DevOps PAT used for the REST call (a Packaging read/write token, the same one used to publish).
-PackagePathStringNoPath to the .nupkg. The package id and version are read from its .nuspec. Mutually exclusive with -PackageId/-Version.
-PackageIdStringYesExplicit package id. Use with -Version instead of -PackagePath.
-VersionStringYesExplicit package version. Use with -PackageId instead of -PackagePath.

Output

System.Boolean ($true on success or when there is nothing to promote).

Examples

Example 1

PowerShellCode
Invoke-BcPackagePromotion -Url $feedUrl -PackagePath .\pkg.1.0.0.nupkg -View Prerelease -ApiKey $env:FEED_PAT

New-BcNuGetPackage

Creates a NuGet package (.nupkg) that contains a Business Central .app.

Reads the .app manifest, derives the package id from the id scheme (or uses -PackageId), and produces a valid OPC NuGet package (with [Content_Types].xml and relationships) containing the .app and a generated .nuspec. Application/platform dependency ranges and extra dependencies can be declared (used by, for example, runtime packages).

Syntax

PowerShellCode
New-BcNuGetPackage -AppFile <String> [-PackageId <String>] [-IdScheme <String>] [-Version <String>] [-Authors <String>] [-Description <String>] [-Dependency <Object[]>] [-OutputFolder <String>]

Parameters

ParameterTypeRequiredDescription
-AppFileStringYesPath to the .app (or .runtime.app) file.
-PackageIdStringNoExplicit package id. If omitted, derived from -IdScheme and the app identity.
-IdSchemeStringNoPackage id template when -PackageId is not supplied. Default '{publisher}.{name}.{id}'. Default: '&#123;publisher}.&#123;name}.&#123;id}'.
-VersionStringNoPackage version. Default: the app version.
-AuthorsStringNoPackage authors. Default: the app publisher.
-DescriptionStringNoPackage description. Default: the app name.
-DependencyObject[]NoAdditional NuGet dependencies as @{ id = ...; version = ... } hashtables.
-OutputFolderStringNoOutput folder for the .nupkg. Default: the app file's folder.

Output

System.String - the path to the created .nupkg.

Examples

Example 1

PowerShellCode
New-BcNuGetPackage -AppFile .\Publisher_App_1.0.0.0.app -IdScheme '{publisher}.{name}.symbols.{id}'

Publish-BcPackage

Pushes a NuGet package (.nupkg) to a NuGet v3 feed.

Resolves the feed's PackagePublish service from its service index and uploads the package using a multipart PUT (the NuGet v3 push protocol). An existing package version is reported as a conflict rather than failing the build (unless -FailOnConflict is set).

Syntax

PowerShellCode
Publish-BcPackage -PackagePath <String> -Url <String> -ApiKey <String> [-FailOnConflict] [-View <String>]

Parameters

ParameterTypeRequiredDescription
-PackagePathStringYesPath to the .nupkg to push.
-UrlStringYesThe feed's NuGet v3 service index URL (.../index.json).
-ApiKeyStringYesThe API key (nuget.org) or PAT (Azure DevOps/GitHub) for publishing.
-FailOnConflictswitchNoThrow if the package version already exists. Default: warn and continue.
-ViewStringNoOptional Azure DevOps Artifacts view (e.g. 'Prerelease' or 'Release') to promote the package to after a successful push. When omitted, only the push is performed. Promotion still runs when the version already existed (a non-failing conflict), since promoting an existing version is valid. Ignored for non-Azure-DevOps feeds (Invoke-BcPackagePromotion throws if misused there).

Output

System.Boolean ($true on success or conflict-when-not-failing).

Examples

Example 1

PowerShellCode
Publish-BcPackage -PackagePath .\pkg.1.0.0.nupkg -Url $feedUrl -ApiKey $env:NUGET_KEY

Example 2

PowerShellCode
Publish-BcPackage -PackagePath .\pkg.1.0.0.nupkg -Url $feedUrl -ApiKey $env:FEED_PAT -View Prerelease

Register-BcFeed

Registers a NuGet package feed for dependency resolution.

Creates a NuGet v3 feed provider and stores it in the session's feed registry. Registered feeds are used by Resolve-BcDependencies (unless feeds are passed explicitly). Use -IncludeMicrosoftDefaults to also register Microsoft's public BC feeds (MSSymbols, AppSourceSymbols, MSApps).

Syntax

PowerShellCode
Register-BcFeed -Name <String> -Url <String> [-Token <String>] [-IdScheme <String>] [-Kind <String>] [-CacheFolder <String>] -IncludeMicrosoftDefaults -FromProjectConfig <String> [-WorkspaceRoot <String>]

Parameters

ParameterTypeRequiredDescription
-NameStringYesA unique name for the feed.
-UrlStringYesThe NuGet v3 service index URL (.../index.json).
-TokenStringNoOptional access token (PAT) for authenticated feeds.
-IdSchemeStringNoPackage id template. Default '{publisher}.{name}.{id}'. Default: '&#123;publisher}.&#123;name}.&#123;id}'.
-KindStringNoPackage kind: symbols (default), apps or runtime. Allowed values: symbols, apps, runtime. Default: 'symbols'.
-CacheFolderStringNoPackage cache folder. Defaults to the configured PackageCacheFolder.
-IncludeMicrosoftDefaultsswitchYesAlso register Microsoft's public BC feeds.
-FromProjectConfigStringYesRegister every feed declared in a project's albuild.json (the 'feeds' array). The value is the app/project folder; the workspace-root config is merged in when -WorkspaceRoot is given. Each entry is a URL string or an object { url, name?, kind?, idScheme?, token?, tokenEnv? }; only 'url' is required. This lets developers declare feeds once in albuild.json instead of repeating Register-BcFeed calls in every pipeline.
-WorkspaceRootStringNoWorkspace root holding the shared albuild.json, merged under the app-folder config.

Output

The registered provider object(s).

Examples

Example 1

PowerShellCode
Register-BcFeed -Name 'MyFeed' -Url 'https://pkgs.dev.azure.com/org/_packaging/Apps/nuget/v3/index.json' -Token $pat -Kind apps

Example 2

PowerShellCode
Register-BcFeed -FromProjectConfig ./MyApp -WorkspaceRoot .

Resolve-BcDependencies

Resolves an AL project's dependencies across feeds and writes them to .alpackages.

Reads the project's app.json, resolves a mutually-compatible, transitively-complete set of dependency packages from the given (or registered) feeds - respecting the target build's platform/application versions and any apps already installed in the build (pinned, e.g. Microsoft first-party apps) - then downloads them in dependency order and writes a dependencies.lock.json for reproducible builds.

Syntax

PowerShellCode
Resolve-BcDependencies -ProjectFolder <String> [-Feeds <Object[]>] [-WorkspaceRoot <String>] [-InstalledApps <Object[]>] [-TargetApplication <String>] [-TargetPlatform <String>] [-Select <String>] [-OutputFolder <String>] [-LockFilePath <String>] [-SkipDownload]

Parameters

ParameterTypeRequiredDescription
-ProjectFolderStringYesThe AL project folder (contains app.json).
-FeedsObject[]NoFeed provider objects. When omitted, uses the feeds registered with Register-BcFeed plus any feeds declared in the project's albuild.json ('feeds' array) - so a pipeline can simply call Resolve-BcDependencies without repeating Register-BcFeed.
-WorkspaceRootStringNoWorkspace root holding the shared albuild.json (merged under the project-folder config) when auto-loading feeds from configuration. Ignored when -Feeds is supplied.
-InstalledAppsObject[]NoApps already present in the target build (objects with AppId/Id and Version), pinned as a baseline. Typically Get-BcContainerAppInfo output.
-TargetApplicationStringNoTarget application version. Defaults to app.json 'application'.
-TargetPlatformStringNoTarget platform version. Defaults to app.json 'platform'.
-SelectStringNoLatest (default; the newest version compatible with the target build) or LowestCompatible (the oldest version that still satisfies every constraint, for maximally reproducible builds). Allowed values: LowestCompatible, Latest. Default: 'Latest'.
-OutputFolderStringNoWhere to place resolved .app files. Default: <ProjectFolder>/.alpackages.
-LockFilePathStringNoWhere to write the lock file. Default: <ProjectFolder>/dependencies.lock.json.
-SkipDownloadswitchNoResolve and write the lock file without downloading packages.

Output

PSCustomObject with Resolved, OutputFolder, LockFile, Packages.

Examples

Example 1

PowerShellCode
Resolve-BcDependencies -ProjectFolder ./app -InstalledApps (Get-BcContainerAppInfo -Name bld)

Resolve-BcDependencyCeiling

Picks the BC version that dependency resolution should cap against, from the available sources.

Pure helper (no I/O, unit-testable) for the Resolve Dependencies task. The dependency version ceiling is the BC version being built against - NOT app.json 'application'/'platform', which are the app's minimum supported versions (using those as the ceiling makes the resolver reject real dependency apps built for the current BC and fall back to symbol-only AppSource packages).

Precedence, highest first:

  1. TargetVersionInput - an explicit pipeline value. Defaults (in the task) to $(bcArtifactVersion) from Get BC Artifact, so a CONTAINER-LESS build still honours the BC version it targets; can also be an author override. An unexpanded '$(...)' macro or an empty value is ignored (a container-less run leaves the default macro unexpanded).
  2. InstalledApp - the platform app installed in the build container (exact build BC version); preserves the original container-based behaviour.
  3. ConfigBcVersion - the 'bcVersion' pinned in albuild.json. Returns an empty Version (Source 'none') when nothing is available, so the caller resolves the newest version each app.json is compatible with.

Syntax

PowerShellCode
Resolve-BcDependencyCeiling [-TargetVersionInput <String>] [-InstalledApp <Object[]>] [-ConfigBcVersion <String>]

Parameters

ParameterTypeRequiredDescription
-TargetVersionInputStringNoThe task's 'targetVersion' input value (may be empty or an unexpanded '$(...)' macro).
-InstalledAppObject[]NoThe apps installed in the build container (objects with Name/Version), or empty for none.
-ConfigBcVersionStringNoThe 'bcVersion' from albuild.json, or empty.

Output

PSCustomObject: Version (string, '' when none) and Source (string).


Resolve-BcExternalDependency

Syntax

PowerShellCode
Resolve-BcExternalDependency [-UniversalPackages <Object[]>] [-LocalPackage <String[]>] [-UrlPackage <Object[]>] -OutputFolder <String> [-Organization <String>] [-Project <String>] [-AccessToken <String>] [-RequireUniversalPackages] [-BaseFolder <String>] [-ContainerName <String>] [-DockerExecutable <String>]

Parameters

ParameterTypeRequiredDescription
-UniversalPackagesObject[]No
-LocalPackageString[]No
-UrlPackageObject[]No
-OutputFolderStringYes
-OrganizationStringNo
-ProjectStringNo
-AccessTokenStringNo
-RequireUniversalPackagesswitchNo
-BaseFolderStringNoDefault: (Get-Location).Path.
-ContainerNameStringNo
-DockerExecutableStringNoDefault: 'docker'.

Select-BcArtifactForDependencies

Picks the newest Business Central artifact whose build every project's dependencies still resolve against - stepping back through minor versions when an ISV has not yet shipped packages for the latest BC (dependency-aware selection with downgrade-on-conflict).

For 'Select = Latest' pipelines only. Enumerates the latest artifact and up to -MaxStepsBack earlier minor versions (crossing a major boundary to the previous major's latest minor when a minor reaches x.0), and - newest first - dry-runs Resolve-BcDependencies (-SkipDownload) for every project against that build. The first version where all projects resolve is chosen. If it is older than the latest, 'Downgraded' is set and 'ConflictReason' explains why the latest was skipped (the caller emits the pipeline warning). Throws if nothing within the window resolves. Because it uses an explicit target build and a synthetic Microsoft baseline, no container is needed - the choice is made before the (single) container is created.

A specific -Version pins the choice: enumeration/downgrade only runs when no explicit version is given.

Syntax

PowerShellCode
Select-BcArtifactForDependencies -ProjectFolder <String[]> [-Type <String>] [-Country <String>] [-Version <String>] [-MaxStepsBack <Int32>] [-Feeds <Object[]>] [-InstalledApps <Object[]>]

Parameters

ParameterTypeRequiredDescription
-ProjectFolderString[]YesThe AL project folder(s) to resolve. Every one must resolve for a version to be chosen.
-TypeStringNoArtifact type (Sandbox or OnPrem). Default 'Sandbox'. Default: 'Sandbox'.
-CountryStringNoArtifact country/localisation.
-VersionStringNoExplicit version/prefix. When given, that version is returned as-is (no downgrade search).
-MaxStepsBackInt32NoMaximum number of minor versions to step back from the latest. Default 5. Default: 5.
-FeedsObject[]NoFeed provider objects for the resolver (as Resolve-BcDependencies -Feeds). When omitted the resolver auto-loads the project/registered feeds.
-InstalledAppsObject[]NoBaseline apps pinned in every dry-run - the already-staged external dependencies (url/local/universal) so the resolver treats them as satisfied instead of fetching from a feed.

Output

PSCustomObject: ArtifactUrl, Version, LatestVersion, Downgraded, StepsBack, ConflictReason.


Last modified on