---
title: Call the LCS Database Movement API from your Azure DevOps Pipelines
description: "### What for? Basically, [automation](http://ariste.info/en/2019/10/devops-alm-automation-in-microsoft-dynamics-365-for-finance-and-operations/). Right now **the API only allows the refresh from one Microsoft Dynamics 365 for Finance and Operations environment to another**, so the idea is having fresh data from production in our UAT environments **daily**. I…"
url: "https://ariste.info/dynamics365almguide/call-the-lcs-database-movement-api-from-your-azure-devops-pipelines/"
updated: "2024-08-25"
category: Legacy Guide / LCS DB API
---

# Call the LCS Database Movement API from your Azure DevOps Pipelines

### What for?

   Basically, [automation](http://ariste.info/en/2019/10/devops-alm-automation-in-microsoft-dynamics-365-for-finance-and-operations/). Right now **the API only allows the refresh from one Microsoft Dynamics 365 for Finance and Operations environment to another**, so the idea is having fresh data from production in our UAT environments **daily**. I don't know which new operations the API will support in the future but another idea could be adding the DB export operation (creating a bacpac) to the pipeline and having a copy of prod ready to be restored in a Dev environment.   Don't forget that the API has a limit of **3 refresh operations per environment per 24 hours**. Don't do this on a CI build! (it makes no sense either). Probably the best idea is to run this nightly with all your tests, once a day.

### Calling the API

   I'll use PowerShell to call the API from a pipeline. PowerShell has a command called [Invoke-RestMethod](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-7&WT.mc_id=DOP-MVP-5003976) that makes HTTP/HTTPS requests. It's really easy and we just need to do the same we did to call the API in my post.

#### Getting the token

```
$projectId = "1234567"
$tokenUrl = "https://login.microsoftonline.com/common/oauth2/token"
$clientId = "12345678-abcd-432a-0666-22de4c4321aa"
$clientSecret = "superSeCrEt12345678"
$username = "youruser@tenant.com"
$password = "strongerThan123456"

$tokenBody = @{
    grant_type = "password"
    client_id = $clientId
    client_secret = $clientSecret
    resource = "https://lcsapi.lcs.dynamics.com"
    username = $username
    password = $password
}

$tokenResponse = Invoke-RestMethod -Method 'POST' -Uri $tokenUrl -Body $tokenBody
$token = $tokenResponse.access_token
```

   To get the token we'll use this script. Just change the variables for the ones of your project, AAD App registration, user (remember it needs access to the preview) and password and run it. If everything is OK you'll get the JSON response in the $tokenResponse variable and from there you can get the token's value using dot notation.

#### Requesting the DB refresh

```
$projectId = "1234567"
$sourceEnvironmentId = "fad26410-03cd-4c3e-89b8-85d2bddc4933"
$targetEnvironmentId = "cab68410-cd13-9e48-12a3-32d585aaa548"
$refreshUrl = "https://lcsapi.lcs.dynamics.com/databasemovement/v1/databases/project/$projectId/source/$sourceEnvironmentId/target/$targetEnvironmentId"

$refreshHeader = @{
    Authorization = "Bearer $token"
    "x-ms-version" = '2017-09-15'
    "Content-Type" = "application/json"
}

$refreshResponse = Invoke-RestMethod $refreshUrl -Method 'POST' -Headers $refreshHeader
```

   This will be the call to trigger the refresh. We'll need the token we've just obtained in the first step to use it in the header and the source and target environment Ids.   If it's successful the response will be a 200 OK.

### Add it to your pipeline

   Adding this to an Azure DevOps pipeline is no mistery. Select and edit your pipeline, I'm doing it on a nigthly build (it's called continuous but it's not...) that runs after the environment has been updated with code, and add a new PowerShell task:

![Call the LCS Database Movement API from your Azure DevOps Pipelines](http://ariste.info/wp-content/uploads/2020/01/2020-01-26-19_33_00-AXZ-Dev-Continuous-Build-Azure-DevOps-Services.png)

   Select the task and change it to "Inline":

![Call the LCS Database Movement API from your Azure DevOps Pipelines](http://ariste.info/wp-content/uploads/2020/01/2020-01-26-19_24_42-AXZ-Prod-Release-Daily-18h-Pipelines.png)

   Then just paste the script we've created in the Script field and done! You'll get a refresh after the tests!   You can also run this on your release pipeline **BUT** if you do it after the deploy step remember to mark the "Wait for Completion" option or the operation will fail because the environment will already be servicing! And even then it could fail if the servicing goes over the timeout time. So... **don't run this on your release pipeline**!   And that's all. Let's which new operations will be added to the API and what we can do with them.

### Use d365fo.tools in your Azure Pipeline

   Thanks to [Mötz's comment](http://ariste.info/en/2020/01/calling-the-lcs-database-movement-api-in-your-azure-devops-pipeline/#comment-77) pointing me to how to add d365fo.tools to a hosted pipeline I've created a pipeline which will install the tools and run the commands. It's even easier to do than with the Invoke-RestMethod.

#### But first...

   Make sure that in your Azure Active Directory app registration you've selected "Treat application as a public client" under Authentication:

![Call the LCS Database Movement API from your Azure DevOps Pipelines](http://ariste.info/wp-content/uploads/2020/01/2020-02-06-15_56_47-LCSDBAPIPreview-Authentication-Microsoft-Azure.png)

#### The task

   First we need to install d365fo.tools and then we can use its commands to call the LCS API:

```
Install-PackageProvider nuget -Scope CurrentUser -Force -Confirm:$false

Install-Module -Name AZ -AllowClobber -Scope CurrentUser -Force -Confirm:$False -SkipPublisherCheck

Install-Module -Name d365fo.tools -AllowClobber -Scope CurrentUser -Force -Confirm:$false

Get-D365LcsApiToken -ClientId "{YOUR_APP_ID}" -Username "{USERNAME}" -Password "{PASSWORD}" -LcsApiUri "https://lcsapi.lcs.dynamics.com" -Verbose | Set-D365LcsApiConfig -ProjectId 1234567

Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -SkipInitialStatusFetch
```

   As you can see it a bit easier to do the refresh using d365fo.tools. We get the token and pipeline the output to the Set-D365LcsApiConfig command which will store the token (and others). This also helps to not having to duplicate AppIds, users, etc. and as you can see to call the refresh operation we just need the source and target environment Ids!

#### Subscribe!

Receive an email when a new post is published
