Scripts/ExportSolution.ps1

#
# ExportSolution.ps1
#

function Get-DataverseSolution {
    Param(
        [string] [Parameter(Mandatory = $true)] $StartPath,
        [string] [Parameter(Mandatory = $true)] $SelectedSolution
    )
    try {
        
        $SolutionName = $SelectedSolution
        Remove-Item (Join-Path $StartPath "\dataverse_*patch*") -Force -Recurse -ErrorAction Ignore
    
        ######################## EXPORT SOLUTION

        ##Export Patches if they Exist
        foreach ($PatchSolution in $PatchQuery.CrmRecords) {
            $SolutionId = $PatchSolution.solutionid
            $SolutionName = $PatchSolution.uniquename
            $SolutionVersion = $PatchSolution.version

            $message = "Exporting Unmanaged Solution for $SolutionName"
            Write-Host $message

            Export-CrmSolution -SolutionName $SolutionName -SolutionZipFileName "$SolutionName.zip" -conn $conn -ErrorAction Stop

            $message = "Exporting Managed Solution for $SolutionName"
            Write-Host $message

            Export-CrmSolution -SolutionName $SolutionName -Managed -SolutionZipFileName $SolutionName"_managed.zip" -conn $conn -ErrorAction Stop

            $Path = (Join-Path $StartPath "\Deployment")
            $ImportConfig = Get-ChildItem -Path $Path -Include "ImportConfig.xml" -Recurse
                                
            [xml] $xdoc = (Get-Content -Path "$($ImportConfig.DirectoryName)\ImportConfig.xml")

            $node = $xdoc.SelectSingleNode("//configsolutionfile[contains(@solutionpackagefilename,'$($SolutionName)_managed.zip')]")               
            If (!$node) {
                $patch = $xdoc.configdatastorage.solutions.FirstChild.Clone()
                $patch.solutionpackagefilename = "$($SolutionName)_managed.zip"
                $patch.overwriteunmanagedcustomizations = "true"
                $xdoc.configdatastorage.solutions.AppendChild($patch)
                $xdoc.Save("$($ImportConfig.DirectoryName)\ImportConfig.xml")
            }
            ######################## EXTRACT SOLUTION
            # $ErrorActionPreference = "SilentlyContinue"
            
            $message = "Unpacking Solution $SolutionName"
            Write-Host $message
            Remove-Item (Join-Path $StartPath "\dataverse_$SolutionName\") -Recurse -Force -ErrorAction Ignore
            & $env:APPDATA\Microsoft.PowerPlatform.DevOps\PACTools\tools\pac.exe solution unpack --folder (Join-Path $StartPath "\dataverse_$SolutionName\") --zipfile "$SolutionName.zip" --packagetype Both --allowDelete No --clobber --useUnmanagedFileForMissingManaged
            

            $canvasApps = Get-ChildItem -Path  (Join-Path $StartPath "\dataverse_$SolutionName\") -Filter *.msapp -Recurse
            try{
            # unpack canvas apps
            $canvasApps | ForEach-Object {
                Write-Host "Unpacking Canvas App $($_.name)";
                & $env:APPDATA\Microsoft.PowerPlatform.DevOps\PACTools\tools\pac.exe canvas unpack --msapp $_.FullName --sources "$($_.DirectoryName)\$($_.BaseName)"
                Remove-Item $_.FullName -Force -ErrorAction SilentlyContinue
            }
            }catch {
                Write-Host "Error in Unpacking Canvas App"
                Write-Host $_
            }
 
        }
    
        ## No Patches
        If (!$PatchQuery.CrmRecords) {
            $message = "Exporting Unmanaged Solution for $SolutionName"
            Write-Host $message

            Export-CrmSolution -SolutionName $SolutionName -SolutionZipFileName "$SolutionName.zip" -conn $conn -ErrorAction Stop

            $message = "Exporting Managed Solution for $SolutionName"
            Write-Host $message

            Export-CrmSolution -SolutionName $SolutionName -Managed -SolutionZipFileName $SolutionName"_managed.zip" -conn $conn -ErrorAction Stop

            $Path = (Join-Path $StartPath "\Deployment")
            $ImportConfig = Get-ChildItem -Path $Path -Include "ImportConfig.xml" -Recurse
                                
            [xml] $xdoc = (Get-Content -Path "$($ImportConfig.DirectoryName)\ImportConfig.xml")

            $nodes = $xdoc.configdatastorage.solutions.SelectNodes("//configsolutionfile")         
            $nodes[0].solutionpackagefilename = "$($SolutionName)_managed.zip"
            $nodes[0].overwriteunmanagedcustomizations = "true"

            for ($i = 1; $i -le ($nodes.Count - 1); $i++) {
                $nodes[$i].ParentNode.RemoveChild($nodes[$i])
            }
            
            $xdoc.Save("$($ImportConfig.DirectoryName)\ImportConfig.xml")
        
            ######################## EXTRACT SOLUTION
            # $ErrorActionPreference = "SilentlyContinue"


            $message = "Unpacking Solution $SolutionName"
            Write-Host $message
            Remove-Item (Join-Path $StartPath "\dataverse_$SolutionName\") -Recurse -Force -ErrorAction Ignore
            & $env:APPDATA\Microsoft.PowerPlatform.DevOps\PACTools\tools\pac.exe solution unpack --folder (Join-Path $StartPath "\dataverse_$SolutionName\") --zipfile "$SolutionName.zip" --packagetype Both --allowDelete No --clobber --useUnmanagedFileForMissingManaged
            $canvasApps = Get-ChildItem -Path  (Join-Path $StartPath "\dataverse_$SolutionName\") -Filter *.msapp -Recurse
    
            # unpack canvas apps
            $canvasApps | ForEach-Object {
                Write-Host "Unpacking Canvas App $($_.name)";
                & $env:APPDATA\Microsoft.PowerPlatform.DevOps\PACTools\tools\pac.exe canvas unpack --msapp $_.FullName --sources "$($_.DirectoryName)\$($_.BaseName)"
                Remove-Item $_.FullName -Force -ErrorAction SilentlyContinue
            }
        
        }
    
    }
    catch {
        Write-Host $_
        pause
    }
    finally {

    }
}