web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

News and Announcements icon
Community site session details

Community site session details

Session Id :
Power Platform Community / Forums / Power Apps / Exporting and Importin...
Power Apps
Answered

Exporting and Importing a PowerApp

(2) ShareShare
ReportReport
Posted on by 60

Is there any way besides the Import/Export function in the PowerApps designer to Export and package a PowerApp and Import it?  Can this be done from PowerShell?

Categories:
I have the same question (0)
  • v-xida-msft Profile Picture
    Microsoft Employee on at

    Hi @bboardman,

     

    Do you want to Export or Import a PowerApps app with packaging without the Import/Export function in PowerApps?

    Do you want to use PowerShell script to Emport/Import a PowerApps app within your PowerApps?

     

    If you want to Export or Import a PowerApps app with packaging without the Import/Export function, I afraid that there is no way to achieve your needs in PowerApps currently.

     

    Currently, we could only Export/Import a PowerApps app with packaging using Import/Export option within PowerApps designer. Please check the following blog:

    https://powerapps.microsoft.com/en-us/blog/powerapps-packaging/

     

    If you want to use PowerShell script to Emport/Import a PowerApps app within your PowerApps, I afraid that there is also no way to achieve your needs in PowerApps currently. The supported PowerSheell Cmdlet within PowerApps, please check the following article:

    https://docs.microsoft.com/en-us/powerapps/administrator/powerapps-powershell

     

    If you would like this feature to be added in PowerApps, please submit an idea to PowerApps Ideas Forum:

    https://powerusers.microsoft.com/t5/PowerApps-Ideas/idb-p/PowerAppsIdeas

     

    Best regards,

    Kris

     

     

  • bboardman Profile Picture
    60 on at

    Thank you for your reply.

  • Verified answer
    DileepGolla Profile Picture
    125 on at

    Hi Everyone,

    I did not find any existing idea about this so I created one in the portal.

    https://powerusers.microsoft.com/t5/PowerApps-Ideas/PowerShell-Cmdlet-to-publish-deploy-the-form-to-different-same/idi-p/253693#M25558

    Thanks,

    Dileep

  • AlyaKoniPA Profile Picture
    16 on at

    You are able to import the package like the portal make.powerapps.com is doing it.

     

    $UsedBapApiHost = "api.bap.microsoft.com"
    
    Import-Module "Microsoft.PowerApps.Administration.PowerShell"
    
    function Get-AudienceForHostName
    {
    [CmdletBinding()]
    Param(
    [string] $Uri
    )
    $hostMapping = @{
    "management.azure.com" = "https://management.azure.com/";
    "api.powerapps.com" = "https://service.powerapps.com/";
    "tip1.api.powerapps.com" = "https://service.powerapps.com/";
    "tip2.api.powerapps.com" = "https://service.powerapps.com/";
    "graph.windows.net" = "https://graph.windows.net/";
    "api.bap.microsoft.com" = "https://service.powerapps.com/";
    "tip1.api.bap.microsoft.com" = "https://service.powerapps.com/";
    "tip2.api.bap.microsoft.com" = "https://service.powerapps.com/";
    "api.flow.microsoft.com" = "https://service.flow.microsoft.com/";
    "tip1.api.flow.microsoft.com" = "https://service.flow.microsoft.com/";
    "tip2.api.flow.microsoft.com" = "https://service.flow.microsoft.com/";
    }
    $uriObject = New-Object System.Uri($Uri)
    $audhost = $uriObject.Host
    if ($hostMapping[$audhost] -ne $null)
    {
    return $hostMapping[$audhost];
    }
    Write-Verbose "Unknown host $audhost. Using https://management.azure.com/ as a default";
    return "https://management.azure.com/";
    }
    
    function Invoke-Request(
    [CmdletBinding()]
    
    [Parameter(Mandatory=$True)]
    [string] $Uri,
    
    [Parameter(Mandatory=$True)]
    [string] $Method,
    
    [object] $Body = $null,
    
    [Hashtable] $Headers = @{},
    
    [switch] $ParseContent,
    
    [switch] $ThrowOnFailure
    )
    {
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    $audience = Get-AudienceForHostName -Uri $Uri
    $token = Get-JwtToken -Audience $audience
    $Headers["Authorization"] = "Bearer $token";
    $Headers["User-Agent"] = "PowerShell cmdlets 1.0";
    try {
    if ($Body -eq $null -or $Body -eq "")
    {
    $response = Invoke-WebRequest -Uri $Uri -Headers $Headers -Method $Method -UseBasicParsing
    }
    else 
    {
    $jsonBody = ConvertTo-Json $Body -Depth 20
    $response = Invoke-WebRequest -Uri $Uri -Headers $Headers -Method $Method -ContentType "application/json; charset=UTF-8" -Body $jsonBody -UseBasicParsing
    }
    if ($ParseContent)
    {
    if ($response.Content)
    {
    return ConvertFrom-Json $response.Content;
    }
    }
    return $response
    } catch {
    $response = $_.Exception.Response
    if ($_.ErrorDetails)
    {
    $errorResponse = ConvertFrom-Json $_.ErrorDetails;
    $code = $response.StatusCode
    $message = $errorResponse.Error.Message
    Write-Verbose "Status Code: '$code'. Message: '$message'" 
    }
    if ($ThrowOnFailure)
    {
    throw;
    }
    else 
    {
    return $response
    }
    }
    }
    
    function Configure-ImportResourcesObject(
    $Resources,
    $EnvironmentName = $null,
    [bool]$DefaultToExportSuggestions = $false,
    [bool] $NewApp = $false,
    [string] $ResourceName
    )
    {
    $includedResourceIds = @()
    $includedSuggestedResourceIds = @()
    $includedResources = $Resources
    $numResources = 0
    $env = Get-AdminPowerAppEnvironment -EnvironmentName $EnvironmentName
    $environmentDisplayName = $env.DisplayName
    $selectedCommonDataServiceOption = $null
    foreach ($resource in Get-Member -InputObject $includedResources -MemberType NoteProperty)
    {
    $numResources = $numResources + 1 
    $property = 'Name'
    $propertyvalue = $resource.$property
    If($includedResources.$propertyvalue.id -ne $null -and $includedResources.$propertyvalue.id -ne "")
    {
    $includedResourceIds = $includedResourceIds + $includedResources.$propertyvalue.id
    }
    If(!$includedSuggestedResourceIds.$propertyvalue.suggestedId)
    {
    $includedSuggestedResourceIds = $includedSuggestedResourceIds + $includedSuggestedResourceIds.$propertyvalue.suggestedId
    }
    $type = $null
    if ($includedResources.$propertyvalue.type -eq "Microsoft.PowerApps/apps")
    {
    $result = $null
    $selection = $null
    
    if($NewApp)
    {
    $type = "New"
    $includedResources.$propertyvalue.details.displayName = $ResourceName
    }
    else 
    {
    $type = "Update"
    $selectedResource = $result.selectedResource
    $includedResources.$propertyvalue | Add-Member -MemberType NoteProperty -name id -value $selectedResource.id
    $includedResources.$propertyvalue | Add-Member -MemberType NoteProperty -name name -value $selectedResource.name
    } 
    }
    if ($includedResources.$propertyvalue.type -eq "Microsoft.Flow/flows")
    {
    $result = $null
    $selection = $null
    
    if($NewApp)
    {
    $type = "New"
    $includedResources.$propertyvalue.details.displayName = $ResourceName
    }
    else 
    {
    $type = "Update"
    $selectedResource = $result.selectedResource
    $includedResources.$propertyvalue | Add-Member -MemberType NoteProperty -name id -value $selectedResource.id
    $includedResources.$propertyvalue | Add-Member -MemberType NoteProperty -name name -value $selectedResource.name
    }
    }
    if ($includedResources.$propertyvalue.type -eq "Microsoft.PowerApps/apis")
    {
    if ($includedResources.$propertyvalue.name -eq $null)
    {
    if (-Not $NewApp) 
    {
    $type = "Existing"
    $selectedResource = $result.selectedResource
    $includedResources.$propertyvalue | Add-Member -MemberType NoteProperty -name id -value $selectedResource.id
    $includedResources.$propertyvalue | Add-Member -MemberType NoteProperty -name name -value $selectedResource.name
    }
    }
    else { 
    $type = "Existing"
    }
    }
    if ($includedResources.$propertyvalue.type -eq "Microsoft.PowerApps/apis/connections")
    {
    if (-Not $NewApp) 
    {
    $type = "Existing"
    $selectedResource = $result.selectedResource
    $includedResources.$propertyvalue | Add-Member -MemberType NoteProperty -name id -value $selectedResource.id
    $includedResources.$propertyvalue | Add-Member -MemberType NoteProperty -name name -value $selectedResource.name
    }
    }
    if ($includedResources.$propertyvalue.type -eq "Microsoft.CommonDataModel/environments/namespaces/enumerations" -or $includedResources.$propertyvalue.type -eq "Microsoft.CommonDataModel/environments/namespaces/entities")
    { 
    if ($includedResources.$propertyvalue.configurableBy -eq "User")
    {
    if($DefaultToExportSuggestions -and ($includedResources.$propertyvalue.suggestedCreationType -ne $null))
    {
    $type = $includedResources.$propertyvalue.suggestedCreationType
    }
    else {
    If($selectedCommonDataServiceOption -eq $null)
    {
    $selectedCommonDataServiceOption = "Overwrite"
    $type = $selectedCommonDataServiceOption
    }
    else {
    $type = $selectedCommonDataServiceOption
    }
    }
    }
    else {
    $type = $includedResources.$propertyvalue.suggestedCreationType
    }
    }
    If($type)
    { 
    If($includedResources.$propertyvalue.suggestedCreationType)
    {
    $includedResources.$propertyvalue.suggestedCreationType = $type
    }
    else
    {
    $includedResources.$propertyvalue | Add-Member -MemberType NoteProperty -name suggestedCreationType -value $type
    }
    $includedResources.$propertyvalue | Add-Member -MemberType NoteProperty -name selectedCreationType -value $type
    }
    }
    $responseObject = @{
    resources = $includedResources
    resourceIds = $includedResourceIds
    suggestedResourceIds = $includedSuggestedResourceIds
    } 
    return $responseObject
    }
    
    function Upload-FileToBlogStorage(
    [string] $EnvironmentName,
    [string] $FilePath,
    [string] $ApiVersion = "2016-11-01"
    )
    {
    try {
    $fileBinary = [IO.File]::ReadAllBytes($FilePath);
    $encoding = [System.Text.Encoding]::GetEncoding("iso-8859-1");
    $file = $encoding.GetString($fileBinary)
    } catch {
    Write-Host "Failed to read the file"
    throw
    }
    $generateResourceStorageUrl = "https://$UsedBapApiHost/providers/Microsoft.BusinessAppPlatform/environments/" + $EnvironmentName + "/generateResourceStorage`?api-version=" + $ApiVersion
    $generateResourceStorageResponse = Invoke-Request -Uri $generateResourceStorageUrl -Method POST -ParseContent -ThrowOnFailure
    $originalBlobUri = $generateResourceStorageResponse.sharedAccessSignature
    $uri = [System.Uri] $originalBlobUri 
    $filename = Split-Path $FilePath -Leaf
    $uriHost = $uri.Host
    $uriPath = $uri.AbsolutePath
    $uriQuery = $uri.Query
    $tempBlobUri = "https://$uriHost$uriPath/$fileName$uriQuery"
    $commitBlobUri = "$tempBlobUri&comp=blocklist"
    $uploadBlobUri = "$tempBlobUri&comp=block"
    $BlockId = "BlockId"
    $Bytes = [System.Text.Encoding]::Unicode.GetBytes($BlockId)
    $EncodedBlockId =[Convert]::ToBase64String($Bytes)
    $uploadBlobUri = "$uploadBlobUri&blockid=$EncodedBlockId"
    try {
    $uploadFiletoBLog = Invoke-WebRequest -Uri $uploadBlobUri -Method Put -ContentType "application/json" -Body $file -UseBasicParsing
    $commitBody = "<?xml version=`"1.0`" encoding=`"utf-8`"?><BlockList><Latest>$EncodedBlockId</Latest></BlockList>"
    $commitFiletoBLog = Invoke-WebRequest -Uri $commitBlobUri -Method Put -ContentType "application/json; charset=UTF-8" -Body $commitBody -UseBasicParsing
    } catch {
    Write-Host "Failed to upload the file to blob storage"
    throw
    }
    return $tempBlobUri
    }
    
    function Get-ImportPackageResources(
    [string] $EnvironmentName,
    [string] $ImportPackageBlobUri,
    [string] $ApiVersion = "2016-11-01"
    )
    {
    $listParametersUri = "https://$UsedBapApiHost/providers/Microsoft.BusinessAppPlatform/environments/" + $EnvironmentName + "/listImportParameters`?api-version=" + $ApiVersion
    $listParametersBody = @{ 
    packageLink = @{
    value = $ImportPackageBlobUri
    } 
    }
    $listParametersResponse = Invoke-Request -Uri $listParametersUri -Method POST -Body $listParametersBody -ThrowOnFailure
    $statusUri= $listParametersResponse.Headers['Location']
    while($listParametersResponse.StatusCode -ne 200) 
    {
    Start-Sleep -s 5
    $listParametersResponse = Invoke-Request -Uri $statusUri -Method GET -ThrowOnFailure
    }
    $parsedListParametersResponse = ConvertFrom-Json $listParametersResponse.Content
    return $parsedListParametersResponse
    }
    
    function Import-Package(
    [string] $EnvironmentName,
    [string] $ImportPackageFilePath,
    [string] $ApiVersion = "2016-11-01",
    [bool] $DefaultToExportSuggestions = $false,
    [bool] $NewApp = $false,
    [string] $ResourceName
    )
    {
    $blobUri = Upload-FileToBlogStorage -EnvironmentName $EnvironmentName -FilePath $ImportPackageFilePath -ApiVersion $ApiVersion
    $parsedListParametersResponse = Get-ImportPackageResources -EnvironmentName $EnvironmentName -ImportPackageBlobUri $blobUri -ApiVersion $ApiVersion
    $includedResources = Configure-ImportResourcesObject -resources $parsedListParametersResponse.properties.resources -EnvironmentName $EnvironmentName -DefaultToExportSuggestions $DefaultToExportSuggestions -NewApp $NewApp -ResourceName $ResourceName
    $validateImportPackageUri = "https://$UsedBapApiHost/providers/Microsoft.BusinessAppPlatform/environments/" + $EnvironmentName + "/validateImportPackage`?api-version=" + $ApiVersion
    $validateImportPackageBody = @{ 
    details = $parsedListParametersResponse.properties.details
    packageLink = $parsedListParametersResponse.properties.packageLink
    resources = $includedResources.resources
    }
    $validateImportPackageResponse = Invoke-Request -Uri $validateImportPackageUri -Method POST -Body $validateImportPackageBody -ThrowOnFailure
    $parsedValidateImportResponse = ConvertFrom-Json $validateImportPackageResponse.Content
    if(($parsedValidateImportResponse.errors).Length -gt 0)
    {
    Write-Host "Package failed validation with the following errors \n" + $parsedValidateImportResponse.errors
    throw
    }
    $importPackageUri = "https://$UsedBapApiHost/providers/Microsoft.BusinessAppPlatform/environments/" + $EnvironmentName + "/importPackage`?api-version=" + $ApiVersion
    $importPackageResponse = Invoke-Request -Uri $importPackageUri -Method POST -Body $validateImportPackageBody -ThrowOnFailure
    $importStatusUri = $importPackageResponse.Headers['Location']
    while($importPackageResponse.StatusCode -ne 200) 
    {
    Start-Sleep -s 5
    $importPackageResponse = Invoke-Request -Uri $importStatusUri -Method GET -ThrowOnFailure
    }
    $parsedImportPackageResponse = ConvertFrom-Json $importPackageResponse.Content
    if(($parsedImportPackageResponse.properties.errors).Length -gt 0)
    {
    Write-Host "Package failed import with the following errors " + $parsedImportPackageResponse.properties.errors
    }
    return $parsedImportPackageResponse
    }
    


    Use the script like:

    $PowerAppEnv = Get-AdminPowerAppEnvironment -Default
    $PowerAppEnvName = $PowerAppEnv.EnvironmentName
    $PowerApp = Get-AdminPowerApp $appTitle
    $impAppResp = Import-Package -EnvironmentName $PowerAppEnvName -ImportPackageFilePath "$PathToZipFile" -ResourceName $appTitle -NewApp (-Not $PowerApp)
    $impAppResp = Publish-PowerApp $appTitle

     

  • CU-20081201-3 Profile Picture
    58 on at

    @AlyaKoniPA Thanks for sharing the snippet. I tried to extend it in order to export packages but get stuck as it seems the same token is not valid for "exportPackage?" part. Any ideas on how to make the export work?

  • AlyaKoniPA Profile Picture
    16 on at

    Hi @Mijata 

    Use this snippet to export a package:

    function Export-Package(
     [string] $EnvironmentName,
     [string] $ExportPackageFilePath,
     [string] $ApiVersion = "2016-11-01",
     [bool] $DefaultToExportSuggestions = $false,
     [object] $App
    )
    {
    
     $getPackageUri = "https://$UsedBapApiHost/providers/Microsoft.BusinessAppPlatform/environments/" + $EnvironmentName + "/listPackageResources`?api-version=" + $ApiVersion
     $getPackageBody = @{ 
     baseResourceIds = @("/providers/Microsoft.PowerApps/apps/$($App.AppName)")
     }
     $getPackageResponse = Invoke-Request -Uri $getPackageUri -Method POST -Body $getPackageBody -ThrowOnFailure
     $getPackageResponse = ConvertFrom-Json $getPackageResponse.Content
     if ($getPackageResponse.Status -ne "Succeeded")
     {
     throw "Error getting package resources"
     }
    
     $resourceIds = @()
     foreach($resource in $getPackageResponse.resources.PSObject.Properties.Name)
     {
     $resourceIds += $getPackageResponse.resources."$resource".id
     }
    
     $exportPackageUri = "https://$UsedBapApiHost/providers/Microsoft.BusinessAppPlatform/environments/" + $EnvironmentName + "/exportPackage`?api-version=" + $ApiVersion
     $exportPackageBody = @{
     includedResourceIds = $resourceIds
     details = @{
     displayName = $App.Internal.properties.displayName
     description = $App.Internal.properties.description
     creator = $App.Owner.displayName
     sourceEnvironment = $EnvironmentName
     }
     resources = $getPackageResponse.resources
     }
     $exportPackageResponse = Invoke-Request -Uri $exportPackageUri -Method POST -Body $exportPackageBody -ThrowOnFailure
     $exportPackageJobUri = $exportPackageResponse.Headers['Location']
     $exportPackageResponse = ConvertFrom-Json $exportPackageResponse.Content
     if ($exportPackageResponse.Status -ne "Running" -and $exportPackageResponse.Status -ne "Succeeded")
     {
     throw "Error export package job creation"
     }
    
     do
     {
     Start-Sleep -Seconds 2
     $exportPackageJob = Invoke-Request -Uri $exportPackageJobUri -Method GET -ThrowOnFailure
     $exportPackageJob = ConvertFrom-Json $exportPackageJob.Content
     } while ($exportPackageJob.properties.status -ne "Succeeded")
    
     $exportPackageZipUri = $exportPackageJob.properties.packageLink.value
     Invoke-WebRequest -Uri $exportPackageZipUri -Method GET -OutFile $ExportPackageFilePath
    }

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Introducing the 2026 Season 1 community Super Users

Congratulations to our 2026 Super Users!

Kudos to our 2025 Community Spotlight Honorees

Congratulations to our 2025 community superstars!

Congratulations to the March Top 10 Community Leaders!

These are the community rock stars!

Leaderboard > Power Apps

#1
11manish Profile Picture

11manish 538

#2
WarrenBelz Profile Picture

WarrenBelz 420 Most Valuable Professional

#3
Haque Profile Picture

Haque 305

Last 30 days Overall leaderboard