functions/remove-d365ceodataentity.ps1


<#
    .SYNOPSIS
        Remove a Data Entity from Dynamics 365 Customer Engagement
         
    .DESCRIPTION
        Removes a Data Entity, defined by the EntityKey, using the OData endpoint of the Dynamics 365 Customer Engagement
         
    .PARAMETER EntityName
        Name of the Data Entity you want to work against
         
        The parameter is Case Sensitive, because the OData endpoint in D365CE is Case Sensitive
         
        Remember that most Data Entities in a D365CE environment is named by its singular name, but most be retrieve using the plural name
         
        E.g. The account Data Entity is named "account", but can only be retrieving using "accounts"
         
        Use the XRMToolBox (https://www.xrmtoolbox.com) to help you identify the names of the Data Entities that you are looking for
         
    .PARAMETER Key
        The key that will select the desired Data Entity uniquely across the OData endpoint
         
        The key would most likely be made up from multiple values, but can also be a single value
         
    .PARAMETER RefPath
        Path for working with the referene capabilities of the OData endpoint
         
        Can be used to unmap / deassiociate an entity from another, like removing a systemuser from a role
         
    .PARAMETER Tenant
        Azure Active Directory (AAD) tenant id (Guid) that the D365CE environment is connected to, that you want to access through OData
         
    .PARAMETER Url
        URL / URI for the D365CE environment you want to access through OData
         
    .PARAMETER ClientId
        The ClientId obtained from the Azure Portal when you created a Registered Application
         
    .PARAMETER ClientSecret
        The ClientSecret obtained from the Azure Portal when you created a Registered Application
         
    .PARAMETER EnableException
        This parameters disables user-friendly warnings and enables the throwing of exceptions
        This is less user friendly, but allows catching exceptions in calling scripts
         
    .EXAMPLE
        PS C:\> Remove-D365CeODataEntity -EntityName ExchangeRates -EntityKey "RateTypeName='TEST'","FromCurrency='DKK'","ToCurrency='EUR'","StartDate=2019-01-13T12:00:00Z"
         
        This will remove a Data Entity from the D365CE environment through OData.
        It will use the ExchangeRate entity, and its EntitySetName / CollectionName "ExchangeRates".
        It will use the "RateTypeName='TEST'","FromCurrency='DKK'","ToCurrency='EUR'","StartDate=2019-01-13T12:00:00Z" as the unique key for the entity.
         
        It will use the default OData configuration details that are stored in the configuration store.
         
    .EXAMPLE
        PS C:\> Remove-D365CeODataEntity -EntityName "systemusers" -Key "00000000-0000-0000-0000-000000000002" -RefPath '/systemuserroles_association(00000000-0000-0000-0000-000000000001)/$ref'
         
        This will remove the mapping / association between 2 Data Entities from the D365CE environment through OData.
        The EntityName is "systemusers" which is the user, that you want to remove from a role.
        The Key "00000000-0000-0000-0000-000000000002" is the unique systemuserid for the user that you want to work against.
        The RefPath '/systemuserroles_association(00000000-0000-0000-0000-000000000001)/$ref' points to the unique roleid that you want to remove the user from.
         
        It will use the default OData configuration details that are stored in the configuration store.
         
    .NOTES
        Tags: OData, Data, Entity, Import, Upload
         
        Author: Mötz Jensen (@Splaxi)
         
    .LINK
        Add-D365CeODataConfig
         
    .LINK
        Get-D365CeActiveODataConfig
         
    .LINK
        Set-D365CeActiveODataConfig
#>


function Remove-D365CeODataEntity {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
    [CmdletBinding()]
    [OutputType()]
    param (
        [Parameter(Mandatory = $true)]
        [string] $EntityName,

        [Parameter(Mandatory = $true)]
        [string] $Key,

        [string] $RefPath,

        [Parameter(Mandatory = $false)]
        [Alias('$AADGuid')]
        [string] $Tenant = $Script:ODataTenant,

        [Parameter(Mandatory = $false)]
        [Alias('URI')]
        [string] $URL = $Script:ODataUrl,

        [Parameter(Mandatory = $false)]
        [string] $ClientId = $Script:ODataClientId,

        [Parameter(Mandatory = $false)]
        [string] $ClientSecret = $Script:ODataClientSecret,

        [switch] $EnableException

    )

    begin {
        $bearerParms = @{
            Url     = $Url
            ClientId     = $ClientId
            ClientSecret = $ClientSecret
            Tenant = $Tenant
        }

        $bearer = New-BearerToken @bearerParms

        $headerParms = @{
            URL         = $URL
            BearerToken = $bearer
        }

        $headers = New-AuthorizationHeaderBearerToken @headerParms

        $apiPath = Get-PSFConfigValue -FullName "d365ce.integrations.api.version"
    }

    process {
        Invoke-TimeSignal -Start

        Write-PSFMessage -Level Verbose -Message "Building request for removing data entity through the OData endpoint for entity named: $EntityName." -Target $EntityName

        [System.UriBuilder] $odataEndpoint = $URL

        $odataEndpoint.Path = "$apiPath/$EntityName($Key)" + $RefPath

        try {
            Write-PSFMessage -Level Verbose -Message "Executing http request against the OData endpoint." -Target $($odataEndpoint.Uri.AbsoluteUri)
            Invoke-RestMethod -Method DELETE -Uri $odataEndpoint.Uri.AbsoluteUri -Headers $headers -ContentType 'application/json'
        }
        catch {
            $messageString = $((ConvertFrom-Json $_).Error.InnerError | ConvertTo-Json -Depth 10)
            Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target $EntityName
            Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($messageString)) -ErrorRecord $_
            return
        }
        
        Invoke-TimeSignal -End
    }
}