January 4, 2021
Estimated Post Reading Time ~

Automating AEM Installation using Powershell

DESCRIPTION:
Following is a PowerShell script to automate the installation of AEM Author/Publish environments along with NAS storage and installation of necessary packages through a single script and deploy AEM as windows service with LogOn details.

The script is run locally on a VM where the AEM environment is to be created. The script is broken into several sections, which are explained in detail.

SCRIPT:Following are the parameters used
$ErrorActionPreference = "Stop
$WarningPreference = "SilentlyContinue"
$AEMINST = Read-Host "Choose Author/Publish Instance to Setup [Author/Publish]"
$AEMPORT = Read-Host "Enter the CQ Port [4502/4503]"
$SRCPATH = "C:\Users\SKYDEVOPS\AEM\zinstaller"
$BASEPATH = "C:\Users\SKYDEVOPS\AEM\instances\$AEMINST"
$SERVICEPATH = "$BASEPATH\crx-quickstart\opt\helpers"
$JARFILE = "$SRCPATH\aem-$AEMINST-p$AEMPORT.jar"
$LicensePath = "$SRCPATH\license.properties"
$AEMUNPACK = "java -jar $JARFILE -unpack"
$ServiceName = "AEMPRD"
$USERNAME = "\SKYDEVOPS"
$HOSTNAME = "192.168.2.8"
$CQ_PORT = "4503"
$CQ_USER = "admin"
$CQ_PASS = "admin"
$CURLEXE = 'C:\tools\curl761\bin\curl.exe'
$GCURL = "http://${HOSTNAME}:${AEMPORT}/crx/packmgr/service.jsp"
$DOCUNSTORECFG = "org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.config"
$FILEDSTORECFG = "org.apache.jackrabbit.oak.plugins.blob.datastore.FiledataStore.config"
$PKGPATH01 = "$SRCPATH\aemgit.ui.apps-1.0-SNAPSHOT.zip"
$PKGPATH02 = "$SRCPATH\aemgit.ui.content-1.0-SNAPSHOT.zip"
$repository = "$BASEPATH\crx-quickstart\repository"

Description of each and every parameter is as following

.PARAMETER AEMINST
Author or Publish Environment
.PARAMETER AEMPORT
Author/Publish Port [4502/4503]
.PARAMETER SRCPATH
Common location for installation files. Example: AEM jar file, packages etc.
.PARAMETER BASEPATH
AEM installation directory
.PARAMETER SERVICEPATH
AEM instsrv.bat file location
.PARAMETER JARFILE
AEM jar file [aem-author-p4502.jar]
.PARAMETER LicensePath
license.properties file location
.PARAMETER AEMUNPACK
command to unpack AEM
.PARAMETER ServiceName
AEM service name
.PARAMETER USERNAME
username for AEM service LogOn
.PARAMETER MPass
password for serive LogOn
.PARAMETER HOSTNAME
Host on which AEM is installed
.PARAMETER CQ_PORT
AEM port
.PARAMETER CQ_USER
AEM login username
.PARAMETER CQ_PASS
AEM login password
.PARAMETER CURLEXE
cURL executable location
.PARAMETER GCURL
CRXDE url
.PARAMETER DOCUNSTORECFG
Document Node Store configuration
.PARAMETER FILEDSTORECFG
File Data Store configuration
.PARAMETER PKGPATH##
AEM package location and name
.PARAMETER repository
Location of Datastore repository

.NOTES
Author: Shashi Yebbare
Organization: Skydevops Pvt. Ltd.
Version: 3.5.2

Logic to check if AEM base directory exists, if not create it, then copy the necessary jar and license file and unpack AEM Author/Publish. If AEM Author/Publish directory exists then check for crx-quickstart folder and if its present then terminate the installation

if (!(Test-Path -Path $BASEPATH)) {
Write-Output "$AEMINST Installation Directory Not Found"
Write-Output "Creating Folder at $BASEPATH"
New-Item -ItemType directory -Path $BASEPATH
Copy-Item -Path $LicensePath -Destination $BASEPATH

Set-Location -Path $BASEPATH
Write-Output ""
Write-Output "Unpacking $AEMINST"
Invoke-Expression -Command:"cmd.exe /c $AEMUNPACK"

if ($AEMINST -eq "Author") {
Write-Output "Creating INSTALL Folder"
New-Item -ItemType directory -Path "$BASEPATH\crx-quickstart\install"
Write-Output ""
Write-Output "Copying Configurations to Install Directory"
Copy-Item -Path "$SRCPATH\$DOCUNSTORECFG" -Destination "$BASEPATH\crx-quickstart\install"
Copy-Item -Path "$SRCPATH\$FILEDSTORECFG" -Destination "$BASEPATH\crx-quickstart\install"

}
Set-Location -Path "C:\Users\SKYDEVOPS\Documents\scripts"
}else {

Write-Output "$BASEPATH Exists"
Write-Output "Checking crx-quickstart Directory"
if (!(Test-Path -Path $BASEPATH\crx-quickstart)) {
Write-Output "crx-quickstart Not Found, Unpacking $AEMINST"
Set-Location -Path $BASEPATH
Write-Output "Unpacking $AEMINST"

Invoke-Expression -Command:"cmd.exe /c $AEMUNPACK"
if ($AEMINST -eq "Author") {
Write-Output "Creating INSTALL Folder"
New-Item -ItemType directory -Path "$BASEPATH\crx-quickstart\install"
Write-Output ""
Write-Output "Copying Configurations to Install Directory"
Copy-Item -Path "$SRCPATH\$DOCUNSTORECFG" -Destination "$BASEPATH\crx-quickstart\install"
Copy-Item -Path "$SRCPATH\$FILEDSTORECFG" -Destination "$BASEPATH\crx-quickstart\install"
}
}else {
Write-Output "crx-quickstart Found, Terminating Installation."
Set-Location -Path "C:\Users\SKYDEVOPS\Documents\scripts"
Exit
}
}

Creating AEM service, adding LogOn details and starting AEM service

$AEMSERVICEPATH = "$BASEPATH\crx-quickstart\opt\helpers\instsrv.bat"
Rename-Item -Path "$AEMSERVICEPATH" -NewName "instsrv.bat.bak"
Copy-Item -Path "${SRCPATH}\instsrv-${AEMINST}.bat" -Destination "${SERVICEPATH}\instsrv.bat"
$AEMSERVICEPATH = "$BASEPATH\crx-quickstart\opt\helpers\instsrv.bat"
$AEMCommand = "$AEMSERVICEPATH $ServiceName"
$MPass="shashi"
Write-Output "Creating $ServiceName Service"
Invoke-Expression -Command:"cmd.exe /c $AEMCommand"
$LogOnD = Get-WmiObject -Class Win32_Service -Filter "Name='$ServiceName'"
Write-Output "Adding LogOn Details"
$LogOnD.Change($null,$null,$null,$null,$null,$null,".$USERNAME","$MPass",$null,$null,$null)
Start-Sleep -seconds 5
$arrservice = (Get-Service $ServiceName)
Write-Output "Starting $ServiceName Service"
Start-Service -Name $arrservice.Name
$arrservice.WaitForStatus("Running")
Write-Output "$ServiceName Successfully Started."

Checking if CQ Package Manager is up and running, once ifs UP, install necessary packages

$count = 0

$success = $null
if ($AEMINST -eq "Author") {
Write-Output "Checking if CQ PackageMgr is UP"
do{
$HTCODE = cmd.exe /c curl -Is http://${CQ_USER}:${CQ_PASS}@${HOSTNAME}:${AEMPORT}/crx/packmgr/index.jsp | findstr "HTTP"
$RESCODE = $HTCODE | %{ $_.Split(' ')[1]; }
if ($RESCODE -eq 200) {
Write-Output ""
Write-Output "CQ PackageMgr Started"
$success = $true
}else {
Write-Host -NoNewLine "."
Start-sleep -Seconds 10
}
$count++
}until($count -eq 180 -or $RESCODE -eq 200)
if(-not($success)){
Write-Output "Timed Out or CQ $AEMINST Dint start Properly"
Write-Output "Package Installation Aborted."
Exit
}
}elseif ($AEMINST -eq "Publish") {
Write-Output "Checking if CQ PackageMgr is UP"
do{
$HTCODE = cmd.exe /c curl -Is http://${CQ_USER}:${CQ_PASS}@${HOSTNAME}:${AEMPORT}/crx/packmgr/index.jsp | findstr "HTTP"
$RESCODE = $HTCODE | %{ $_.Split(' ')[1]; }
if ($RESCODE -eq 200) {
Write-Output ""
Write-Output "CQ PackageMgr Started"
$success = $true
}else {
Write-Host -NoNewLine "."
Start-sleep -Seconds 10
}
$count++
}until($count -eq 50 -or $RESCODE -eq 200)
if(-not($success)){
Write-Output "Timed Out or CQ $AEMINST Dint start Properly"
Write-Output "Package Installation Aborted."
Exit
}
}

Installing AEM packages using cURL

Write-Output "Installing APPS Package"
cmd.exe /c $CURLEXE -u "${CQ_USER}:${CQ_PASS}" -F file=@"$PKGPATH01" -F name="aemgit.ui.apps" -F force=true -F install=false "$GCURL" | Out-Null
Write-Output "Package Installation Complete"

Checking if AEM is completely installed and running

$COUNTNAS = 0
$NASSuccess = $null

if ($AEMINST -eq "Author") {
Write-Output "Checking if CQ Author is UP"
do{
$CPCODE = cmd.exe /c curl -Is "http://${HOSTNAME}:${AEMPORT}/libs/granite/core/content/login.html" | findstr "HTTP"
$RESCPCODE = $CPCODE | %{ $_.Split(' ')[1]; }
if ($RESCPCODE -eq 200) {
Write-Output ""
Write-Output "CQ $AEMINST Started"
$NASSuccess = $true
}else {
Write-Host -NoNewLine "."
Start-sleep -Seconds 10
}
$COUNTNAS++
}until($COUNTNAS -eq 180 -or $RESCPCODE -eq 200)
if(-not($NASSuccess)){
Write-Output "Timed Out or CQ $AEMINST Dint start Properly"
Write-Output "Package Installation Aborted."
Exit
}
}elseif ($AEMINST -eq "Publish") {
Write-Output "Checking if CQ Publish is UP"
do{
$CPCODE = cmd.exe /c curl -Is "http://${HOSTNAME}:${AEMPORT}/libs/granite/core/content/login.html" | findstr "HTTP"
$RESCPCODE = $CPCODE | %{ $_.Split(' ')[1]; }
if ($RESCPCODE -eq 200) {
Write-Output ""
Write-Output "CQ $AEMINST Started"
$NASSuccess = $true
}else {
Write-Host -NoNewLine "."
Start-sleep -Seconds 10
}
$COUNTNAS++
}until($COUNTNAS -eq 50 -or $RESCPCODE -eq 200)
if(-not($NASSuccess)){
Write-Output "Timed Out or CQ $AEMINST Dint start Properly"
Write-Output "Package Installation Aborted."
Exit
}
}
Write-Output "AEM $AEMINST Installation Successfully Completed."

Adding NAS storage, checking if AEM is up, stopping AEM completely, then creating a symlink for AEM NAS datastore and copying to NAS and starting AEM

Write-Output "Commencing NAS Drive Setup for CQ $AEMINST"
$arrStatus = (Get-WmiObject -Class Win32_Service -Filter "Name='$ServiceName'").state
$AEMSERVICE = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($AEMSERVICE.status -eq 'Running') {
Write-Output "$ServiceName is Up and Running"
Write-Output "Stopping $ServiceName Service"
Stop-Service $ServiceName
$AEMSERVICE.WaitForStatus("Stopped")
Start-Sleep -seconds 60
Write-Output "$ServiceName Service Stopped"
Write-Output "Renaming the Datastore Directory"
Rename-Item -Path "${repository}\datastore" -NewName "${repository}\datastore-old" -Force
Write-Output "Creating SymbolicLink for Datastore"
New-Item -Path "${repository}\datastore" -ItemType SymbolicLink -Value "C:\Users\SKYDEVOPS\AEM\NAS\dr_$AEMINST" | Out-Null
Write-Output "Copying files from Datastore to NAS"
Get-ChildItem "${repository}\datastore-old" | Copy -Destination "${repository}\datastore" -Recurse -Force
Write-Output "Copying Complete."
Write-Output "Starting $ServiceName Service"
Start-Service -Name $ServiceName
$AEMSERVICE.WaitForStatus("Running")
Start-Sleep -seconds 120
Write-Output "$ServiceName Successfully Started."
}

Here is the final complete script
$ErrorActionPreference = "Stop"
$WarningPreference = "SilentlyContinue"
$AEMINST = Read-Host "Choose Author/Publish Instance to Setup [Author/Publish]"
$AEMPORT = Read-Host "Enter the CQ Port [4502/4503]"
$SRCPATH = "C:\Users\SKYDEVOPS\AEM\zinstaller"
$BASEPATH = "C:\Users\SKYDEVOPS\AEM\instances\$AEMINST"
$SERVICEPATH = "$BASEPATH\crx-quickstart\opt\helpers"
$JARFILE = "$SRCPATH\aem-$AEMINST-p$AEMPORT.jar"
$LicensePath = "$SRCPATH\license.properties"
$AEMUNPACK = "java -jar $JARFILE -unpack"
$ServiceName = "AEMPRD"
$USERNAME = "\SKYDEVOPS"
$HOSTNAME = "192.168.2.8"
$CQ_PORT = "4503"
$CQ_USER = "admin"
$CQ_PASS = "admin"
$CURLEXE = 'C:\tools\curl761\bin\curl.exe'
$GCURL = "http://${HOSTNAME}:${AEMPORT}/crx/packmgr/service.jsp"

$DOCUNSTORECFG = "org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.config"

$FILEDSTORECFG = "org.apache.jackrabbit.oak.plugins.blob.datastore.FiledataStore.config"

$PKGPATH01 = "$SRCPATH\aemgit.ui.apps-1.0-SNAPSHOT.zip"
$PKGPATH02 = "$SRCPATH\aemgit.ui.content-1.0-SNAPSHOT.zip"
$repository = "$BASEPATH\crx-quickstart\repository"

if (!(Test-Path -Path $BASEPATH)) {
Write-Output "$AEMINST Installation Directory Not Found"
Write-Output "Creating Folder at $BASEPATH"
New-Item -ItemType directory -Path $BASEPATH
Copy-Item -Path $LicensePath -Destination $BASEPATH
Set-Location -Path $BASEPATH
Write-Output ""
Write-Output "Unpacking $AEMINST"
Invoke-Expression -Command:"cmd.exe /c $AEMUNPACK"

if ($AEMINST -eq "Author") {
Write-Output "Creating INSTALL Folder"
New-Item -ItemType directory -Path "$BASEPATH\crx-quickstart\install"
Write-Output ""
Write-Output "Copying Configurations to Install Directory"

Copy-Item -Path "$SRCPATH\$DOCUNSTORECFG" -Destination "$BASEPATH\crx-quickstart\install"

Copy-Item -Path "$SRCPATH\$FILEDSTORECFG" -Destination "$BASEPATH\crx-quickstart\install"
}
Set-Location -Path "C:\Users\SKYDEVOPS\Documents\scripts"

}else {
Write-Output "$BASEPATH Exists"
Write-Output "Checking crx-quickstart Directory"
if (!(Test-Path -Path $BASEPATH\crx-quickstart)) {
Write-Output "crx-quickstart Not Found, Unpacking $AEMINST"
Set-Location -Path $BASEPATH
Write-Output "Unpacking $AEMINST"

Invoke-Expression -Command:"cmd.exe /c $AEMUNPACK"
if ($AEMINST -eq "Author") {
Write-Output "Creating INSTALL Folder"
New-Item -ItemType directory -Path "$BASEPATH\crx-quickstart\install"
Write-Output ""
Write-Output "Copying Configurations to Install Directory"
Copy-Item -Path "$SRCPATH\$DOCUNSTORECFG" -Destination "$BASEPATH\crx-quickstart\install"
Copy-Item -Path "$SRCPATH\$FILEDSTORECFG" -Destination "$BASEPATH\crx-quickstart\install"
}
}else {
Write-Output "crx-quickstart Found, Terminating Installation."
Set-Location -Path "C:\Users\SKYDEVOPS\Documents\scripts"
Exit
}
}

$AEMSERVICEPATH = "$BASEPATH\crx-quickstart\opt\helpers\instsrv.bat"
Rename-Item -Path "$AEMSERVICEPATH" -NewName "instsrv.bat.bak"
Copy-Item -Path "${SRCPATH}\instsrv-${AEMINST}.bat" -Destination "${SERVICEPATH}\instsrv.bat"
$AEMSERVICEPATH = "$BASEPATH\crx-quickstart\opt\helpers\instsrv.bat"
$AEMCommand = "$AEMSERVICEPATH $ServiceName"
$MPass="shashi"
Write-Output "Creating $ServiceName Service"
Invoke-Expression -Command:"cmd.exe /c $AEMCommand"
$LogOnD = Get-WmiObject -Class Win32_Service -Filter "Name='$ServiceName'"
Write-Output "Adding LogOn Details"
$LogOnD.Change($null,$null,$null,$null,$null,$null,".$USERNAME","$MPass",$null,$null,$null)
Start-Sleep -seconds 5
$arrservice = (Get-Service $ServiceName)
Write-Output "Starting $ServiceName Service"
Start-Service -Name $arrservice.Name
$arrservice.WaitForStatus("Running")
Write-Output "$ServiceName Successfully Started."
Write-Output "Waiting for AEM Services to Come Up"
# Start-Sleep -s 480
$count = 0
$success = $null
if ($AEMINST -eq "Author") {
Write-Output "Checking if CQ PackageMgr is UP"
do{
$HTCODE = cmd.exe /c curl -Is http://${CQ_USER}:${CQ_PASS}@${HOSTNAME}:${AEMPORT}/crx/packmgr/index.jsp | findstr "HTTP"
$RESCODE = $HTCODE | %{ $_.Split(' ')[1]; }
if ($RESCODE -eq 200) {
Write-Output ""
Write-Output "CQ PackageMgr Started"
$success = $true
}else {
Write-Host -NoNewLine "."
Start-sleep -Seconds 10
}
$count++
}until($count -eq 180 -or $RESCODE -eq 200)
if(-not($success)){
Write-Output "Timed Out or CQ $AEMINST Dint start Properly"
Write-Output "Package Installation Aborted."
Exit
}
}elseif ($AEMINST -eq "Publish") {
Write-Output "Checking if CQ PackageMgr is UP"
do{
$HTCODE = cmd.exe /c curl -Is http://${CQ_USER}:${CQ_PASS}@${HOSTNAME}:${AEMPORT}/crx/packmgr/index.jsp | findstr "HTTP"
$RESCODE = $HTCODE | %{ $_.Split(' ')[1]; }
if ($RESCODE -eq 200) {
Write-Output ""
Write-Output "CQ PackageMgr Started"
$success = $true
}else {
Write-Host -NoNewLine "."
Start-sleep -Seconds 10
}
$count++
}until($count -eq 50 -or $RESCODE -eq 200)
if(-not($success)){
Write-Output "Timed Out or CQ $AEMINST Dint start Properly"
Write-Output "Package Installation Aborted."
Exit
}
}
Write-Output "Installing APPS Package"
cmd.exe /c $CURLEXE -u "${CQ_USER}:${CQ_PASS}" -F file=@"$PKGPATH01" -F name="aemgit.ui.apps" -F force=true -F install=false "$GCURL" | Out-Null
Write-Output "Package Installation Complete"
$COUNTNAS = 0
$NASSuccess = $null
if ($AEMINST -eq "Author") {
Write-Output "Checking if CQ Author is UP"
do{
$CPCODE = cmd.exe /c curl -Is "http://${HOSTNAME}:${AEMPORT}/libs/granite/core/content/login.html" | findstr "HTTP"
$RESCPCODE = $CPCODE | %{ $_.Split(' ')[1]; }
if ($RESCPCODE -eq 200) {
Write-Output ""
Write-Output "CQ $AEMINST Started"
$NASSuccess = $true
}else {
Write-Host -NoNewLine "."
Start-sleep -Seconds 10
}
$COUNTNAS++
}until($COUNTNAS -eq 180 -or $RESCPCODE -eq 200)
if(-not($NASSuccess)){
Write-Output "Timed Out or CQ $AEMINST Dint start Properly"
Write-Output "Package Installation Aborted."
Exit
}
}elseif ($AEMINST -eq "Publish") {
Write-Output "Checking if CQ Publish is UP"
do{
$CPCODE = cmd.exe /c curl -Is "http://${HOSTNAME}:${AEMPORT}/libs/granite/core/content/login.html" | findstr "HTTP"
$RESCPCODE = $CPCODE | %{ $_.Split(' ')[1]; }
if ($RESCPCODE -eq 200) {
Write-Output ""
Write-Output "CQ $AEMINST Started"
$NASSuccess = $true
}else {
Write-Host -NoNewLine "."
Start-sleep -Seconds 10
}
$COUNTNAS++
}until($COUNTNAS -eq 50 -or $RESCPCODE -eq 200)
if(-not($NASSuccess)){
Write-Output "Timed Out or CQ $AEMINST Dint start Properly"
Write-Output "Package Installation Aborted."
Exit
}
}
Write-Output "AEM $AEMINST Installation Successfully Completed."
Write-Output "Commencing NAS Drive Setup for CQ $AEMINST"
$arrStatus = (Get-WmiObject -Class Win32_Service -Filter "Name='$ServiceName'").state
$AEMSERVICE = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($AEMSERVICE.status -eq 'Running') {
Write-Output "$ServiceName is Up and Running"
Write-Output "Stopping $ServiceName Service"
Stop-Service $ServiceName
$AEMSERVICE.WaitForStatus("Stopped")
Start-Sleep -seconds 60
Write-Output "$ServiceName Service Stopped"
Write-Output "Renaming the Datastore Directory"
Rename-Item -Path "${repository}\datastore" -NewName "${repository}\datastore-old" -Force
Write-Output "Creating SymbolicLink for Datastore"
New-Item -Path "${repository}\datastore" -ItemType SymbolicLink -Value "C:\Users\SKYDEVOPS\AEM\NAS\dr_$AEMINST" | Out-Null
Write-Output "Copying files from Datastore to NAS"
Get-ChildItem "${repository}\datastore-old" | Copy -Destination "${repository}\datastore" -Recurse -Force
Write-Output "Copying Complete."
Write-Output "Starting $ServiceName Service"
Start-Service -Name $ServiceName
$AEMSERVICE.WaitForStatus("Running")
Start-Sleep -seconds 120
Write-Output "$ServiceName Successfully Started."
}


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.