Functions/Solutions/Export-CdsSolution.ps1

<#
    .SYNOPSIS
    Export solution.
#>

function Export-CdsSolution {
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$false, ValueFromPipeline)]
        [Microsoft.Xrm.Tooling.Connector.CrmServiceClient]
        $CdsClient = $Global:CdsClient,

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [String]
        $SolutionUniqueName,

        [Parameter(Mandatory = $false)]
        [Boolean]
        $Managed = $false,

        [Parameter(Mandatory = $false)]
        [ValidateScript( { Test-Path $_ })]
        [String]
        $ExportPath = $env:TEMP,

        [Parameter(Mandatory = $false)]
        [Boolean]
        $ExportCalendarSettings = $false,
        
        [Parameter(Mandatory = $false)]
        [Boolean]
        $ExportCustomizationSettings = $false,

        [Parameter(Mandatory = $false)]
        [Boolean]
        $ExportEmailTrackingSettings = $false,

        [Parameter(Mandatory = $false)]
        [Boolean]
        $ExportAutoNumberingSettings = $false,

        [Parameter(Mandatory = $false)]
        [Boolean]
        $ExportIsvConfig = $false,

        [Parameter(Mandatory = $false)]
        [Boolean]
        $ExportOutlookSynchronizationSettings = $false,

        [Parameter(Mandatory = $false)]
        [Boolean]
        $ExportGeneralSettings = $false,

        [Parameter(Mandatory = $false)]
        [Boolean]
        $ExportMarketingSettings = $false,

        [Parameter(Mandatory = $false)]
        [Boolean]
        $ExportRelationshipRoles = $false,

        [Parameter(Mandatory = $false)]
        [Boolean]
        $AddVersionToFileName = $false
    )
    begin {   
        $StopWatch = [System.Diagnostics.Stopwatch]::StartNew(); 
        Trace-CdsFunction -Name $MyInvocation.MyCommand.Name -Stage Start -Parameters ($MyInvocation.MyCommand.Parameters); 
    }    
    process {

        # Build solution file name
        $solutionFileName = $SolutionUniqueName;
        if ($AddVersionToFileName) {            
            $solution = $CdsClient | Get-CdsRecord -LogicalName "solution" -AttributeName "uniquename" -Value $SolutionUniqueName -Columns "version";
            $version = $solution.version;
            $version = $version.Replace(".", "_");
            $solutionFileName = "$($solutionFileName)_$($version)";
        }
        
        if ($managed) {
            $solutionFileName = "$($solutionFileName)_managed";
        }

        $solutionFileName = "$($solutionFileName).zip";

        # Build output path
        $solutionFilePath = [System.IO.Path]::Combine($ExportPath, $solutionFileName);

        # Define async export solution feature
        Set-CdsOrganizationFeature -Name "FCB.AllowExportSolutionAsync" -Value "true";
        
        # Build request
        
        #$exportSolutionRequest = New-Object -TypeName Microsoft.Crm.Sdk.Messages.ExportSolutionRequest;
        #$exportSolutionRequest.RequestName = "ExportSolutionAsync";
        #$exportSolutionRequest.SolutionName = $SolutionUniqueName;
        #$exportSolutionRequest.Managed = $Managed;
        #$exportSolutionRequest.ExportCalendarSettings = $ExportCalendarSettings;
        #$exportSolutionRequest.ExportCustomizationSettings = $ExportCustomizationSettings;
        #$exportSolutionRequest.ExportEmailTrackingSettings = $ExportEmailTrackingSettings;
        #$exportSolutionRequest.ExportAutoNumberingSettings = $ExportAutoNumberingSettings;
        #$exportSolutionRequest.ExportIsvConfig = $ExportIsvConfig;
        #$exportSolutionRequest.ExportOutlookSynchronizationSettings = $ExportOutlookSynchronizationSettings;
        #$exportSolutionRequest.ExportGeneralSettings = $ExportGeneralSettings;
        #$exportSolutionRequest.ExportMarketingSettings = $ExportMarketingSettings;
        #$exportSolutionRequest.ExportRelationshipRoles = $ExportRelationshipRoles;
        
        $exportSolutionRequest = New-CdsRequest -Name "ExportSolutionAsync";
        $exportSolutionRequest | Add-CdsRequestParameter -Name "SolutionName" -Value $SolutionUniqueName | Out-Null;
        $exportSolutionRequest | Add-CdsRequestParameter -Name "Managed" -Value $Managed | Out-Null;    
        $exportSolutionRequest | Add-CdsRequestParameter -Name "ExportCalendarSettings" -Value $ExportCalendarSettings | Out-Null;
        $exportSolutionRequest | Add-CdsRequestParameter -Name "ExportCustomizationSettings" -Value $ExportCustomizationSettings | Out-Null;
        $exportSolutionRequest | Add-CdsRequestParameter -Name "ExportEmailTrackingSettings" -Value $ExportEmailTrackingSettings | Out-Null;
        $exportSolutionRequest | Add-CdsRequestParameter -Name "ExportAutoNumberingSettings" -Value $ExportAutoNumberingSettings | Out-Null;
        $exportSolutionRequest | Add-CdsRequestParameter -Name "ExportIsvConfig" -Value $ExportIsvConfig | Out-Null;
        $exportSolutionRequest | Add-CdsRequestParameter -Name "ExportOutlookSynchronizationSettings" -Value $ExportOutlookSynchronizationSettings | Out-Null;
        $exportSolutionRequest | Add-CdsRequestParameter -Name "ExportGeneralSettings" -Value $ExportGeneralSettings | Out-Null;
        $exportSolutionRequest | Add-CdsRequestParameter -Name "ExportMarketingSettings" -Value $ExportMarketingSettings | Out-Null;
        $exportSolutionRequest | Add-CdsRequestParameter -Name "ExportRelationshipRoles" -Value $ExportRelationshipRoles | Out-Null;

        # Run request
        try {
            $exportSolutionResponse = $CdsClient | Invoke-CdsRequest -Request $exportSolutionRequest;
        }
        catch {
            throw $_.Exception.Message;
        }
        $asyncOperationId = $exportSolutionResponse.Results["AsyncOperationId"];
        $exportJobId = $exportSolutionResponse.Results["ExportJobId"];

        # Monitor request execution
        $CdsClient | Watch-CdsAsynchOperation -AsyncOperationId $asyncOperationId;

        # Retrieve solution file binary
        $downloadSolutionExportDataRequest = New-CdsRequest -Name "DownloadSolutionExportData";
        $downloadSolutionExportDataRequest | Add-CdsRequestParameter -Name "ExportJobId" -Value $exportJobId | Out-Null;
        try {
            $downloadSolutionExportDataResponse = $CdsClient | Invoke-CdsRequest -Request $downloadSolutionExportDataRequest;
        }
        catch {
            throw $_.Exception.Message;
        }
        $solutionBinaries = $downloadSolutionExportDataResponse.Results["ExportSolutionFile"];

        # Save solution file
        [System.IO.File]::WriteAllBytes($solutionFilePath, $solutionBinaries);

        # Output solution file path
        $solutionFilePath;
    }
    end {
        $StopWatch.Stop();
        Trace-CdsFunction -Name $MyInvocation.MyCommand.Name -Stage Stop -StopWatch $StopWatch;
    }    
}

Export-ModuleMember -Function Export-CdsSolution -Alias *;