functions/Add-PpePublisher.ps1
|
<# .SYNOPSIS Add a publisher to a Power Platform environment. .DESCRIPTION Creates a new Dataverse publisher (publishers) with the bare minimum of required fields. The cmdlet is idempotent and works as an upsert keyed on UniqueName. If a publisher with the same unique name already exists, it is updated in place with the supplied values instead of failing. Only values explicitly supplied by the caller are updated - omitted optional values are left untouched on existing publishers. Requires the unique name, display name, customization prefix and option value prefix. The option value prefix defaults to a random value between 10000 and 99999 when omitted on create. It is left untouched on update when omitted. .PARAMETER EnvironmentId The id of the environment that you want to work against. .PARAMETER UniqueName The unique name of the publisher. Must be unique across the environment. .PARAMETER FriendlyName The display / friendly name of the publisher. .PARAMETER Prefix The customization prefix used for new entities, attributes and relationships for solutions associated with this publisher. .PARAMETER OptionValuePrefix The default option value prefix used for newly created options for solutions associated with this publisher. Must be between 10000 and 99999. Defaults to a random value in that range when omitted. .PARAMETER Description An optional description of the publisher. .PARAMETER EmailAddress An optional email address for the publisher. .PARAMETER SupportingWebsiteUrl An optional supporting website URL for the publisher. .PARAMETER AddressLine1 An optional first street line for address 1. .PARAMETER AddressLine2 An optional second street line for address 1. .PARAMETER AddressLine3 An optional third street line for address 1. .PARAMETER AddressCity An optional city for address 1. .PARAMETER AddressStateOrProvince An optional state or province for address 1. .PARAMETER AddressPostalCode An optional ZIP / postal code for address 1. .PARAMETER AddressCountry An optional country / region for address 1. .PARAMETER AddressPhone An optional phone number for address 1. .EXAMPLE PS C:\> Add-PpePublisher -EnvironmentId "eec2c11a-a4c7-4e1d-b8ed-f62acc9c74c6" -UniqueName "contoso" -FriendlyName "Contoso" -Prefix "cont" This will create the "Contoso" publisher with the prefix "cont" and a random option value prefix. .EXAMPLE PS C:\> Add-PpePublisher -EnvironmentId "eec2c11a-a4c7-4e1d-b8ed-f62acc9c74c6" -UniqueName "contoso" -FriendlyName "Contoso" -Prefix "cont" -OptionValuePrefix 12345 -Description "Contoso publisher" This will create the "Contoso" publisher with full details. .EXAMPLE PS C:\> Add-PpePublisher -EnvironmentId "eec2c11a-a4c7-4e1d-b8ed-f62acc9c74c6" -UniqueName "contoso" -FriendlyName "Contoso" -Prefix "cont" -AddressLine1 "One Microsoft Way" -AddressCity "Redmond" -AddressCountry "USA" -EmailAddress "publisher@contoso.com" This will update the existing "contoso" publisher with address details if it already exists, or create it with address details if it does not exist. .NOTES Author: Mötz Jensen (@Splaxi) #> function Add-PpePublisher { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType('System.Object[]')] param ( [Parameter (Mandatory = $true)] [string] $EnvironmentId, [Parameter (Mandatory = $true)] [string] $UniqueName, [Parameter (Mandatory = $true)] [Alias('DisplayName')] [string] $FriendlyName, [Parameter (Mandatory = $true)] [Alias('CustomizationPrefix')] [string] $Prefix, [Alias('CustomizationOptionValuePrefix')] [ValidateRange(10000, 99999)] [int] $OptionValuePrefix, [string] $Description, [string] $EmailAddress, [Alias('Website')] [string] $SupportingWebsiteUrl, [string] $AddressLine1, [string] $AddressLine2, [string] $AddressLine3, [string] $AddressCity, [string] $AddressStateOrProvince, [string] $AddressPostalCode, [string] $AddressCountry, [Alias('Phone', 'Telephone1')] [string] $AddressPhone ) begin { # Make sure all *BapEnvironment* cmdlets will validate that the environment exists prior running anything. $envObj = Get-BapEnvironment ` -EnvironmentId $EnvironmentId | ` Select-Object -First 1 if ($null -eq $envObj) { $messageString = "The supplied EnvironmentId: <c='em'>$EnvironmentId</c> didn't return any matching environment details. Please verify that the EnvironmentId is correct - try running the <c='em'>Get-BapEnvironment</c> cmdlet." Write-PSFMessage -Level Important -Message $messageString Stop-PSFFunction -Message "Stopping because environment was NOT found based on the id." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) } if (Test-PSFFunctionInterrupt) { return } $baseUri = $envObj.PpacEnvUri $secureToken = (Get-AzAccessToken -ResourceUrl $baseUri -AsSecureString).Token $tokenWebApiValue = ConvertFrom-SecureString -AsPlainText -SecureString $secureToken $headersWebApi = @{ "Authorization" = "Bearer $($tokenWebApiValue)" } } process { if (Test-PSFFunctionInterrupt) { return } $existingPublisher = Get-PpePublisher ` -EnvironmentId $envObj.PpacEnvId ` -Name $UniqueName | ` Where-Object { $_.SystemName -eq $UniqueName -or $_.PpePublisherId -eq $UniqueName } | ` Select-Object -First 1 if ($null -ne $existingPublisher) { # Idempotent upsert: update the existing publisher in place with explicitly supplied values. # Note: PSBoundParameters keys are checked with aliases included, as callers may use them. $updatePayload = [ordered]@{} if ($PSBoundParameters.ContainsKey('FriendlyName') -or $PSBoundParameters.ContainsKey('DisplayName')) { $updatePayload.friendlyname = $FriendlyName } # Prefix and option value prefix are only sent when they actually differ - they are # effectively immutable after create and re-sending them can trigger server-side # recalculation of the option value prefix. if ($PSBoundParameters.ContainsKey('Prefix') -or $PSBoundParameters.ContainsKey('CustomizationPrefix')) { if ("$($existingPublisher.customizationprefix)" -ne "$Prefix") { $updatePayload.customizationprefix = $Prefix } } if ($PSBoundParameters.ContainsKey('OptionValuePrefix') -or $PSBoundParameters.ContainsKey('CustomizationOptionValuePrefix')) { if ("$($existingPublisher.customizationoptionvalueprefix)" -ne "$OptionValuePrefix") { $updatePayload.customizationoptionvalueprefix = $OptionValuePrefix } } if ($PSBoundParameters.ContainsKey('Description')) { $updatePayload.description = $Description } if ($PSBoundParameters.ContainsKey('EmailAddress')) { $updatePayload.emailaddress = $EmailAddress } if ($PSBoundParameters.ContainsKey('SupportingWebsiteUrl') -or $PSBoundParameters.ContainsKey('Website')) { $updatePayload.supportingwebsiteurl = $SupportingWebsiteUrl } if ($PSBoundParameters.ContainsKey('AddressLine1')) { $updatePayload.address1_line1 = $AddressLine1 } if ($PSBoundParameters.ContainsKey('AddressLine2')) { $updatePayload.address1_line2 = $AddressLine2 } if ($PSBoundParameters.ContainsKey('AddressLine3')) { $updatePayload.address1_line3 = $AddressLine3 } if ($PSBoundParameters.ContainsKey('AddressCity')) { $updatePayload.address1_city = $AddressCity } if ($PSBoundParameters.ContainsKey('AddressStateOrProvince')) { $updatePayload.address1_stateorprovince = $AddressStateOrProvince } if ($PSBoundParameters.ContainsKey('AddressPostalCode')) { $updatePayload.address1_postalcode = $AddressPostalCode } if ($PSBoundParameters.ContainsKey('AddressCountry')) { $updatePayload.address1_country = $AddressCountry } if ($PSBoundParameters.ContainsKey('AddressPhone') -or $PSBoundParameters.ContainsKey('Phone') -or $PSBoundParameters.ContainsKey('Telephone1')) { $updatePayload.address1_telephone1 = $AddressPhone } if ($updatePayload.Count -eq 0) { Write-PSFMessage -Level Verbose -Message "The publisher: $UniqueName already exists and no updatable values were supplied. Returning the existing publisher." return $existingPublisher } $isDifferent = $false foreach ($key in @($updatePayload.Keys)) { $desiredValue = $updatePayload[$key] $currentValue = $existingPublisher.$key if ($null -eq $desiredValue -and $null -eq $currentValue) { continue } if ([string]::IsNullOrEmpty($desiredValue) -and [string]::IsNullOrEmpty($currentValue)) { continue } if ("$currentValue" -ne "$desiredValue") { $isDifferent = $true break } } if (-not $isDifferent) { Write-PSFMessage -Level Verbose -Message "The publisher: $UniqueName already exists with the supplied values. Returning the existing publisher." return $existingPublisher } Write-PSFMessage -Level Verbose -Message "The publisher: $UniqueName already exists. Updating it with the supplied values." Invoke-RestMethod -Method Patch ` -Uri $($baseUri + "/api/data/v9.2/publishers($($existingPublisher.PpePublisherId))") ` -Headers $headersWebApi ` -ContentType "application/json" ` -Body $($updatePayload | ConvertTo-Json -Depth 10) ` -StatusCodeVariable statusUpdate > $null 4> $null if (-not ($statusUpdate -like "2*")) { $messageString = "Failed to update the publisher: <c='em'>$UniqueName</c> in the Power Platform environment. HTTP status: <c='em'>$statusUpdate</c>. Please try updating the publisher manually via the Power Platform maker portal - <c='em'>https://make.powerapps.com</c>" Write-PSFMessage -Level Important -Message $messageString Stop-PSFFunction -Message "Stopping because updating the publisher failed." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) return } Get-PpePublisher ` -EnvironmentId $envObj.PpacEnvId ` -Name $existingPublisher.PpePublisherId return } if (-not ($PSBoundParameters.ContainsKey('OptionValuePrefix') -or $PSBoundParameters.ContainsKey('CustomizationOptionValuePrefix'))) { $OptionValuePrefix = Get-Random -Minimum 10000 -Maximum 99999 } $payload = [ordered]@{ uniquename = $UniqueName friendlyname = $FriendlyName customizationprefix = $Prefix customizationoptionvalueprefix = $OptionValuePrefix } if ($PSBoundParameters.ContainsKey('Description')) { $payload.description = $Description } if ($PSBoundParameters.ContainsKey('EmailAddress')) { $payload.emailaddress = $EmailAddress } if ($PSBoundParameters.ContainsKey('SupportingWebsiteUrl') -or $PSBoundParameters.ContainsKey('Website')) { $payload.supportingwebsiteurl = $SupportingWebsiteUrl } if ($PSBoundParameters.ContainsKey('AddressLine1')) { $payload.address1_line1 = $AddressLine1 } if ($PSBoundParameters.ContainsKey('AddressLine2')) { $payload.address1_line2 = $AddressLine2 } if ($PSBoundParameters.ContainsKey('AddressLine3')) { $payload.address1_line3 = $AddressLine3 } if ($PSBoundParameters.ContainsKey('AddressCity')) { $payload.address1_city = $AddressCity } if ($PSBoundParameters.ContainsKey('AddressStateOrProvince')) { $payload.address1_stateorprovince = $AddressStateOrProvince } if ($PSBoundParameters.ContainsKey('AddressPostalCode')) { $payload.address1_postalcode = $AddressPostalCode } if ($PSBoundParameters.ContainsKey('AddressCountry')) { $payload.address1_country = $AddressCountry } if ($PSBoundParameters.ContainsKey('AddressPhone') -or $PSBoundParameters.ContainsKey('Phone') -or $PSBoundParameters.ContainsKey('Telephone1')) { $payload.address1_telephone1 = $AddressPhone } Invoke-RestMethod -Method Post ` -Uri $($baseUri + "/api/data/v9.2/publishers") ` -Headers $headersWebApi ` -ContentType "application/json" ` -Body $($payload | ConvertTo-Json -Depth 10) ` -ResponseHeadersVariable responseHeaders ` -StatusCodeVariable statusPublisher > $null 4> $null if (-not ($statusPublisher -like "2*")) { $messageString = "Failed to create the publisher: <c='em'>$UniqueName</c> in the Power Platform environment. Please try creating the publisher manually via the Power Platform maker portal - <c='em'>https://make.powerapps.com</c>" Write-PSFMessage -Level Important -Message $messageString Stop-PSFFunction -Message "Stopping because creating the publisher failed." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) return } $newPublisherId = [regex]::Match("$($responseHeaders.'OData-EntityId')", '\(([0-9a-fA-F-]{36})\)').Groups[1].Value Get-PpePublisher ` -EnvironmentId $envObj.PpacEnvId ` -Name $newPublisherId } end { } } |