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 from PowerShell Gallery
Install-Module EpiCloud -Repository PSGalleryVerify installation
Get-Module EpiCloud -ListAvailableAuthentication
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 $myProjectIdCommand 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
| Parameter | Type | Required | Description |
|---|---|---|---|
ClientKey | String | Yes | The API client key used to access the project. |
ClientSecret | String | Yes | The API client secret used to access the project. |
ProjectId | String | No | The GUID of the project. When provided, the credentials are validated immediately by making a test API call. |
Behavior
- When
ProjectIdis supplied, the function validates the credentials by callingGet-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 $myProjectIdSet 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-EpiDeploymentPackageLocationGet-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
| Parameter | Type | Required | Description |
|---|---|---|---|
ClientKey | String | Yes | The API client key. |
ClientSecret | String | Yes | The API client secret. |
ProjectId | String | Yes | The 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.nupkgAdd-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
| Parameter | Type | Required | Description |
|---|---|---|---|
SasUrl | String | Yes | The SAS link to the deployment packages container (obtained from Get-EpiDeploymentPackageLocation). |
Path | String | Yes | The full local file path of the package to upload. Accepts pipeline input via the FullName property. |
BlobName | String | No | The name for the blob in the container. Defaults to the file name from Path. Accepts pipeline input via the Name property. |
ClientKey | String | No | The API client key. When provided along with ClientSecret and ProjectId, enables a pre-upload existence check to avoid duplicate uploads. |
ClientSecret | String | No | The API client secret. |
ProjectId | String | No | The GUID of the project. |
Package Naming Convention
The package file name (or BlobName) must match one of these recognized patterns:
| Pattern | Example |
|---|---|
{prefix}.cms.app.{version}.nupkg | site.cms.app.1.0.0.nupkg |
{prefix}.commerce.app.{version}.nupkg | site.commerce.app.2.3.1.nupkg |
{prefix}.head.app.{version}.zip | site.head.app.1.0.0.zip |
cms.app.{version}.nupkg | cms.app.1.0.0.nupkg |
commerce.app.{version}.nupkg | commerce.app.1.0.0.nupkg |
{prefix}.cms.sqldb.{version}.bacpac | site.cms.sqldb.1.0.0.bacpac |
{prefix}.commerce.sqldb.{version}.bacpac | site.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.nupkgUpload 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 $myProjectIdUpload via pipeline (multiple files):
$sasUrl = Get-EpiDeploymentPackageLocation -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId
Get-ChildItem -Path .\packages\*.nupkg | Add-EpiDeploymentPackage -SasUrl $sasUrlStart-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:
- DeploymentPackage (default) — Deploy previously uploaded code packages.
- SourceEnvironment — Promote code, blobs, and/or databases from a source environment.
Parameters
| Parameter | Type | Required | Parameter Set | Description |
|---|---|---|---|---|
ClientKey | String | Yes | Both | The API client key. |
ClientSecret | String | Yes | Both | The API client secret. |
ProjectId | String | Yes | Both | The GUID of the project. |
TargetEnvironment | String | Yes | Both | The environment to deploy to (e.g., Integration, Preproduction, Production). |
DeploymentPackage | String[] | Yes | DeploymentPackage | The name(s) of the uploaded code package(s) to deploy. |
SourceEnvironment | String | Yes | SourceEnvironment | The environment to copy code/content from. |
SourceApp | String[] | No | SourceEnvironment | The app(s) to copy. Valid values: cms, commerce. |
IncludeBlob | Switch | No | SourceEnvironment | Include blobs from the source environment. |
IncludeDb | Switch | No | SourceEnvironment | Include the SQL database from the source environment. |
UseMaintenancePage | Switch | No | Both | Display a maintenance page during deployment. |
ZeroDownTimeMode | String | No | Both | Database mode for the primary web app during deployment. Values: ReadOnly, ReadWrite. Enables zero-downtime deployment when specified. |
DirectDeploy | Switch | No | Both | Deploy directly to the target web app without a slot swap. Faster for Integration/Development environments. Note: Resetting is not supported for direct deployments. |
Wait | Switch | No | Both | Poll the deployment until it completes (or times out). |
ShowProgress | Switch | No | Both | Display a progress bar during polling (requires -Wait). |
WaitTimeoutMinutes | Int | No | Both | Maximum minutes to wait for deployment completion. Default: 240. |
PollingIntervalSec | Int | No | Both | Seconds 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 @DeploymentHashDeploy 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 @DeploymentHashPromote 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 @DeploymentHashDeploy to Production with zero-downtime (ReadOnly mode):
$DeploymentHash = @{
ClientKey = $myKey
ClientSecret = $mySecret
ProjectId = $myProjectId
SourceEnvironment = 'Preproduction'
TargetEnvironment = 'Production'
ZeroDownTimeMode = 'ReadOnly'
}
Start-EpiDeployment @DeploymentHashDeploy 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 @DeploymentHashGet-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
| Parameter | Type | Required | Description |
|---|---|---|---|
ClientKey | String | Yes | The API client key. |
ClientSecret | String | Yes | The API client secret. |
ProjectId | String | Yes | The GUID of the project. |
Id | String | No | The 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 $myProjectIdGet 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
| Parameter | Type | Required | Description |
|---|---|---|---|
ClientKey | String | Yes | The API client key. |
ClientSecret | String | Yes | The API client secret. |
ProjectId | String | Yes | The GUID of the project. |
Id | String | Yes | The GUID of the deployment to complete. |
Wait | Switch | No | Poll until completion finishes. |
ShowProgress | Switch | No | Display a progress bar (requires -Wait). |
WaitTimeoutMinutes | Int | No | Maximum minutes to wait. Default: 240. |
PollingIntervalSeconds | Int | No | Seconds between polls. Default: 30. |
Examples
Complete a deployment:
Complete-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Id $deploymentIdComplete a deployment and wait:
Complete-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Id $deploymentId -Wait -WaitTimeoutMinutes 10 -PollingIntervalSeconds 10Reset-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
| Parameter | Type | Required | Parameter Set | Description |
|---|---|---|---|---|
ClientKey | String | Yes | Both | The API client key. |
ClientSecret | String | Yes | Both | The API client secret. |
ProjectId | String | Yes | Both | The GUID of the project. |
Id | String | Yes | Both | The GUID of the deployment to reset. |
RollbackDatabase | Switch | No | StartReset | Rollback the database if maintenance mode was applied. |
ValidateBeforeSwap | Switch | No | StartReset | Validate the target site before completing the reset swap. |
Complete | Switch | No | CompleteReset | Complete (finalize) an in-progress reset operation. |
Wait | Switch | No | Both | Poll until the reset finishes. |
ShowProgress | Switch | No | Both | Display a progress bar (requires -Wait). |
WaitTimeoutMinutes | Int | No | Both | Maximum minutes to wait. Default: 240. |
PollingIntervalSeconds | Int | No | Both | Seconds between polls. Default: 30. |
Note: Resetting is not supported for deployments made with the
-DirectDeployflag.
Examples
Reset a deployment:
Reset-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Id $deploymentIdReset with database rollback and pre-swap validation:
Reset-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Id $deploymentId -RollbackDatabase -ValidateBeforeSwapComplete a reset operation:
Reset-EpiDeployment -ClientKey $myKey -ClientSecret $mySecret -ProjectId $myProjectId -Id $deploymentId -CompleteGet-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
| Parameter | Type | Required | Description |
|---|---|---|---|
ClientKey | String | Yes | The API client key. |
ClientSecret | String | Yes | The API client secret. |
ProjectId | String | Yes | The GUID of the project. |
Environment | String | Yes | The environment name (e.g., Integration, Preproduction, Production). |
Writable | Switch | No | Only 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 @containerHashList writable containers only:
$containerHash = @{
ClientKey = $myKey
ClientSecret = $mySecret
ProjectId = $myProjectId
Environment = 'Integration'
Writable = $true
}
Get-EpiStorageContainer @containerHashGet-EpiStorageContainerSasLink
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
| Parameter | Type | Required | Description |
|---|---|---|---|
ClientKey | String | Yes | The API client key. |
ClientSecret | String | Yes | The API client secret. |
ProjectId | String | Yes | The GUID of the project. |
Environment | String | Yes | The environment name. |
StorageContainer | String[] | Yes | One or more blob storage container names. Also accepts storageContainers as an alias. |
RetentionHours | Int | No | How long (in hours) the SAS link remains valid. Range: 1–168. Default: 24. |
Writable | Switch | No | Request 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 @containerHashGet 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 @containerHashStart-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
| Parameter | Type | Required | Description |
|---|---|---|---|
ClientKey | String | Yes | The API client key. |
ClientSecret | String | Yes | The API client secret. |
ProjectId | String | Yes | The GUID of the project. |
Environment | String | Yes | The environment name (e.g., Integration). |
DatabaseName | String | Yes | The database to export. Valid values: epicms, epicommerce. |
RetentionHours | Int | No | How long to retain the exported bacpac. Default: 24. |
Wait | Switch | No | Poll until the export completes. |
ShowProgress | Switch | No | Display progress text during polling. |
WaitTimeoutMinutes | Int | No | Maximum minutes to wait. Default: 60. |
PollingIntervalSec | Int | No | Seconds 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 48Get-EpiDatabaseExport
Retrieves the status and details of a specific database export.
Queries the API for information about a previously started database export.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ClientKey | String | Yes | The API client key. |
ClientSecret | String | Yes | The API client secret. |
ProjectId | String | Yes | The GUID of the project. |
Environment | String | Yes | The environment the export belongs to. |
DatabaseName | String | Yes | The database name (epicms or epicommerce). |
Id | String | Yes | The 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.idGet-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
| Parameter | Type | Required | Description |
|---|---|---|---|
ClientKey | String | Yes | The API client key. |
ClientSecret | String | Yes | The API client secret. |
ProjectId | String | Yes | The 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
| Issue | Cause | Solution |
|---|---|---|
| Failed to validate the credentials | Invalid ClientKey/ClientSecret or wrong ProjectId | Verify credentials in the DXP PaaS Portal |
| The deployment package is not recognized | Package file name doesn't match the required naming convention | Rename the file to match an accepted pattern (see Package Naming Convention) |
| A package named 'X' already exists | A package with the same name but different content is already uploaded | Upload with a different version number or package name |
LeaseIdMissing error during upload | The package is currently linked to an active deployment | Wait for the deployment to finish, or upload with a new name |
Timeout during -Wait | Deployment took longer than WaitTimeoutMinutes | Increase the timeout value or check deployment status manually with Get-EpiDeployment |
| Reset not supported | Attempted to reset a -DirectDeploy deployment | Direct 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 -VerboseChecking 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 $deploymentIdThis documentation covers EpiCloud module version 1.10.0. For the latest updates, refer to the PowerShell Gallery listing.