Skip to Main content

Optimizely CMS: EpiCloud Pubic Commands

The EpiCloud PowerShell module provides a comprehensive set of commands for managing deployments, packages, storage, and database exports for Optimizely (formerly Episerver) DXP (Digital Experience Platform) projects through the Deployment API. This guide covers every public command available in the module, including detailed parameter descriptions, usage examples, and common workflow patterns.

Prerequisites

  • PowerShell 5.1 or later (Desktop or Core editions are both supported)
  • A valid API Client Key and Client Secret for your Optimizely DXP project
  • Your Project ID (a GUID identifying your DXP project)

API credentials can be generated from the Optimizely DXP PaaS Portal under the API tab of your project.

Installation

Install-Module EpiCloud -Repository PSGallery

Verify installation

Get-Module EpiCloud -ListAvailable

Authentication

Every command in the EpiCloud module requires a ClientKey and ClientSecret for authentication. You can either pass them explicitly to each command, or use Connect-EpiCloud to set them as defaults for the entire session.

# Option 1: Set credentials once for the session
Connect-EpiCloud -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId

# Option 2: Pass credentials explicitly per command
Get-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId

Command Reference

Connect-EpiCloud

Stores default credentials (and optionally a Project ID) for all EpiCloud commands in the current PowerShell session.

Sets the default ClientKey, ClientSecret, and optionally ProjectId so you do not need to pass them to every subsequent command.

Parameters

ParameterTypeRequiredDescription
ClientKeyStringYesThe API client key used to access the project.
ClientSecretStringYesThe API client secret used to access the project.
ProjectIdStringNoThe GUID of the project. When provided, the credentials are validated immediately by making a test API call.

Behavior

  • When ProjectId is supplied, the function validates the credentials by calling Get-EpiDeployment. If validation fails, an error is thrown.
  • Credentials are stored via $Global:PSDefaultParameterValues, making them automatically available to all EpiCloud commands for the remainder of the session.

Examples

Set credentials without immediate validation:

Connect-EpiCloud -ClientKey $myKey -ClientSecret $mySecret

# Now call commands without specifying credentials each time
Get-EpiDeploymentPackageLocation -ProjectId $myProjectId

Set credentials with validation and a default project:

Connect-EpiCloud -ClientKey $myKey -ClientSecret $mySecret -ProjectId '3c84b95d-42d5-4a3a-9e65-d5c83e945fe7'

# ProjectId is also set as a default — no parameters needed
Get-EpiDeploymentPackageLocation

Get-EpiDeploymentPackageLocation

Retrieves a SAS link to the Azure Blob Storage container where deployment packages should be uploaded.

Returns a SAS URL that grants temporary, scoped access to the project's deployment package container. This URL is required by Add-EpiDeploymentPackage to upload packages.

Parameters

ParameterTypeRequiredDescription
ClientKeyStringYesThe API client key.
ClientSecretStringYesThe API client secret.
ProjectIdStringYesThe GUID of the project.

Output

Returns a String — the SAS URL pointing to the deployment packages blob container.

Examples

$sasUrl = Get-EpiDeploymentPackageLocation -ClientKey $myKey -ClientSecret $mySecret -ProjectId 'd117c12c-d02e-4b53-aabd-aa8e00a47cdv'

# Use the SAS URL when uploading
Add-EpiDeploymentPackage -SasUrl $sasUrl -Path .\cms.app.1.0.0.nupkg

Add-EpiDeploymentPackage

Uploads a deployment package file to the project's code package container using a SAS link.

Uploads a .nupkg, .zip, or .bacpac deployment package to Azure Blob Storage so it can be used in a deployment.

Parameters

ParameterTypeRequiredDescription
SasUrlStringYesThe SAS link to the deployment packages container (obtained from Get-EpiDeploymentPackageLocation).
PathStringYesThe full local file path of the package to upload. Accepts pipeline input via the FullName property.
BlobNameStringNoThe name for the blob in the container. Defaults to the file name from Path. Accepts pipeline input via the Name property.
ClientKeyStringNoThe API client key. When provided along with ClientSecret and ProjectId, enables a pre-upload existence check to avoid duplicate uploads.
ClientSecretStringNoThe API client secret.
ProjectIdStringNoThe GUID of the project.

Package Naming Convention

The package file name (or BlobName) must match one of these recognized patterns:

PatternExample
{prefix}.cms.app.{version}.nupkgsite.cms.app.1.0.0.nupkg
{prefix}.commerce.app.{version}.nupkgsite.commerce.app.2.3.1.nupkg
{prefix}.head.app.{version}.zipsite.head.app.1.0.0.zip
cms.app.{version}.nupkgcms.app.1.0.0.nupkg
commerce.app.{version}.nupkgcommerce.app.1.0.0.nupkg
{prefix}.cms.sqldb.{version}.bacpacsite.cms.sqldb.1.0.0.bacpac
{prefix}.commerce.sqldb.{version}.bacpacsite.commerce.sqldb.1.0.0.bacpac

Packages that do not match a recognized naming pattern will be rejected with an error.

Duplicate Detection

When ClientKey, ClientSecret, and ProjectId are all provided, the command checks whether a package with the same name already exists:

  • Same name, same content hash — the upload is skipped (no error).
  • Same name, different content — an error is thrown. Upload with a different package name instead.
  • Package not found — the upload proceeds normally.

Examples

Basic upload:

$sasUrl = Get-EpiDeploymentPackageLocation -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId

Add-EpiDeploymentPackage -SasUrl $sasUrl -Path .\site.cms.app.1.0.0.nupkg

Upload with duplicate detection:

$sasUrl = Get-EpiDeploymentPackageLocation -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId

Add-EpiDeploymentPackage -SasUrl $sasUrl -Path .\cms.app.2.0.0.nupkg -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId

Upload via pipeline (multiple files):

$sasUrl = Get-EpiDeploymentPackageLocation -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId

Get-ChildItem -Path .\packages\*.nupkg | Add-EpiDeploymentPackage -SasUrl $sasUrl

Start-EpiDeployment

Starts a new deployment for a project. Supports deploying uploaded code packages or promoting content/code from one environment to another.

Initiates a deployment against a target environment. The command supports two modes:

  1. DeploymentPackage (default) — Deploy previously uploaded code packages.
  2. SourceEnvironment — Promote code, blobs, and/or databases from a source environment.

Parameters

ParameterTypeRequiredParameter SetDescription
ClientKeyStringYesBothThe API client key.
ClientSecretStringYesBothThe API client secret.
ProjectIdStringYesBothThe GUID of the project.
TargetEnvironmentStringYesBothThe environment to deploy to (e.g., Integration, Preproduction, Production).
DeploymentPackageString[]YesDeploymentPackageThe name(s) of the uploaded code package(s) to deploy.
SourceEnvironmentStringYesSourceEnvironmentThe environment to copy code/content from.
SourceAppString[]NoSourceEnvironmentThe app(s) to copy. Valid values: cms, commerce.
IncludeBlobSwitchNoSourceEnvironmentInclude blobs from the source environment.
IncludeDbSwitchNoSourceEnvironmentInclude the SQL database from the source environment.
UseMaintenancePageSwitchNoBothDisplay a maintenance page during deployment.
ZeroDownTimeModeStringNoBothDatabase mode for the primary web app during deployment. Values: ReadOnly, ReadWrite. Enables zero-downtime deployment when specified.
DirectDeploySwitchNoBothDeploy directly to the target web app without a slot swap. Faster for Integration/Development environments. Note: Resetting is not supported for direct deployments.
WaitSwitchNoBothPoll the deployment until it completes (or times out).
ShowProgressSwitchNoBothDisplay a progress bar during polling (requires -Wait).
WaitTimeoutMinutesIntNoBothMaximum minutes to wait for deployment completion. Default: 240.
PollingIntervalSecIntNoBothSeconds between status polls. Default: 30.

Examples

Deploy a code package directly to Integration:

$DeploymentHash = @{
    ClientKey         = $myKey
    ClientSecret      = $mySecret
    ProjectId         = $myProjectId
    TargetEnvironment = 'Integration'
    DeploymentPackage = 'cms.app.1.0.0.nupkg'
    DirectDeploy      = $true
}
Start-EpiDeployment @DeploymentHash

Deploy a code package and wait for completion:

$DeploymentHash = @{
    ClientKey          = $myKey
    ClientSecret       = $mySecret
    ProjectId          = $myProjectId
    TargetEnvironment  = 'Integration'
    DeploymentPackage  = 'cms.app.1.0.0.nupkg'
    Wait               = $true
    ShowProgress       = $true
    PollingIntervalSec = 10
    WaitTimeoutMinutes = 30
}
Start-EpiDeployment @DeploymentHash

Promote from Integration to Preproduction with blobs and database:

$DeploymentHash = @{
    ClientKey         = $myKey
    ClientSecret      = $mySecret
    ProjectId         = $myProjectId
    SourceEnvironment = 'Integration'
    SourceApp         = 'cms'
    TargetEnvironment = 'Preproduction'
    IncludeBlob       = $true
    IncludeDb         = $true
}
Start-EpiDeployment @DeploymentHash

Deploy to Production with zero-downtime (ReadOnly mode):

$DeploymentHash = @{
    ClientKey         = $myKey
    ClientSecret      = $mySecret
    ProjectId         = $myProjectId
    SourceEnvironment = 'Preproduction'
    TargetEnvironment = 'Production'
    ZeroDownTimeMode  = 'ReadOnly'
}
Start-EpiDeployment @DeploymentHash

Deploy multiple packages (code + database):

$DeploymentHash = @{
    ClientKey         = $myKey
    ClientSecret      = $mySecret
    ProjectId         = $myProjectId
    TargetEnvironment = 'Integration'
    DeploymentPackage = @('cms.app.1.0.0.nupkg', 'cms.sqldb.1.bacpac')
    DirectDeploy      = $true
}
Start-EpiDeployment @DeploymentHash

Get-EpiDeployment

Retrieves deployment information for a project. Can list all deployments or fetch a specific deployment by ID.

Queries the Deployment API for deployments triggered on the specified project.

Parameters

ParameterTypeRequiredDescription
ClientKeyStringYesThe API client key.
ClientSecretStringYesThe API client secret.
ProjectIdStringYesThe GUID of the project.
IdStringNoThe GUID of a specific deployment. When omitted, all deployments for the project are returned.

Examples

List all deployments:

Get-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId

Get a specific deployment:

Get-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Id 'd142a635-c09e-4c56-a4ba-394d0dd7a14a'

Poll a deployment's status:

$deployment = Start-EpiDeployment @deploymentParams

# Check status periodically
do {
    Start-Sleep -Seconds 30
    $status = Get-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Id $deployment.id
    Write-Host "Status: $($status.status) — Progress: $($status.percentComplete)%"
} while ($status.status -notin @('Succeeded', 'Failed', 'AwaitingVerification'))

Complete-EpiDeployment

Completes (finalizes) a deployment that is in the AwaitingVerification state. This performs the final slot swap for non-direct deployments.

After a deployment reaches the AwaitingVerification status, this command completes it by performing the final swap to make the new code live.

Parameters

ParameterTypeRequiredDescription
ClientKeyStringYesThe API client key.
ClientSecretStringYesThe API client secret.
ProjectIdStringYesThe GUID of the project.
IdStringYesThe GUID of the deployment to complete.
WaitSwitchNoPoll until completion finishes.
ShowProgressSwitchNoDisplay a progress bar (requires -Wait).
WaitTimeoutMinutesIntNoMaximum minutes to wait. Default: 240.
PollingIntervalSecondsIntNoSeconds between polls. Default: 30.

Examples

Complete a deployment:

Complete-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Id $deploymentId

Complete a deployment and wait:

Complete-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Id $deploymentId -Wait -WaitTimeoutMinutes 10 -PollingIntervalSeconds 10

Reset-EpiDeployment

Resets a deployment, rolling back to the previous state. Supports a two-phase reset process: initiate the reset, then complete it.

Rolls back a deployment that is in the AwaitingVerification or similar state. Optionally rolls back the database and validates the target site before completing the swap.

Parameters

ParameterTypeRequiredParameter SetDescription
ClientKeyStringYesBothThe API client key.
ClientSecretStringYesBothThe API client secret.
ProjectIdStringYesBothThe GUID of the project.
IdStringYesBothThe GUID of the deployment to reset.
RollbackDatabaseSwitchNoStartResetRollback the database if maintenance mode was applied.
ValidateBeforeSwapSwitchNoStartResetValidate the target site before completing the reset swap.
CompleteSwitchNoCompleteResetComplete (finalize) an in-progress reset operation.
WaitSwitchNoBothPoll until the reset finishes.
ShowProgressSwitchNoBothDisplay a progress bar (requires -Wait).
WaitTimeoutMinutesIntNoBothMaximum minutes to wait. Default: 240.
PollingIntervalSecondsIntNoBothSeconds between polls. Default: 30.

Note: Resetting is not supported for deployments made with the -DirectDeploy flag.

Examples

Reset a deployment:

Reset-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Id $deploymentId

Reset with database rollback and pre-swap validation:

Reset-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Id $deploymentId -RollbackDatabase -ValidateBeforeSwap

Complete a reset operation:

Reset-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Id $deploymentId -Complete

Get-EpiStorageContainer

Lists blob storage containers for a given project and environment.

Retrieves the names of blob storage containers available in a specific environment. Optionally filters for writable containers only.

Parameters

ParameterTypeRequiredDescription
ClientKeyStringYesThe API client key.
ClientSecretStringYesThe API client secret.
ProjectIdStringYesThe GUID of the project.
EnvironmentStringYesThe environment name (e.g., Integration, Preproduction, Production).
WritableSwitchNoOnly return writable containers. Note: Writable containers are not available for Preproduction and Production environments.

Examples

List all containers:

$containerHash = @{
    ClientKey    = $myKey
    ClientSecret = $mySecret
    ProjectId    = $myProjectId
    Environment  = 'Integration'
}
Get-EpiStorageContainer @containerHash

List writable containers only:

$containerHash = @{
    ClientKey    = $myKey
    ClientSecret = $mySecret
    ProjectId    = $myProjectId
    Environment  = 'Integration'
    Writable     = $true
}
Get-EpiStorageContainer @containerHash

Generates a SAS link for one or more blob storage containers, granting temporary access.

Retrieves a SAS (Shared Access Signature) link for specified blob storage containers in a given environment. Supports read-only and writable access.

Parameters

ParameterTypeRequiredDescription
ClientKeyStringYesThe API client key.
ClientSecretStringYesThe API client secret.
ProjectIdStringYesThe GUID of the project.
EnvironmentStringYesThe environment name.
StorageContainerString[]YesOne or more blob storage container names. Also accepts storageContainers as an alias.
RetentionHoursIntNoHow long (in hours) the SAS link remains valid. Range: 1–168. Default: 24.
WritableSwitchNoRequest a writable SAS link (for writable containers).

Examples

Get read-only SAS links for log containers:

$containerHash = @{
    ClientKey        = $myKey
    ClientSecret     = $mySecret
    ProjectId        = $myProjectId
    Environment      = 'Integration'
    StorageContainer = @('azure-application-logs', 'azure-web-logs')
}
Get-EpiStorageContainerSasLink @containerHash

Get a writable SAS link for a media container:

$containerHash = @{
    ClientKey        = $myKey
    ClientSecret     = $mySecret
    ProjectId        = $myProjectId
    Environment      = 'Integration'
    StorageContainer = 'mysitemedia'
    Writable         = $true
    RetentionHours   = 48
}
Get-EpiStorageContainerSasLink @containerHash

Start-EpiDatabaseExport

Starts an export of a database from a specific environment.

Initiates a database export as a .bacpac file for the specified project, environment, and database. The export is retained for a configurable number of hours.

Parameters

ParameterTypeRequiredDescription
ClientKeyStringYesThe API client key.
ClientSecretStringYesThe API client secret.
ProjectIdStringYesThe GUID of the project.
EnvironmentStringYesThe environment name (e.g., Integration).
DatabaseNameStringYesThe database to export. Valid values: epicms, epicommerce.
RetentionHoursIntNoHow long to retain the exported bacpac. Default: 24.
WaitSwitchNoPoll until the export completes.
ShowProgressSwitchNoDisplay progress text during polling.
WaitTimeoutMinutesIntNoMaximum minutes to wait. Default: 60.
PollingIntervalSecIntNoSeconds between polls. Default: 30.

Examples

Start a database export:

$export = Start-EpiDatabaseExport -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Environment 'Integration' -DatabaseName 'epicms'

Start an export and wait for it to finish:

$export = Start-EpiDatabaseExport -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Environment 'Integration' -DatabaseName 'epicms' -Wait -ShowProgress -RetentionHours 48

Get-EpiDatabaseExport

Retrieves the status and details of a specific database export.

Queries the API for information about a previously started database export.

Parameters

ParameterTypeRequiredDescription
ClientKeyStringYesThe API client key.
ClientSecretStringYesThe API client secret.
ProjectIdStringYesThe GUID of the project.
EnvironmentStringYesThe environment the export belongs to.
DatabaseNameStringYesThe database name (epicms or epicommerce).
IdStringYesThe GUID of the database export.

Examples

# Start an export, then check its status
$export = Start-EpiDatabaseExport -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Environment 'Integration' -DatabaseName 'epicms'

Get-EpiDatabaseExport -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Environment 'Integration' -DatabaseName 'epicms' -Id $export.id

Get-EpiEdgeLogLocation

Retrieves the location (SAS link) for edge logs.

Returns a SAS URL pointing to the Azure Blob Storage container that contains edge (CDN) logs for the project.

Parameters

ParameterTypeRequiredDescription
ClientKeyStringYesThe API client key.
ClientSecretStringYesThe API client secret.
ProjectIdStringYesThe GUID of the project.

Output

Returns a String — the SAS URL to the edge logs blob container.

Examples

$edgeLogUrl = Get-EpiEdgeLogLocation -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId

Write-Host "Edge logs available at: $edgeLogUrl"

Common Workflows

Deploy a Code Package to Integration

This is the most common workflow — upload a package and deploy it directly to the Integration environment.

# 1. Authenticate
Connect-EpiCloud -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId

# 2. Get the upload location
$sasUrl = Get-EpiDeploymentPackageLocation

# 3. Upload the package
Add-EpiDeploymentPackage -SasUrl $sasUrl -Path .\cms.app.1.0.0.nupkg

# 4. Start the deployment with DirectDeploy for faster Integration deployments
$deployment = Start-EpiDeployment -TargetEnvironment 'Integration' `
    -DeploymentPackage 'cms.app.1.0.0.nupkg' `
    -DirectDeploy `
    -Wait `
    -ShowProgress `
    -WaitTimeoutMinutes 30

Write-Host "Deployment finished with status: $($deployment.status)"

Promote Code Between Environments

Promote code (and optionally content) from one environment to another. Non-direct deployments go through a verification step.

# 1. Authenticate
Connect-EpiCloud -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId

# 2. Start promotion from Integration to Preproduction
$deployment = Start-EpiDeployment `
    -SourceEnvironment 'Integration' `
    -SourceApp 'cms' `
    -TargetEnvironment 'Preproduction' `
    -IncludeBlob `
    -IncludeDb `
    -Wait `
    -ShowProgress

# 3. Verify the Preproduction site manually, then complete or reset
if ($deployment.status -eq 'AwaitingVerification') {
    # If everything looks good:
    Complete-EpiDeployment -Id $deployment.id -Wait

    # If something is wrong, reset instead:
    # Reset-EpiDeployment -Id $deployment.id -Wait
}

Export and Download a Database

Export a database to a .bacpac file and retrieve its download link.

# 1. Authenticate
Connect-EpiCloud -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId

# 2. Start the export and wait
$export = Start-EpiDatabaseExport `
    -Environment 'Integration' `
    -DatabaseName 'epicms' `
    -RetentionHours 48 `
    -Wait `
    -ShowProgress

# 3. Check the export result for the download link
$exportDetails = Get-EpiDatabaseExport `
    -Environment 'Integration' `
    -DatabaseName 'epicms' `
    -Id $export.id

Write-Host "Download URL: $($exportDetails.downloadLink)"

Access Blob Storage Containers

List available containers and generate SAS links for direct access (e.g., for downloading logs or media files).

# 1. Authenticate
Connect-EpiCloud -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId

# 2. List all containers in Integration
$containers = Get-EpiStorageContainer -Environment 'Integration'
$containers | Format-Table

# 3. Get SAS links for specific containers
$sasLinks = Get-EpiStorageContainerSasLink `
    -Environment 'Integration' `
    -StorageContainer @('azure-application-logs', 'azure-web-logs') `
    -RetentionHours 12

$sasLinks | ForEach-Object {
    Write-Host "$($_.storageContainer): $($_.sasLink)"
}

Troubleshooting

Common Issues

IssueCauseSolution
Failed to validate the credentialsInvalid ClientKey/ClientSecret or wrong ProjectIdVerify credentials in the DXP PaaS Portal
The deployment package is not recognizedPackage file name doesn't match the required naming conventionRename the file to match an accepted pattern (see Package Naming Convention)
A package named 'X' already existsA package with the same name but different content is already uploadedUpload with a different version number or package name
LeaseIdMissing error during uploadThe package is currently linked to an active deploymentWait for the deployment to finish, or upload with a new name
Timeout during -WaitDeployment took longer than WaitTimeoutMinutesIncrease the timeout value or check deployment status manually with Get-EpiDeployment
Reset not supportedAttempted to reset a -DirectDeploy deploymentDirect deployments cannot be reset; redeploy with the previous package instead

Verbose Logging

Add -Verbose to any command to see detailed logging output:

Start-EpiDeployment @deploymentParams -Verbose

Checking Deployment Status

If a long-running deployment times out, you can always check its current state:

Get-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Id $deploymentId

This documentation covers EpiCloud module version 1.10.0. For the latest updates, refer to the PowerShell Gallery listing.