Intro
About a year ago I wrote an article on the new features that Microsoft introduced on Business Central Admin Center. This time, in this blog post, I will focus on Microsoft BC API for admin center, introduced with version 20. In this blog post I am going to present a PowerShell script that copies a Business Central Production environment into a Sandbox and deletes the sandbox created the day before. Moreover, I will look into adding Telemetry to these 2 operations.
A while back I read an older article of Microsoft MVP Zhu’s article on Business Central Admin Center API and I wanted to try this API by resolving an older request I’ve got from a customer, which was at its core about copying of a Business Central environment using PowerShell.
Customer request was as following:
- Create every day a sandbox based on current data in Production.
- Delete previous day sandbox ProdCopy(dd-1)mmyyyy
- Name the sandbox ProdCopyddmmyyyy.
I also added a 4th condition:
2. Telemetry logs for both operations (delete previous date sandbox and new sandbox with today’s date)
Let’s get started
First, to be able to send requests to Business Central Admin Center API we need to create an app registration,
Authenticate using service-to-service AAD Apps
This step is quite similar to creating an app registration to facilitate OAuth2 authentication for accessing Business Central exposed API.
Follow the steps enumerated in this Microsoft document:
- Sign into the Azure portal.
- Register an application for Business Central administration center in your Azure Active Directory tenant
- Create a client secret for the registered application
- Grant the registered application AdminCenter.ReadWrite.All permission to the Dynamics 365 Business Central administration center API
You can also consult Zhu’s article on creating the ap registration for BC Admin Center authentication.
Install Azure AD Powershell module
As the authentication is interactive and getting the access token relies on Microsoft.IdentityModel.Clients.ActiveDirectory module, we need to install AzureAD module locally:
Install-Module AzureAD
Below is the script.
First, we need to get the access token:
$aadAppId = "850b5f07-c2ad-4c75-9921-54e16e54e54b" # application id
$aadAppRedirectUri = "http://localhost" # app registration redirect url
$aadTenantId = "e92a969e-d2c0-4b61-b70d-5a6832856f6d" # customer's tenant id
Add-Type -Path "C:\Program Files\WindowsPowerShell\Modules\AzureAD\2.0.2.140\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
# Get access token
$ctx = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext]::new("https://login.microsoftonline.com/$aadTenantId")
$redirectUri = New-Object -TypeName System.Uri -ArgumentList $aadAppRedirectUri
$platformParameters = New-Object -TypeName Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters -ArgumentList ([Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior]::Always)
$accessToken = $ctx.AcquireTokenAsync("https://api.businesscentral.dynamics.com", $aadAppId, $redirectUri, $platformParameters).GetAwaiter().GetResult().AccessToken
Then, generate strings for today’s date and yesterday’s date:
#generate dates
$td = (Get-Date).Date
$Today = $td.Day.ToString()+$td.Month.ToString()+$td.Year.ToString() #this yields: 12122022
$td = (Get-Date).Date.AddDays(-1).Date
$Yesterday = $td.Day.ToString()+$td.Month.ToString()+$td.Year.ToString() #this yields: 11122022
Send a DELETE request against affected sandbox to delete yesterday sandbox:
# Delete ProdCopy environment from the previous day and create one for today
$newEnvironmentName = "ProdCopy"+$Yesterday
$response = Invoke-WebRequest `
-Method Delete `
-Uri "https://api.businesscentral.dynamics.com/admin/v2.3/applications/businesscentral/environments/$newEnvironmentName" `
-Headers @{Authorization=("Bearer $accessToken")}
Lastly, we want a copy of Production with today’s date. This is done with a POST request again Production environment:
$environmentName = "Production"
$newEnvironmentName = "ProdCopy"+$Today
$response = Invoke-WebRequest `
-Method Post `
-Uri "https://api.businesscentral.dynamics.com/admin/v2.3/applications/businesscentral/environments/$environmentName" `
-Body (@{
EnvironmentName = $newEnvironmentName
Type = "Sandbox"
} | ConvertTo-Json) `
-Headers @{Authorization=("Bearer $accessToken")} `
-ContentType "application/json"
Before script run, environments showed yesterday sandbox:
After the script run, we have a sandbox with today’s data:
The only requirement left was to log telemetry for these 2 operations.
I found this useful library created by a Microsoft engineer, Keith Babinec, and used one if his PowerShell functions, Send-AppInsightsTraceTelemetry to log the deletions and creations of sandboxes as you can see below:
# import telemetry logging tool
Import-Module C:\_source\AzurePowerShellUtilityFunctions\AzurePowerShellUtilityFunctions.psd1
$LogStart = 'Create ProdCopy' + $Today + ' sandbox.'
# plug in your AI instrumentation key, trace message, and severity.
$AppInsightKey = 'bf7f93fd-72af-4ad1-982d-e738da3454a4'
Send-AppInsightsTraceTelemetry -InstrumentationKey $AppInsightKey -Message $LogStart -Severity Information
For deleting sandbox:
$LogDeleteSandbox = 'Delete ProdCopy' + $Yesterday + ' sandbox.'
Send-AppInsightsTraceTelemetry -InstrumentationKey $AppInsightKey -Message $LogDeleteSandbox -Severity Information
For creating new sandbox:
$LogCreateNewSandbox = 'Create new ProdCopy' + $Today + ' sandbox.'
Send-AppInsightsTraceTelemetry -InstrumentationKey $AppInsightKey -Message $LogCreateNewSandbox -Severity Information
And if I log in the Azure portal and look at the logs recorded under Tracers under by AppInsight I can see those 2 logs:
Conclusions
You can find the whole script here.
All in all, the script is interactive, therefore it requires the user to enter credentials for Azure tenant. With a combination of an Azure automation tool (Automation, webjob, or azure function) and with the credentials stored in a key vault the script could be scheduled to run automatically. Need to find the time to investigate this enhancement 🙂
The script requires setting up an app registration, but once you’re successful in getting the token you have access to all endpoints for BC Admin Center API:
- App management endpoints: install, uninstall apps
- list of Azure Apps Id
- environments endpoints: GET all environments, or just one environment, Copy environment, Delete environment, Rename and Restore environments, available restore periods, used storage for all environments, allowed quotas for environments.
- environment exports endpoint
- reported outages
- notification recipients
- scheduled updates or rescheduling
- active sessions per environment session details; session management (delete)
- environment Telemetry
Check out the main Microsoft document on the APIs included above.
One Response