# Backup Solutions from Dataverse Environment # https://gist.github.com/alirobe/17864cb8336ea9dc3d4da61fb5d6a596 ### Settings ### $skipExisting = $false # change to $true to update ### Script ### $solutionsList = pac solution list $solutionsList > solutions-list.txt $firstLine = 5 # to be changed if output from pac tool changes $existing = Get-ChildItem -Path . -Directory $extracted = @() if ($solutionsList.Count -lt 5 -or -not $solutionsList[4].StartsWith("Unique Name")) { Write-Host "Unexpected output format. Ensure you are connected to the correct Dataverse organization and the solutions list is formatted correctly." } foreach ($line in $solutionsList[$firstLine..999]) { $solution = $line -split ' ' | Select-Object -First 1 if($line.Trim().EndsWith("True") -or $solution -eq "Default") { Write-Host "Skipping managed or default solution: $solution" continue } if ($solution -eq $null -or $solution.Trim() -eq "" -or -not $line.Trim().EndsWith("False")) { Write-Host "Skipping invalid solution definition in line: $line" continue } if($existing.Name -contains $solution) { if($skipExisting) { Write-Host "Skipping existing solution: $solution (turn off skipExisting to updae)" continue } else { Write-Host "Removing existing solution for update: $solution" Remove-Item -Path ./$solution -Recurse -Force } } Write-Host "Processing solution: $solution" pac solution export --name $solution Expand-Archive -Path "$solution.zip" -DestinationPath ./$solution $extracted += "./$solution.zip" } foreach ($zip in $extracted) { Write-Host "Cleaning up zip: $zip" Start-Sleep -Seconds 2 # expansion can sometimes exit prematurely Remove-Item -Path $zip }