@Julien2
We use a PowerShell script in the pipeline to deploy the bulk deletion job. I am planning to write up a detailed blog post about it but if you cannot wait for it, here's a glimpse of it.
You may add the checking of the bulkDeletionJobName in the FetchXML filter but the script that I wrote is for multiple jobs. So, the checking is done outside of the query.
try {
Write-Output "Fetching existing active recurring bulk deletion jobs from environment..."
$fetchQuery = "<fetch>
<entity name='asyncoperation'>
<attribute name='name' />
<attribute name='statuscode' />
<filter>
<condition attribute='statuscode' operator='eq' value='10' />
</filter>
<link-entity name='bulkdeleteoperation' from='asyncoperationid' to='asyncoperationid' alias='bulkdeleteoperation'>
<attribute name='bulkdeleteoperationid' />
<attribute name='isrecurring' />
<filter>
<condition attribute='isrecurring' operator='eq' value='1' />
</filter>
</link-entity>
</entity>
</fetch>"
$existingBulkDeletionJobs = Get-CrmRecordsByFetch -Fetch $fetchQuery -conn $connection
Write-Output "Existing Bulk Deletion Jobs"
Write-Output "====================================================="
$existingBulkDeletionJobs.CrmRecords | ForEach-Object {
Write-Output "- $($_.name)"
}
Write-Output "Checking the bulk deletion job is already existing..."
$_bulkDeletionJobName = "Bulk Deletion - Test Records - Status = Skipped or Successful"
$_exists = $existingBulkDeletionJobs.CrmRecords | Where-Object { $_.name -eq $_bulkDeletionJobName }
if ($_exists) {
Write-Output "Skipping $($_bulkDeletionJobName) as it is already created"
}
else {
Write-Output "Creating bulk deletion job - $($_bulkDeletionJobName)..."
$query = New-Object Microsoft.Xrm.Sdk.Query.QueryExpression('lzw_test')
$query.Criteria.AddCondition('statuscode', [Microsoft.Xrm.Sdk.Query.ConditionOperator]::In, @(3,4))
$query.Criteria.AddCondition('createdon', [Microsoft.Xrm.Sdk.Query.ConditionOperator]::OlderThanXDays, 28)
Write-Output "New QueryExpression initialised. - $($query.GetType())"
[Microsoft.Xrm.Sdk.Query.QueryExpression[]]$querySet = @($query)
Write-Output "QuerySet initialised. - $($querySet.GetType())"
$nextSunday = (Get-Date -Hour 3 -Minute 0 -Second 0).AddDays(7-((Get-Date).DayOfWeek.value__))
Invoke-CrmAction -conn $connection -Name 'BulkDelete' -Parameters @{
QuerySet = $querySet;
JobName = $_bulkDeletionJobName;
SendEmailNotification = $false;
ToRecipients = [System.Guid[]]@();
CCRecipients = [System.Guid[]]@();
RecurrencePattern = "FREQ=DAILY;INTERVAL=7";
StartDateTime = $nextSunday;
}
}
Write-Output "Bulk deletion jobs creation completed."
}
finally {
$connection.Dispose()
}
If there is no pipeline to run a PowerShell script in the project, you may create an instant cloud flow which does the same thing and it needs to be run manually as a post deployment step after the solution import.
1. Dataverse List Rows step for System Jobs (asyncoperation) with the FetchXML from the script above
2. If the result does not contain the bulkDeletionJobName that you want to create, call Perform an unbound action step to create a Bulk Deletion Job.
Note: ToRecipients and CCRecipients are empty array [] because it is a required parameter.
