Automating AEM Installation using Powershell

DISCLAIMER
If you require any more information or have any questions about our site’s disclaimer, please feel free to contact us by email at admin@skydevops.in
All the information on this website – https://skydevops.wordpress.com – is published in good faith and for general information purpose only. SKYDEVOPS does not make any warranties about the completeness, reliability and accuracy of this information. Any action you take upon the information you find on this website (skydevops), is strictly at your own risk.
SKYDEVOPS will not be liable for any losses and/or damages in connection with the use of our website.
From our website, you can visit other websites by following hyperlinks to such external sites. While we strive to provide only quality links to useful and ethical websites, we have no control over the content and nature of these sites. These links to other websites do not imply a recommendation for all the content found on these sites. Site owners and content may change without notice and may occur before we have the opportunity to remove a link which may have gone ‘bad’.
Please be also aware that when you leave our website, other sites may have different privacy policies and terms which are beyond our control. Please be sure to check the Privacy Policies of these sites as well as their “Terms of Service” before engaging in any business or uploading any information.
CONSENT
By using our website, you hereby consent to our disclaimer and agree to its terms.
UPDATE
Should we update, amend or make any changes to this document, those changes will be prominently posted here.
-== & ==-
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 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 nad 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." }