Ahora que Microsoft va a actualizar los entornos sandbox adicionales de Dynamics 365 Finance and Operations, los partners y clientes solo nos tendremos que ocupar de los entornos hospedados en la nube (cloud-hosted environments), como hemos hecho siempre.
Estoy seguro de que cada equipo gestiona esto a su manera, quizá dejando que cada desarrollador actualice su máquina, o que hay alguien en el partner que se lo hace. Y eso en el mejor de los casos, quizá nadie actualiza las máquinas de desarrollo…
Vamos a ver qué hace paso a paso.
Instalo las d365fo.tools en el primer paso con este script:
Y en la segunda tarea ejecuto el script de actualización que acabamos de ver al principio de este post.
Por supuesto se puede hacer todo en una única tarea, pero yo prefiero separarlo porque me parece más bonito.
Si quieres saber más sobre builds, releases y el ALM de desarrollo de Dynamics 365 puedes leer mi guía sobre MSDyn365 y Azure DevOps ALM.
¡Hoy os traigo un script de PowerShell que podemos ejecutar en un pipeline para actualizar automáticamente todas las máquinas de desarrollo!¡A actualizar se ha dicho! #
Como ya he hecho varias veces, voy a usar las d365fo.tools de Mötz Jensen para ejecutar todas las operaciones. Este es el script al completo:# CHANGE THIS!!
$AssetId = "LCS_ASSET_ID"
$User = "YOUR_USER"
$Pass = "YOUR_USER_PASSWORD"
$ClientId = "AAD AppId"
$ProjectId = "LCS_PROJECT_ID"
#Get LCS auth token
Get-D365LcsApiToken -ClientId $ClientId -Username $User -Password $Pass -LcsApiUri https://lcsapi.lcs.dynamics.com | Set-D365LcsApiConfig -ProjectId $ProjectId
Get-D365LcsApiConfig
# Get list of all LCS project environments
$Environments = Get-D365LcsEnvironmentMetadata -TraverseAllPages
$StartedEnvs = @()
Write-Host "=================== STARTING ENVIRONMENTS ==================="
Foreach ($Env in $Environments)
{
# Start Dev VMs only
if ($Env.EnvironmentType -eq "DevTestDev" -and $Env.CanStart)
{
$EnvStatus = Invoke-D365LcsEnvironmentStart -EnvironmentId $Env.EnvironmentId
if ($EnvStatus.IsSuccess -eq "True") {
Write-Host ("Environment {0} started." -f $Env.EnvironmentName)
$StartedEnvs += $Env.EnvironmentId
}
else {
Write-Host ("Environment {0} couldn't be started. Error message: {1}" -f $Env.EnvironmentName, $EnvStatus.ErrorMessage)
}
}
}
Write-Host "=================== STARTING ENVIRONMENTS DONE ==================="
Write-Host "=================== SLEEPING FOR 180 seconds ==================="
# Wait 3 minutes for the VMs to start
Start-Sleep -Seconds 180
$Retries = 0
Write-Host "=================== STARTING DEPLOYMENT ==================="
Do
{
Foreach ($EnvD in $StartedEnvs)
{
$EnvStatus = Get-D365LcsEnvironmentMetadata -EnvironmentId $EnvD
# If the VM has started, deploy the DP
if ($EnvStatus.DeploymentStatusDisplay -eq "Deployed")
{
$OpResult = Invoke-D365LcsDeployment -AssetId $AssetId -EnvironmentId $EnvD
if ($OpResult.IsSuccess -eq "True") {
Write-Host ("Updating environment {0} has started." -f $EnvD)
$StartedEnvs = $StartedEnvs -notmatch $EnvD
}
else {
Write-Host ("Updating environment {0} has failed. Error Message: {1}." -f $EnvD, $OpResult.ErrorMessage)
Write-Host ("Will retry {0} more time(s)" -f 3 - $Retries)
}
}
}
$Retries++
} While ($StartedEnvs.Count -ne 0 -or $Retries -eq 3)
Write-Host "=================== STARTING DEPLOYMENT DONE ==================="
Write-Host "Done"
Autenticación y obtener entornos #
El primer paso será autenticarse en LCS con el cmdlet Get-D365LcsApiToken y obtener una lista de nuestros entornos con Get-D365LcsEnvironmentMetadata. Esto va a incluir todos los entornos sandbox e incluso producción, pero no hay que preocuparse, no los vamos a actualizar. En la última línea inicializaremos un array para guardar los ID de los entornos arrancados en el siguiente paso.# CHANGE THIS!!
$AssetId = "LCS_ASSET_ID"
$User = "YOUR_USER"
$Pass = "YOUR_USER_PASSWORD"
$ClientId = "AAD AppId"
$ProjectId = "LCS_PROJECT_ID"
#Get LCS auth token
Get-D365LcsApiToken -ClientId $ClientId -Username $User -Password $Pass -LcsApiUri https://lcsapi.lcs.dynamics.com | Set-D365LcsApiConfig -ProjectId $ProjectId
Get-D365LcsApiConfig
# Get list of all LCS project environments
$Environments = Get-D365LcsEnvironmentMetadata -TraverseAllPages
$StartedEnvs = @()
Arrancar las máquinas de desarrollo #
Ahora que tenemos una lista con los entornos, tenemos que arrancar solo los hospedados en la nube. Lo haremos recorriendo los entornos que obtuvimos en la primera parte y filtrando por la propiedad EnvironmentType cuando sea igual a DevTestDev. Y, usando el comando Invoke-D365LcsEnvironmentStart arrancamos cada máquina. Ahora comprobamos si la operación ha ido bien o no. Cuando lo hayamos hecho para todas las máquinas, llamaremos a Start-Sleep y les daremos 3 minutos para que terminen de arrancar.Write-Host "=================== STARTING ENVIRONMENTS ==================="
Foreach ($Env in $Environments)
{
# Start Dev VMs only
if ($Env.EnvironmentType -eq "DevTestDev" -and $Env.CanStart)
{
$EnvStatus = Invoke-D365LcsEnvironmentStart -EnvironmentId $Env.EnvironmentId
if ($EnvStatus.IsSuccess -eq "True") {
Write-Host ("Environment {0} started." -f $Env.EnvironmentName)
$StartedEnvs += $Env.EnvironmentId
}
else {
Write-Host ("Environment {0} couldn't be started. Error message: {1}" -f $Env.EnvironmentName, $EnvStatus.ErrorMessage)
}
}
}
Write-Host "=================== STARTING ENVIRONMENTS DONE ==================="
Write-Host "=================== SLEEPING FOR 180 seconds ==================="
# Wait 3 minutes for the VMs to start
Start-Sleep -Seconds 180
Lanzar los updates #
En la parte final iniciaremos los despliegues en cada máquina de las que estén arrancadas. Recorreremos el array que hemos creado al principio, y usando el comando Get-D365LcsEnvironmentMetadata obtendremos su estado, y si está lista llamaremos al despliegue con Invoke-D365LcsDeployment. Si la operación va bien, quitaremos ese entorno del array y continuaremos, si no lo vamos a volver a probar hasta tres veces (ved que está todo dentro de un Do-While).$Retries = 0 Write-Host "=================== STARTING DEPLOYMENT ===================" Do { Foreach ($EnvD in $StartedEnvs) { $EnvStatus = Get-D365LcsEnvironmentMetadata -EnvironmentId $EnvD # If the VM has started, deploy the DP if ($EnvStatus.DeploymentStatusDisplay -eq "Deployed") { $OpResult = Invoke-D365LcsDeployment -AssetId $AssetId -EnvironmentId $EnvD if ($OpResult.IsSuccess -eq "True") { Write-Host ("Updating environment {0} has started." -f $EnvD) $StartedEnvs = $StartedEnvs -notmatch $EnvD } else { Write-Host ("Updating environment {0} has failed. Error Message: {1}." -f $EnvD, $OpResult.ErrorMessage) Write-Host ("Will retry {0} more time(s)" -f 3 - $Retries) } } } $Retries++ } While ($StartedEnvs.Count -ne 0 -or $Retries -eq 3) Write-Host "=================== STARTING DEPLOYMENT DONE ===================" Write-Host "Done"Y una vez hecho esto deberíamos tener nuestras máquinas desplegando en LCS.
Ejecutándolo en un pipeline #
Una vez el script funciona, ejecutarlo en un pipeline es algo trivial, y lo podemos hacer en un pipeline de build o release, a gusto de cada uno. Mi pipeline es así:Install-Module -Name d365fo.tools -AllowClobber -Scope CurrentUser -Force -Confirm:$false