Following is the guide to Download, Install, Replicate AEM Package and Flush the Dispatcher Cache. The Job can be achieved in several different ways, and there is always room for improvement. In this tutorial we shall download the package from lower environments and install the downloaded package to a different environment.
This Tutorial is an advancement to the following blog AEM-Download,Install,Replicate.
Tools Used:
- Powershell
- cURL
- Windows 10 Enterprise
- Jenkins
Prerequisites:
ACS Commons Package, make sure the package is available on the Author instance where the package is being installed, Script utilizes the acs commons dispatcher flush component to trigger the dispatcher flush agent under the Replication — agents on author.
Compatibility — Check package compatibility with the following at Compatibility chart and Download the respective package
Download — Package can be downloaded from Download–ACS Commons 3.19.0
ACS Commons Installation Guide
Jenkins Plugins used
STEP-01: Agents on Author — Target Host
Configuring the Dispatcher flush agent of the Target Host machine, and ACS Commons dispatcher flush component on Target Host.

- Go to the miscadmin URL
- From the left sidebar menu select Replication
- Under the Replication, select Agents on Author
- From the Main Menu, Double-Click Dispatcher Flush Agent

- Go to Dispatcher Flush Agent URL
- Click Edit, to configure Dispatcher

- Go to SETTINGS tab
- Name the Dispatcher flush Agent
- Enable Flush Agent

- Go to Transport TAB
- Add the URI for the Dispatcher instance

- Go to the Triggers TAB
- Enable the on/off time Boundary value for page
- Finally Save all settings by clicking OK.
Using the acs commons package, we shall trigger the dispatcher flush agent and the path to flush using dispatcher flush agent

- Go to acs commons dispatcher flush url
- Select Acs Commons from the left sidebar
- Select Dispatcher Flush under ACS Commons
- Click New on the main dispatcher flush page

- Add Title to the agent
- Select the dispatcher flush Template
- Finally, Click create

- Select the newly created flush agent ‘sd-disp-flush’
- Double Click on the Flush agent to configure

- Verify the Name of the Agent
- This is the Dispatcher Flush Agent from Agents on Author (from previous step)
- Click on EDIT, to configure the flush agent

Select whether to delete or invalidate cache

- Click on Add Item, to add path to be flushed
- Select the appropriate path to form the list
- Repeat step-2 to add additional paths
- When done adding paths, click OK to save configuration
- Declaring required Parameters and variables
2. Function Block — Begin{}
Custom Code to Check if Group Name contains spaces and replace them with HTML URL encoding — PROCESS{} Block
if ($GroupName -like "* *") {
$DCURL = ($DCURL).Replace(' ','%20')
$ICURL = ($ICURL).Replace(' ','%20')
$RCURL = ($RCURL).Replace(' ','%20')
$DFLUSH = ($DFLUSH).Replace(' ','%20')
$ValidationURL = ($ValidationURL).Replace(' ','%20')
}
Custom code block to check if the Installation Host is using http or https and based on that change the URL
if ($AEMPORTI -eq '5443') {
$ICURL = ($ICURL).Replace('http','https')
$RCURL = ($RCURL).Replace('http','https')
$DFLUSH = ($DFLUSH).Replace('http','https')
$ValidationURL = ($ValidationURL).Replace('http','https')
}
Custom code to Download the package
# Downlaod Package --BEGIN
Write-Host " "
Write-Host -F Green ">>>> Downloading Package $PKGNAME from $HOSTNAMED"
Write-Host -F Green " "
cmd.exe /c $CURLEXE -u "${CQ_USER}:${CQ_PASSD}" "${DCURL}" --Output "${PKGPATH}"
if ($?) {
$DwnEC = "True"
Write-Host -F Green " "
Write-Host -F Green ">>>> Package Downlaod Complete"
Write-Host -F Green " "
}else {
Write-Host -F Green " "
Write-Host -F RED ">>>> Package Downlaod Failed"
Write-Host -F Green " "
}
Custom code to upload and install the downloaded package, the upload and installation will only commence if the package download is successful.
# Download package --END
if ($DwnEC -eq "True") {
# Installing the Package --BEGIN
Write-Host -F Green " "
Write-Host -F Green ">>>> Installing $PKGNAME Package on $HOSTNAMEI"
Write-Host -F Green " "
if ($AEMPORTI -eq 5443) {
cmd.exe /c $CURLEXE -ku "${CQ_USER}:${CQ_PASSD}" -F file=@"${PKGPATH}" -F name="${packageName}" -F force=true -F install=true "${ICURL}" | Out-Null
}else {
cmd.exe /c $CURLEXE -u "${CQ_USER}:${CQ_PASSD}" -F file=@"${PKGPATH}" -F name="${packageName}" -F force=true -F install=true "${ICURL}" | Out-Null
}
if ($?) {
$INSTEC = "True"
Write-Host -F Green " "
Write-Host -F Green ">>>> Package Installation Complete"
Write-Host -F Green " "
}else {
Write-Host -F Green " "
Write-Host -F RED ">>>> Package Installation Failed"
Write-Host -F Green " "
}
# Package Installation --END
}
Following is the entire script to download the package, upload and install, replicate the package and finally clear the dispatcher cache
param(
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$CURLEXE = "C:\tools\curl76\bin\curl.exe",
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$AEMENV = "PROD",
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$packageName = "$ENV:Enter_Package_Name",
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$CQ_USER = "$ENV:SDUsernameUAT",
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$CQ_PASSD = "$ENV:SDPasswordUAT",
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$CQ_PASSI = "$ENV:SDpasswordPRD",
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$HOSTNAMED = "192.168.2.7",
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$HOSTNAMEI = "192.168.2.9",
[parameter(Mandatory=$False,ValueFromPipeline=$False)][Int]$AEMPORTD = 4502,
[parameter(Mandatory=$False,ValueFromPipeline=$False)][Int]$AEMPORTI = 4502,
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$packURL = "http://${HOSTNAMED}:${AEMPORTD}/crx/packmgr/list.jsp",
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$packData = (cmd.exe /c $CURLEXE -u "${CQ_USER}:${CQ_PASSD}" "${packURL}" 2>$null),
[parameter(Mandatory=$False,ValueFromPipeline=$False)]$psData = ( $packData | ConvertFrom-JSON ),
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String[]]$packDName = @(($psData.results | ? { $_.Name -eq "$packageName"}).downloadName),
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String[]]$GroupData = @(($psData.results | ? { $_.Name -eq "$packageName" }).group),
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$GroupName = ($GroupData[($GroupData.length)-1]),
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$PKGNAME = $packDName[($packDName.length)-1],
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$PKGPATH = "${PKGNAME}",
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$ValidationURL = "http://${HOSTNAMEI}:${AEMPORTI}/crx/packmgr/index.jsp#/etc/packages/${GroupName}/${PKGNAME}",
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$DCURL = "http://${HOSTNAMED}:${AEMPORTD}/etc/packages/${GroupName}/${PKGNAME}",
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$ICURL = "http://${HOSTNAMEI}:${AEMPORTI}/crx/packmgr/service.jsp",
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$RCURL = "http://${HOSTNAMEI}:${AEMPORTI}/crx/packmgr/service/script.html/etc/packages/${GroupName}/${PKGNAME}?cmd=replicate",
[parameter(Mandatory=$False,ValueFromPipeline=$False)][String]$DFLUSH = "http://${HOSTNAMEI}:${AEMPORTI}/etc/acs-commons/dispatcher-flush/sd-disp-flush/_jcr_content/configuration.flush.html"
)
Function SDProdDeploy {
Begin {
# Stopping the job if it encounters error
$ErrorActionPreference = 'Stop'
$ScriptName = $MyInvocation.MyCommand.Name
# Clear-Host
Write-Host -F Green " "
Write-Host -F Green "***************************************************************"
Write-Host -F Green "Starting $AEMENV Deploy Process at [$([DateTime]::Now)]."
Write-Host -F Green "*************************************************************"
Write-Host -F Green " "
Write-Host -F Green "Script Name: $ScriptName"
Write-Host -F Green "Environment: $AEMENV"
Write-Host -F Green "Download Host Details: $HOSTNAMED, $AEMPORTD"
Write-Host -F Green "Install Host Details: $HOSTNAMEI, $AEMPORTI"
Write-Host -F Green "Package Name: $PKGNAME"
Write-Host -F Green "Package Group: $GroupName"
Write-Host -F Green " "
Write-Host -F Green "**************************************************************"
Write-Host -F Green " "
}
Process {
if ($packDName -ne $null) {
# Check if group name contains spaces
if ($GroupName -like "* *") {
$DCURL = ($DCURL).Replace(' ','%20')
$ICURL = ($ICURL).Replace(' ','%20')
$RCURL = ($RCURL).Replace(' ','%20')
$DFLUSH = ($DFLUSH).Replace(' ','%20')
$ValidationURL = ($ValidationURL).Replace(' ','%20')
}
if ($AEMPORTI -eq '5443') {
$ICURL = ($ICURL).Replace('http','https')
$RCURL = ($RCURL).Replace('http','https')
$DFLUSH = ($DFLUSH).Replace('http','https')
$ValidationURL = ($ValidationURL).Replace('http','https')
}
# Downlaod Package --BEGIN
Write-Host " "
Write-Host -F Green ">>>> Downloading Package $PKGNAME from $HOSTNAMED"
Write-Host -F Green " "
cmd.exe /c $CURLEXE -u "${CQ_USER}:${CQ_PASSD}" "${DCURL}" --Output "${PKGPATH}"
if ($?) {
$DwnEC = "True"
Write-Host -F Green " "
Write-Host -F Green ">>>> Package Downlaod Complete"
Write-Host -F Green " "
}else {
Write-Host -F Green " "
Write-Host -F RED ">>>> Package Downlaod Failed"
Write-Host -F Green " "
}
# Download package --END
if ($DwnEC -eq "True") {
# Installing the Package --BEGIN
Write-Host -F Green " "
Write-Host -F Green ">>>> Installing $PKGNAME Package on $HOSTNAMEI"
Write-Host -F Green " "
if ($AEMPORTI -eq 5443) {
cmd.exe /c $CURLEXE -ku "${CQ_USER}:${CQ_PASSD}" -F file=@"${PKGPATH}" -F name="${packageName}" -F force=true -F install=true "${ICURL}" | Out-Null
}else {
cmd.exe /c $CURLEXE -u "${CQ_USER}:${CQ_PASSD}" -F file=@"${PKGPATH}" -F name="${packageName}" -F force=true -F install=true "${ICURL}" | Out-Null
}
if ($?) {
$INSTEC = "True"
Write-Host -F Green " "
Write-Host -F Green ">>>> Package Installation Complete"
Write-Host -F Green " "
}else {
Write-Host -F Green " "
Write-Host -F RED ">>>> Package Installation Failed"
Write-Host -F Green " "
}
# Package Installation --END
}
if ($INSTEC -eq "True") {
# Replicate Package --BEGIN
Write-Host -F Green " "
Write-Host -F Green ">>>> Replicating Package $PKGNAME on $HOSTNAMEI"
Write-Host -F Green " "
if ($AEMPORTI -eq 5443) {
cmd.exe /c $CURLEXE -ku "${CQ_USER}:${CQ_PASSI}" -X POST $RCURL | Out-Null
}else {
cmd.exe /c $CURLEXE -u "${CQ_USER}:${CQ_PASSI}" -X POST $RCURL | Out-Null
}
if ($?) {
$REPEC = "True"
Write-Host -F Green " "
Write-Host -F Green ">>>> Package Replication Complete"
Write-Host -F Green " "
}else {
Write-Host -F Green " "
Write-Host -F RED ">>>> Package Replication Failed"
Write-Host -F Green " "
}
# Package Replication --END
}
if ($REPEC -eq "True") {
# Flush Dispatcher using ACS Commons --BEGIN
Write-Host -F Green " "
Write-Host -F Green ">>>> Flushing Dispatcher Cache"
Write-Host -F Green " "
if ($AEMPORTI -eq 5443) {
cmd.exe /c $CURLEXE -ku "${CQ_USER}:${CQ_PASSI}" -X POST $DFLUSH | Out-Null
}else {
cmd.exe /c $CURLEXE -u "${CQ_USER}:${CQ_PASSI}" -X POST $DFLUSH | Out-Null
}
if ($?) {
Write-Host -F Green " "
Write-Host -F Green ">>>> Dispatcher Flush Complete"
Write-Host -F Green " "
}else {
Write-Host -F Green " "
Write-Host -F RED ">>>> Dispatcher Flush Failed"
Write-Host -F Green " "
}
}
}else {
Write-Host -F Red ">>>>" Package Name: ($packageName).toupper() "-- Not Found."
}
}
End {
If ($?) {
Write-Host -F Green ""
Write-Host -F Green ">>>> Verification URL"
Write-Host -F Green "Install Host URL: $ValidationURL"
Write-Host -F Green ""
Write-Host -F Green "**************************************************************"
Write-Host -F Green "Finished processing at [$([DateTime]::Now)]."
Write-Host -F Green "*************************************************************"
Write-Host -F Green ""
}
}
}
SDProdDeploy
STEP-04: Automating the Package deployment using Jenkins and Powershell
Following is the process, where package name is given as input to the build job on Jenkins. Then based on the package name, script will parse through AEM [Download Host], if found, will gather DownloadName, Groupname of the package.

- Go to General TAB
- Add the project description

- Select the House keeping strategy for the project
- Mention the number of days to keep the builds
- Mention max number of builds to keep

We shall use the extensible choice parameter, if not already install, got to plugin manager and install the plugin, see prerequisites
- Select the Extensible choice parameter
- Name of the Variable in the Script
- Describe the Variable
- Select the Textarea Choice parameter
- Add the choices as shown in the above figure
- Select the option, which would be displayed as the default choice
- Enable Editable option, to manually add package name, if package is not listed on the list
- Parameter to display all of selected choices

Use the credentials bindings parameter to enter the credentials for AEM instances
- Enable bindings by selecting Use secrets option under Build Environment
- Binding parameter
- Use the separated option
- Declare username variable
- Declare password variable
- Choose the credentials from credentials list to assign them to above variables

Select Build Step
Add windows powershell from the list
Add the powershell script from STEP-03

Clean up the workspace after building the project

- Select “Build with Parameters“
- click on the Textarea, Can manually enter package name here if not in list
- Select the desired package from the list


- Console output of the Build
- Describes the Environment, AEM hosts, Port numbers, Package name and Group
- Information about the package being downloaded
- Information about the package being uploaded and installed
- Information about the package being Replicated
- Information about the flushing dispatcher cache
- Link/URL to the deployed AEM instance to verify the Deployment
- Workspace cleanup
https://skydevops.co.in/2019/02/17/aem-automation-package-deployment/
No comments:
Post a Comment
If you have any doubts or questions, please let us know.