Generic RMM Deployment using PowerShell commands
Learn how to efficiently deploy remote monitoring and management (RMM) tools through PowerShell commands, streamlining the process and ensuring smooth implementation.
Table of Contents
Overview
This generic PowerShell script deploys the AutoElevate MSI Agent through Group Policy, Microsoft Intune, or any RMM tool that supports running PowerShell but doesn't yet have a dedicated CyberFOX deployment script for it (i.e., ConnectWise Automate, Datto RMM, Kaseya VSA, Syncro, N-able). It silently downloads and installs the latest AutoElevate Agent build, using a handful of variables you set at the top of the script to identify the license, company, and location the endpoint belongs to.
How It Works
Setting Your Variables
Read through the top section of the script and fill in your License Key, Company Name, Location Name, Elevation Mode, and Blocker Mode between the quotation marks (""). Company Initials is optional — leave it as the placeholder if you don't use it, and it will be skipped automatically.
The Script
The script downloads the current AutoElevate MSI Agent build directly from CyberFOX as part of the deployment, so you don't need to host or attach the installer yourself.
# Copyright (c) 2026 CyberFOX, LLC
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the names of CyberFOX, AutoElevate nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL CyberFOX, LLC. BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<#
.SYNOPSIS
Installs the AutoElevate agent using the License Key, Company Name, and Location supplied below.
.DIRECTIONS
Insert your license key below. Change the default agent mode if you desire
(audit, live, policy), and set the "Company Name" & "Location Name" that will be used to
"group" these assets. "Company Initials" is optional and may be left blank/placeholder.
This script is written so it can be deployed as-is from any RMM: set the values below
directly (RMMs that do raw text/variable substitution into the script body, e.g.
ConnectWise Automate-style templating, or manual per-tenant copies), or overwrite this
block programmatically before push if your RMM supports that instead.
#>
$LICENSE_KEY = "__LICENSE_KEY_HERE__"
$COMPANY_NAME = "__COMPANY_NAME_HERE__"
$COMPANY_INITIALS = "__COMPANY_INITIALS_HERE__"
$LOCATION_NAME = "__LOCATION_NAME_HERE__"
$ELEVATION_MODE = "audit"
$BLOCKER_MODE = "disabled"
# Set $DebugPrintEnabled = 1 to enable debug log printing to see what's going on.
$DebugPrintEnabled = 0
# You don't need to change anything below this line...
$InstallerName = "AESetup.msi"
$InstallerPath = Join-Path $Env:TEMP $InstallerName
$DownloadURL = "https://apollo.autoelevate.com/api/agentBuilds/latest/download/windows"
$ServiceName = "AutoElevateAgent"
$MsiExecPath = Join-Path $Env:SystemRoot "System32\msiexec.exe"
$ScriptFailed = "Script Failed!"
function Get-TimeStamp {
return "[{0:MM/dd/yy} {0:HH:mm:ss}]" -f (Get-Date)
}
function Confirm-ServiceExists ($service) {
if (Get-Service $service -ErrorAction SilentlyContinue) {
return $true
}
return $false
}
function Debug-Print ($msg) {
if ($DebugPrintEnabled -eq 1) {
Write-Host "$(Get-TimeStamp) [DEBUG] $msg"
}
}
function Get-Installer {
Debug-Print("Downloading installer from $DownloadURL...")
curl.exe -fL -o $InstallerPath $DownloadURL
if ($LASTEXITCODE -ne 0 -Or ! (Test-Path $InstallerPath)) {
$DownloadError = "Failed to download the AutoElevate Installer from $DownloadURL (curl exit code $LASTEXITCODE)"
Write-Host "$(Get-TimeStamp) $DownloadError"
throw $ScriptFailed
}
Debug-Print("Installer downloaded to $InstallerPath...")
}
function Install-Agent () {
Debug-Print("Checking for AutoElevateAgent service...")
if (Confirm-ServiceExists($ServiceName)) {
Write-Host "$(Get-TimeStamp) Service exists. Continuing with possible upgrade..."
}
else {
Write-Host "$(Get-TimeStamp) Service does not exist. Continuing with initial installation..."
}
Debug-Print("Checking for installer file...")
if ( ! (Test-Path $InstallerPath)) {
$InstallerError = "The installer was unexpectedly removed from $InstallerPath"
Write-Host "$(Get-TimeStamp) $InstallerError"
Write-Host ("$(Get-TimeStamp) A security product may have quarantined the installer. Please check " +
"your logs. If the issue continues to occur, please send the log to the AutoElevate " +
"Team for help at support@autoelevate.com")
throw $ScriptFailed
}
Debug-Print("Executing installer...")
$MsiArgs = @(
"/i", $InstallerName,
"/quiet",
"/lv", "AEInstallLog.log",
"LICENSE_KEY=""$LICENSE_KEY""",
"COMPANY_NAME=""$COMPANY_NAME""",
"LOCATION_NAME=""$LOCATION_NAME""",
"ELEVATION_MODE=""$ELEVATION_MODE""",
"BLOCKER_MODE=""$BLOCKER_MODE"""
)
if ($COMPANY_INITIALS -and $COMPANY_INITIALS -ne "__COMPANY_INITIALS_HERE__") {
$MsiArgs += "COMPANY_INITIALS=""$COMPANY_INITIALS"""
}
$Process = Start-Process $MsiExecPath -Wait -PassThru -WorkingDirectory $Env:TEMP -ArgumentList $MsiArgs
if ($Process.ExitCode -ne 0) {
$InstallError = "msiexec exited with code $($Process.ExitCode). Check $(Join-Path $Env:TEMP 'AEInstallLog.log') for details."
Write-Host "$(Get-TimeStamp) $InstallError"
throw $ScriptFailed
}
}
function Verify-Installation () {
Debug-Print("Verifying Installation...")
if ( ! (Confirm-ServiceExists($ServiceName))) {
$VerificationError = "The AutoElevateAgent service is not running. Installation failed!"
Write-Host "$(Get-TimeStamp) $VerificationError"
throw $ScriptFailed
}
}
function main () {
Debug-Print("Checking for LICENSE_KEY...")
if ($LICENSE_KEY -eq "__LICENSE_KEY_HERE__" -Or $LICENSE_KEY -eq "") {
Write-Warning "$(Get-TimeStamp) LICENSE_KEY not set, exiting script!"
exit 1
}
if ($COMPANY_NAME -eq "__COMPANY_NAME_HERE__" -Or $COMPANY_NAME -eq "") {
Write-Warning "$(Get-TimeStamp) COMPANY_NAME not specified, exiting script!"
exit 1
}
if ($LOCATION_NAME -eq "__LOCATION_NAME_HERE__" -Or $LOCATION_NAME -eq "") {
Write-Warning "$(Get-TimeStamp) LOCATION_NAME not specified, exiting script!"
exit 1
}
Write-Host "$(Get-TimeStamp) CompanyName: " $COMPANY_NAME
if ($COMPANY_INITIALS -and $COMPANY_INITIALS -ne "__COMPANY_INITIALS_HERE__") {
Write-Host "$(Get-TimeStamp) CompanyInitials: " $COMPANY_INITIALS
}
Write-Host "$(Get-TimeStamp) LocationName: " $LOCATION_NAME
Write-Host "$(Get-TimeStamp) ElevationMode: " $ELEVATION_MODE
Write-Host "$(Get-TimeStamp) BlockerMode: " $BLOCKER_MODE
Get-Installer
Install-Agent
Verify-Installation
Write-Host "$(Get-TimeStamp) AutoElevate Agent successfully installed!"
}
try
{
main
} catch {
$ErrorMessage = $_.Exception.Message
Write-Host "$(Get-TimeStamp) $ErrorMessage"
exit 1
}
Best Practices
-
Enable debug logging while validating a new deployment. Set
$DebugPrintEnabled = 1at the top of the script to print step-by-step progress to the console, then set it back to0before rolling out to production endpoints. -
Check
AEInstallLog.logafter any failed run before opening a support ticket. It's written to the same temp working directory the installer runs from (%TEMP%) and will usually show the MSI-level cause of a failure. - Pilot on a single test endpoint before a full rollout. Push the script through your RMM to one test machine first, to confirm the License Key / Company / Location values route the asset to the correct AutoElevate Admin Portal group before deploying to a full site or client.
-
Start new tenant deployments in
auditElevation Mode to collect events for rule creation in the Admin Portal. Once you’ve established a solid ruleset, switch the tenant toliveElevation Mode.
Troubleshooting
Installer fails to download
The script throws “Failed to download the AutoElevate Installer...” and stops. This usually means the endpoint can't reach the download URL — confirm outbound HTTPS access to apollo.autoelevate.com isn't blocked by a firewall or proxy.
Installer file is missing right before install
The script throws “The installer was unexpectedly removed from [path]”, along with a note that a security product may have quarantined the installer. Check your antivirus/EDR quarantine log, and add an exclusion for %TEMP%\AESetup.msi if needed. If the issue continues, the script points admins to support@autoelevate.com.
MSI install exits with a non-zero code
The script throws “msiexec exited with code [code]”. Check AEInstallLog.log in %TEMP% on the endpoint for the specific MSI-level error before re-running.
Script exits immediately with a "not set" warning
If LICENSE_KEY, COMPANY_NAME, or LOCATION_NAME is left at its placeholder value (or blank), the script warns and exits before attempting anything. Double-check the top section of the script was actually edited for this deployment.
Security Notes
-
Elevation Mode defaults to
audit. Audit mode logs elevation events without granting live privilege changes — switch toliveonly once you've reviewed audit output for the tenant, and topolicyif you're driving elevation from AutoElevate rules instead. - The script always installs the latest published Agent build. The download URL points at CyberFOX's "latest" build endpoint rather than a pinned version, so re-running this script on an existing install will upgrade the agent in place.
-
Install log location: the MSI install log (
AEInstallLog.log) is written to the same temp working directory the installer runs from, not a fixed path — check%TEMP%on the endpoint if you need to review it. - Company Name, Company Initials, and Location Name are used only to group and label assets in the AutoElevate Admin Portal — they don't affect enforcement.