src/Solutions/Customization/AppModule/Remove-XrmAppModule.ps1
|
<# .SYNOPSIS Delete a model-driven app from Microsoft Dataverse. .DESCRIPTION Remove an appmodule record (model-driven app). Publishing an app makes the platform add Dataverse search rows (dvtablesearch) for it: M365_Primary_model_<unique name>, which prevents the app deletion, and new_dvtablesearch_aiplugin_model_<unique name>, which the app deletion leaves behind. These rows are deleted first. .PARAMETER XrmClient Xrm connector initialized to target instance. Use latest one by default. (Dataverse ServiceClient) .PARAMETER AppModuleReference EntityReference of the appmodule record to delete. .OUTPUTS System.Void. .EXAMPLE Remove-XrmAppModule -AppModuleReference $appRef; .LINK https://github.com/AymericM78/PowerDataOps/blob/main/documentation/commands/Remove-XrmAppModule.md #> function Remove-XrmAppModule { [CmdletBinding(SupportsShouldProcess)] [OutputType([System.Void])] param ( [Parameter(Mandatory = $false, ValueFromPipeline)] [Microsoft.PowerPlatform.Dataverse.Client.ServiceClient] $XrmClient = $Global:XrmClient, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [Microsoft.Xrm.Sdk.EntityReference] $AppModuleReference ) begin { $StopWatch = [System.Diagnostics.Stopwatch]::StartNew(); Trace-XrmFunction -Name $MyInvocation.MyCommand.Name -Stage Start -Parameters ($MyInvocation.MyCommand.Parameters); } process { if (Test-XrmTable -XrmClient $XrmClient -LogicalName "dvtablesearch") { # m365appmoduleid blocks the delete; appmoduleid (no relationship) would stay orphaned $query = New-XrmQueryExpression -LogicalName "dvtablesearch" -Columns "name"; $query.Criteria.FilterOperator = [Microsoft.Xrm.Sdk.Query.LogicalOperator]::Or; $query = $query | Add-XrmQueryCondition -Field "m365appmoduleid" -Condition Equal -Values $AppModuleReference.Id; $query = $query | Add-XrmQueryCondition -Field "m365appmoduleidsecondary" -Condition Equal -Values $AppModuleReference.Id; $query = $query | Add-XrmQueryCondition -Field "appmoduleid" -Condition Equal -Values $AppModuleReference.Id; $searchRows = Get-XrmMultipleRecords -XrmClient $XrmClient -Query $query -AsArray; foreach ($searchRow in $searchRows) { $XrmClient | Remove-XrmRecord -LogicalName "dvtablesearch" -Id $searchRow.Id -IfExists; } } $XrmClient | Remove-XrmRecord -LogicalName "appmodule" -Id $AppModuleReference.Id; } end { $StopWatch.Stop(); Trace-XrmFunction -Name $MyInvocation.MyCommand.Name -Stage Stop -StopWatch $StopWatch; } } Export-ModuleMember -Function Remove-XrmAppModule -Alias *; |