Modules/businessdev.ALbuild.Marketplace/Public/Get-BcMarketplaceProduct.ps1
|
function Get-BcMarketplaceProduct { <# .SYNOPSIS Retrieves Business Central products from the Microsoft product-ingestion API. .DESCRIPTION Mirrors the proven Publish-AppSourceApp / Get-AppSourceProduct implementation: the product name lives in the product's 'alias' (NOT 'name'), the product type is 'dynamics365BusinessCentral' (camelCase - the hyphenated form returns 400), and the working schema version is '2022-03-01-preview3'. Results are paged via '@nextLink'. .PARAMETER AuthContext An auth context from New-BcMarketplaceAuthContext (Graph scope: 'https://graph.microsoft.com/.default'). .PARAMETER Name Optional product-name (alias) filter: exact match first, then wildcard/substring. .PARAMETER ProductType Product type. Default 'dynamics365BusinessCentral'. .PARAMETER ApiVersion Product ingestion API version. Default '2022-03-01-preview3'. .OUTPUTS The product object(s) (each with id, alias, identity.externalId, ...). #> [CmdletBinding()] param( [Parameter(Mandatory)] [PSCustomObject] $AuthContext, [string] $Name, [string] $ProductType = 'dynamics365BusinessCentral', [string] $ApiVersion = '2022-03-01-preview3' ) # Product-ingestion responses are dynamic JSON whose OPTIONAL properties (e.g. '@nextLink' on the # last page) are simply absent. The module runs under Set-StrictMode -Version Latest, which throws # on a missing property; relax it here (as the proven Publish-AppSourceApp script runs) so an absent # property reads as $null. Set-StrictMode -Off $headers = @{ Authorization = "Bearer $($AuthContext.AccessToken)"; 'Content-Type' = 'application/json' } # List every product of the type, following @nextLink. '$version' must be a literal ($ escaped). $url = "https://graph.microsoft.com/rp/product-ingestion/product?type=$ProductType&`$version=$ApiVersion" $products = [System.Collections.Generic.List[object]]::new() while ($url) { try { $response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get -ErrorAction Stop } catch { $detail = Get-BcMarketplaceErrorDetail -ErrorRecord $_ throw "Product-ingestion product query failed: $($_.Exception.Message)$(if ($detail) { " - $detail" })" } foreach ($p in @($response.value)) { $products.Add($p) } $url = $response.'@nextLink' } $all = @($products.ToArray()) if ($Name) { # The product NAME is the 'alias'. Prefer an exact match, then fall back to wildcard/substring. $exact = @($all | Where-Object { "$($_.alias)" -eq $Name }) if ($exact.Count -gt 0) { return $exact } return @($all | Where-Object { "$($_.alias)" -like "*$Name*" }) } return $all } |