Deploy Elastic Agent 8.3.2 via Windows GPO


The following is a working PowerShell script to deploy Elastic Agent to Windows workstations via Group Policy 'Startup Script'. Group Policy service by default does not include the permission for it to create SymLinks so the PowerShell script adds this privilege to those requested when starting scripts.

Creates HKLM\SOFTWARE\Admin_Scripts\ElasticAgent when installed, to avoid constantly recopying files.

GPO settings are as simple as it gets:

I prefer placing smaller deployment tools on the replicated netlogon share. The script copies the content to the local workstation and then installs and registers the agent:

# Variables:
$Source       = "\\\netlogon\ElasticAgent\elastic-agent-8.3.2-windows-x86_64"
$Destination  = "$env:temp\ElasticAgent"
$RegistryHive = "HKLM:\\SOFTWARE"
$RegistryKey  = "Admin_Scripts"
$ScriptName   = "ElasticAgent"

# Group Policies are installed via the gpsvc service, extend rights so that it can create symbolic links and install it next time:
$perm = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\gpsvc").RequiredPrivileges;
If ($perm -NotContains "SeCreateSymbolicLinkPrivilege") {
	$perm = $perm + "SeCreateSymbolicLinkPrivilege";
	Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\gpsvc" -Name RequiredPrivileges -Value $perm -Type MultiString;
	Exit 1

# Make non-terminating errors terminating.
Trap {
	Write-Error $_ -ErrorAction Continue
	Exit 1
$ErrorActionPreference = 'Stop'

function GetAgent {
	If (!(Test-Path "$env:temp\ElasticAgent")) {
		New-Item -Path $env:temp -Name $ScriptName -ItemType "directory" | Out-Null
	Start-Transcript -Path $Destination"\"install_log.txt -Append -IncludeInvocationHeader
	If (!(Test-Path $Source) -Or !(Test-Path $Destination)) { Throw "$Source and/or $Destination folders are invalid." }
	Copy-Item -Path "$Source\*" -Destination $Destination -Recurse -Force
	If (!(Test-Path $Destination"\elastic-agent.exe")) { Throw "Copy failed." }

function InstallAgent {
	cd $Destination
	$ErrorActionPreference = 'Continue'
	.\elastic-agent.exe install --force --url= --enrollment-token=***************************************** 2>&1 | Out-Default
	if ($LastExitCode -ne 0) { Throw "Installation failed." }
	$ErrorActionPreference = 'Stop'
	cd ..
	Start-Sleep -Seconds 5

If (Test-Path $RegistryHive"\"$RegistryKey) {
	$reg = Get-Itemproperty -Path $RegistryHive"\"$RegistryKey -Name $ScriptName -ErrorAction SilentlyContinue
If (!($reg)) {
	If (!(Test-Path $RegistryHive"\"$RegistryKey)) {
		New-Item -Path $RegistryHive -Name $RegistryKey | Out-Null
	New-ItemProperty -Path $RegistryHive"\"$RegistryKey -Name $ScriptName -Value "1" -PropertyType "DWord" -Force | Out-Null
	Remove-Item -Force -Recurse $Destination
Exit 0

Kept stumbling in to the following post which provided the base structure of the script I hacked together: