├── .github └── workflows │ ├── codacy.yml │ └── powershell.yml ├── .gitignore ├── Addigy ├── InstallHuntress-macOS-Addigy.sh ├── README.md └── facts │ ├── agent.sh │ ├── fda.sh │ └── sysext.sh ├── Atera ├── InstallHuntress-macOS-Atera.sh └── README.md ├── Bash ├── HuntressSystemExtensionProfile.mobileconfig ├── InstallHuntress-macOS-bash.sh ├── MicrosoftDefenderForEndpoint │ └── mdatp.mobileconfig ├── README.md ├── legacy-mobileconfigs │ ├── Huntress PPPC.mobileconfig │ ├── HuntressLegacyAgentProfile.mobileconfig │ └── README.md └── mdm_overrides_parser.sh ├── ConnectWise-Automate ├── Huntress Agent Install script - Download.xml ├── Monitors │ ├── Endpoints with Huntress Agents installed Group with Monitors, searches, and groups.xml │ ├── Huntress Service Remote Monitor │ │ └── README.md │ ├── Orpaned Agent Remote Monitor │ │ ├── CWA Orphan monitor powershell code │ │ ├── README.md │ │ └── raw code.ps1 │ ├── Searches │ │ ├── Computer.Application.Name Contains Huntress.xml │ │ └── README.md │ └── readme.md ├── README.md ├── Reinstall │ ├── README.md │ └── Update Huntress Agent - Download.xml └── staged │ ├── Huntress Agent Install - Download.xml │ ├── Huntress Agent Install script.xml │ ├── InstallHuntress.automate.ps1 │ └── README.md ├── ConnectWise-Control └── InstallHuntress.ConnectWiseControl.ps1 ├── Continuum ├── InstallHuntress.continuum.2008.ps1 ├── InstallHuntress.continuum.ps1 └── README.md ├── Datto-RMM ├── Huntress Agent Deployment WIN.cpt ├── Mac │ ├── .gitattributes │ ├── InstallHuntress-macOS-DattoRmm.cpt │ ├── command.bat │ ├── icon.png │ └── resource.xml ├── README.md ├── images │ ├── AEM - Completed Job - Agents.png │ ├── AEM - Completed Job - Tab - marked.png │ ├── AEM - Completed Job - Tab.png │ ├── AEM - Component - Just Imported - script section.png │ ├── AEM - Component - Just Imported.png │ ├── AEM - Component - KEY variable.png │ ├── AEM - Component - Replace KEY in script.png │ ├── AEM - Component - Save Component.png │ ├── AEM - Import Component Button.png │ ├── AEM - Import Component Window.png │ ├── AEM - Job - Component Selected.png │ ├── AEM - Job - Name Job and Add Component.png │ ├── AEM - Job - Name Scheduled Component and Populate ORG_KEY.png │ ├── AEM - Job - ORG_KEY ChangeMe.png │ ├── AEM - Job - Save.png │ ├── AEM - Job - Select Component.png │ ├── AEM - Job - Set ORG_KEY.png │ ├── AEM - Run Job Now.png │ └── AEM - Sites - Select Site to Schedule Job.png └── scripts │ ├── Archive │ ├── Huntress Agent Deployment WIN.cpt │ └── InstallHuntress.dattormm - April 2020.ps1 │ ├── InstallHuntress.dattormm.comstore.ps1 │ └── README.md ├── Kaseya ├── .gitattributes ├── InstallHuntress-macOS-Kaseya.xml └── Procedure Huntress Agent Deployment.xml ├── Mosyle ├── InstallHuntress-macOS-Mosyle.sh └── README.md ├── N-able (SolarWinds) N-central ├── 2.4.1.9 │ ├── Huntress Deployment Policy.amp │ └── Readme.md ├── Huntress Agent Deployment.amp ├── InstallHuntress-macOS-nable.sh ├── README.md └── powershell │ └── InstallHuntress.powershellv2.ps1 ├── Naverisk ├── Huntress Labs - Install Huntress Agent.nsp └── README.md ├── Ninja-RMM ├── .gitattributes ├── InstallHuntress-macOS-NinjaRMM.sh └── README.md ├── Powershell ├── InstallHuntress.bat ├── InstallHuntress.powershellv1.ps1 ├── InstallHuntress.powershellv2.ps1 ├── Legacy │ ├── InstallHuntress.bat │ └── InstallHuntress.powershellv1.ps1 ├── README.md ├── gpo_startup.png └── gpo_startup_script.png ├── README.md ├── SentinelOne └── syslog_huntress_io.crt ├── SolarwindsRMM ├── Huntress N-able Deployment Script.amp ├── README.md └── scripts │ ├── InstallHuntress.SolarWindsRMM.ps1 │ └── README.md └── Syncro ├── InstallHuntress-macOS-Syncro.sh ├── InstallHuntress.syncro.ps1 └── README.md /.github/workflows/codacy.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | # This workflow checks out code, performs a Codacy security scan 7 | # and integrates the results with the 8 | # GitHub Advanced Security code scanning feature. For more information on 9 | # the Codacy security scan action usage and parameters, see 10 | # https://github.com/codacy/codacy-analysis-cli-action. 11 | # For more information on Codacy Analysis CLI in general, see 12 | # https://github.com/codacy/codacy-analysis-cli. 13 | 14 | name: Codacy Security Scan 15 | 16 | on: 17 | push: 18 | branches: [ "main" ] 19 | pull_request: 20 | # The branches below must be a subset of the branches above 21 | branches: [ "main" ] 22 | schedule: 23 | - cron: '38 15 * * 5' 24 | 25 | permissions: 26 | contents: read 27 | 28 | jobs: 29 | codacy-security-scan: 30 | permissions: 31 | contents: read # for actions/checkout to fetch code 32 | security-events: write # for github/codeql-action/upload-sarif to upload SARIF results 33 | actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status 34 | name: Codacy Security Scan 35 | runs-on: ubuntu-latest 36 | steps: 37 | # Checkout the repository to the GitHub Actions runner 38 | - name: Checkout code 39 | uses: actions/checkout@v3 40 | 41 | # Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis 42 | - name: Run Codacy Analysis CLI 43 | uses: codacy/codacy-analysis-cli-action@d840f886c4bd4edc059706d09c6a1586111c540b 44 | with: 45 | # Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository 46 | # You can also omit the token and run the tools that support default configurations 47 | project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} 48 | verbose: true 49 | output: results.sarif 50 | format: sarif 51 | # Adjust severity of non-security issues 52 | gh-code-scanning-compat: true 53 | # Force 0 exit code to allow SARIF file generation 54 | # This will handover control about PR rejection to the GitHub side 55 | max-allowed-issues: 2147483647 56 | 57 | # Upload the SARIF file generated in the previous step 58 | - name: Upload SARIF results file 59 | uses: github/codeql-action/upload-sarif@v2 60 | with: 61 | sarif_file: results.sarif 62 | -------------------------------------------------------------------------------- /.github/workflows/powershell.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | # 6 | # https://github.com/microsoft/action-psscriptanalyzer 7 | # For more information on PSScriptAnalyzer in general, see 8 | # https://github.com/PowerShell/PSScriptAnalyzer 9 | 10 | name: PSScriptAnalyzer 11 | 12 | on: 13 | push: 14 | branches: [ "main" ] 15 | pull_request: 16 | branches: [ "main" ] 17 | schedule: 18 | - cron: '23 10 * * 2' 19 | 20 | permissions: 21 | contents: read 22 | 23 | jobs: 24 | build: 25 | permissions: 26 | contents: read # for actions/checkout to fetch code 27 | security-events: write # for github/codeql-action/upload-sarif to upload SARIF results 28 | actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status 29 | name: PSScriptAnalyzer 30 | runs-on: ubuntu-latest 31 | steps: 32 | - uses: actions/checkout@v3 33 | 34 | - name: Run PSScriptAnalyzer 35 | uses: microsoft/psscriptanalyzer-action@6b2948b1944407914a58661c49941824d149734f 36 | with: 37 | # Check https://github.com/microsoft/action-psscriptanalyzer for more info about the options. 38 | # The below set up runs PSScriptAnalyzer to your entire repository and runs some basic security rules. 39 | path: .\ 40 | recurse: true 41 | # Include your own basic security rules. Removing this option will run all the rules 42 | includeRule: '"PSAvoidGlobalAliases", "PSAvoidUsingConvertToSecureStringWithPlainText"' 43 | output: results.sarif 44 | 45 | # Upload the SARIF file generated in the previous step 46 | - name: Upload SARIF results file 47 | uses: github/codeql-action/upload-sarif@v2 48 | with: 49 | sarif_file: results.sarif 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### macOS ### 2 | *.DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | 6 | # Icon must end with two \r 7 | Icon 8 | 9 | # Thumbnails 10 | ._* 11 | 12 | # Files that might appear in the root of a volume 13 | .DocumentRevisions-V100 14 | .fseventsd 15 | .Spotlight-V100 16 | .TemporaryItems 17 | .Trashes 18 | .VolumeIcon.icns 19 | .com.apple.timemachine.donotpresent 20 | 21 | # Directories potentially created on remote AFP share 22 | .AppleDB 23 | .AppleDesktop 24 | Network Trash Folder 25 | Temporary Items 26 | .apdisk 27 | 28 | # Other 29 | .idea 30 | -------------------------------------------------------------------------------- /Addigy/InstallHuntress-macOS-Addigy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #shellcheck disable=SC2181,SC2295,SC2116 3 | 4 | # Copyright (c) 2024 Huntress Labs, Inc. 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # * Neither the name of the Huntress Labs nor the names of its contributors 15 | # may be used to endorse or promote products derived from this software 16 | # without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL HUNTRESS LABS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 24 | # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | 30 | # The Huntress installer needs an Account Key and an Organization Key (a user 31 | # specified name or description) which is used to affiliate an Agent with a 32 | # specific Organization within the Huntress Partner's Account. These keys can be 33 | # hard coded below or passed in when the script is run. 34 | 35 | # For more details, see our KB article 36 | # https://support.huntress.io/hc/en-us/articles/25013857741331-Critical-Steps-for-Complete-macOS-EDR-Deployment 37 | 38 | 39 | ##################################################################################### 40 | ## 41 | ## Begin user modified variables. Modify per documentation before running in Addigy. 42 | ## 43 | ##################################################################################### 44 | 45 | 46 | # Replace __ACCOUNT_KEY__ with your account secret key (from your Huntress portal's "download agent" section) 47 | defaultAccountKey="__ACCOUNT_KEY__" 48 | 49 | # If the organization key is passed as a parameter, it will be used instead of this defaultOrgKey variable. 50 | # If you have a preferred "placeholder" organization name for Mac agents, you can set that below. 51 | defaultOrgKey="__ORGANIZATION_KEY__" 52 | 53 | # Option to install the system extension after the Huntress Agent is installed. In order for this to happen 54 | # without security prompts on the endpoint, permissions need to be applied to the endpoint by Addigy before this script 55 | # is run. See the following KB article for more information: 56 | # https://support.huntress.io/hc/en-us/articles/21286543756947-Instructions-for-the-MDM-Configuration-for-macOS 57 | install_system_extension=true 58 | 59 | ############################################################################## 60 | ## In many multitenant environments, the Top-Level Addigy Policy name 61 | ## matches the name of each Organization. If you wish to dynamically use the 62 | ## Top-Level policy name as your Organization Name, you can pull the 63 | ## $POLICY_PATH environment variable from Addigy's Policy pipeline. 64 | ## 65 | ## For this method, comment line 51 above and uncomment lines 62-63 below. 66 | ############################################################################## 67 | 68 | # topLevelPolicy=$(echo ${POLICY_PATH} | awk -F ' \\| ' '{print $1}') 69 | # defaultOrgKey="$topLevelPolicy" 70 | 71 | ############################################################################## 72 | ## Do not modify anything below this line 73 | ############################################################################## 74 | dd=$(date "+%Y%m%d-%H%M%S") 75 | log_file="/tmp/HuntressInstaller.log" 76 | install_script="/tmp/HuntressMacInstall.sh" 77 | invalid_key="Invalid account secret key" 78 | pattern="[a-f0-9]{32}" 79 | rmm="Addigy macOS deployment script" 80 | version="1.3 - March 25, 2025" 81 | 82 | ## Using logger function to provide helpful logs within RMM tools in addition to log file 83 | logger() { 84 | echo "$dd -- $*"; 85 | echo "$dd -- $*" >> $log_file; 86 | } 87 | 88 | # Check for root 89 | if [ $EUID -ne 0 ]; then 90 | logger "This script must be run as root, exiting..." 91 | exit 1 92 | fi 93 | 94 | # Clean up any old installer scripts. 95 | if [ -f "$install_script" ]; then 96 | logger "Installer file present in /tmp; deleting." 97 | rm -f "$install_script" 98 | fi 99 | 100 | # Log policy path if Addigy policies are being. Useful for troubleshooting 101 | if [ -n "$topLevelPolicy" ]; then 102 | logger "Policy Path: ${POLICY_PATH}" 103 | logger "Policy Path (base64): $(echo ${POLICY_PATH} | base64)" 104 | logger "Top Level Policy: $topLevelPolicy" 105 | fi 106 | 107 | ## 108 | ## This section handles the assigning `=` character for options. 109 | ## Since most RMMs treat spaces as delimiters in Mac Scripting, 110 | ## we have to use `=` to assign the option value, but must remove 111 | ## it because, well, bash. https://stackoverflow.com/a/28466267/519360 112 | ## 113 | 114 | usage() { 115 | cat < --organization_key= 117 | 118 | -a, --account_key The account key to use for this agent install 119 | -o, --organization_key The org key to use for this agent install 120 | -h, --help Print this message 121 | 122 | EOF 123 | } 124 | 125 | while getopts a:o:h:-: OPT; do 126 | if [ "$OPT" = "-" ]; then 127 | OPT="${OPTARG%%=*}" # extract long option name 128 | OPTARG="${OPTARG#$OPT}" # extract long option argument (may be empty) 129 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 130 | else 131 | # the user used a short option, but we still want to strip the assigning `=` 132 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 133 | fi 134 | case "$OPT" in 135 | a | account_key) 136 | account_key="$OPTARG" 137 | ;; 138 | o | organization_key) 139 | organization_key="$OPTARG" 140 | ;; 141 | h | help) 142 | usage 143 | ;; 144 | ??*) 145 | logger "Illegal option --$OPT" 146 | exit 2 147 | ;; # bad long option 148 | \? ) 149 | exit 2 150 | ;; # bad short option (error reported via getopts) 151 | esac 152 | done 153 | shift $((OPTIND-1)) # remove parsed options and args from $@ list 154 | 155 | logger "=========== INSTALL START AT $dd ===============" 156 | logger "=========== $rmm | Version: $version ===============" 157 | 158 | # VALIDATE OPTIONS PASSED TO SCRIPT 159 | if [ -z "$organization_key" ]; then 160 | organizationKey=$(echo "$defaultOrgKey" | xargs) 161 | logger "--organization_key parameter not present, using defaultOrgKey instead: $defaultOrgKey" 162 | else 163 | organizationKey=$(echo "$organization_key" | xargs) 164 | logger "--organization_key parameter present, set to: $organizationKey" 165 | fi 166 | 167 | if ! [[ "$account_key" =~ $pattern ]]; then 168 | logger "Missing --account_key parameter, switching to use defaultAccountKey..." 169 | accountKey=$(echo "$defaultAccountKey" | xargs) 170 | if ! [[ $accountKey =~ $pattern ]]; then 171 | logger "ERROR: Invalid account_key provided. Please check Huntress support documentation." 172 | exit 1 173 | fi 174 | else 175 | accountKey=$(echo "$account_key" | xargs) 176 | fi 177 | 178 | # OPTIONS REQUIRED 179 | if [ -z "$accountKey" ] || [ -z "$organizationKey" ] 180 | then 181 | logger "Error: --account_key and --organization_key are both required" 182 | echo 183 | usage 184 | exit 1 185 | fi 186 | 187 | # Hide most of the account key in the logs, keeping the front and tail end for troubleshooting 188 | masked="$(echo "${accountKey:0:4}")" 189 | masked+="************************" 190 | masked+="$(echo "${accountKey: (-4)}")" 191 | 192 | logger "Provided Huntress key: $masked" 193 | logger "Provided Organization Key: $organizationKey" 194 | 195 | result=$(curl -w "%{http_code}" -L "https://huntress.io/script/darwin/$accountKey" -o "$install_script") 196 | 197 | if [ $? != "0" ]; then 198 | logger "ERROR: Download failed with error: $result" 199 | exit 1 200 | fi 201 | 202 | if grep -Fq "$invalid_key" "$install_script"; then 203 | logger "ERROR: --account_key is invalid. You entered: $accountKey" 204 | exit 1 205 | fi 206 | 207 | logger "=============== Begin Installer Logs ===============" 208 | if [ "$install_system_extension" = true ]; then 209 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -v --install_system_extension)" 210 | else 211 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -v)" 212 | fi 213 | 214 | if [ $? != "0" ]; then 215 | logger "Installer Error: $install_result" 216 | exit 1 217 | fi 218 | 219 | logger "$install_result" 220 | logger "=========== INSTALL FINISHED AT $dd ===============" 221 | exit 222 | -------------------------------------------------------------------------------- /Addigy/README.md: -------------------------------------------------------------------------------- 1 | ### Deploying the Huntress macOS Agent with Addigy 2 | 3 | This script will install the Huntress macOS Agent. For full usage details please see our support [documentation](https://support.huntress.io/hc/en-us/articles/9151297797907). 4 | -------------------------------------------------------------------------------- /Addigy/facts/agent.sh: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | declare -a HuntressDaemons=("HuntressAgent" "HuntressUpdater" "Huntress") 3 | 4 | for i in "${HuntressDaemons[@]}"; do 5 | pgrep -x "$i" >/dev/null 6 | daemon_status=$? 7 | if [ "$daemon_status" != "0" ]; then 8 | echo "No - Service $i is not running" 9 | exit 10 | fi 11 | done; 12 | 13 | if [ ! -d "/Library/Application Support/Huntress" ]; then 14 | echo "No - App Support Dir missing" 15 | exit 16 | fi 17 | 18 | echo "Yes" -------------------------------------------------------------------------------- /Addigy/facts/fda.sh: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | 3 | out=$(sqlite3 -line "/Library/Application Support/com.apple.TCC/TCC.db" "SELECT * FROM access where client == 'com.huntress.app';" | grep service | awk '{print $3}') 4 | if [[ $out != "kTCCServiceSystemPolicyAllFiles" ]]; then 5 | echo "No - com.huntress.app does not have Full Disk Access" 6 | exit 7 | fi 8 | 9 | out=$(sqlite3 -line "/Library/Application Support/com.apple.TCC/TCC.db" "SELECT * FROM access where client == 'com.huntress.sysext';" | grep service | awk '{print $3}') 10 | if [[ $out != "kTCCServiceSystemPolicyAllFiles" ]]; then 11 | echo "No - com.huntress.sysext does not have Full Disk Access" 12 | exit 13 | fi 14 | 15 | echo "Yes" -------------------------------------------------------------------------------- /Addigy/facts/sysext.sh: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | output=$(/Applications/Huntress.app/Contents/MacOS/Huntress extensionctl status) 3 | 4 | if [[ $output != *"Extension Status: installed"* ]]; then 5 | echo "No - Extension Not Installed"; 6 | exit 7 | fi 8 | 9 | if [[ $output != *"Full Disk Access for Extension: enabled"* ]]; then 10 | echo "No - Full Disk Access not granted for Extension" 11 | exit 12 | fi; 13 | 14 | if [[ $output != *"EDR: enabled"* ]]; then 15 | echo "No - EDR is not Enabled" 16 | exit 17 | fi; 18 | 19 | if [[ $output != *"Preauthorization Status: granted"* ]]; then 20 | echo "No - Preauthorization not granted" 21 | exit 22 | fi 23 | 24 | echo "Yes" 25 | -------------------------------------------------------------------------------- /Atera/InstallHuntress-macOS-Atera.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #shellcheck disable=SC2181,SC2295,SC2116 3 | 4 | # Copyright (c) 2022 Huntress Labs, Inc. 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # * Neither the name of the Huntress Labs nor the names of its contributors 15 | # may be used to endorse or promote products derived from this software 16 | # without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL HUNTRESS LABS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 24 | # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | 30 | # The Huntress installer needs an Account Key and an Organization Key (a user 31 | # specified name or description) which is used to affiliate an Agent with a 32 | # specific Organization within the Huntress Partner's Account. These keys can be 33 | # hard coded below or passed in when the script is run. 34 | 35 | # For more details, see our KB article 36 | # https://support.huntress.io/hc/en-us/articles/25013857741331-Critical-Steps-for-Complete-macOS-EDR-Deployment 37 | 38 | 39 | ############################################################################## 40 | ## Begin user modified variables 41 | ############################################################################## 42 | 43 | 44 | # Replace __ACCOUNT_KEY__ with your account secret key (from your Huntress portal's "download agent" section) 45 | defaultAccountKey="__ACCOUNT_KEY__" 46 | 47 | # If you have a preferred "placeholder" organization name for Mac agents, you can set that below. 48 | # Otherwise, provide the appropriate Organization Key when running the script in Atera. 49 | defaultOrgKey="{[huntress_orgkey]}" 50 | 51 | # Option to install the system extension after the Huntress Agent is installed. In order for this to happen 52 | # without security prompts on the endpoint, permissions need to be applied to the endpoint by Addigy before this script 53 | # is run. See the following KB article for more information: 54 | # https://support.huntress.io/hc/en-us/articles/21286543756947-Instructions-for-the-MDM-Configuration-for-macOS 55 | install_system_extension=true 56 | 57 | ############################################################################## 58 | ## Do not modify anything below this line 59 | ############################################################################## 60 | dd=$(date "+%Y%m%d-%H%M%S") 61 | log_file="/tmp/HuntressInstaller.log" 62 | install_script="/tmp/HuntressMacInstall.sh" 63 | invalid_key="Invalid account secret key" 64 | pattern="[a-f0-9]{32}" 65 | rmm="Atera macOS deployment script" 66 | version="1.1 - March 25, 2025" 67 | 68 | ## Using logger function to provide helpful logs within RMM tools in addition to log file 69 | logger() { 70 | echo "$dd -- $*"; 71 | echo "$dd -- $*" >> $log_file; 72 | } 73 | 74 | # Check for root 75 | if [ $EUID -ne 0 ]; then 76 | logger "This script must be run as root, exiting..." 77 | exit 1 78 | fi 79 | 80 | # Clean up any old installer scripts. 81 | if [ -f "$install_script" ]; then 82 | logger "Installer file present in /tmp; deleting." 83 | rm -f "$install_script" 84 | fi 85 | 86 | ## 87 | ## This section handles the assigning `=` character for options. 88 | ## Since most RMMs treat spaces as delimiters in Mac Scripting, 89 | ## we have to use `=` to assign the option value, but must remove 90 | ## it because, well, bash. https://stackoverflow.com/a/28466267/519360 91 | ## 92 | 93 | usage() { 94 | cat < --organization_key= 96 | 97 | -a, --account_key The account key to use for this agent install 98 | -o, --organization_key The org key to use for this agent install 99 | -h, --help Print this message 100 | 101 | EOF 102 | } 103 | 104 | while getopts a:o:h:-: OPT; do 105 | if [ "$OPT" = "-" ]; then 106 | OPT="${OPTARG%%=*}" # extract long option name 107 | OPTARG="${OPTARG#$OPT}" # extract long option argument (may be empty) 108 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 109 | else 110 | # the user used a short option, but we still want to strip the assigning `=` 111 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 112 | fi 113 | case "$OPT" in 114 | a | account_key) 115 | account_key="$OPTARG" 116 | ;; 117 | o | organization_key) 118 | organization_key="$OPTARG" 119 | ;; 120 | h | help) 121 | usage 122 | ;; 123 | ??*) 124 | logger "Illegal option --$OPT" 125 | exit 2 126 | ;; # bad long option 127 | \? ) 128 | exit 2 129 | ;; # bad short option (error reported via getopts) 130 | esac 131 | done 132 | shift $((OPTIND-1)) # remove parsed options and args from $@ list 133 | 134 | logger "=========== INSTALL START AT $dd ===============" 135 | logger "=========== $rmm | Version: $version ===============" 136 | 137 | # VALIDATE OPTIONS PASSED TO SCRIPT 138 | if [ -z "$organization_key" ]; then 139 | organizationKey=$(echo "$defaultOrgKey" | xargs) 140 | logger "--organization_key parameter not present, using defaultOrgKey instead: $defaultOrgKey" 141 | else 142 | organizationKey=$(echo "$organization_key" | xargs) 143 | logger "--organization_key parameter present, set to: $organizationKey" 144 | fi 145 | 146 | if ! [[ "$account_key" =~ $pattern ]]; then 147 | logger "Invalid --account_key provided, checking defaultAccountKey..." 148 | accountKey=$(echo "$defaultAccountKey" | xargs) 149 | if ! [[ $accountKey =~ $pattern ]]; then 150 | logger "ERROR: Invalid --account_key. Please check Huntress support documentation." 151 | exit 1 152 | fi 153 | else 154 | accountKey=$(echo "$account_key" | xargs) 155 | fi 156 | 157 | # OPTIONS REQUIRED 158 | if [ -z "$accountKey" ] || [ -z "$organizationKey" ] 159 | then 160 | logger "Error: --account_key and --organization_key are both required" >> $log_file 161 | echo 162 | usage 163 | exit 1 164 | fi 165 | 166 | # Hide most of the account key in the logs, keeping the front and tail end for troubleshooting 167 | masked="$(echo "${accountKey:0:4}")" 168 | masked+="************************" 169 | masked+="$(echo "${accountKey: (-4)}")" 170 | 171 | logger "Provided Huntress key: $masked" 172 | logger "Provided Organization Key: $organizationKey" 173 | 174 | result=$(curl -w "%{http_code}" -L "https://huntress.io/script/darwin/$accountKey" -o "$install_script") 175 | 176 | if [ $? != "0" ]; then 177 | logger "ERROR: Download failed with error: $result" 178 | exit 1 179 | fi 180 | 181 | if grep -Fq "$invalid_key" "$install_script"; then 182 | logger "ERROR: --account_key is invalid. You entered: $accountKey" 183 | exit 1 184 | fi 185 | 186 | logger "=============== Begin Installer Logs ===============" 187 | if [ "$install_system_extension" = true ]; then 188 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -v --install_system_extension)" 189 | else 190 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -v)" 191 | fi 192 | 193 | if [ $? != "0" ]; then 194 | logger "Installer Error: $install_result" 195 | exit 1 196 | fi 197 | 198 | if [ $? != "0" ]; then 199 | logger "Installer Error: $install_result" 200 | exit 1 201 | fi 202 | 203 | logger "$install_result" 204 | logger "=========== INSTALL FINISHED AT $dd ===============" 205 | exit 206 | -------------------------------------------------------------------------------- /Atera/README.md: -------------------------------------------------------------------------------- 1 | ### Deploying the Huntress macOS Agent with Atera 2 | 3 | Please refer to the following documentation articles for instructions on how to use this script 4 | 5 | [Critical Steps for Complete macOS EDR Deployment](https://support.huntress.io/hc/en-us/articles/25013857741331-Critical-Steps-for-Complete-macOS-EDR-Deployment) 6 | 7 | [Deploying Huntress via Atera](https://support.huntress.io/hc/en-us/articles/4404012689811-Deploying-Huntress-with-Atera) 8 | -------------------------------------------------------------------------------- /Bash/HuntressSystemExtensionProfile.mobileconfig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PayloadContent 6 | 7 | 8 | FilterDataProviderBundleIdentifier 9 | com.huntress.sysext 10 | FilterDataProviderDesignatedRequirement 11 | identifier "com.huntress.sysext" and anchor apple generic and certificate leaf[subject.OU] = "7W6HQ9J9XA" and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13] 12 | FilterGrade 13 | firewall 14 | FilterSockets 15 | 16 | FilterType 17 | Plugin 18 | PayloadDisplayName 19 | Web Content Filter 20 | PayloadIdentifier 21 | com.apple.webcontent-filter.CA40CCD3-78D3-45AD-83D4-87B83A27BB5C 22 | PayloadType 23 | com.apple.webcontent-filter 24 | PayloadUUID 25 | 6A41F61C-A9A0-4DA9-A72A-AF57D3ADFF33 26 | PayloadVersion 27 | 1 28 | PluginBundleID 29 | com.huntress.app 30 | UserDefinedName 31 | Huntress 32 | 33 | 34 | AllowedTeamIdentifiers 35 | 36 | 7W6HQ9J9XA 37 | 38 | PayloadDisplayName 39 | Huntress System Extension 40 | PayloadIdentifier 41 | com.apple.system-extension-policy.50653D8C-681B-496C-A50E-A33E2F45B03E 42 | PayloadType 43 | com.apple.system-extension-policy 44 | PayloadUUID 45 | 937026A5-86ED-40F7-B6C7-B1F65F4917B6 46 | PayloadVersion 47 | 1 48 | RemovableSystemExtensions 49 | 50 | 7W6HQ9J9XA 51 | 52 | com.huntress.sysext 53 | 54 | 55 | 56 | 57 | PayloadDisplayName 58 | Huntress PPPC 59 | PayloadIdentifier 60 | com.apple.TCC.configuration-profile-policy.341605DE-C729-4B02-A91F-43D9ECF7D145 61 | PayloadType 62 | com.apple.TCC.configuration-profile-policy 63 | PayloadUUID 64 | C1FC3CD5-8DF4-495A-8343-376A3E35C647 65 | PayloadVersion 66 | 1 67 | Services 68 | 69 | SystemPolicyAllFiles 70 | 71 | 72 | Allowed 73 | 74 | CodeRequirement 75 | identifier "com.huntress.app" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "7W6HQ9J9XA" 76 | Comment 77 | Full Disk Access for the Huntress Agent 78 | Identifier 79 | com.huntress.app 80 | IdentifierType 81 | bundleID 82 | StaticCode 83 | 84 | 85 | 86 | Allowed 87 | 88 | CodeRequirement 89 | identifier "com.huntress.sysext" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "7W6HQ9J9XA" 90 | Comment 91 | Full Disk Access for the Huntress Endpoint Security 92 | Identifier 93 | com.huntress.sysext 94 | IdentifierType 95 | bundleID 96 | StaticCode 97 | 98 | 99 | 100 | SystemPolicySysAdminFiles 101 | 102 | 103 | Allowed 104 | 105 | CodeRequirement 106 | identifier "com.huntress.app" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "7W6HQ9J9XA" 107 | Comment 108 | Full Disk Access for the Huntress Agent 109 | Identifier 110 | com.huntress.app 111 | IdentifierType 112 | bundleID 113 | StaticCode 114 | 115 | 116 | 117 | Allowed 118 | 119 | CodeRequirement 120 | identifier "com.huntress.sysext" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "7W6HQ9J9XA" 121 | Comment 122 | Full Disk Access for the Huntress Endpoint Security 123 | Identifier 124 | com.huntress.sysext 125 | IdentifierType 126 | bundleID 127 | StaticCode 128 | 129 | 130 | 131 | 132 | 133 | 134 | PayloadDisplayName 135 | Service Management - Managed Login Items 136 | PayloadIdentifier 137 | com.apple.servicemanagement.33C54CE5-CC01-48BF-86EA-931088636C47 138 | PayloadType 139 | com.apple.servicemanagement 140 | PayloadUUID 141 | 33C54CE5-CC01-48BF-86EA-931088636C47 142 | PayloadVersion 143 | 1 144 | Rules 145 | 146 | 147 | RuleType 148 | TeamIdentifier 149 | RuleValue 150 | 7W6HQ9J9XA 151 | 152 | 153 | 154 | 155 | PayloadDescription 156 | Huntress PPPC for FDA and System Extension 157 | PayloadDisplayName 158 | Huntress Agent with System Extension v3 159 | PayloadIdentifier 160 | com.huntress.app 161 | PayloadOrganization 162 | Huntress 163 | PayloadScope 164 | System 165 | PayloadType 166 | Configuration 167 | PayloadUUID 168 | C8501822-7E2C-4CE9-90B8-FC5F31B60921 169 | PayloadVersion 170 | 1 171 | TargetDeviceType 172 | 5 173 | 174 | 175 | -------------------------------------------------------------------------------- /Bash/InstallHuntress-macOS-bash.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | # Copyright (c) 2025 Huntress Labs, Inc. 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # * Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # * Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # * Neither the name of the Huntress Labs nor the names of its contributors 14 | # may be used to endorse or promote products derived from this software 15 | # without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | # DISCLAIMED. IN NO EVENT SHALL HUNTRESS LABS BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 23 | # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | 29 | # The Huntress installer needs an Account Key and an Organization Key (a user 30 | # specified name or description) which is used to affiliate an Agent with a 31 | # specific Organization within the Huntress Partner's Account. These keys can be 32 | # hard coded below or passed in when the script is run. 33 | 34 | # For more details, see our KB article 35 | # https://support.huntress.io/hc/en-us/articles/25013857741331-Critical-Steps-for-Complete-macOS-EDR-Deployment 36 | 37 | 38 | ############################################################################## 39 | ## Begin user modified variables 40 | ############################################################################## 41 | 42 | # Replace __ACCOUNT_KEY__ with your account secret key (from your Huntress portal's "download agent" section) 43 | defaultAccountKey="__ACCOUNT_KEY__" 44 | 45 | # If you have a preferred "placeholder" organization name for Mac agents, you can set that below. 46 | # Otherwise, provide the appropriate Organization Key when running the script in your RMM. 47 | defaultOrgKey="Mac Agents" 48 | 49 | # Put the name of your RMM below. This helps our support team understand which RMM tools 50 | # are being used to deploy the Huntress macOS Agent. Simply replace the text in quotes below. 51 | rmm="Unspecified RMM" 52 | 53 | # Option to install the system extension after the Huntress Agent is installed. In order for this to happen 54 | # without security prompts on the endpoint, permissions need to be applied to the endpoint by an MDM before this script 55 | # is run. See the following KB article for instructions: 56 | # https://support.huntress.io/hc/en-us/articles/21286543756947-Instructions-for-the-MDM-Configuration-for-macOS 57 | install_system_extension=true 58 | 59 | ############################################################################## 60 | ## Do not modify anything below this line 61 | ############################################################################## 62 | 63 | 64 | scriptVersion="April 15, 2025" 65 | 66 | version="1.1 - $scriptVersion" 67 | dd=$(date "+%Y-%m-%d %H:%M:%S") 68 | log_file="/tmp/HuntressInstaller.log" 69 | log_file_location="/Users/Shared/" 70 | install_script="/tmp/HuntressMacInstall.sh" 71 | invalid_key="Invalid account secret key" 72 | pattern="[a-f0-9]{32}" 73 | 74 | # Using logger function to provide helpful logs within RMM tools in addition to log file 75 | logger() { 76 | echo "$dd -- $*"; 77 | echo "$dd -- $*" >> $log_file; 78 | } 79 | 80 | # Copies the log from a temp location to /users/shared/ and exits with the given code 81 | # Using this folder as /tmp/ is wiped on reboot, Huntress folders are protected by TP, and because any user should have access to this folder 82 | copyLog() { 83 | # capture exit command for script finish-up 84 | local exitCode="$?" 85 | if [ -d $log_file_location ]; then 86 | logger "Copying log file to /Users/Shared/" 87 | cp "$log_file" "${log_file_location}/HuntressInstaller.log" 88 | fi 89 | if [ $exitCode -ne "0" ]; then 90 | logger "Exit with error, please send ${log_file_location}HuntressInstaller.log to support." 91 | fi 92 | exit "$exitCode" 93 | } 94 | trap copyLog EXIT 95 | 96 | # Log system info for troubleshooting 97 | logger "macOS version: $(sw_vers --ProductVersion)" 98 | logger "Free disk space: "$(df -Pk . | sed 1d | grep -v used | awk '{ print $4 "\t" }') 99 | logger $(top -l 1 | head -n 7 | tail -n 1) 100 | logger $(top -l 1 | head -n 3 | tail -n 1) 101 | logger "System uptime: $(uptime)" 102 | logger "User id (should be 0): "$(id -u) 103 | logger "Huntress install script last updated $scriptVersion" 104 | 105 | # Check for root 106 | if [ $EUID -ne 0 ]; then 107 | logger "This script must be run as root, exiting..." 108 | exit 1 109 | fi 110 | 111 | # Clean up any old installer scripts. 112 | if [ -f "$install_script" ]; then 113 | logger "Installer file present in /tmp; deleting." 114 | rm -f "$install_script" 115 | fi 116 | 117 | ## 118 | ## This section handles the assigning `=` character for options. 119 | ## Since most RMMs treat spaces as delimiters in Mac Scripting, 120 | ## we have to use `=` to assign the option value, but must remove 121 | ## it because, well, bash. https://stackoverflow.com/a/28466267/519360 122 | ## 123 | 124 | usage() { 125 | cat < --organization_key= 127 | 128 | -a, --account_key The account key to use for this agent install 129 | -o, --organization_key The org key to use for this agent install 130 | -t, --tags A comma-separated list of agent tags to use for this agent install 131 | -i, --install_system_extension If passed, automatically install the system extension 132 | -h, --help Print this message 133 | 134 | EOF 135 | } 136 | 137 | reinstall=false 138 | while getopts "a:o:t:ihr-:" OPT; do 139 | if [ "$OPT" = "-" ]; then 140 | OPT="${OPTARG%%=*}" # extract long option name 141 | OPTARG="${OPTARG#$OPT}" # extract long option argument (may be empty) 142 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 143 | else 144 | # the user used a short option, but we still want to strip the assigning `=` 145 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 146 | fi 147 | case "$OPT" in 148 | a | account_key) 149 | account_key="$OPTARG" 150 | ;; 151 | o | organization_key) 152 | organization_key="$OPTARG" 153 | ;; 154 | t | tags) 155 | tags="$OPTARG" 156 | ;; 157 | i | install_system_extension) 158 | logger "Running with System Extension immediate install option" 159 | install_system_extension=true 160 | ;; 161 | r | reinstall) 162 | logger "Running with the -reinstall flag" 163 | reinstall=true 164 | ;; 165 | h | help) 166 | usage 167 | exit 0 168 | ;; 169 | ??*) 170 | logger "Illegal option --$OPT" 171 | exit 2 172 | ;; # bad long option 173 | \? ) 174 | exit 2 175 | ;; # bad short option (error reported via getopts) 176 | esac 177 | done 178 | shift $((OPTIND-1)) # remove parsed options and args from $@ list 179 | 180 | # try/catch, if the connectivity tester fails to execute we'll log that as an error. 181 | for hostn in "update.huntress.io" "huntress.io" "eetee.huntress.io" "huntress-installers.s3.amazonaws.com" "huntress-updates.s3.amazonaws.com" "huntress-uploads.s3.us-west-2.amazonaws.com" "huntress-user-uploads.s3.amazonaws.com" "huntress-rio.s3.amazonaws.com" "huntress-survey-results.s3.amazonaws.com"; do 182 | logger "$(nc -z -v $hostn 443 2>&1)" || (logger "error occured during network connectivity test") 183 | done 184 | 185 | # Check for existing Huntress install, if already installed exit with error. Bypass if using the reinstall flag. 186 | if [ $reinstall = false ]; then 187 | if [ -d "/Applications/Huntress.app/Contents/Macos" ]; then 188 | logger "Huntress assets found, checking for running processes" 189 | numServicesStopped=0 190 | for HuntressProcess in "HuntressAgent" "HuntressUpdater"; do 191 | if [ $(pgrep "$HuntressProcess" > /dev/null) ]; then 192 | logger "Warning: process $HuntressProcess is stopped" 193 | numServicesStopped++ 194 | else 195 | logger "Process $HuntressProcess is running" 196 | fi 197 | done 198 | if [ $numServicesStopped -gt 0 ]; then 199 | logger "Installation appears damaged, suggest running with the -reinstall flag" 200 | else 201 | logger "Installation found and processes are running. If you suspect this agent is damaged try running this script with the -reinstall flag" 202 | fi 203 | exit 1 204 | fi 205 | fi 206 | 207 | 208 | logger "=========== INSTALL START AT $dd ===============" 209 | logger "=========== $rmm Deployment Script | Version: $version ===============" 210 | 211 | # validate options passed to script, remove all invalid characters except spaces are converted to dash 212 | if [ -z "$organization_key" ]; then 213 | organizationKey=$(echo "$defaultOrgKey" | tr -dc '[:alnum:]- ' | tr ' ' '-' | xargs) 214 | logger "--organization_key parameter not present, using defaultOrgKey instead: $defaultOrgKey, formatted to $organizationKey " 215 | else 216 | organizationKey=$(echo "$organization_key" | tr -dc '[:alnum:]- ' | tr ' ' '-' | xargs) 217 | logger "--organization_key parameter present, set to: $organization_key, formatted to $organizationKey " 218 | fi 219 | 220 | if ! [[ "$account_key" =~ $pattern ]]; then 221 | logger "Invalid --account_key provided, checking defaultAccountKey..." 222 | accountKey=$(echo "$defaultAccountKey" | xargs) 223 | if ! [[ $accountKey =~ $pattern ]]; then 224 | # account key is invalid if script gets to this branch, so write the key unmasked for troubleshooting 225 | logger "ERROR: Invalid --account_key, $accountKey was provided. Please check Huntress support documentation." 226 | exit 1 227 | fi 228 | else 229 | accountKey=$(echo "$account_key" | xargs) 230 | fi 231 | 232 | if [ -n "$tags" ]; then 233 | logger "using tags: $tags" 234 | fi 235 | 236 | if [ "$install_system_extension" = true ]; then 237 | logger "automatically installing system extension" 238 | fi 239 | 240 | # Hide most of the account key in the logs, keeping the front and tail end for troubleshooting 241 | masked="$(echo "${accountKey:0:4}")" 242 | masked+="************************" 243 | masked+="$(echo "${accountKey: (-4)}")" 244 | 245 | # OPTIONS REQUIRED (account key could be invalid in this branch, so mask it) 246 | if [ -z "$accountKey" ] || [ -z "$organizationKey" ] 247 | then 248 | logger "Error: --account_key and --organization_key are both required" >> $log_file 249 | logger "Account key: $masked and Org Key: $organizationKey were provided" 250 | echo 251 | usage 252 | exit 1 253 | fi 254 | 255 | 256 | logger "Provided Huntress key: $masked" 257 | logger "Provided Organization Key: $organizationKey" 258 | 259 | result=$(curl -w "%{http_code}" -L "https://huntress.io/script/darwin/$accountKey" -o "$install_script") 260 | 261 | if [ $? != "0" ]; then 262 | logger "ERROR: Download failed with error: $result" 263 | exit 1 264 | fi 265 | 266 | if grep -Fq "$invalid_key" "$install_script"; then 267 | logger "ERROR: --account_key is invalid. You entered: $accountKey" 268 | exit 1 269 | fi 270 | 271 | if [ "$install_system_extension" = true ]; then 272 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -t "$tags" -v --install_system_extension)" 273 | else 274 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -t "$tags" -v)" 275 | fi 276 | 277 | logger "=============== Begin Installer Logs ===============" 278 | 279 | if [ $? != "0" ]; then 280 | logger "Installer Error: $install_result" 281 | exit 1 282 | fi 283 | 284 | logger "$install_result" 285 | logger "=========== INSTALL FINISHED AT $dd ===============" 286 | 287 | exit 0 288 | -------------------------------------------------------------------------------- /Bash/MicrosoftDefenderForEndpoint/mdatp.mobileconfig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PayloadContent 6 | 7 | 8 | PayloadDescription 9 | Background Service Management for Microsoft Defender 10 | PayloadDisplayName 11 | Background Service Management for Microsoft Defender 12 | PayloadIdentifier 13 | 4DB96276-2310-44C2-AE11-C6E761FB0304.privacy.04102481-C1F1-44F2-B548-E0B554890493 14 | PayloadType 15 | com.apple.servicemanagement 16 | PayloadUUID 17 | AF4BB8C6-CA48-4E33-9F2E-7769C2DDD22A 18 | PayloadVersion 19 | 1 20 | Rules 21 | 22 | 23 | RuleType 24 | LabelPrefix 25 | RuleValue 26 | com.microsoft.fresno 27 | 28 | 29 | RuleType 30 | LabelPrefix 31 | RuleValue 32 | com.microsoft.dlp 33 | 34 | 35 | RuleType 36 | LabelPrefix 37 | RuleValue 38 | com.microsoft.autoupdate2 39 | 40 | 41 | 42 | 43 | FilterDataProviderBundleIdentifier 44 | com.microsoft.wdav.netext 45 | FilterDataProviderDesignatedRequirement 46 | identifier "com.microsoft.wdav.netext" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = UBF8T346G9 47 | FilterGrade 48 | inspector 49 | FilterPackets 50 | 51 | FilterSockets 52 | 53 | FilterType 54 | Plugin 55 | PayloadDisplayName 56 | Web Content Filter Payload 57 | PayloadIdentifier 58 | 283F4BF0-788A-4435-9B62-3E00896358D7 59 | PayloadOrganization 60 | JAMF Software 61 | PayloadType 62 | com.apple.webcontent-filter 63 | PayloadUUID 64 | 283F4BF0-788A-4435-9B62-3E00896358D7 65 | PayloadVersion 66 | 1 67 | PluginBundleID 68 | com.microsoft.wdav 69 | UserDefinedName 70 | Microsoft Defender Content Filter 71 | 72 | 73 | NotificationSettings 74 | 75 | 76 | AlertType 77 | 1 78 | BadgesEnabled 79 | 80 | BundleIdentifier 81 | com.microsoft.autoupdate2 82 | CriticalAlertEnabled 83 | 84 | NotificationsEnabled 85 | 86 | ShowInLockScreen 87 | 88 | ShowInNotificationCenter 89 | 90 | SoundsEnabled 91 | 92 | 93 | 94 | AlertType 95 | 1 96 | BadgesEnabled 97 | 98 | BundleIdentifier 99 | com.microsoft.wdav.tray 100 | CriticalAlertEnabled 101 | 102 | NotificationsEnabled 103 | 104 | ShowInLockScreen 105 | 106 | ShowInNotificationCenter 107 | 108 | SoundsEnabled 109 | 110 | 111 | 112 | PayloadDisplayName 113 | Notifications Payload 114 | PayloadIdentifier 115 | 05BF7221-2470-477D-99B3-1729B1932BDB 116 | PayloadOrganization 117 | Microsoft Corporation 118 | PayloadType 119 | com.apple.notificationsettings 120 | PayloadUUID 121 | 05BF7221-2470-477D-99B3-1729B1932BDB 122 | PayloadVersion 123 | 1 124 | 125 | 126 | AllowUserOverrides 127 | 128 | AllowedSystemExtensions 129 | 130 | UBF8T346G9 131 | 132 | com.microsoft.wdav.epsext 133 | com.microsoft.wdav.netext 134 | 135 | 136 | PayloadDescription 137 | 138 | PayloadDisplayName 139 | System Extensions 140 | PayloadEnabled 141 | 142 | PayloadIdentifier 143 | 605B85D6-5CE9-49C9-A10F-6B12B4D0B84E 144 | PayloadOrganization 145 | Microsoft Corporation 146 | PayloadType 147 | com.apple.system-extension-policy 148 | PayloadUUID 149 | 39FE7525-DFE9-4AC6-B152-E093375C62C2 150 | PayloadVersion 151 | 1 152 | RemovableSystemExtensions 153 | 154 | UBF8T346G9 155 | 156 | com.microsoft.wdav.epsext 157 | com.microsoft.wdav.netext 158 | 159 | 160 | 161 | 162 | PayloadDescription 163 | 164 | PayloadDisplayName 165 | Privacy Preferences Policy Control 166 | PayloadEnabled 167 | 168 | PayloadIdentifier 169 | E23CA4BE-65BA-4685-89D6-041F82994606 170 | PayloadOrganization 171 | Microsoft Corporation 172 | PayloadType 173 | com.apple.TCC.configuration-profile-policy 174 | PayloadUUID 175 | E23CA4BE-65BA-4685-89D6-041F82994606 176 | PayloadVersion 177 | 1 178 | Services 179 | 180 | Accessibility 181 | 182 | 183 | Allowed 184 | 1 185 | CodeRequirement 186 | identifier "com.microsoft.dlp.daemon" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = UBF8T346G9 187 | Identifier 188 | com.microsoft.dlp.daemon 189 | IdentifierType 190 | bundleID 191 | StaticCode 192 | 0 193 | 194 | 195 | SystemPolicyAllFiles 196 | 197 | 198 | Allowed 199 | 1 200 | CodeRequirement 201 | identifier "com.microsoft.wdav" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = UBF8T346G9 202 | Identifier 203 | com.microsoft.wdav 204 | IdentifierType 205 | bundleID 206 | StaticCode 207 | 0 208 | 209 | 210 | Allowed 211 | 1 212 | CodeRequirement 213 | identifier "com.microsoft.wdav.epsext" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = UBF8T346G9 214 | Identifier 215 | com.microsoft.wdav.epsext 216 | IdentifierType 217 | bundleID 218 | StaticCode 219 | 0 220 | 221 | 222 | Allowed 223 | 1 224 | CodeRequirement 225 | identifier "com.microsoft.dlp.daemon" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = UBF8T346G9 226 | Identifier 227 | com.microsoft.dlp.daemon 228 | IdentifierType 229 | bundleID 230 | StaticCode 231 | 0 232 | 233 | 234 | 235 | 236 | 237 | PayloadDescription 238 | 239 | PayloadDisplayName 240 | Defender onboarding settings - version 2 241 | PayloadEnabled 242 | 243 | PayloadIdentifier 244 | CFAD2020-407F-11EF-9579-4A3093669CD7 245 | PayloadOrganization 246 | Microsoft Corporation 247 | PayloadRemovalDisallowed 248 | 249 | PayloadScope 250 | System 251 | PayloadType 252 | Configuration 253 | PayloadUUID 254 | EFA8B8E8-A94A-4F3B-A9E8-540A7186BCA3 255 | PayloadVersion 256 | 1 257 | 258 | 259 | -------------------------------------------------------------------------------- /Bash/README.md: -------------------------------------------------------------------------------- 1 | ## Installing the Huntress macOS Agent 2 | 3 | This script is meant to be a generic script for deploying the Huntress macOS agent with any tool that supports bash (or shell) scripting. 4 | 5 | ### Required Values 6 | 7 | On lines 44 and 48 you will see two variables (`defaultAccountKey` and `defaultOrgKey`) that need to be updated. The [Account Key](https://support.huntress.io/hc/en-us/articles/4404012734227#account-key) is located in your Huntress Portal. This value is used to associate the agent with your tenant. The [Organization Key](https://support.huntress.io/hc/en-us/articles/4404012734227#organization-keys) is used to organizations agents by customer within your portal. You can replace the provided `"Mac Agents"` value in the script with your customer name whem you run the script (spaces are permitted if you keep the name in double quotes), or you may simply [move the agents](https://support.huntress.io/hc/en-us/articles/4404012577299-Moving-Agents-Between-Organizations) to the appropriate organization after installation. 8 | 9 | ### Optional Values 10 | 11 | On line 52 you'll notice a value for `RMM`. This optional value allows you to name the tool you're using to install the Huntress macOS agent, which may be helpful for our support team when troubleshooting. The value there is written to the `/tmp/HuntressInstaller.log` log file during installation and is not automatically sent to Huntress. 12 | 13 | On line 58, there is an option called `install_system_extension`. If set to `true`, the script will attempt to install the system extension after the Huntress Agent is installed. This will only succeed if the endpoint is [properly configured with MDM permissions](https://support.huntress.io/hc/en-us/articles/21286543756947-Instructions-for-the-MDM-Configuration-for-macOS) for the system extension. If the endpoint does not have these permissions in place beforehand, then the currently logged in user will receive security prompt pop-ups asking to authorize the system extension and content filter. Examples of this can be found in [this KB article](https://support.huntress.io/hc/en-us/articles/21286469262867-Install-the-System-Extension-for-macOS) 14 | 15 | **NOTE**: Please do not modify anything below line 58. 16 | 17 | ### Running from command line with arguments 18 | 19 | Some tools don't have a scripting engine, but will permit you to upload a script and pass parameters to it. If you need to run this as a script with parameters, simply follow the guidelines below: 20 | 21 | ``` 22 | -a, --account_key The account key to use for this agent install 23 | -o, --organization_key The org key to use for this agent install 24 | ``` 25 | 26 | As noted above, there are two required fields that can be defined statically in the script, or you can pass the values as parameters. The `organization_key` parameter supports strings, so if you pass `My Company`, just be sure to put it in double quotes like so: `"My Company"` 27 | 28 | Example usage: 29 | 30 | `./InstallHuntress-macOS-bash.sh --account_key 123456abcdef --organization_key "My Awesome Coffee Shop"` 31 | 32 | ### Logging and Troubleshooting 33 | 34 | The installer log is located in `/tmp/HuntressInstaller.log` and the output of a successful install would look like: 35 | 36 | ``` 37 | 20221103-085511 -- =========== INSTALL START AT 20221103-085511 =============== 38 | 20221103-085511 -- =========== Syncro macOS deployment component | Version: 1.0 =============== 39 | 20221103-085511 -- --organization_key parameter present, set to: My Awesome Coffee Shop 40 | 20221103-085511 -- Provided Huntress key: 1234************************cdef 41 | 20221103-085511 -- Provided Organization Key: My Awesome Coffee Shop 42 | 20221103-085511 -- =============== Begin Installer Logs =============== 43 | 20221103-085511 -- creating /tmp/hagent.yaml... 44 | running the installer... 45 | installer: Package name is Huntress Agent 46 | installer: Upgrading at base path / 47 | installer: The upgrade was successful. 48 | cleaning up... 49 | 20221103-085511 -- =========== INSTALL FINISHED AT 20221103-085511 =============== 50 | ``` 51 | 52 | ## Huntress Mobileconfig 53 | 54 | The `mobileconfig` file in this directory contains preconfigured settings for MDMs. It is designed to upload/import to your MDM and can then be scoped to a collection of devices. 55 | 56 | `HuntressSystemExtension.mobileconfig` grants all the permissions required by the Huntress Agent and the Huntress System Extension. It enables FDA (full disk access) for both and provides the System Extension with the neccessary permissions for install and operation. Most partners will use this set of configurations. 57 | 58 | The mobileconfig file is suffixed with a version number (as of Nov 2024), which will be updated when changes are made to it. 59 | 60 | ## Legacy Mobileconfigs 61 | 62 | These are kept around for historical reasons in the `legacy-mobileconfigs` folder. **Do not use these these files unless you are specifically directed to by Huntress Support** 63 | 64 | ## Microsoft Defender for Endpoint 65 | 66 | **These configs are not for the Huntress Agent.** 67 | These profiles allow for proper provisioning of Microsoft Defender for Endpoint on a macOS host, per Microsoft documentation. 68 | 69 | -------------------------------------------------------------------------------- /Bash/legacy-mobileconfigs/Huntress PPPC.mobileconfig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PayloadContent 6 | 7 | 8 | PayloadDescription 9 | Huntress PPPC payload for FDA 10 | PayloadDisplayName 11 | Huntress PPPC 12 | PayloadIdentifier 13 | 1669B5F3-EAA4-4480-B4A9-A3F2B92050DA 14 | PayloadOrganization 15 | Huntress 16 | PayloadType 17 | com.apple.TCC.configuration-profile-policy 18 | PayloadUUID 19 | 6108E81E-A29E-4427-84DC-9BBD95AF8FFC 20 | PayloadVersion 21 | 1 22 | Services 23 | 24 | SystemPolicyAllFiles 25 | 26 | 27 | Allowed 28 | 29 | CodeRequirement 30 | identifier "com.huntresslabs.www" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "7W6HQ9J9XA" 31 | Comment 32 | 33 | Identifier 34 | com.huntresslabs.www 35 | IdentifierType 36 | bundleID 37 | 38 | 39 | SystemPolicySysAdminFiles 40 | 41 | 42 | Allowed 43 | 44 | CodeRequirement 45 | identifier "com.huntresslabs.www" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "7W6HQ9J9XA" 46 | Comment 47 | 48 | Identifier 49 | com.huntresslabs.www 50 | IdentifierType 51 | bundleID 52 | 53 | 54 | 55 | 56 | 57 | PayloadDescription 58 | Huntress PPPC payload for FDA 59 | PayloadDisplayName 60 | Huntress PPPC 61 | PayloadIdentifier 62 | 1669B5F3-EAA4-4480-B4A9-A3F2B92050DA 63 | PayloadOrganization 64 | Huntress 65 | PayloadScope 66 | System 67 | PayloadType 68 | Configuration 69 | PayloadUUID 70 | 8702331E-CA3D-48EB-BC2F-D6A60D579B65 71 | PayloadVersion 72 | 1 73 | 74 | 75 | -------------------------------------------------------------------------------- /Bash/legacy-mobileconfigs/HuntressLegacyAgentProfile.mobileconfig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PayloadContent 6 | 7 | 8 | PayloadDisplayName 9 | Huntress PPPC 10 | PayloadIdentifier 11 | com.apple.TCC.configuration-profile-policy.1451C4BD-BB6D-4071-AAA5-D99D1F32483E 12 | PayloadType 13 | com.apple.TCC.configuration-profile-policy 14 | PayloadUUID 15 | 1E1E7FD1-9960-49CD-949B-9FDF518FD5CD 16 | PayloadVersion 17 | 1 18 | Services 19 | 20 | SystemPolicyAllFiles 21 | 22 | 23 | Allowed 24 | 25 | CodeRequirement 26 | identifier "com.huntresslabs.www" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "7W6HQ9J9XA" 27 | Comment 28 | Full Disk Access for the Huntress Agent 29 | Identifier 30 | com.huntresslabs.www 31 | IdentifierType 32 | bundleID 33 | 34 | 35 | SystemPolicySysAdminFiles 36 | 37 | 38 | Allowed 39 | 40 | CodeRequirement 41 | identifier "com.huntresslabs.www" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "7W6HQ9J9XA" 42 | Comment 43 | Full Disk Access for the Huntress Agent 44 | Identifier 45 | com.huntresslabs.www 46 | IdentifierType 47 | bundleID 48 | 49 | 50 | 51 | 52 | 53 | PayloadDescription 54 | Huntress PPPC for FDA 55 | PayloadDisplayName 56 | Huntress Agent 57 | PayloadIdentifier 58 | com.huntresslabs.www 59 | PayloadOrganization 60 | Huntress 61 | PayloadScope 62 | System 63 | PayloadType 64 | Configuration 65 | PayloadUUID 66 | 7B74953A-43C8-44E5-9D12-64265793F45D 67 | PayloadVersion 68 | 1 69 | TargetDeviceType 70 | 5 71 | 72 | 73 | -------------------------------------------------------------------------------- /Bash/legacy-mobileconfigs/README.md: -------------------------------------------------------------------------------- 1 | # Legacy Mobileconfigs 2 | 3 | These are kept around for legacy usage 4 | 5 | ## Do not use these these files unless you are specifically directed to by Huntress Support 6 | 7 | - `Huntress PPPC.mobileconfig`: This payload will grant the Huntress agent FDA (full disk access). This file does not configure the System Extension and should be used for deployments that only use the Huntress Agent. No partners should use this unless expressly directed to by Huntress Support. 8 | 9 | - `HuntressLegacyAgentProfile.mobileconfig`: A legacy profile used for versions of the Huntress macOS Agent before version `0.13.72`. Kept around for historical reasons, no partners should use this unless expressly directed to by Huntress Support. 10 | -------------------------------------------------------------------------------- /Bash/mdm_overrides_parser.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | bundle_ids=("com.huntress.app" "com.huntress.sysext" "com.huntress.HuntressAgent") # bundle_ids=("bundle_id_1" "bundle_id_2") 4 | 5 | ## Using logger function to provide helpful logs within RMM tools in addition to log file 6 | logger() { 7 | echo "$dd -- $*"; 8 | echo "$dd -- $*" >> $log_file; 9 | } 10 | 11 | dd=$(date "+%Y%m%d-%H%M%S") 12 | version_date="March 28, 2025" 13 | version="1.0" 14 | log_file="/tmp/overrides_parser.log" 15 | 16 | logger "Script last updated $version_date" 17 | 18 | #Check for root 19 | if [ $EUID -ne 0 ]; then 20 | logger "This script must be run as root, exiting..." 21 | exit 1 22 | fi 23 | 24 | 25 | logger "======== SCRIPT START AT $dd ============" 26 | logger "======== Script | Version: $version ============" 27 | 28 | 29 | plistbuddy_helper() { 30 | # Helper function to interact with plists. 31 | # All options utilize the "-c" option (non-interactive mode). 32 | # All options except a file path to be passed _except_ for the action "print_stdin" 33 | # Arguments 34 | # $1 = (str) action to perform on the plist; Supported options are: 35 | # "print_xml" - returns xml formatted text 36 | # "print_stdin" - expects to work with xml formatted text (passed to PlistBuddy via stdin) 37 | # "print" - returns PlistBuddy's standard descriptive text format, optionally provide a key 38 | # "read" - returns the specified key's value 39 | # "add" - add or set values for a specified key, optionally provide a the key's type 40 | # "delete" - delete the specified key/value pair 41 | # "clear" - clear the value for a specified key 42 | # $2 = (str) Path to plist or generated xml 43 | # $3 = (str) Key or key path to read 44 | # $4 = (str) Type that will be used for the value 45 | # $5 = (str) Value to be set to the passed key 46 | local action="${1}" 47 | local plist="${2}" 48 | local key="${3}" 49 | local type="${4}" 50 | local value="${5}" 51 | 52 | case "${action}" in 53 | "print_xml" ) 54 | # Dump plist file as XML 55 | /usr/libexec/PlistBuddy -x -c "Print" "${plist}" 56 | ;; 57 | "print_stdin" ) 58 | # Read plist "str" (as a heredoc) and print the passed key 59 | /usr/libexec/PlistBuddy -c "Print :${key}" /dev/stdin <<< "${plist}" 2> /dev/null || \ 60 | /usr/libexec/PlistBuddy -c "Print" /dev/stdin <<< "${plist}" 2> /dev/null 61 | ;; 62 | "print" ) 63 | # Read a key (leaving for previous function revision support) 64 | /usr/libexec/PlistBuddy -c "Print :'${key}'" "${plist}" 2> /dev/null || \ 65 | # Print the entire plist file 66 | /usr/libexec/PlistBuddy -c "Print" "${plist}" 67 | ;; 68 | "read" ) 69 | # Read a key 70 | /usr/libexec/PlistBuddy -c "Print :'${key}'" "${plist}" 2> /dev/null 71 | ;; 72 | "add" ) 73 | # Configure values 74 | /usr/libexec/PlistBuddy -c "Add :${key} ${type} ${value}" "${plist}" > /dev/null 2>&1 \ 75 | || /usr/libexec/PlistBuddy -c "Set :${key} ${value}" "${plist}" > /dev/null 2>&1 76 | ;; 77 | "delete" ) 78 | # Delete a key 79 | /usr/libexec/PlistBuddy -c "Delete :${key} ${type}" "${plist}" > /dev/null 2>&1 80 | ;; 81 | "clear" ) 82 | # Clear a key's value 83 | /usr/libexec/PlistBuddy -c "clear ${type}" "${plist}" > /dev/null 2>&1 84 | ;; 85 | esac 86 | } 87 | 88 | parse_mdm_overrides() { 89 | 90 | if [[ -z "${bundle_ids}" ]]; then 91 | logger "No Bundle ID provided. Please provide as array on line 3" 92 | exit 1 93 | fi 94 | 95 | mdm_overrides_path="/Library/Application Support/com.apple.TCC/MDMOverrides.plist" 96 | 97 | if [[ -e "${mdm_overrides_path}" ]] 98 | then 99 | tcc_mdm_db=$( plistbuddy_helper "print_xml" \ 100 | "/Library/Application Support/com.apple.TCC/MDMOverrides.plist" ) 101 | 102 | for id in "${bundle_ids[@]}" 103 | do 104 | mdm_fda_enabled=$( plistbuddy_helper "print_stdin" "${tcc_mdm_db}" \ 105 | "${id}:kTCCServiceSystemPolicyAllFiles:Allowed" ) 106 | 107 | if [ "${mdm_fda_enabled}" = "true" ]; then 108 | result="Approved" 109 | elif [ "${mdm_fda_enabled}" = "false" ]; then 110 | result="Denied" 111 | else 112 | logger "$id: Unknown Bundle ID" 113 | continue 114 | fi 115 | 116 | logger "Bundle ID: $id" 117 | logger "Status: $result" 118 | done 119 | 120 | else 121 | logger "=========== No MDMOverrides - Check TCC database for permissions not provisioned by an MDM ===========" 122 | fi 123 | } 124 | 125 | parse_mdm_overrides 126 | 127 | logger "======== SCRIPT FINISHED AT $dd ============" 128 | exit 129 | -------------------------------------------------------------------------------- /ConnectWise-Automate/Huntress Agent Install script - Download.xml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 6301 9 | 266 10 | Huntress Agent Install - Download 11 | Downloads and installs the Huntress Agent silently. Sets Org Key to company name (ClientName) for easy grouping of clients and uses the LocationName as a tag. 12 | 13 | Windows & macOS support 14 | 15 | Requirements: 16 | - Set your ACCT_KEY on Globals and Parameters tab 17 | 18 | Updated: 08 March 2024, Cameron Granger 19 | 0, 20 | 0, 21 | 1 22 | 0 23 | 0 24 | 0 25 | H4sIAAAAAAAEAFWPzQrCMBCE74LvkAdoSLZ/alkCYsWLXlS8N8kecjAtaQP27bVFoR6GYWf4FgbPzpDvqW6GRuF97EgBitnxGv2hjX6goCSKxYXHV+fCxJC6R+ptMyasJkNPTYGlMvkISgaygrTKJNtfUCwQvJnguuFBoXetn37/B9/+FJ1VhspymxHxPDeSA5DmWmvLpYSisECbncx+/AygWC5ar95wg2/34QAAAA== 26 | H4sIAAAAAAAEAOVbW2+jOBR+X2n/gxWp2pelxBCaNmqjVJm2U21HHU06O1pppcjAmcQqNVkw05l/vwRwbgInJbiU9Ckccwn+8p3Ld+ycj5yAzvgHwkn/998QOk/tMDFi8+onD8j87DUFzw2RLk58JgF5Ag7BytiN59vEC/vEcfj4EX5dDKeETeAT/DlIH3vFJpTBFSO2B3f+ZALB4IIHEZzr4tbsSenlf8dPpz7r43N9fWDtqpuIun0HTk5OTQCt03HaGsZga7Ztu1q7jS3LxdA9a5viKckNyWT11dlmjxtxmC3e49Lh2QtkR9n4dcQS+9adn1uxVtHBG2gZG7a5YXc2bGtpj/yA99vx+84/s7GhzzhlEczHF8fZufvwjj7R5BZxmJ25ZS4wTpLJxGdXzVVIlihIYDEksBjtYlzmmGVHa/j0HxIuZMYaVP1iBmU3mIeLpdV5NY7hJuGCpST7GDEeQBiiy0n89QWM6y2v8gIg7i9EWciJ54GbT8QX4mlUjSdW6bPWqQTPnjMF5xERj6OpAI3FOSAf2T15aB4eD3ejIVFCw06TaIiNMxkNb1NkkIBMCf+sJvFvi99u5Va10J00CTrT2s9z98SqW4AVLsYKd2tzzJ3A+jpzSSwLlMB12ii4pGHslZ3yrEkJwLAkyFVd8FauBGqs0F4lNeJmaQRT5oXDpKTlU8KRaFqgSdKKQD9IQOcqE01JiGwAhkJQkwRw5SJBJaBdWa0rQCwoc40CcS/6RPlSvt9Lc8o4bRJlF3XkmDZLQEhJ+o0y139W5MwllIFm4E63c2qemPht5tYP/jPzfOJSNkEZeLImwL4QNksrSIu4doHj3rIf/iNo38D+Av9FEHKkfQ0oak05n4U9XRcNgWPq626Gvj4Q0WDQQtp9xK9pHE1bRxyeZi4Njv4VWSrLWhAcw09o7aZ3F2+6EQb6g3AKXlxShZHHRWvQWv+9SgiUt1pF5s22YnYXSZTyaBkqIymW9Er7S+4JwtJV7hWQHxdkrZ6IM+NrQpeF+8sa0bhI07xRNkrDh1GA4BafR/rlcPgw/uvqn4tlzED6/ZebZKx15Hg0ns682XjUQvrD5c0oHvR8J5mgGB6pjxwlVNT7jRxGCWW1BS2zthrsiTj3IzUwlZBTywrMqq9L25bh5USBhzQfLTxfF57/iTiZ8x+HU6TdobwaIkxeSXdJ8EzZSiGx2y+QS+6XhWWjhCaba46a0l7drl5CbW1BS6mr71Yk5FO2jiLBKKHSamSjPDTYJPb7rXGBoJVSIA4kG0WAxtFmBfB6saGE4HvHsaGM3KoxNkjLgF7SMBxnRFWDVwnBVWM7YWt3dd6EWd+KIZY61MBXQk+9i509RqOWgKrY2jOKHCe+6HvkbTjsfnspzMpXjJTm4v33pqjCsfJ1pNqyaH58Q9+Tiu8YffaAhIDS/VOeP1HTyjebtdcMSxpJFYc+s/LFIKWhT16B5K2FVUykyneL1VaBjECysOszxKeA0l7DHyHK9qAjwlyU3J9ub+fEToYCCCKmBvDKV5AOxnMr30xWo+fmdwIqptLhqAcB1yKNDhXnz8qVw8F4YbOkg9wLC6vZatnUadQ/TMpUt2EKpBr0KtcGOzBO2Nmf4f4HTnBZkBs3AAA= 27 | 1 28 | ce6683ee-44c0-11eb-bbbd-00155d1e7903 29 | 0 30 | 31 |
32 |
33 | 34 | 35 | 36 | 266 37 | 0 38 | Huntress Scripts 39 | f6016cba-5efc-4cd5-a502-e61da703275f 40 |
41 |
42 |
43 |
44 |
-------------------------------------------------------------------------------- /ConnectWise-Automate/Monitors/Endpoints with Huntress Agents installed Group with Monitors, searches, and groups.xml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 1719 9 | 0 10 | , 11 | , 12 | 0 13 | Endpoints with Huntress Agent Installed 14 | Endpoints with Huntress Agent Installed 15 | 0 16 | 17 | 1176 18 | 0 19 | 0 20 | 0 21 | 0 22 | 23 | 0 24 | 2022-08-24T13:56:01-07:00 25 | 0 26 | 5 27 | 5aea263f-8bdd-11ea-a7cc-00155d1e7903 28 | 0 29 | 0 30 | 0 31 | 0 32 |
33 |
34 | 35 | 36 | 37 | 1176 38 | Software - Huntress Installed - Universal 39 | SELECT 40 | computers.computerid as `Computer Id`, 41 | computers.name as `Computer Name`, 42 | clients.name as `Client Name`, 43 | computers.domain as `Computer Domain`, 44 | computers.username as `Computer User`, 45 | Software.Name as `Computer.Applications.Name` 46 | FROM Computers 47 | LEFT JOIN inv_operatingsystem ON (Computers.ComputerId=inv_operatingsystem.ComputerId) 48 | LEFT JOIN Clients ON (Computers.ClientId=Clients.ClientId) 49 | LEFT JOIN Locations ON (Computers.LocationId=Locations.LocationID) 50 | LEFT JOIN Software ON (Software.ComputerId = Computers.ComputerId) 51 | WHERE 52 | ((Instr(Software.Name,'Huntress') > 0)) 53 | 54 | 4 55 | Select||=||=||=|^Select|||||||^ 56 | 9 57 | a517770d-c8a6-4647-9bd4-9473a839fec2 58 | <LabTechAbstractSearch><asn><st>AndNode</st><cn><asn><st>ComparisonNode</st><lon>Computer.Applications.Name</lon><lok>Computer.Applications.Name</lok><lmo>Contains</lmo><dv>Huntress</dv><dk>Huntress</dk></asn></cn></asn></LabTechAbstractSearch> 59 |
60 |
61 |
62 | 63 | 64 | 65 | 1185 66 | 1719 67 | 0 68 | Huntress Agent Orphan Detector 69 | 6 70 | 56 71 | %NAME% reports that the Huntress Agent %STATUS% on %CLIENTNAME%\%COMPUTERNAME% at %LOCATIONNAME% for %FIELDNAME% result %RESULT%.!!!%NAME% reports that the Huntress Agent %STATUS% on %CLIENTNAME%\%COMPUTERNAME% at %LOCATIONNAME% for %FIELDNAME% result %RESULT%. 72 | 0 73 | 3600 74 | 127.0.0.1 75 | 7 76 | %SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Bypass -Encoded WwBTAHkAcwB0AGUAbQAuAFQAZQB4AHQALgBFAG4AYwBvAGQAaQBuAGcAXQA6ADoAVQBUAEYAOAAuAEcAZQB0AFMAdAByAGkAbgBnACgAWwBTAHkAcwB0AGUAbQAuAEMAbwBuAHYAZQByAHQAXQA6ADoARgByAG8AbQBCAGEAcwBlADYANABTAHQAcgBpAG4AZwAoACgAJwB7ACIAUwBjAHIAaQBwAHQAIgA6ACIASgBHAFoAcABiAEcAVQBnAFAAUwBBAG4AUQB6AHAAYwBVAEgASgB2AFoAMwBKAGgAYgBTAEIARwBhAFcAeABsAGMAeQBBAG8AZQBEAGcAMgBLAFYAeABJAGQAVwA1ADAAYwBtAFYAegBjADEAeABJAGQAVwA1ADAAYwBtAFYAegBjADAARgBuAFoAVwA1ADAATABtAHgAdgBaAHkAYwBOAEMAZwAwAEsAYQBXAFkAZwBLAEMAMQB1AGIAMwBRAG8AVgBHAFYAegBkAEMAMQBRAFkAWABSAG8ASQBDADEAUQBZAFgAUgBvAEkAQwBSAG0AYQBXAHgAbABJAEMAMQBRAFkAWABSAG8AVgBIAGwAdwBaAFMAQgBNAFoAVwBGAG0ASwBTAGsAZwBlAHcAMABLAEkAQwBBAGcASQBDAFIAbQBhAFcAeABsAEkARAAwAGcASgAwAE0ANgBYAEYAQgB5AGIAMgBkAHkAWQBXADAAZwBSAG0AbABzAFoAWABOAGMAUwBIAFYAdQBkAEgASgBsAGMAMwBOAGMAUwBIAFYAdQBkAEgASgBsAGMAMwBOAEIAWgAyAFYAdQBkAEMANQBzAGIAMgBjAG4ARABRAG8AZwBJAEMAQQBnAFIAMgBWADAATABVAE4AdgBiAG4AUgBsAGIAbgBRAGcASgBHAFoAcABiAEcAVQBnAEwAVgBSAGgAYQBXAHcAZwBNAFQAQQBnAGYAQwBCAEcAYgAzAEoARgBZAFcATgBvAEwAVQA5AGkAYQBtAFYAagBkAEMAQgA3AEkARwBsAG0ASQBDAGcAawBYAHkAQQB0AGIAVwBGADAAWQAyAGcAZwBKAHoAUQB3AE0AUwBjAHAASQBIAHQARgBZADIAaAB2AEkAQwBkAFAAVQBsAEIASQBRAFUANQBGAFIAQwBkADkAZgBRADAASwBJAEgAMABOAEMAaQBCAGwAYgBIAE4AbABEAFEAbwBnAGUAdwAwAEsASQBFAGQAbABkAEMAMQBEAGIAMgA1ADAAWgBXADUAMABJAEMAUgBtAGEAVwB4AGwASQBDADEAVQBZAFcAbABzAEkARABFAHcASQBIAHcAZwBSAG0AOQB5AFIAVwBGAGoAYQBDADEAUABZAG0AcABsAFkAMwBRAGcAZQB5AEIAcABaAGkAQQBvAEoARgA4AGcATABXADEAaABkAEcATgBvAEkAQwBjADAATQBEAEUAbgBLAFMAQgA3AFIAVwBOAG8AYgB5AEEAbgBUADEASgBRAFMARQBGAE8AUgBVAFEAbgBmAFgAMABOAEMAaQBCADkARABRAG8ATgBDAGcAMABLAEQAUQBvAD0AIgB9ACcAIAB8ACAAQwBvAG4AdgBlAHIAdABGAHIAbwBtAC0ASgBzAG8AbgApAC4AUwBjAHIAaQBwAHQAKQApACAAfAAgAGkAZQB4AA== 77 | 9 78 | ORPHANED 79 | 80 | 1 81 | 82 | 83 | 5 84 | 0 85 | 1 86 | 42ae9b08-bfa1-4d90-a12b-5acb85b16151 87 |
88 |
89 |
90 | 91 | 92 | 93 | 1187 94 | 1719 95 | 78 96 | SVC-HuntressAgent 97 | 6 98 | 15 99 | Huntree Agent is running~~~%NAME% %STATUS% on %CLIENTNAME%\%COMPUTERNAME% at %LOCATIONNAME% for %FIELDNAME% result %RESULT%.!!!Huntress Agent is not running! ~~~%NAME% %STATUS% on %CLIENTNAME%\%COMPUTERNAME% at %LOCATIONNAME% for %FIELDNAME% result %RESULT%. 100 | 0 101 | 300 102 | 127.0.0.1 103 | 2 104 | HuntressAgent 105 | 1 106 | 1 107 | 108 | 0 109 | 0 110 | 111 | 5 112 | 135 113 | 1 114 | 75bfcb2d-31d9-4b5d-a5c1-e721da8581e4 115 | cgranger 116 | 2022-08-24T14:06:48-07:00 117 |
118 |
119 | 120 | 121 | 122 | 78 123 | Windows Computers 124 | SELECT 125 | computers.computerid as `Computer Id`, 126 | computers.name as `Computer Name`, 127 | clients.name as `Client Name`, 128 | computers.domain as `Computer Domain`, 129 | computers.username as `Computer User`, 130 | IF(INSTR(IFNULL(inv_operatingsystem.Name, Computers.OS), 'windows')>0, 1, IF(INSTR(IFNULL(inv_operatingsystem.Name, Computers.OS), 'darwin') >0, 2, 3)) as `Computer.OS.Type` 131 | FROM Computers 132 | LEFT JOIN inv_operatingsystem ON (Computers.ComputerId=inv_operatingsystem.ComputerId) 133 | LEFT JOIN Clients ON (Computers.ClientId=Clients.ClientId) 134 | LEFT JOIN Locations ON (Computers.LocationId=Locations.LocationID) 135 | WHERE 136 | ((IF(INSTR(IFNULL(inv_operatingsystem.Name, Computers.OS), 'windows')>0, 1, IF(INSTR(IFNULL(inv_operatingsystem.Name, Computers.OS), 'darwin') >0, 2, 3)) = '1')) 137 | 138 | 4 139 | READONLY 140 | 1 141 | 4477e4d6-40f7-11e0-8c74-0050568b5553 142 | <LabTechAbstractSearch><asn><st>AndNode</st><cn><asn><st>ComparisonNode</st><lon>Computer.OS.Type</lon><lok>Computer.OS.Type</lok><lmo>Equals</lmo><dv>Windows</dv><dk>1</dk></asn></cn></asn></LabTechAbstractSearch> 143 |
144 |
145 |
146 |
147 |
148 |
-------------------------------------------------------------------------------- /ConnectWise-Automate/Monitors/Huntress Service Remote Monitor/README.md: -------------------------------------------------------------------------------- 1 | For individual/customized setup of the Huntress Agent Service monitor please see: https://support.huntress.io/hc/en-us/articles/8949567617939 2 | -------------------------------------------------------------------------------- /ConnectWise-Automate/Monitors/Orpaned Agent Remote Monitor/CWA Orphan monitor powershell code: -------------------------------------------------------------------------------- 1 | powershell.exe -exec bypass -enc cABvAHcAZQByAHMAaABlAGwAbAAuAGUAeABlACAALQBlAHgAZQBjACAAYgB5AHAAYQBzAHMAIAAtAGUAbgBjACAASgBBAEIAbQBBAEcAawBBAGIAQQBCAGwAQQBDAEEAQQBQAFEAQQBnAEEAQwBJAEEAUQB3AEEANgBBAEYAdwBBAFUAQQBCAHkAQQBHADgAQQBaAHcAQgB5AEEARwBFAEEAYgBRAEEAZwBBAEUAWQBBAGEAUQBCAHMAQQBHAFUAQQBjAHcAQQBnAEEAQwBnAEEAZQBBAEEANABBAEQAWQBBAEsAUQBCAGMAQQBFAGcAQQBkAFEAQgB1AEEASABRAEEAYwBnAEIAbABBAEgATQBBAGMAdwBCAGMAQQBFAGcAQQBkAFEAQgB1AEEASABRAEEAYwBnAEIAbABBAEgATQBBAGMAdwBCAEIAQQBHAGMAQQBaAFEAQgB1AEEASABRAEEATABnAEIAcwBBAEcAOABBAFoAdwBBAGkAQQBDAEEAQQBEAFEAQQBLAEEARwBrAEEAWgBnAEEAZwBBAEMAZwBBAEwAUQBCAHUAQQBHADgAQQBkAEEAQQBvAEEARgBRAEEAWgBRAEIAegBBAEgAUQBBAEwAUQBCAFEAQQBHAEUAQQBkAEEAQgBvAEEAQwBBAEEATABRAEIAUQBBAEcARQBBAGQAQQBCAG8AQQBDAEEAQQBKAEEAQgBtAEEARwBrAEEAYgBBAEIAbABBAEMAQQBBAEwAUQBCAFEAQQBHAEUAQQBkAEEAQgBvAEEARgBRAEEAZQBRAEIAdwBBAEcAVQBBAEkAQQBCAE0AQQBHAFUAQQBZAFEAQgBtAEEAQwBrAEEASwBRAEEAZwBBAEgAcwBBAEQAUQBBAEsAQQBDAFEAQQBaAGcAQgBwAEEARwB3AEEAWgBRAEEAZwBBAEQAMABBAEkAQQBBAGkAQQBFAE0AQQBPAGcAQgBjAEEARgBBAEEAYwBnAEIAdgBBAEcAYwBBAGMAZwBCAGgAQQBHADAAQQBJAEEAQgBHAEEARwBrAEEAYgBBAEIAbABBAEgATQBBAFgAQQBCAEkAQQBIAFUAQQBiAGcAQgAwAEEASABJAEEAWgBRAEIAegBBAEgATQBBAFgAQQBCAEkAQQBIAFUAQQBiAGcAQgAwAEEASABJAEEAWgBRAEIAegBBAEgATQBBAFEAUQBCAG4AQQBHAFUAQQBiAGcAQgAwAEEAQwA0AEEAYgBBAEIAdgBBAEcAYwBBAEkAZwBBAGcAQQBBADAAQQBDAGcAQgBIAEEARwBVAEEAZABBAEEAdABBAEUATQBBAGIAdwBCAHUAQQBIAFEAQQBaAFEAQgB1AEEASABRAEEASQBBAEEAawBBAEcAWQBBAGEAUQBCAHMAQQBHAFUAQQBJAEEAQQB0AEEARgBRAEEAWQBRAEIAcABBAEcAdwBBAEkAQQBBAHkAQQBEAEEAQQBJAEEAQgA4AEEAQwBBAEEAUgBnAEIAdgBBAEgASQBBAFIAUQBCAGgAQQBHAE0AQQBhAEEAQQB0AEEARQA4AEEAWQBnAEIAcQBBAEcAVQBBAFkAdwBCADAAQQBDAEEAQQBlAHcAQQBnAEEARwBrAEEAWgBnAEEAZwBBAEMAZwBBAEoAQQBCAGYAQQBDAEEAQQBMAFEAQgBzAEEARwBrAEEAYQB3AEIAbABBAEMAQQBBAEkAZwBBAHEAQQBHAEkAQQBZAFEAQgBrAEEAQwBBAEEAYwB3AEIAMABBAEcARQBBAGQAQQBCADEAQQBIAE0AQQBJAEEAQgBqAEEARwA4AEEAWgBBAEIAbABBAEQAbwBBAEkAQQBBADAAQQBEAEEAQQBNAFEAQQBxAEEAQwBJAEEASQBBAEEAdABBAEcAOABBAGMAZwBBAGcAQQBDAFEAQQBYAHcAQQBnAEEAQwAwAEEAYgBBAEIAcABBAEcAcwBBAFoAUQBBAGcAQQBDAEkAQQBLAGcAQgBpAEEARwBFAEEAWgBBAEEAZwBBAEgATQBBAGQAQQBCAGgAQQBIAFEAQQBkAFEAQgB6AEEAQwBBAEEAWQB3AEIAdgBBAEcAUQBBAFoAUQBBADYAQQBEAFEAQQBNAEEAQQB3AEEAQwBvAEEASQBnAEEAcABBAEMAQQBBAGUAdwBCAEYAQQBHAE0AQQBhAEEAQgB2AEEAQwBBAEEASQBnAEIAUABBAEYASQBBAFUAQQBCAEkAQQBFAEUAQQBUAGcAQgBGAEEARQBRAEEASQBnAEIAOQBBAEgAMABBAGYAUQBBAGcAQQBHAFUAQQBiAEEAQgB6AEEARwBVAEEASQBBAEIANwBBAEUAYwBBAFoAUQBCADAAQQBDADAAQQBRAHcAQgB2AEEARwA0AEEAZABBAEIAbABBAEcANABBAGQAQQBBAGcAQQBDAFEAQQBaAGcAQgBwAEEARwB3AEEAWgBRAEEAZwBBAEMAMABBAFYAQQBCAGgAQQBHAGsAQQBiAEEAQQBnAEEARABJAEEATQBBAEEAZwBBAEgAdwBBAEkAQQBCAEcAQQBHADgAQQBjAGcAQgBGAEEARwBFAEEAWQB3AEIAbwBBAEMAMABBAFQAdwBCAGkAQQBHAG8AQQBaAFEAQgBqAEEASABRAEEASQBBAEIANwBBAEMAQQBBAGEAUQBCAG0AQQBDAEEAQQBLAEEAQQBrAEEARgA4AEEASQBBAEEAdABBAEcAdwBBAGEAUQBCAHIAQQBHAFUAQQBJAEEAQQBpAEEAQwBvAEEAWQBnAEIAaABBAEcAUQBBAEkAQQBCAHoAQQBIAFEAQQBZAFEAQgAwAEEASABVAEEAYwB3AEEAZwBBAEcATQBBAGIAdwBCAGsAQQBHAFUAQQBPAGcAQQBnAEEARABRAEEATQBBAEEAeABBAEMAbwBBAEkAZwBBAGcAQQBDADAAQQBiAHcAQgB5AEEAQwBBAEEASgBBAEIAZgBBAEMAQQBBAEwAUQBCAHMAQQBHAGsAQQBhAHcAQgBsAEEAQwBBAEEASQBnAEEAcQBBAEcASQBBAFkAUQBCAGsAQQBDAEEAQQBjAHcAQgAwAEEARwBFAEEAZABBAEIAMQBBAEgATQBBAEkAQQBCAGoAQQBHADgAQQBaAEEAQgBsAEEARABvAEEATgBBAEEAdwBBAEQAQQBBAEsAZwBBAGkAQQBDAGsAQQBJAEEAQgA3AEEARQBVAEEAWQB3AEIAbwBBAEcAOABBAEkAQQBBAGkAQQBFADgAQQBVAGcAQgBRAEEARQBnAEEAUQBRAEIATwBBAEUAVQBBAFIAQQBBAGkAQQBIADAAQQBmAFEAQQBnAEEASAAwAEEA 2 | -------------------------------------------------------------------------------- /ConnectWise-Automate/Monitors/Orpaned Agent Remote Monitor/README.md: -------------------------------------------------------------------------------- 1 | For individual/customized setup of the Huntress Orphaned Agent monitor please see: https://support.huntress.io/hc/en-us/articles/4404004935059-ConnectWise-Automate-Remote-monitor-orphaned-agent- 2 | -------------------------------------------------------------------------------- /ConnectWise-Automate/Monitors/Orpaned Agent Remote Monitor/raw code.ps1: -------------------------------------------------------------------------------- 1 | $file = "C:\Program Files (x86)\Huntress\HuntressAgent.log" 2 | if (-not(Test-Path -Path $file -PathType Leaf)) { 3 | $file = "C:\Program Files\Huntress\HuntressAgent.log" 4 | Get-Content $file -Tail 20 | ForEach-Object { if ($_ -like "*bad status code: 401*" -or $_ -like "*bad status code:400*") {Echo "ORPHANED"}} 5 | } else { 6 | Get-Content $file -Tail 20 | ForEach-Object { if ($_ -like "*bad status code: 401*" -or $_ -like "*bad status code:400*") {Echo "ORPHANED"}} 7 | } 8 | -------------------------------------------------------------------------------- /ConnectWise-Automate/Monitors/Searches/Computer.Application.Name Contains Huntress.xml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 1176 9 | Software - Huntress Installed - Universal 10 | SELECT 11 | computers.computerid as `Computer Id`, 12 | computers.name as `Computer Name`, 13 | clients.name as `Client Name`, 14 | computers.domain as `Computer Domain`, 15 | computers.username as `Computer User`, 16 | Software.Name as `Computer.Applications.Name` 17 | FROM Computers 18 | LEFT JOIN inv_operatingsystem ON (Computers.ComputerId=inv_operatingsystem.ComputerId) 19 | LEFT JOIN Clients ON (Computers.ClientId=Clients.ClientId) 20 | LEFT JOIN Locations ON (Computers.LocationId=Locations.LocationID) 21 | LEFT JOIN Software ON (Software.ComputerId = Computers.ComputerId) 22 | WHERE 23 | ((Instr(Software.Name,'Huntress') > 0)) 24 | 25 | 4 26 | Select||=||=||=|^Select|||||||^ 27 | 9 28 | a517770d-c8a6-4647-9bd4-9473a839fec2 29 | <LabTechAbstractSearch><asn><st>AndNode</st><cn><asn><st>ComparisonNode</st><lon>Computer.Applications.Name</lon><lok>Computer.Applications.Name</lok><lmo>Contains</lmo><dv>Huntress</dv><dk>Huntress</dk></asn></cn></asn></LabTechAbstractSearch> 30 |
31 |
32 |
33 |
-------------------------------------------------------------------------------- /ConnectWise-Automate/Monitors/Searches/README.md: -------------------------------------------------------------------------------- 1 | Uploading this XML expansion via the Automate Control Center will add the Search "Software - Huntress Installed - Universal" 2 | -------------------------------------------------------------------------------- /ConnectWise-Automate/Monitors/readme.md: -------------------------------------------------------------------------------- 1 | The XML file in this repository will automatically create: 2 | 3 | - A Search containing Application contains "Huntress" 4 | - A Group with the search above applied 5 | - A Remote Monitor checking for Orphaned Agents 6 | - A Remote Monitor checking that the Huntress Service is running 7 | 8 | 9 | If you import the XML expansion via the Automate Control Center, the above items will be added automatically. 10 | 11 | To upload XML: 12 | - Log into CW Automate Control center 13 | - Click System in the bottom left 14 | - Click General>Import>XML Expansion 15 | - Select the "Computer.Application.Name Contains Huntress.xml" 16 | - Click Open 17 | -------------------------------------------------------------------------------- /ConnectWise-Automate/README.md: -------------------------------------------------------------------------------- 1 | ConnectWise Automate (formerly LabTech) script for installing the Huntress Agent. 2 | 3 | Each client will download the most recent installer directly from the Huntress server and execute it. 4 | 5 | - [Huntress Agent Install script - Download.xml](https://raw.githubusercontent.com/huntresslabs/deployment-scripts/main/ConnectWise-Automate/Huntress%20Agent%20Install%20script%20-%20Download.xml) 6 | 7 | [Please see the following document for usage details](https://support.huntress.io/hc/en-us/articles/4404012708627-Install-via-ConnectWise-Automate-Labtech-RMM) 8 | 9 | macOS deployments require additional considerations and configuration before installing. [Please refer to this document for more information](https://support.huntress.io/hc/en-us/articles/25013857741331-Critical-Steps-for-Complete-macOS-EDR-Deployment) before planning your macOS deployment. 10 | -------------------------------------------------------------------------------- /ConnectWise-Automate/Reinstall/README.md: -------------------------------------------------------------------------------- 1 | # Automate (LabTech) Script for Re-Installing the Huntress Agent 2 | 3 | **NOTE:** In most cases, you do not need to use this script. This script is meant to re-install the Huntress Agent. It does not check if the Huntress Agent is already installed. If run repeatedly (e.g. on a schedule), it will keep re-installing the agent. 4 | 5 | For normal deployments please use: 6 | https://github.com/huntresslabs/deployment-scripts/tree/master/LabTech 7 | 8 | ## Overview 9 | 10 | This script will download the most recent Huntress Agent installer from the Huntress servers and run the installer. The installer will overwrite any previously installed version of the Huntress Agent. It will not change any existing agent's configuration. 11 | 12 | - [Update Huntress Agent - Download.xml](https://raw.githubusercontent.com/huntresslabs/deployment-scripts/master/LabTech/Reinstall/Update%20Huntress%20Agent%20-%20Download.xml) 13 | 14 | The setup is the same as the normal deployment script. You will need to update the script with your Huntress account key. When scheduled, it should only be run once. 15 | 16 | Please see the following document for usage details: 17 | https://huntress.zendesk.com/hc/en-us/articles/4402100845459-Deploying-Huntress-with-ConnectWise-Automate-Labtech- 18 | -------------------------------------------------------------------------------- /ConnectWise-Automate/Reinstall/Update Huntress Agent - Download.xml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 5976 9 | 191 10 | Update Huntress Agent - Download 11 | NOTE: This script does not check if the Huntress Agent was already installed. 12 | 13 | Dowloads and installs/updates the Huntress Agent silently. Sets Org Key to company name (ClientName) for easy grouping of clients and uses the LocationName as a tag. 14 | 15 | Requirements: 16 | - Set your ACCT_KEY on Globals and Parameters tab 17 | 18 | Updated: 5 October 2018 19 | 0, 20 | 0, 21 | 1 22 | 0 23 | 0 24 | 0 25 | H4sIAAAAAAAEAFWPwQqDMBBE74X+gx9gSFYbLbIESi29tJdWeo9xhRwaJRqof98qLdjDMOwMb2HwYg25gUo9aoXV1JMC5IvjLbhjF9xIXgnkqwtPr976mSFVBRoaPcVRSYaeNfkoEfFHkEUgCkiKVESHK/IVgnfjbT8+yA+2c/Pv/+Dbn4NtFNV7LbWpmcnSlgFQxvawk0wkudGS8raV8OMXAPl60XbzBmk+TInhAAAA 26 | H4sIAAAAAAAEAOWZUW/aMBCA3yftP1iV0J5oSCDQIhoV0ZahbWq1dJMmTUImOYhV10Gxs3X/fsE4EKLElbpEKOwJ39lO7M93vrswcr2IrMUNFth5/w6h0VbmUkjE2xcR4U3vHQHqc2SkHQ84ws8gIMropjRcYMod7Hli/gR/riYBZiv4AiMj7VIjt2/5nswmIXPMkXGoOBg1jYnvwOIC29hbtL1+d9k2Tei3L8ye3e5YAw/bMFgu7d1T5AS5GSO7G/U4V8B6t46xJ9QCVEvp72Im5Zm/6ctI2d2bORpWTu7m5F5OtveyG0bC6STr3fwq3SRkgrAYNvpdW/Xd88/kmcgpaVP1zJgPTGC5maQ3K2aR7ClosFg6LN3LcjDOJADvCYkAC5QaA1pJE0C/cETwggIKMEcLAIY4iJGhJv63PAcdDc6UYTGmzXNV6wCXs3c/pTig5wy/rX0sYL71TTWop0VqNgmp1dH4rhMIseZDwwhiJiLg/JyEhh/+ZjTEvnGdEr8uQd4S8Lz2SdT6+VHNnzEuMKUQncMLlBxIp/gkXrFjq0nQTbOngb7HlmInBdjysM0SnMMbdV7zO0wo+G+i220SXatra+habzNWZIwnk8f5p9sfV3u7R8b916nUnbU8SpLtsCTet86Q8TieuomShp7cYKp2iw8pf2fvfCB30Tg8AEqTtcU0jQb2wTn1GnVOuuB4ndlqyf3yj5HPPhlWMpEgbIVSy0XjVbIMpK6NWuj1m0RPn4cNJb/5rEZagybRsjXBqeJs/qJqLmadVmTp0s9D3ysJMkM39rxk0DKmOXt7JSK8wvGySRy1d1nxFYaWMnc5Rw8UMAfkydKJhitei7ualVdFtfI0NflOxQ5rVl7c1Oqx+nu/qLSr2JAaVZZoHdMFzWeKkCERAOLytR84Ul+yEGY+ynwEE3ghVRFEMasHeOWVysl4buW1wRE9t7imrdiUTqdASHHtwuik5vhZeXVwMl5YeSVwRC8sTWYrtqbKq4SjOWJJdsu3IOuhd4zaIJXVX2Z/AbB5MSpBGwAA 27 | 1 28 | eb8a5acb-c63f-11e6-8145-027ca5e7ff51 29 | 0 30 | 31 |
32 |
33 | 34 | 35 | 36 | 191 37 | 0 38 | Custom Scripts 39 | 2913a92b-4d16-4166-969d-ae4a804426b3 40 |
41 |
42 |
43 |
44 |
-------------------------------------------------------------------------------- /ConnectWise-Automate/staged/Huntress Agent Install - Download.xml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 6301 9 | 266 10 | Huntress Agent Install - Download 11 | Downloads and installs the Huntress Agent silently. Sets Org Key to company name (ClientName) for easy grouping of clients and uses the LocationName as a tag. 12 | 13 | Windows & macOS support 14 | 15 | Requirements: 16 | - Set your ACCT_KEY on Globals and Parameters tab 17 | 18 | Updated: 07 July 2022 19 | 0, 20 | 0, 21 | 1 22 | 0 23 | 0 24 | 0 25 | H4sIAAAAAAAEAFWPzQrCMBCE74LvkAdoSLZ/alkCYsWLXlS8N8kecjAtaQP27bVFoR6GYWf4FgbPzpDvqW6GRuF97EgBitnxGv2hjX6goCSKxYXHV+fCxJC6R+ptMyasJkNPTYGlMvkISgaygrTKJNtfUCwQvJnguuFBoXetn37/B9/+FJ1VhspymxHxPDeSA5DmWmvLpYSisECbncx+/AygWC5ar95wg2/34QAAAA== 26 | H4sIAAAAAAAEAOVbXW+jOBR9X2n+gzVSNU8pGELTRh3UKtN2q+2oo013VyONFBm4E6yhJgIzH/9+Cdj5QOC0BILIPIVrmwQfzr2+x9e5nLoRXfAPhBP7zR8IXeZ2nBmpefOTR2TZe0sh8GKkyY5PJCLPwCHaaLsLQocEsU1cl8++wa/3E5+wOXyES012iZH5r/yb3k1DZuNLbbtha9RdQj3bhbOzcxNgMBy6+gBjcAaO43gDXceW5WEYXeim/Jbshmwy2uZsxNdNOSxWz3HtcvEA4kq03yYss++9Zd+GtTl7XEDDKNhmwR4WbGttT8OI23r6vMtP0TYJGacsgWX76lr0PcYP9Jlmt8hL0XPPPGCcZJNJezfNTUjWKChgMRSwGHo1LkvMxNUWPvZTlIDoMrahsvOnuGFzyuCGESeAh3A+h0gMN48XSWt4MIbhPuGClRT7M2E8gjhG1/P05yv4Nl6PCiIg3i9EWcxJEIBXTsNX4mk0jSdu02OtcwWeY9cH9xsiAUe+BI2lEb4c2T15aB4fD19GQ9IKDYd9oiE2LlQ0vM+RQRKyVvhn9Yl/O/x2J7eahe6sV9CpqHZg4EZ9clIDWwdLSs57BYzaGQ8SvS765ILYVPngJEs6uE84kqIRzTOpiL6TiC5lAPJJjBwAhmKoWGD3zYp7JRdGqmxEgliRiBgV4mut08vElj3+Z+ERDrNcxItBQzWm/ZIaSpL+R5kX/mjHl3ENCTEw8HA0PDfPTNxdHNQV+yK2z/kiHmuaVBKnNNRSCFkQEk+7kiS9qmDpCYfnhUejky8yjIqwCtEp/KzaQNBr7RTgGlIEj5SwG20SFSs2CzaAk8DTEuCKcOMKQMcfxBub3RK6zopeiW8NbdIhvoapyHtW4fOVhEXa9WTyNPvr5vP7NfeR9vj3Xdb29sQNaDqdpdo+eYu0p+u7adoYhG42Qdk8fZlUXPlBIT7bV7EPQZrpxknApedZ2++qhizq8l2pYnbZbBuO3DWU0A60zM6WuGfiPk7bgamG7lkvcFZ32xS6Ci83iQI0CNHK8zXp+R+JK5z/NPbR4AGVrYVx9kiaR6IflO1cEItvoJTcrwzLNUTXcqn8TV29huLagVarrv6yJKGcsl0kCUYNAdYhG9WhwSGp3++MCwRtpAJpICkkAQOOihnAwWKDUUO6/b6xwagh4LqMDco0YJztx8wEUdvBq1e1HyW5MrAom6PtWqTcR24HvsZrPUdS2jYar+m0WwTbv7Y9TVw3HfQ1CQoOu2dNu/EKT6tr8f7F2bZwbLzg09kqWh7f0Ncs4ztFnwIgMaD8AEEQztvZKTX6VSc6YAHNaLwg1GroU2cgZaWGhg+f9Krco3TMKSjqZiFD3AeU7zW8i5E4gokI81B2f356kxMna4ogSlg7gDdeCzoWzzV7dYBsh+eW7wQ0TKXjUQ8SrtUyOml3/TR7dUrsoF7YL+mg9sLKbLZhNh3hObDt7DbOgWwHvS4Og0lb/Nfjf4ItT4n6MQAA 27 | 1 28 | ce6683ee-44c0-11eb-bbbd-00155d1e7903 29 | 0 30 | 31 |
32 |
33 | 34 | 35 | 36 | 266 37 | 0 38 | Huntress Scripts 39 | f6016cba-5efc-4cd5-a502-e61da703275f 40 |
41 |
42 |
43 |
44 |
-------------------------------------------------------------------------------- /ConnectWise-Automate/staged/Huntress Agent Install script.xml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 5972 9 | 191 10 | Huntress Agent Install 11 | Installs the Huntress Agent silently. Sets Org Key to company name (ClientName) for easy grouping of clients and uses the LocationName as a tag. 12 | 13 | Requirements: 14 | - Set your ACCT_KEY on Globals and Parameters tab 15 | - Installer file needs to be saved in the root of the transfer (LabTech/Transfer) folder as huntressinstaller.exe. 16 | 17 | Updated: 9 December 2017 18 | 0, 19 | 0, 20 | 1 21 | 0 22 | 0 23 | 0 24 | H4sIAAAAAAAEAFWPwQqDMBBE74X+gx9gSFYbLbIESi29tJdWeo9xhRwaJRqof98qLdjDMOwMb2HwYg25gUo9aoXV1JMC5IvjLbhjF9xIXgnkqwtPr976mSFVBRoaPcVRSYaeNfkoEfFHkEUgCkiKVESHK/IVgnfjbT8+yA+2c/Pv/+Dbn4NtFNV7LbWpmcnSlgFQxvawk0wkudGS8raV8OMXAPl60XbzBmk+TInhAAAA 25 | H4sIAAAAAAAEAN2Z7W+aQBjAvy/Z/3BpYvbJIiDaGks0dnVmW9qMbsmSJeaERyG9HoY7tva/Hz0PBSMXm8IcfJLnuePl+fG84tBxo2DNrzHH9vt3CA03MhNCIn584hF+Wb0JgHgMaenCHY7wI3CIMropCReYMBu7Lp8/wPPVxMd0BV9hqKVLcufmLj+Ss4OQ2vpQyytyu6Zx4NmwuMAWdhdtt2cu27oOvfaF3rXaHaPvYgv6y6W1vYo4QRijZa2Rl3M4rLfPMXa5fAB5JPU3MRXyzLN7xlDLiFnzdftTTHkEjKHxCigfalKd3WTYHak3cnpzj2V3T7Z2shNG/OUq4lfqJiHlAY3hRb89lmu37EvwGIhT0kO5MqNe8pxYmJqsZsUssB0jBTRDAc24PAYaJhFg7xkFlHFMCHiHAe6BaTY43Somt2foW8Ho/xsYUwFGN1UuNfHBfUDcxxylyQetRMpBv3EU4AUB5GOGFgAUMSiI1KY5mopnv6PAmTIsSGjG4YRm79K9VOTo2YPvaw9zmG9qgdzUbY6LGh0V0zTrzWSyi87hCQoAtzg8rr0gav1SnfW2emLUCa2udxVod7h8iSs4ArJe4MWD6/APJSH25jc42BUl81V0zTrRNUxF0dlG+yudFGnjyeR+/vnjz6tRmk9GSLv9NhW6s5ZLgsQcmnSRrTOk3Y+nTqIkoSsMTNXOcb6+7bH20onNfCBJl8FikuZ8K/eeurV6T6oSOMqYOqqkvlmNYSXahYCuUL5/TxvRSuj16kRP3W0NBL/5rEJa/TrRshTFqeSe/aJsLnqVXmQc0xApZ+eBE7tusmkZkz1/e1v3c1knjsdN07kUhpaidzlHdwQwA+SKAYmEK1ZJuOqlzz6V8vyXQ3bpI0ylEavO+4cGuJIdqVZjiTIwHVB8jAgp4j4gJm77gSH5fRRh6qHMp1WOF0IVQRTTaoCXPqk0JnJLnw1OGLmHZ9qSXak5A0KKa1tGJxXXz9Kng8ZEYemTwAmjsLCZLdmbSp8SThaIBd0t24Csht4pZoNUln/E/gU8bPcclx0AAA== 26 | 1 27 | eb8a5acb-c63f-11e6-8145-027ca5e7ff51 28 | 0 29 | 30 |
31 |
32 | 33 | 34 | 35 | 191 36 | 0 37 | Custom Scripts 38 | 2913a92b-4d16-4166-969d-ae4a804426b3 39 |
40 |
41 |
42 |
43 |
-------------------------------------------------------------------------------- /ConnectWise-Automate/staged/InstallHuntress.automate.ps1: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Huntress Labs, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # * Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # * Neither the name of the Huntress Labs nor the names of its contributors 12 | # may be used to endorse or promote products derived from this software 13 | # without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL HUNTRESS LABS BE LIABLE FOR ANY DIRECT, INDIRECT, 19 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 21 | # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 23 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | 27 | # The Huntress installer needs an Account Key and an Organization Key (a user 28 | # specified name or description) which is used to affiliate an Agent with a 29 | # specific Organization within the Huntress Partner's Account. These keys can be 30 | # hard coded below or passed in when the script is run. 31 | 32 | # See https://support.huntress.io/article/7-using-account-and-organization-keys 33 | # for more details. 34 | 35 | # Usage: 36 | # powershell -executionpolicy bypass -f ./InstallHuntress.powershellv1.ps1 [-acctkey ] [-orgkey ] 37 | 38 | # Optional command line params, this has to be the first line in the script. 39 | param ( 40 | [string]$acctkey, 41 | [string]$orgkey, 42 | [switch]$reregister, 43 | [switch]$reinstall 44 | ) 45 | 46 | # The Huntress account secret comes from the Automate @acct_key@ global parameter. 47 | $AccountKey = "@acct_key@" 48 | 49 | # Use the Automate clientname as the Huntress organization key. 50 | $OrganizationKey = "%clientname%" 51 | 52 | # Set to "Continue" to enable verbose logging. 53 | $DebugPreference = "SilentlyContinue" 54 | 55 | ############################################################################## 56 | ## The following should not need to be adjusted. 57 | 58 | # Find poorly written code faster with the most stringent setting. 59 | Set-StrictMode -Version Latest 60 | 61 | # Do not modify the following variables. 62 | # These are used by the Huntress support team when troubleshooting. 63 | $ScriptVersion = "Version 2, major revision 7, 2023 June 21" 64 | $ScriptType = "Automate" 65 | 66 | # Check for an account key specified on the command line. 67 | if ( ! [string]::IsNullOrEmpty($acctkey) ) { 68 | $AccountKey = $acctkey 69 | } 70 | $AccountKey = $AccountKey.Trim() 71 | 72 | # Check for an organization key specified on the command line. 73 | if ( ! [string]::IsNullOrEmpty($orgkey) ) { 74 | $OrganizationKey = $orgkey 75 | } 76 | $OrganizationKey = $OrganizationKey.Trim() 77 | 78 | # Variables used throughout the Huntress Deployment Script. 79 | $X64 = 64 80 | $X86 = 32 81 | $InstallerName = "HuntressInstaller.exe" 82 | $InstallerPath = Join-Path $Env:TMP $InstallerName 83 | $DebugLog = Join-Path $Env:TMP HuntressInstaller.log 84 | $DownloadURL = "https://update.huntress.io/download/" + $AccountKey + "/" + $InstallerName 85 | $HuntressAgentServiceName = "HuntressAgent" 86 | $HuntressUpdaterServiceName = "HuntressUpdater" 87 | 88 | $ScriptFailed = "Script Failed!" 89 | $SupportMessage = "Please send the error message to the Huntress Team for help at support@huntress.com" 90 | 91 | function Get-TimeStamp { 92 | return "[{0:yyyy/MM/dd} {0:HH:mm:ss}]" -f (Get-Date) 93 | } 94 | 95 | function LogMessage ($msg) { 96 | Add-Content $DebugLog "$(Get-TimeStamp) $msg" 97 | Write-Host "$(Get-TimeStamp) $msg" 98 | } 99 | 100 | function Test-Parameters { 101 | LogMessage "Verifying received parameters..." 102 | 103 | # Ensure mutually exclusive parameters were not both specified. 104 | if ($reregister -and $reinstall) { 105 | $err = "Cannot specify both `-reregister` and `-reinstall` parameters, exiting script!" 106 | LogMessage $err 107 | exit 1 108 | } 109 | 110 | # Ensure we have an account key (either hard coded or from the command line params). 111 | if ($AccountKey -eq "__ACCOUNT_KEY__") { 112 | $err = "AccountKey not set!" 113 | LogMessage $err 114 | throw $ScriptFailed + " " + $err 115 | exit 1 116 | } elseif ($AccountKey.length -ne 32) { 117 | $err = "Invalid AccountKey specified (incorrect length)!" 118 | LogMessage $err 119 | throw $ScriptFailed + " " + $err 120 | exit 1 121 | } 122 | 123 | # Ensure we have an organization key (either hard coded or from the command line params). 124 | if ($OrganizationKey -eq "__ORGANIZATION_KEY__") { 125 | $err = "OrganizationKey not specified!" 126 | LogMessage $err 127 | throw $ScriptFailed + " " + $err 128 | exit 1 129 | } elseif ($OrganizationKey.length -lt 1) { 130 | $err = "Invalid OrganizationKey specified (length is 0)!" 131 | LogMessage $err 132 | throw $ScriptFailed + " " + $err 133 | exit 1 134 | } 135 | } 136 | 137 | function Confirm-ServiceExists ($service) { 138 | if (Get-Service $service -ErrorAction SilentlyContinue) { 139 | return $true 140 | } 141 | return $false 142 | } 143 | 144 | function Confirm-ServiceRunning ($service) { 145 | $arrService = Get-Service $service 146 | $status = $arrService.Status.ToString() 147 | if ($status.ToLower() -eq 'running') { 148 | return $true 149 | } 150 | return $false 151 | } 152 | 153 | function Get-WindowsArchitecture { 154 | if ($env:ProgramW6432) { 155 | $WindowsArchitecture = $X64 156 | } else { 157 | $WindowsArchitecture = $X86 158 | } 159 | 160 | return $WindowsArchitecture 161 | } 162 | 163 | function verifyInstaller ($file) { 164 | # Ensure the installer was not modified during download by validating the file signature. 165 | $varChain = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Chain 166 | try { 167 | $varChain.Build((Get-AuthenticodeSignature -FilePath "$file").SignerCertificate) | out-null 168 | } catch [System.Management.Automation.MethodInvocationException] { 169 | $err = ( 170 | "ERROR: '$file' did not contain a valid digital certificate. " + 171 | "Something may have corrupted/modified the file during the download process. " + 172 | "If the problem persists please file a support ticket.") 173 | LogMessage $err 174 | LogMessage $SupportMessage 175 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 176 | } 177 | } 178 | 179 | function Get-Installer { 180 | $msg = "Downloading installer to '$InstallerPath'..." 181 | LogMessage $msg 182 | 183 | # Ensure a secure TLS version is used. 184 | $ProtocolsSupported = [enum]::GetValues('Net.SecurityProtocolType') 185 | if ( ($ProtocolsSupported -contains 'Tls13') -and ($ProtocolsSupported -contains 'Tls12') ){ 186 | LogMessage "Using TLS 1.3 or 1.2..." 187 | [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 -bor [System.Net.SecurityProtocolType]::Tls13 188 | } else { 189 | LogMessage "Using TLS 1.2..." 190 | try { 191 | # In certain .NET 4.0 patch levels, SecurityProtocolType does not have a TLS 1.2 entry. 192 | # Rather than check for 'Tls12', we force-set TLS 1.2 and catch the error if it's truly unsupported. 193 | [Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 194 | } catch { 195 | $msg = $_.Exception.Message 196 | $err = "ERROR: Unable to use a secure version of TLS. Please verify Hotfix KB3140245 is installed." 197 | LogMessage $msg 198 | LogMessage $err 199 | throw $ScriptFailed + " " + $msg + " " + $err 200 | } 201 | } 202 | 203 | $WebClient = New-Object System.Net.WebClient 204 | 205 | try { 206 | $WebClient.DownloadFile($DownloadURL, $InstallerPath) 207 | } catch { 208 | $msg = $_.Exception.Message 209 | $err = ( 210 | "ERROR: Failed to download the Huntress Installer. Please try accessing $DownloadURL " + 211 | "from a web browser on the host where the download failed. If the issue persists, please " + 212 | "send the error message to the Huntress Team for help at support@huntress.com.") 213 | LogMessage $msg 214 | LogMessage $err 215 | throw $ScriptFailed + " " + $err + " " + $msg 216 | } 217 | 218 | if ( ! (Test-Path $InstallerPath) ) { 219 | $err = "ERROR: Failed to download the Huntress Installer from $DownloadURL." 220 | LogMessage $err 221 | LogMessage $SupportMessage 222 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 223 | } 224 | 225 | $msg = "Installer downloaded to '$InstallerPath'..." 226 | LogMessage $msg 227 | } 228 | 229 | function Install-Huntress ($OrganizationKey) { 230 | LogMessage "Checking for installer '$InstallerPath'..." 231 | if ( ! (Test-Path $InstallerPath) ) { 232 | $err = "ERROR: The installer was unexpectedly removed from $InstallerPath" 233 | $msg = ( 234 | "A security product may have quarantined the installer. Please check " + 235 | "your logs. If the issue continues to occur, please send the log to the Huntress " + 236 | "Team for help at support@huntresslabs.com") 237 | LogMessage $err 238 | LogMessage $msg 239 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 240 | } 241 | 242 | verifyInstaller($InstallerPath) 243 | 244 | $msg = "Executing installer..." 245 | LogMessage $msg 246 | 247 | $timeout = 30 # Seconds 248 | $process = Start-Process $InstallerPath "/ACCT_KEY=`"$AccountKey`" /ORG_KEY=`"$OrganizationKey`" /S" -PassThru 249 | try { 250 | $process | Wait-Process -Timeout $timeout -ErrorAction Stop 251 | } catch { 252 | $process | Stop-Process -Force 253 | $err = "ERROR: Installer failed to complete in $timeout seconds." 254 | LogMessage $err 255 | LogMessage $SupportMessage 256 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 257 | } 258 | } 259 | 260 | function Test-Installation { 261 | LogMessage "Verifying installation..." 262 | 263 | # Give the agent a few seconds to start and register. 264 | Start-Sleep -Seconds 8 265 | 266 | # Ensure we resolve the correct Huntress directory regardless of operating system or process architecture. 267 | $WindowsArchitecture = Get-WindowsArchitecture 268 | if ($WindowsArchitecture -eq $X86) { 269 | $HuntressDirPath = Join-Path $Env:ProgramFiles "Huntress" 270 | } elseif ($WindowsArchitecture -eq $X64) { 271 | $HuntressDirPath = Join-Path $Env:ProgramW6432 "Huntress" 272 | } else { 273 | $err = "ERROR: Failed to determine the Windows Architecture. Received $WindowsArchitecture." 274 | LogMessage $err 275 | LogMessage $SupportMessage 276 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 277 | } 278 | 279 | $HuntressAgentPath = Join-Path $HuntressDirPath "HuntressAgent.exe" 280 | $HuntressUpdaterPath = Join-Path $HuntressDirPath "HuntressUpdater.exe" 281 | $hUpdaterPath = Join-Path $HuntressDirPath "hUpdate.exe" 282 | $HuntressKeyPath = "HKLM:\SOFTWARE\Huntress Labs\Huntress" 283 | $AgentIdKeyValueName = "AgentId" 284 | $OrganizationKeyValueName = "OrganizationKey" 285 | $TagsValueName = "Tags" 286 | 287 | # Ensure the critical files were created. 288 | foreach ( $file in ($HuntressAgentPath, $HuntressUpdaterPath, $hUpdaterPath) ) { 289 | if ( ! (Test-Path $file) ) { 290 | $err = "ERROR: $file did not exist." 291 | LogMessage $err 292 | LogMessage $SupportMessage 293 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 294 | } 295 | } 296 | 297 | # Ensure the Huntress registry key is present. 298 | if ( ! (Test-Path $HuntressKeyPath) ) { 299 | $err = "ERROR: The registry key '$HuntressKeyPath' did not exist." 300 | LogMessage $err 301 | LogMessage $SupportMessage 302 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 303 | } 304 | 305 | $HuntressKeyObject = Get-ItemProperty $HuntressKeyPath 306 | 307 | # Ensure the Huntress registry values are present. 308 | foreach ( $value in ($AgentIdKeyValueName, $OrganizationKeyValueName, $TagsValueName) ) { 309 | If ( ! (Get-Member -inputobject $HuntressKeyObject -name $value -Membertype Properties) ) { 310 | $err = "ERROR: The registry value $value did not exist within $HuntressKeyPath." 311 | LogMessage $err 312 | LogMessage $SupportMessage 313 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 314 | } 315 | } 316 | 317 | # Ensure the services are installed and running. 318 | foreach ( $svc in ($HuntressAgentServiceName, $HuntressUpdaterServiceName) ) { 319 | # service installed? 320 | if ( ! (Confirm-ServiceExists($svc)) ) { 321 | $err = "ERROR: The $svc service is not installed." 322 | LogMessage $err 323 | LogMessage $SupportMessage 324 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 325 | } 326 | 327 | # service running? 328 | if ( ! (Confirm-ServiceRunning($svc)) ) { 329 | $err = "ERROR: The $svc service is not running." 330 | LogMessage $err 331 | LogMessage $SupportMessage 332 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 333 | } 334 | } 335 | 336 | # Verify the agent registered. 337 | If ($HuntressKeyObject.$AgentIdKeyValueName -eq 0) { 338 | $err = ("ERROR: The agent did not register. Check the log (%ProgramFiles%\Huntress\HuntressAgent.log) for errors.") 339 | LogMessage $err 340 | LogMessage $SupportMessage 341 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 342 | } 343 | 344 | $msg = "Installation verified!" 345 | LogMessage $msg 346 | } 347 | 348 | function StopHuntressServices { 349 | LogMessage "Stopping Huntress services..." 350 | Stop-Service -Name "$HuntressAgentServiceName" 351 | Stop-Service -Name "$HuntressUpdaterServiceName" 352 | } 353 | 354 | function StartHuntressServices { 355 | LogMessage "Starting Huntress services..." 356 | Start-Service -Name "$HuntressAgentServiceName" 357 | Start-Service -Name "$HuntressUpdaterServiceName" 358 | } 359 | 360 | function PrepReregister { 361 | LogMessage "Preparing to re-register agent..." 362 | StopHuntressServices 363 | 364 | $HuntressKeyPath = "HKLM:\SOFTWARE\Huntress Labs\Huntress" 365 | Remove-Item -Path "$HuntressKeyPath" -Recurse -ErrorAction SilentlyContinue 366 | } 367 | 368 | function main () { 369 | LogMessage "Script type: '$ScriptType'" 370 | LogMessage "Script version: '$ScriptVersion'" 371 | LogMessage "Host name: '$env:computerName'" 372 | $os = (get-WMiObject -computername $env:computername -Class win32_operatingSystem).caption 373 | LogMessage "Host OS: '$os'" 374 | LogMessage "Host Architecture: '$(Get-WindowsArchitecture)'" 375 | LogMessage "Re-register agent: '$reregister'" 376 | LogMessage "Installer location: '$InstallerPath'" 377 | LogMessage "Installer log: '$DebugLog'" 378 | 379 | $masked = $AccountKey.Substring(0,10) + "XXXXXXXXXXXXXXXXXXXXXXX" 380 | LogMessage "AccountKey: '$masked'" 381 | LogMessage "OrganizationKey: '$OrganizationKey'" 382 | 383 | Test-Parameters 384 | 385 | if ($reregister) { 386 | PrepReregister 387 | } elseif ($reinstall) { 388 | LogMessage "Re-installing agent..." 389 | if ( !(Confirm-ServiceExists($HuntressAgentServiceName)) ) { 390 | $err = "The Huntress Agent is NOT installed; nothing to re-install. Exiting." 391 | LogMessage "$err" 392 | exit 1 393 | } 394 | StopHuntressServices 395 | } else { 396 | LogMessage "Checking for HuntressAgent service..." 397 | if ( Confirm-ServiceExists($HuntressAgentServiceName) ) { 398 | StartHuntressServices 399 | $err = "The Huntress Agent is already installed. Exiting." 400 | LogMessage "$err" 401 | exit 0 402 | } 403 | } 404 | 405 | Get-Installer 406 | Install-Huntress $OrganizationKey 407 | Test-Installation 408 | LogMessage "Huntress Agent successfully installed!" 409 | } 410 | 411 | try 412 | { 413 | main 414 | } catch { 415 | $ErrorMessage = $_.Exception.Message 416 | LogMessage $ErrorMessage 417 | exit 1 418 | } 419 | -------------------------------------------------------------------------------- /ConnectWise-Automate/staged/README.md: -------------------------------------------------------------------------------- 1 | *NOTE* This script is deprecated and has been superceded by [a new script](https://github.com/huntresslabs/deployment-scripts/tree/master/LabTech) that automatically downloads the most recent version of the installer. 2 | 3 | Automate (LabTech) script for installing the Huntress Agent. 4 | 5 | With this version of the script, the Huntress Agent installer is staged on the LabTech Transfer share. 6 | 7 | - [Huntress Agent Install script.xml](https://raw.githubusercontent.com/huntresslabs/deployment-scripts/master/LabTech/Huntress%20Agent%20Install%20script.xml): the Huntress Agent installer must be staged on the LabTech Transfer Share 8 | 9 | Please see the following document for details about importing and customizing the script: 10 | https://support.huntress.io/article/41-deploying-huntress-via-labtech-automate 11 | 12 | In addition, you will need to [download the Huntress Agent Installer](https://support.huntress.io/article/6-installing-the-huntress-agent#download) and place it in the root of the LabTech transfer share (C:\LTShare\Transfer by default for non-hosted Automate servers). 13 | -------------------------------------------------------------------------------- /ConnectWise-Control/InstallHuntress.ConnectWiseControl.ps1: -------------------------------------------------------------------------------- 1 | #!ps 2 | #timeout=90000 3 | 4 | $AccountKey="__ACCOUNT_KEY__" 5 | $OrganizationKey="__ORGANIZATION_KEY__" 6 | # Set to "Continue" to enable verbose logging. 7 | $DebugPreference = "SilentlyContinue" 8 | $timeout = 180 # Seconds 9 | 10 | ############################################################################## 11 | ## The following should not need to be adjusted. 12 | ############################################################################## 13 | $reregister = $false 14 | $reinstall = $false 15 | $acctkey = $AccountKey 16 | $orgkey = $OrganizationKey 17 | Set-StrictMode -Version Latest 18 | $ScriptVersion = "Version 1, major revision 1, 2023 Oct 9" 19 | $ScriptType = "PowerShell (ConnectWise Control / ScreenConnect)" 20 | if ( ! [string]::IsNullOrEmpty($acctkey) ) { 21 | $AccountKey = $acctkey 22 | } 23 | if ( ! [string]::IsNullOrEmpty($orgkey) ) { 24 | $OrganizationKey = $orgkey 25 | } 26 | $X64 = 64 27 | $X86 = 32 28 | $InstallerName = "HuntressInstaller.exe" 29 | $InstallerPath = Join-Path $Env:TMP $InstallerName 30 | $DebugLog = Join-Path $Env:TMP HuntressInstaller.log 31 | $DownloadURL = "https://update.huntress.io/download/" + $AccountKey + "/" + $InstallerName 32 | $HuntressAgentServiceName = "HuntressAgent" 33 | $HuntressUpdaterServiceName = "HuntressUpdater" 34 | 35 | $PowerShellArch = $X86 36 | if ([IntPtr]::size -eq 8) { 37 | $PowerShellArch = $X64 38 | } 39 | $ScriptFailed = "Script Failed!" 40 | $SupportMessage = "Please send the error message to the Huntress Team for help at support@huntress.com" 41 | function Get-TimeStamp { 42 | return "[{0:yyyy/MM/dd} {0:HH:mm:ss}]" -f (Get-Date) 43 | } 44 | function LogMessage ($msg) { 45 | Add-Content $DebugLog "$(Get-TimeStamp) $msg" 46 | Write-Host "$(Get-TimeStamp) $msg" 47 | } 48 | function Test-Parameters { 49 | LogMessage "Verifying received parameters..." 50 | if ($reregister -and $reinstall) { 51 | $err = "Cannot specify both `-reregister` and `-reinstall` parameters, exiting script!" 52 | LogMessage $err 53 | exit 1 54 | } 55 | if ($AccountKey -eq "__ACCOUNT_KEY__") { 56 | $err = "AccountKey not set!" 57 | LogMessage $err 58 | throw $ScriptFailed + " " + $err 59 | exit 1 60 | } elseif ($AccountKey.length -ne 32) { 61 | $err = "Invalid AccountKey specified (incorrect length)!" 62 | LogMessage $err 63 | throw $ScriptFailed + " " + $err 64 | exit 1 65 | } 66 | if ($OrganizationKey -eq "__ORGANIZATION_KEY__") { 67 | $err = "OrganizationKey not specified!" 68 | LogMessage $err 69 | throw $ScriptFailed + " " + $err 70 | exit 1 71 | } elseif ($OrganizationKey.length -lt 1) { 72 | $err = "Invalid OrganizationKey specified (length is 0)!" 73 | LogMessage $err 74 | throw $ScriptFailed + " " + $err 75 | exit 1 76 | } 77 | } 78 | 79 | function Confirm-ServiceExists ($service) { 80 | if (Get-Service $service -ErrorAction SilentlyContinue) { 81 | return $true 82 | } 83 | return $false 84 | } 85 | 86 | function Confirm-ServiceRunning ($service) { 87 | $arrService = Get-Service $service 88 | $status = $arrService.Status.ToString() 89 | if ($status.ToLower() -eq 'running') { 90 | return $true 91 | } 92 | return $false 93 | } 94 | 95 | function Get-WindowsArchitecture { 96 | if ($env:ProgramW6432) { 97 | $WindowsArchitecture = $X64 98 | } else { 99 | $WindowsArchitecture = $X86 100 | } 101 | 102 | return $WindowsArchitecture 103 | } 104 | 105 | function verifyInstaller ($file) { 106 | $varChain = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Chain 107 | try { 108 | $varChain.Build((Get-AuthenticodeSignature -FilePath "$file").SignerCertificate) | out-null 109 | } catch [System.Management.Automation.MethodInvocationException] { 110 | $err = ( 111 | "ERROR: '$file' did not contain a valid digital certificate. " + 112 | "Something may have corrupted/modified the file during the download process. " + 113 | "If the problem persists please file a support ticket.") 114 | LogMessage $err 115 | LogMessage $SupportMessage 116 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 117 | } 118 | } 119 | 120 | function Get-Installer { 121 | $msg = "Downloading installer to '$InstallerPath'..." 122 | LogMessage $msg 123 | $ProtocolsSupported = [enum]::GetValues('Net.SecurityProtocolType') 124 | if ( ($ProtocolsSupported -contains 'Tls13') -and ($ProtocolsSupported -contains 'Tls12') ) { 125 | # Use only TLS 1.3 or 1.2 126 | LogMessage "Using TLS 1.3 or 1.2..." 127 | [Net.ServicePointManager]::SecurityProtocol = ( 128 | [Enum]::ToObject([Net.SecurityProtocolType], 12288) -bOR [Enum]::ToObject([Net.SecurityProtocolType], 3072) 129 | ) 130 | } else { 131 | LogMessage "Using TLS 1.2..." 132 | try { 133 | [Net.ServicePointManager]::SecurityProtocol = [Enum]::ToObject([Net.SecurityProtocolType], 3072) 134 | } catch { 135 | $msg = $_.Exception.Message 136 | $err = "ERROR: Unable to use a secure version of TLS. Please verify Hotfix KB3140245 is installed." 137 | LogMessage $msg 138 | LogMessage $err 139 | throw $ScriptFailed + " " + $msg + " " + $err 140 | } 141 | } 142 | $WebClient = New-Object System.Net.WebClient 143 | try { 144 | $WebClient.DownloadFile($DownloadURL, $InstallerPath) 145 | } catch { 146 | $msg = $_.Exception.Message 147 | $err = ( 148 | "ERROR: Failed to download the Huntress Installer. Please try accessing $DownloadURL " + 149 | "from a web browser on the host where the download failed. If the issue persists, please " + 150 | "send the error message to the Huntress Team for help at support@huntress.com.") 151 | LogMessage $msg 152 | LogMessage $err 153 | throw $ScriptFailed + " " + $err + " " + $msg 154 | } 155 | 156 | if ( ! (Test-Path $InstallerPath) ) { 157 | $err = "ERROR: Failed to download the Huntress Installer from $DownloadURL." 158 | LogMessage $err 159 | LogMessage $SupportMessage 160 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 161 | } 162 | 163 | $msg = "Installer downloaded to '$InstallerPath'..." 164 | LogMessage $msg 165 | } 166 | 167 | function Install-Huntress ($OrganizationKey) { 168 | LogMessage "Checking for installer '$InstallerPath'..." 169 | if ( ! (Test-Path $InstallerPath) ) { 170 | $err = "ERROR: The installer was unexpectedly removed from $InstallerPath" 171 | $msg = ( 172 | "A security product may have quarantined the installer. Please check " + 173 | "your logs. If the issue continues to occur, please send the log to the Huntress " + 174 | "Team for help at support@huntresslabs.com") 175 | LogMessage $err 176 | LogMessage $msg 177 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 178 | } 179 | verifyInstaller($InstallerPath) 180 | $msg = "Executing installer..." 181 | LogMessage $msg 182 | $process = Start-Process $InstallerPath "/ACCT_KEY=`"$AccountKey`" /ORG_KEY=`"$OrganizationKey`" /S" -PassThru 183 | try { 184 | $process | Wait-Process -Timeout $timeout -ErrorAction Stop 185 | } catch { 186 | $process | Stop-Process -Force 187 | $err = "ERROR: Installer failed to complete in $timeout seconds." 188 | LogMessage $err 189 | LogMessage $SupportMessage 190 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 191 | } 192 | } 193 | 194 | function Test-Installation { 195 | LogMessage "Verifying installation..." 196 | Start-Sleep -Seconds 8 197 | $WindowsArchitecture = Get-WindowsArchitecture 198 | if ($WindowsArchitecture -eq $X86) { 199 | $HuntressDirPath = Join-Path $Env:ProgramFiles "Huntress" 200 | } elseif ($WindowsArchitecture -eq $X64) { 201 | $HuntressDirPath = Join-Path $Env:ProgramW6432 "Huntress" 202 | } else { 203 | $err = "ERROR: Failed to determine the Windows Architecture. Received $WindowsArchitecture." 204 | LogMessage $err 205 | LogMessage $SupportMessage 206 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 207 | } 208 | $HuntressAgentPath = Join-Path $HuntressDirPath "HuntressAgent.exe" 209 | $HuntressUpdaterPath = Join-Path $HuntressDirPath "HuntressUpdater.exe" 210 | $hUpdaterPath = Join-Path $HuntressDirPath "hUpdate.exe" 211 | $HuntressKeyPath = "HKLM:\SOFTWARE\Huntress Labs\Huntress" 212 | $AgentIdKeyValueName = "AgentId" 213 | $OrganizationKeyValueName = "OrganizationKey" 214 | $TagsValueName = "Tags" 215 | foreach ( $file in ($HuntressAgentPath, $HuntressUpdaterPath, $hUpdaterPath) ) { 216 | if ( ! (Test-Path $file) ) { 217 | $err = "ERROR: $file did not exist." 218 | LogMessage $err 219 | LogMessage $SupportMessage 220 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 221 | } 222 | LogMessage "'$file' is present." 223 | } 224 | foreach ( $svc in ($HuntressAgentServiceName, $HuntressUpdaterServiceName) ) { 225 | # service installed? 226 | if ( ! (Confirm-ServiceExists($svc)) ) { 227 | $err = "ERROR: The $svc service is not installed." 228 | LogMessage $err 229 | LogMessage $SupportMessage 230 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 231 | } 232 | if ( ! (Confirm-ServiceRunning($svc)) ) { 233 | $err = "ERROR: The $svc service is not running." 234 | LogMessage $err 235 | LogMessage $SupportMessage 236 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 237 | } 238 | LogMessage "'$svc' is running." 239 | } 240 | if ( ($PowerShellArch -eq $X86) -and ($WindowsArchitecture -eq $X64) ) { 241 | LogMessage "WARNING: Can't verify registry settings due to 32bit PowerShell on 64bit host." 242 | } else { 243 | # Ensure the Huntress registry key is present. 244 | if ( ! (Test-Path $HuntressKeyPath) ) { 245 | $err = "ERROR: The registry key '$HuntressKeyPath' did not exist." 246 | LogMessage $err 247 | LogMessage $SupportMessage 248 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 249 | } 250 | 251 | $HuntressKeyObject = Get-ItemProperty $HuntressKeyPath 252 | foreach ( $value in ($AgentIdKeyValueName, $OrganizationKeyValueName, $TagsValueName) ) { 253 | If ( ! (Get-Member -inputobject $HuntressKeyObject -name $value -Membertype Properties) ) { 254 | $err = "ERROR: The registry value $value did not exist within $HuntressKeyPath." 255 | LogMessage $err 256 | LogMessage $SupportMessage 257 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 258 | } 259 | } 260 | } 261 | if ( ($PowerShellArch -eq $X86) -and ($WindowsArchitecture -eq $X64) ) { 262 | LogMessage "WARNING: Can't verify agent registration due to 32bit PowerShell on 64bit host." 263 | } else { 264 | If ($HuntressKeyObject.$AgentIdKeyValueName -eq 0) { 265 | $err = ("ERROR: The agent did not register. Check the log (%ProgramFiles%\Huntress\HuntressAgent.log) for errors.") 266 | LogMessage $err 267 | LogMessage $SupportMessage 268 | throw $ScriptFailed + " " + $err + " " + $SupportMessage 269 | } 270 | LogMessage "Agent registered." 271 | } 272 | 273 | LogMessage "Installation verified!" 274 | } 275 | 276 | function StopHuntressServices { 277 | LogMessage "Stopping Huntress services..." 278 | Stop-Service -Name "$HuntressAgentServiceName" 279 | Stop-Service -Name "$HuntressUpdaterServiceName" 280 | } 281 | function PrepReregister { 282 | LogMessage "Preparing to re-register agent..." 283 | StopHuntressServices 284 | $HuntressKeyPath = "HKLM:\SOFTWARE\Huntress Labs\Huntress" 285 | Remove-Item -Path "$HuntressKeyPath" -Recurse -ErrorAction SilentlyContinue 286 | } 287 | function main () { 288 | LogMessage "Script type: '$ScriptType'" 289 | LogMessage "Script version: '$ScriptVersion'" 290 | LogMessage "Host name: '$env:computerName'" 291 | $os = (get-WMiObject -computername $env:computername -Class win32_operatingSystem).caption.Trim() 292 | LogMessage "Host OS: '$os'" 293 | LogMessage "Host Architecture: '$(Get-WindowsArchitecture)'" 294 | LogMessage "PowerShell Architecture: '$PowerShellArch'" 295 | if ($reinstall) { 296 | LogMessage "Re-install agent: '$reinstall'" 297 | } 298 | if ($reregister) { 299 | LogMessage "Re-register agent: '$reregister'" 300 | } 301 | LogMessage "Installer location: '$InstallerPath'" 302 | LogMessage "Installer log: '$DebugLog'" 303 | $AccountKey = $AccountKey.Trim() 304 | $OrganizationKey = $OrganizationKey.Trim() 305 | Test-Parameters 306 | $masked = $AccountKey.Substring(0,10) + "XXXXXXXXXXXXXXXXXXXXXXX" 307 | LogMessage "AccountKey: '$masked'" 308 | LogMessage "OrganizationKey: '$OrganizationKey'" 309 | if ($reregister) { 310 | PrepReregister 311 | } elseif ($reinstall) { 312 | LogMessage "Re-installing agent..." 313 | if ( !(Confirm-ServiceExists($HuntressAgentServiceName)) ) { 314 | $err = "The Huntress Agent is NOT installed; nothing to re-install. Exiting." 315 | LogMessage "$err" 316 | exit 1 317 | } 318 | StopHuntressServices 319 | } else { 320 | LogMessage "Checking for HuntressAgent service..." 321 | if ( Confirm-ServiceExists($HuntressAgentServiceName) ) { 322 | $err = "The Huntress Agent is already installed. Exiting." 323 | LogMessage "$err" 324 | exit 0 325 | } 326 | } 327 | 328 | Get-Installer 329 | Install-Huntress $OrganizationKey 330 | Test-Installation 331 | LogMessage "Huntress Agent successfully installed!" 332 | } 333 | try 334 | { 335 | main 336 | } catch { 337 | $ErrorMessage = $_.Exception.Message 338 | LogMessage $ErrorMessage 339 | exit 1 340 | } 341 | -------------------------------------------------------------------------------- /Continuum/README.md: -------------------------------------------------------------------------------- 1 | ### Deploying the Huntress Agent with Continuum 2 | 3 | This policy will install the Huntress Agent. For full usage details please see https://huntress.zendesk.com/hc/en-us/articles/4404012779923-Deploying-Huntress-with-Continuum-RMM-2-1- 4 | -------------------------------------------------------------------------------- /Datto-RMM/Huntress Agent Deployment WIN.cpt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/Huntress Agent Deployment WIN.cpt -------------------------------------------------------------------------------- /Datto-RMM/Mac/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.bat eol=lf 3 | -------------------------------------------------------------------------------- /Datto-RMM/Mac/InstallHuntress-macOS-DattoRmm.cpt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/Mac/InstallHuntress-macOS-DattoRmm.cpt -------------------------------------------------------------------------------- /Datto-RMM/Mac/command.bat: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #shellcheck disable=SC2181,SC2295,SC2116 3 | # 4 | 5 | # Copyright (c) 2022 Huntress Labs, Inc. 6 | # All rights reserved. 7 | # 8 | # Redistribution and use in source and binary forms, with or without 9 | # modification, are permitted provided that the following conditions are met: 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above copyright 13 | # notice, this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # * Neither the name of the Huntress Labs nor the names of its contributors 16 | # may be used to endorse or promote products derived from this software 17 | # without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | # DISCLAIMED. IN NO EVENT SHALL HUNTRESS LABS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 25 | # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | # The Huntress installer needs an Account Key and an Organization Key (a user 32 | # specified name or description) which is used to affiliate an Agent with a 33 | # specific Organization within the Huntress Partner's Account. These keys can be 34 | # hard coded below or passed in when the script is run. 35 | 36 | # For more details, see our KB article 37 | # https://support.huntress.io/hc/en-us/articles/10780146108563 38 | 39 | 40 | ############################################################################## 41 | ## Begin user modified variables 42 | ############################################################################## 43 | 44 | 45 | # By default, Datto will pull from your HUNTRESS_ACCOUNT_KEY global variable. 46 | # Otherwise, you may specify your key inside the quotes below. 47 | defaultAccountKey="$HUNTRESS_ACCOUNT_KEY" 48 | 49 | # If the organization key is passed as a parameter, it will be used instead of this DEFAULT_ORG_KEY variable. 50 | # Otherwise, Datto provides the CS_PROFILE_NAME as an environment variable that we will use as the 51 | # Organization Name in Huntress. If you want to have customer names match Datto, leave the line below as-is. 52 | defaultOrgKey="$CS_PROFILE_NAME" 53 | 54 | 55 | ############################################################################## 56 | ## Do not modify anything below this line 57 | ############################################################################## 58 | dd=$(date "+%Y%m%d-%H%M%S") 59 | log_file="/tmp/HuntressInstaller.log" 60 | install_script="/tmp/HuntressMacInstall.sh" 61 | invalid_key="Invalid account secret key" 62 | pattern="[a-f0-9]{32}" 63 | rmm="DattoRMM macOS deployment component" 64 | version="1.0" 65 | 66 | ## Using logger function to provide helpful logs within RMM tools in addition to log file 67 | logger() { 68 | echo "$dd -- $*"; 69 | echo "$dd -- $*" >> $log_file; 70 | } 71 | 72 | # Check for root 73 | if [ $EUID -ne 0 ]; then 74 | logger "This script must be run as root, exiting..." 75 | exit 1 76 | fi 77 | 78 | # Clean up any old installer scripts. 79 | if [ -f "$install_script" ]; then 80 | logger "Installer file present in /tmp; deleting." 81 | rm -f "$install_script" 82 | fi 83 | 84 | ## 85 | ## This section handles the assigning `=` character for options. 86 | ## Since most RMMs treat spaces as delimiters in Mac Scripting, 87 | ## we have to use `=` to assign the option value, but must remove 88 | ## it because, well, bash. https://stackoverflow.com/a/28466267/519360 89 | ## 90 | 91 | usage() { 92 | cat < --organization_key= 94 | 95 | -a, --account_key The account key to use for this agent install 96 | -o, --organization_key The org key to use for this agent install 97 | -h, --help Print this message 98 | 99 | EOF 100 | } 101 | 102 | while getopts a:o:h:-: OPT; do 103 | if [ "$OPT" = "-" ]; then 104 | OPT="${OPTARG%%=*}" # extract long option name 105 | OPTARG="${OPTARG#$OPT}" # extract long option argument (may be empty) 106 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 107 | else 108 | # the user used a short option, but we still want to strip the assigning `=` 109 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 110 | fi 111 | case "$OPT" in 112 | a | account_key) 113 | account_key="$OPTARG" 114 | ;; 115 | o | organization_key) 116 | organization_key="$OPTARG" 117 | ;; 118 | h | help) 119 | usage 120 | ;; 121 | ??*) 122 | logger "Illegal option --$OPT" 123 | exit 2 124 | ;; # bad long option 125 | \? ) 126 | exit 2 127 | ;; # bad short option (error reported via getopts) 128 | esac 129 | done 130 | shift $((OPTIND-1)) # remove parsed options and args from $@ list 131 | 132 | logger "=========== INSTALL START AT $dd ===============" 133 | logger "=========== $rmm | Version: $version ===============" 134 | 135 | # VALIDATE OPTIONS PASSED TO SCRIPT 136 | if [ -z "$organization_key" ]; then 137 | organizationKey=$(echo "$defaultOrgKey" | xargs) 138 | logger "--organization_key parameter not present, using defaultKey instead: $defaultOrgKey" 139 | else 140 | organizationKey=$(echo "$organization_key" | xargs) 141 | logger "--organization_key parameter present, set to: $organizationKey" 142 | fi 143 | 144 | if ! [[ $account_key =~ $pattern ]]; then 145 | logger "Checking defaultAccountKey (hardcoded key) because parameter for --account_key was invalid" 146 | accountKey=$(echo "$defaultAccountKey" | xargs) 147 | if ! [[ $accountKey =~ $pattern ]]; then 148 | logger "ERROR: Invalid --account_key. Please check Huntress support documentation." 149 | exit 1 150 | fi 151 | else 152 | accountKey=$(echo "$account_key" | xargs) 153 | fi 154 | 155 | # OPTIONS REQUIRED 156 | if [ -z "$accountKey" ] || [ -z "$organizationKey" ] 157 | then 158 | logger "Error: --account_key and --organization_key are both required" >> $log_file 159 | echo 160 | usage 161 | exit 1 162 | fi 163 | 164 | # Hide most of the account key in the logs, keeping the front and tail end for troubleshooting 165 | masked="$(echo "${accountKey:0:4}")" 166 | masked+="************************" 167 | masked+="$(echo "${accountKey: (-4)}")" 168 | 169 | logger "Provided Huntress key: $masked" 170 | logger "Provided Organization Key: $organizationKey" 171 | 172 | result=$(curl -w "%{http_code}" -L "https://huntress.io/script/darwin/$accountKey" -o "$install_script") 173 | 174 | if [ $? != "0" ]; then 175 | logger "ERROR: Download failed with error: $result" 176 | exit 1 177 | fi 178 | 179 | if grep -Fq "$invalid_key" "$install_script"; then 180 | logger "ERROR: --account_key is invalid. You entered: $accountKey" 181 | exit 1 182 | fi 183 | 184 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -v)" 185 | logger "=============== Begin Installer Logs ===============" 186 | 187 | if [ $? != "0" ]; then 188 | logger "Installer Error: $install_result" 189 | exit 1 190 | fi 191 | 192 | logger "$install_result" 193 | logger "=========== INSTALL FINISHED AT $dd ===============" 194 | exit 195 | -------------------------------------------------------------------------------- /Datto-RMM/Mac/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/Mac/icon.png -------------------------------------------------------------------------------- /Datto-RMM/Mac/resource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Huntress Agent Deployment [MAC] 4 | scripts 5 | This script will install the Huntress Agent on your computers. The variable HUNTRESS_ACCOUNT_KEY must be defined with the secret key from Huntress' download section. See https://support.huntress.io/hc/en-us/articles/10780146108563 for complete details. 6 | c88f421f-f362-461a-b62f-7e2df68a8800 7 | 8 | 12 9 | 3600 10 | 5 11 | unix 12 | 13 | -------------------------------------------------------------------------------- /Datto-RMM/README.md: -------------------------------------------------------------------------------- 1 | "Huntress Agent Deployment 2.0.cpt" is the component script for installing the Huntress Agent using Datto RMM (formerly AEM). 2 | 3 | Please see the following document for usage details: 4 | https://support.huntress.io/hc/en-us/articles/4404012624147-Deploying-Huntress-with-Datto-RMM-ComStore- 5 | 6 | macOS deployments require additional considerations and configuration before installing. [Please refer to this document for more information](https://support.huntress.io/hc/en-us/documents/25013857741331-Critical-Steps-for-Complete-macOS-EDR-Deployment) before planning your macOS deployment. 7 | -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Completed Job - Agents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Completed Job - Agents.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Completed Job - Tab - marked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Completed Job - Tab - marked.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Completed Job - Tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Completed Job - Tab.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Component - Just Imported - script section.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Component - Just Imported - script section.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Component - Just Imported.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Component - Just Imported.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Component - KEY variable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Component - KEY variable.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Component - Replace KEY in script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Component - Replace KEY in script.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Component - Save Component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Component - Save Component.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Import Component Button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Import Component Button.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Import Component Window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Import Component Window.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Job - Component Selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Job - Component Selected.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Job - Name Job and Add Component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Job - Name Job and Add Component.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Job - Name Scheduled Component and Populate ORG_KEY.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Job - Name Scheduled Component and Populate ORG_KEY.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Job - ORG_KEY ChangeMe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Job - ORG_KEY ChangeMe.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Job - Save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Job - Save.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Job - Select Component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Job - Select Component.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Job - Set ORG_KEY.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Job - Set ORG_KEY.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Run Job Now.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Run Job Now.png -------------------------------------------------------------------------------- /Datto-RMM/images/AEM - Sites - Select Site to Schedule Job.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/images/AEM - Sites - Select Site to Schedule Job.png -------------------------------------------------------------------------------- /Datto-RMM/scripts/Archive/Huntress Agent Deployment WIN.cpt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Datto-RMM/scripts/Archive/Huntress Agent Deployment WIN.cpt -------------------------------------------------------------------------------- /Datto-RMM/scripts/README.md: -------------------------------------------------------------------------------- 1 | This is just the PowerShell script for installing the Huntress Agent using AEM. 2 | 3 | The component file includes the resource file which contains variables needed to run the script. 4 | 5 | Please see the following document for usage details: 6 | https://support.huntress.io/article/45-deploying-huntress-with-aem 7 | 8 | This script will install the Huntress Agent on your computers. The variable HUNTRESS_ACCOUNT_KEY must be defined first. The DattoRMM site name will be used to associate the agent to an organization within the Huntress console. Any organizations that do not exist will be created automatically. See https://support.huntress.io/article/116-deploying-huntress-with-datto-rmm-comstore for complete details. 9 | -------------------------------------------------------------------------------- /Kaseya/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /Kaseya/InstallHuntress-macOS-Kaseya.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /Kaseya/Procedure Huntress Agent Deployment.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Mosyle/InstallHuntress-macOS-Mosyle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #shellcheck disable=SC2181,SC2295,SC2116 3 | 4 | # Copyright (c) 2024 Huntress Labs, Inc. 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # * Neither the name of the Huntress Labs nor the names of its contributors 15 | # may be used to endorse or promote products derived from this software 16 | # without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL HUNTRESS LABS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 24 | # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | 30 | # The Huntress installer needs an Account Key and an Organization Key (a user 31 | # specified name or description) which is used to affiliate an Agent with a 32 | # specific Organization within the Huntress Partner's Account. These keys can be 33 | # hard coded below or passed in when the script is run. 34 | 35 | # For more details, see our KB article 36 | # https://support.huntress.io/hc/en-us/articles/25013857741331-Critical-Steps-for-Complete-macOS-EDR-Deployment 37 | 38 | 39 | ##################################################################################### 40 | ## 41 | ## Begin user modified variables. Modify per documentation before running in Mosyle. 42 | ## 43 | ##################################################################################### 44 | 45 | 46 | # Replace __ACCOUNT_KEY__ with your account secret key (from your Huntress portal's "download agent" section) 47 | defaultAccountKey="__ACCOUNT_KEY__" 48 | 49 | # If the organization key is passed as a parameter, it will be used instead of this defaultOrgKey variable. 50 | # If you have a preferred "placeholder" organization name for Mac agents, you can set that below. 51 | defaultOrgKey="__ORGANIZATION_KEY__" 52 | 53 | # Option to install the system extension after the Huntress Agent is installed. In order for this to happen 54 | # without security prompts on the endpoint, permissions need to be applied to the endpoint by Mosyle before this script 55 | # is run. See the following KB article for more information: 56 | # https://support.huntress.io/hc/en-us/articles/21286543756947-Instructions-for-the-MDM-Configuration-for-macOS 57 | install_system_extension=true 58 | 59 | 60 | ############################################################################## 61 | ## Do not modify anything below this line 62 | ############################################################################## 63 | dd=$(date "+%Y%m%d-%H%M%S") 64 | log_file="/tmp/HuntressInstaller.log" 65 | install_script="/tmp/HuntressMacInstall.sh" 66 | invalid_key="Invalid account secret key" 67 | pattern="[a-f0-9]{32}" 68 | rmm="Mosyle macOS deployment script" 69 | version="1.1 - March 25, 2025" 70 | 71 | ## Using logger function to provide helpful logs within RMM tools in addition to log file 72 | logger() { 73 | echo "$dd -- $*"; 74 | echo "$dd -- $*" >> $log_file; 75 | } 76 | 77 | # Check for root 78 | if [ $EUID -ne 0 ]; then 79 | logger "This script must be run as root, exiting..." 80 | exit 1 81 | fi 82 | 83 | # Clean up any old installer scripts. 84 | if [ -f "$install_script" ]; then 85 | logger "Installer file present in /tmp; deleting." 86 | rm -f "$install_script" 87 | fi 88 | 89 | 90 | ## 91 | ## This section handles the assigning `=` character for options. 92 | ## Since most RMMs treat spaces as delimiters in Mac Scripting, 93 | ## we have to use `=` to assign the option value, but must remove 94 | ## it because, well, bash. https://stackoverflow.com/a/28466267/519360 95 | ## 96 | 97 | usage() { 98 | cat < --organization_key= 100 | 101 | -a, --account_key The account key to use for this agent install 102 | -o, --organization_key The org key to use for this agent install 103 | -h, --help Print this message 104 | 105 | EOF 106 | } 107 | 108 | while getopts a:o:h:-: OPT; do 109 | if [ "$OPT" = "-" ]; then 110 | OPT="${OPTARG%%=*}" # extract long option name 111 | OPTARG="${OPTARG#$OPT}" # extract long option argument (may be empty) 112 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 113 | else 114 | # the user used a short option, but we still want to strip the assigning `=` 115 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 116 | fi 117 | case "$OPT" in 118 | a | account_key) 119 | account_key="$OPTARG" 120 | ;; 121 | o | organization_key) 122 | organization_key="$OPTARG" 123 | ;; 124 | h | help) 125 | usage 126 | ;; 127 | ??*) 128 | logger "Illegal option --$OPT" 129 | exit 2 130 | ;; # bad long option 131 | \? ) 132 | exit 2 133 | ;; # bad short option (error reported via getopts) 134 | esac 135 | done 136 | shift $((OPTIND-1)) # remove parsed options and args from $@ list 137 | 138 | logger "=========== INSTALL START AT $dd ===============" 139 | logger "=========== $rmm | Version: $version ===============" 140 | 141 | # VALIDATE OPTIONS PASSED TO SCRIPT 142 | if [ -z "$organization_key" ]; then 143 | organizationKey=$(echo "$defaultOrgKey" | xargs) 144 | logger "--organization_key parameter not present, using defaultOrgKey instead: $defaultOrgKey" 145 | else 146 | organizationKey=$(echo "$organization_key" | xargs) 147 | logger "--organization_key parameter present, set to: $organizationKey" 148 | fi 149 | 150 | if ! [[ "$account_key" =~ $pattern ]]; then 151 | logger "Missing --account_key parameter, switching to use defaultAccountKey..." 152 | accountKey=$(echo "$defaultAccountKey" | xargs) 153 | if ! [[ $accountKey =~ $pattern ]]; then 154 | logger "ERROR: Invalid account_key provided. Please check Huntress support documentation." 155 | exit 1 156 | fi 157 | else 158 | accountKey=$(echo "$account_key" | xargs) 159 | fi 160 | 161 | # OPTIONS REQUIRED 162 | if [ -z "$accountKey" ] || [ -z "$organizationKey" ] 163 | then 164 | logger "Error: --account_key and --organization_key are both required" 165 | echo 166 | usage 167 | exit 1 168 | fi 169 | 170 | # Hide most of the account key in the logs, keeping the front and tail end for troubleshooting 171 | masked="$(echo "${accountKey:0:4}")" 172 | masked+="************************" 173 | masked+="$(echo "${accountKey: (-4)}")" 174 | 175 | logger "Provided Huntress key: $masked" 176 | logger "Provided Organization Key: $organizationKey" 177 | 178 | result=$(curl -w "%{http_code}" -L "https://huntress.io/script/darwin/$accountKey" -o "$install_script") 179 | 180 | if [ $? != "0" ]; then 181 | logger "ERROR: Download failed with error: $result" 182 | exit 1 183 | fi 184 | 185 | if grep -Fq "$invalid_key" "$install_script"; then 186 | logger "ERROR: --account_key is invalid. You entered: $accountKey" 187 | exit 1 188 | fi 189 | 190 | logger "=============== Begin Installer Logs ===============" 191 | if [ "$install_system_extension" = true ]; then 192 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -v --install_system_extension)" 193 | else 194 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -v)" 195 | fi 196 | 197 | if [ $? != "0" ]; then 198 | logger "Installer Error: $install_result" 199 | exit 1 200 | fi 201 | 202 | logger "$install_result" 203 | logger "=========== INSTALL FINISHED AT $dd ===============" 204 | exit -------------------------------------------------------------------------------- /Mosyle/README.md: -------------------------------------------------------------------------------- 1 | ### Deploying the Huntress macOS Agent with Mosyle 2 | 3 | This script will install the Huntress macOS Agent. 4 | -------------------------------------------------------------------------------- /N-able (SolarWinds) N-central/2.4.1.9/Readme.md: -------------------------------------------------------------------------------- 1 | This policy was created with Automation Manager 2.4.1.9. 2 | -------------------------------------------------------------------------------- /N-able (SolarWinds) N-central/InstallHuntress-macOS-nable.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #shellcheck disable=SC2181,SC2295,SC2116 3 | 4 | # Copyright (c) 2022 Huntress Labs, Inc. 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # * Neither the name of the Huntress Labs nor the names of its contributors 15 | # may be used to endorse or promote products derived from this software 16 | # without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL HUNTRESS LABS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 24 | # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | 30 | # The Huntress installer needs an Account Key and an Organization Key (a user 31 | # specified name or description) which is used to affiliate an Agent with a 32 | # specific Organization within the Huntress Partner's Account. These keys can be 33 | # hard coded below or passed in when the script is run. 34 | 35 | # For more details, see our KB article 36 | # https://support.huntress.io/hc/en-us/articles/25013857741331-Critical-Steps-for-Complete-macOS-EDR-Deployment 37 | 38 | 39 | ############################################################################## 40 | ## Begin user modified variables 41 | ## These can be passed as parameters from N-Central, 42 | ## or set statically in this script. 43 | ############################################################################## 44 | 45 | 46 | # Replace __ACCOUNT_KEY__ with your account secret key (from your Huntress portal's "download agent" section) 47 | defaultAccountKey="__ACCOUNT_KEY__" 48 | 49 | # If the organization key is passed as a parameter, it will be used instead of this defaultOrgKey variable. 50 | # If you have a preferred "placeholder" organization name for Mac agents, you can set that below. 51 | defaultOrgKey="__ORGANIZATION_KEY__" 52 | 53 | # Option to install the system extension after the Huntress Agent is installed. In order for this to happen 54 | # without security prompts on the endpoint, permissions need to be applied to the endpoint by an MDM before this script 55 | # is run. See the following KB article for instructions: 56 | # https://support.huntress.io/hc/en-us/articles/21286543756947-Instructions-for-the-MDM-Configuration-for-macOS 57 | install_system_extension=true 58 | 59 | ############################################################################## 60 | ## Do not modify anything below this line 61 | ############################################################################## 62 | dd=$(date "+%Y%m%d-%H%M%S") 63 | log_file="/tmp/HuntressInstaller.log" 64 | install_script="/tmp/HuntressMacInstall.sh" 65 | invalid_key="Invalid account secret key" 66 | pattern="[a-f0-9]{32}" 67 | rmm="N-Able (SolarWinds) macOS deployment script" 68 | version="1.2 - March 25, 2025" 69 | 70 | ## Using logger function to provide helpful logs within RMM tools in addition to log file 71 | logger() { 72 | echo "$dd -- $*"; 73 | echo "$dd -- $*" >> $log_file; 74 | } 75 | 76 | # Check for root 77 | if [ $EUID -ne 0 ]; then 78 | logger "This script must be run as root, exiting..." 79 | exit 1 80 | fi 81 | 82 | # Clean up any old installer scripts. 83 | if [ -f "$install_script" ]; then 84 | logger "Installer file present in /tmp; deleting." 85 | rm -f "$install_script" 86 | fi 87 | 88 | ## 89 | ## This section handles the assigning `=` character for options. 90 | ## Since most RMMs treat spaces as delimiters in Mac Scripting, 91 | ## we have to use `=` to assign the option value, but must remove 92 | ## it because, well, bash. https://stackoverflow.com/a/28466267/519360 93 | ## 94 | 95 | usage() { 96 | cat < --organization_key= 98 | 99 | -a, --account_key The account key to use for this agent install 100 | -o, --organization_key The org key to use for this agent install 101 | -h, --help Print this message 102 | 103 | EOF 104 | } 105 | 106 | while getopts a:o:h:-: OPT; do 107 | if [ "$OPT" = "-" ]; then 108 | OPT="${OPTARG%%=*}" # extract long option name 109 | OPTARG="${OPTARG#$OPT}" # extract long option argument (may be empty) 110 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 111 | else 112 | # the user used a short option, but we still want to strip the assigning `=` 113 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 114 | fi 115 | case "$OPT" in 116 | a | account_key) 117 | account_key="$OPTARG" 118 | ;; 119 | o | organization_key) 120 | organization_key="$OPTARG" 121 | ;; 122 | h | help) 123 | usage 124 | ;; 125 | ??*) 126 | logger "Illegal option --$OPT" 127 | exit 2 128 | ;; # bad long option 129 | \? ) 130 | exit 2 131 | ;; # bad short option (error reported via getopts) 132 | esac 133 | done 134 | shift $((OPTIND-1)) # remove parsed options and args from $@ list 135 | 136 | logger "=========== INSTALL START AT $dd ===============" 137 | logger "=========== $rmm | Version: $version ===============" 138 | 139 | # VALIDATE OPTIONS PASSED TO SCRIPT 140 | if [ -z "$organization_key" ]; then 141 | organizationKey=$(echo "$defaultOrgKey" | xargs) 142 | logger "--organization_key parameter not present, using defaultOrgKey instead: $defaultOrgKey" 143 | else 144 | organizationKey=$(echo "$organization_key" | xargs) 145 | logger "--organization_key parameter present, set to: $organizationKey" 146 | fi 147 | 148 | if ! [[ "$account_key" =~ $pattern ]]; then 149 | logger "Invalid --account_key provided, checking defaultAccountKey..." 150 | accountKey=$(echo "$defaultAccountKey" | xargs) 151 | if ! [[ $accountKey =~ $pattern ]]; then 152 | logger "ERROR: Invalid --account_key. Please check Huntress support documentation." 153 | exit 1 154 | fi 155 | else 156 | accountKey=$(echo "$account_key" | xargs) 157 | fi 158 | 159 | # OPTIONS REQUIRED 160 | if [ -z "$accountKey" ] || [ -z "$organizationKey" ] 161 | then 162 | logger "Error: --account_key and --organization_key are both required" >> $log_file 163 | echo 164 | usage 165 | exit 1 166 | fi 167 | 168 | # Hide most of the account key in the logs, keeping the front and tail end for troubleshooting 169 | masked="$(echo "${accountKey:0:4}")" 170 | masked+="************************" 171 | masked+="$(echo "${accountKey: (-4)}")" 172 | 173 | logger "Provided Huntress key: $masked" 174 | logger "Provided Organization Key: $organizationKey" 175 | 176 | result=$(curl -w "%{http_code}" -L "https://huntress.io/script/darwin/$accountKey" -o "$install_script") 177 | 178 | if [ $? != "0" ]; then 179 | logger "ERROR: Download failed with error: $result" 180 | exit 1 181 | fi 182 | 183 | if grep -Fq "$invalid_key" "$install_script"; then 184 | logger "ERROR: --account_key is invalid. You entered: $accountKey" 185 | exit 1 186 | fi 187 | 188 | logger "=============== Begin Installer Logs ===============" 189 | if [ "$install_system_extension" = true ]; then 190 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -v --install_system_extension)" 191 | else 192 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -v)" 193 | fi 194 | 195 | if [ $? != "0" ]; then 196 | logger "Installer Error: $install_result" 197 | exit 1 198 | fi 199 | 200 | logger "$install_result" 201 | logger "=========== INSTALL FINISHED AT $dd ===============" 202 | exit 203 | -------------------------------------------------------------------------------- /N-able (SolarWinds) N-central/README.md: -------------------------------------------------------------------------------- 1 | ### Deploying the Huntress Agent with N-Central 2 | 3 | This policy will install the Huntress Agent. For full usage details please see https://support.huntress.io/article/46-deploying-huntress-with-solarwinds. 4 | 5 | When run, the policy will automatically download and install the Huntress Agent. Before installing the agent, it will check to see if the agent is already installed. It will also verfiy the installation completed and log any errors. 6 | 7 | 8 | The policy will pass the use specified [Account Key and Organization Key](https://support.huntress.io/article/7-using-account-and-organization-keys) to the installer via a simple Powershell script. 9 | ``` 10 | Start-Process $installer "/ACCT_KEY=`"$acctkey`" /ORG_KEY=`"$orgkey`" /S" -Wait 11 | ``` 12 | 13 | macOS deployments require additional considerations and configuration before installing. [Please refer to this document for more information](https://support.huntress.io/hc/en-us/documents/25013857741331-Critical-Steps-for-Complete-macOS-EDR-Deployment) before planning your macOS deployment. 14 | -------------------------------------------------------------------------------- /Naverisk/Huntress Labs - Install Huntress Agent.nsp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Naverisk/Huntress Labs - Install Huntress Agent.nsp -------------------------------------------------------------------------------- /Naverisk/README.md: -------------------------------------------------------------------------------- 1 | Naverisk Script Pack for deploying the Huntress agent. 2 | 3 | Each client will download the most recent installer directly from the Huntress server and execute it. 4 | 5 | - [Huntress Labs - Install Huntress Agent.nsp](https://github.com/huntresslabs/deployment-scripts/blob/master/Naverisk/Huntress%20Labs%20-%20Install%20Huntress%20Agent.nsp?raw=true) 6 | 7 | Please see the following document for usage details: 8 | https://support.huntress.io/article/94-deploying-huntress-with-naverisk-rmm 9 | -------------------------------------------------------------------------------- /Ninja-RMM/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /Ninja-RMM/InstallHuntress-macOS-NinjaRMM.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #shellcheck disable=SC2181,SC2295,SC2116 3 | # 4 | 5 | # Copyright (c) 2022 Huntress Labs, Inc. 6 | # All rights reserved. 7 | # 8 | # Redistribution and use in source and binary forms, with or without 9 | # modification, are permitted provided that the following conditions are met: 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above copyright 13 | # notice, this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # * Neither the name of the Huntress Labs nor the names of its contributors 16 | # may be used to endorse or promote products derived from this software 17 | # without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | # DISCLAIMED. IN NO EVENT SHALL HUNTRESS LABS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 25 | # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | # The Huntress installer needs an Account Key and an Organization Key (a user 32 | # specified name or description) which is used to affiliate an Agent with a 33 | # specific Organization within the Huntress Partner's Account. These keys can be 34 | # hard coded below or passed in when the script is run. 35 | 36 | # For more details, see our KB article 37 | # https://support.huntress.io/hc/en-us/articles/7628230803987-Deploy-Huntress-for-Mac-with-NinjaRMM 38 | 39 | 40 | ############################################################################## 41 | ## Begin user modified variables 42 | ############################################################################## 43 | 44 | 45 | # Replace __ACCOUNT_KEY__ with your account secret key (from your Huntress portal's "download agent" section) 46 | defaultAccountKey="__ACCOUNT_KEY__" 47 | 48 | # If the organization key is passed as a parameter, it will be used instead of this DEFAULT_ORG_KEY variable. 49 | # As of NinjaRMM macOS Agent Version 5.3.4848, environment variables are available to pull the customer Organization name in scripting. 50 | # If you have a preferred "placeholder" organization name, you can set that below within the double quotes. 51 | defaultOrgKey="$NINJA_ORGANIZATION_NAME" 52 | 53 | # Option to install the system extension after the Huntress Agent is installed. In order for this to happen 54 | # without security prompts on the endpoint, permissions need to be applied to the endpoint by an MDM before this script 55 | # is run. See the following KB article for instructions: 56 | # https://support.huntress.io/hc/en-us/articles/21286543756947-Instructions-for-the-MDM-Configuration-for-macOS 57 | install_system_extension=true 58 | 59 | ############################################################################## 60 | ## Do not modify anything below this line 61 | ############################################################################## 62 | dd=$(date "+%Y%m%d-%H%M%S") 63 | log_file="/tmp/HuntressInstaller.log" 64 | install_script="/tmp/HuntressMacInstall.sh" 65 | invalid_key="Invalid account secret key" 66 | pattern="[a-f0-9]{32}" 67 | rmm="NinjaRMM macOS deployment script" 68 | version="1.2 - March 25, 2025" 69 | 70 | ## Using logger function to provide helpful logs within RMM tools in addition to log file 71 | logger() { 72 | echo "$dd -- $*"; 73 | echo "$dd -- $*" >> $log_file; 74 | } 75 | 76 | # Check for root 77 | if [ $EUID -ne 0 ]; then 78 | logger "This script must be run as root, exiting..." 79 | exit 1 80 | fi 81 | 82 | # Clean up any old installer scripts. 83 | if [ -f "$install_script" ]; then 84 | logger "Installer file present in /tmp; deleting." 85 | rm -f "$install_script" 86 | fi 87 | 88 | ## 89 | ## This section handles the assigning `=` character for options. 90 | ## Since most RMMs treat spaces as delimiters in Mac Scripting, 91 | ## we have to use `=` to assign the option value, but must remove 92 | ## it because, well, bash. https://stackoverflow.com/a/28466267/519360 93 | ## 94 | 95 | usage() { 96 | cat < --organization_key= 98 | 99 | -a, --account_key The account key to use for this agent install 100 | -o, --organization_key The org key to use for this agent install 101 | -h, --help Print this message 102 | 103 | EOF 104 | } 105 | 106 | while getopts a:o:h:-: OPT; do 107 | if [ "$OPT" = "-" ]; then 108 | OPT="${OPTARG%%=*}" # extract long option name 109 | OPTARG="${OPTARG#$OPT}" # extract long option argument (may be empty) 110 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 111 | else 112 | # the user used a short option, but we still want to strip the assigning `=` 113 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 114 | fi 115 | case "$OPT" in 116 | a | account_key) 117 | account_key="$OPTARG" 118 | ;; 119 | o | organization_key) 120 | organization_key="$OPTARG" 121 | ;; 122 | h | help) 123 | usage 124 | ;; 125 | ??*) 126 | logger "Illegal option --$OPT" 127 | exit 2 128 | ;; # bad long option 129 | \? ) 130 | exit 2 131 | ;; # bad short option (error reported via getopts) 132 | esac 133 | done 134 | shift $((OPTIND-1)) # remove parsed options and args from $@ list 135 | 136 | logger "=========== INSTALL START AT $dd ===============" 137 | logger "=========== $rmm | Version: $version ===============" 138 | 139 | # VALIDATE OPTIONS PASSED TO SCRIPT 140 | if [ -z "$organization_key" ]; then 141 | organizationKey=$(echo "$defaultOrgKey" | xargs) 142 | logger "--organization_key parameter not present, using defaultKey instead: $defaultOrgKey" 143 | else 144 | organizationKey=$(echo "$organization_key" | xargs) 145 | logger "--organization_key parameter present, set to: $organizationKey" 146 | fi 147 | 148 | if ! [[ $account_key =~ $pattern ]]; then 149 | logger "Invalid --account_key provided, checking defaultAccountKey..." 150 | accountKey=$(echo "$defaultAccountKey" | xargs) 151 | if ! [[ $accountKey =~ $pattern ]]; then 152 | logger "ERROR: Invalid --account_key. Please check Huntress support documentation." 153 | exit 1 154 | fi 155 | else 156 | accountKey=$(echo "$account_key" | xargs) 157 | fi 158 | 159 | # OPTIONS REQUIRED 160 | if [ -z "$accountKey" ] || [ -z "$organizationKey" ] 161 | then 162 | logger "Error: --account_key and --organization_key are both required" >> $log_file 163 | echo 164 | usage 165 | exit 1 166 | fi 167 | 168 | # Hide most of the account key in the logs, keeping the front and tail end for troubleshooting 169 | masked="$(echo "${accountKey:0:4}")" 170 | masked+="************************" 171 | masked+="$(echo "${accountKey: (-4)}")" 172 | 173 | logger "Provided Huntress key: $masked" 174 | logger "Provided Organization Key: $organizationKey" 175 | 176 | result=$(curl -w "%{http_code}" -L "https://huntress.io/script/darwin/$accountKey" -o "$install_script") 177 | 178 | if [ $? != "0" ]; then 179 | logger "ERROR: Download failed with error: $result" 180 | exit 1 181 | fi 182 | 183 | if grep -Fq "$invalid_key" "$install_script"; then 184 | logger "ERROR: --account_key is invalid. You entered: $accountKey" 185 | exit 1 186 | fi 187 | 188 | logger "=============== Begin Installer Logs ===============" 189 | if [ "$install_system_extension" = true ]; then 190 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -v --install_system_extension)" 191 | else 192 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -v)" 193 | fi 194 | 195 | if [ $? != "0" ]; then 196 | logger "Installer Error: $install_result" 197 | exit 1 198 | fi 199 | 200 | logger "$install_result" 201 | logger "=========== INSTALL FINISHED AT $dd ===============" 202 | exit 203 | -------------------------------------------------------------------------------- /Ninja-RMM/README.md: -------------------------------------------------------------------------------- 1 | ### Huntress Agent Windows Deployment 2 | 3 | For deploying Huntress for Windows via NinjaRMM please reference [this](https://support.huntress.io/hc/en-us/articles/4404012714003-Deploying-Huntress-with-Ninja-RMM) document. 4 | 5 | macOS deployments require additional considerations and configuration before installing. [Please refer to this document for more information](https://support.huntress.io/hc/en-us/documents/25013857741331-Critical-Steps-for-Complete-macOS-EDR-Deployment) before planning your macOS deployment. 6 | -------------------------------------------------------------------------------- /Powershell/InstallHuntress.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem This batch file was created as a wrapper for RMM tools that support Powershell scripts, but don't give the option to control the 4 | rem executionpolicy options and/or pass arguments. 5 | 6 | rem This requires InstallHuntress.powershellv2.ps1 dated July 21, 2022 ! 7 | rem You can always find the most updated version here: https://github.com/huntresslabs/deployment-scripts/tree/main/Powershell 8 | 9 | rem Replace __ACCOUNT_KEY__ below with your Huntress account key. 10 | set ACCTKEY=__ACCOUNT_KEY__ 11 | 12 | rem This batch file takes up to 2 arguments, your org key and a tag (optional) 13 | rem 14 | rem Example below will install using the org key "Johns IT" and attach the tag "production" to the end point: 15 | rem .\huntress.bat "Johns IT" "production" 16 | rem 17 | rem Example below will just install using the org key "IT Solutions" 18 | rem .\huntress.bat "IT Solutions" 19 | 20 | rem Some RMM agents are 32-bit only, so they will start 32-bit Powershell. If the 64-bit Powershell exists, we'll use that. 21 | set POWERSHELL=powershell 22 | if exist %SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe ( 23 | set POWERSHELL=%SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe 24 | ) 25 | 26 | rem if 2 params were passed, the 2nd set is tags, 1st is org key 27 | if [%~2]==[] goto NOTAGS 28 | %POWERSHELL% -executionpolicy bypass -f ./InstallHuntress.powershellv2.ps1 -acctkey %ACCTKEY% -orgkey %1 -tags %2 29 | goto END 30 | 31 | rem if only 1 param was passed, it's the org key 32 | :NOTAGS 33 | %POWERSHELL% -executionpolicy bypass -f ./InstallHuntress.powershellv2.ps1 -acctkey %ACCTKEY% -orgkey %1 34 | 35 | 36 | :END 37 | -------------------------------------------------------------------------------- /Powershell/InstallHuntress.powershellv1.ps1: -------------------------------------------------------------------------------- 1 | This version has been deprecated. 2 | 3 | Please update your links to point to the new version of this script - https://github.com/huntresslabs/deployment-scripts/blob/main/Powershell/InstallHuntress.powershellv2.ps1 4 | 5 | You can still find v1 as our legacy PoSh script here - https://github.com/huntresslabs/deployment-scripts/tree/main/Powershell/Legacy 6 | -------------------------------------------------------------------------------- /Powershell/Legacy/InstallHuntress.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem This batch file was created as a wrapper for RMM tools that support 4 | rem Powershell scripts, but don't give you the option to control the 5 | rem executionpolicy options and pass arguments. 6 | 7 | rem Replace __ACCOUNT_KEY__ with your Huntress account key. 8 | rem This batch file takes a single argument, the Organization Key. 9 | rem This can be passed in when the script is run. 10 | set ACCTKEY=__ACCOUNT_KEY__ 11 | 12 | rem Some RMM agents are 32-bit only, so they will start 32-bit Powershell. 13 | rem If the 64-bit Powershell exists, we'll use that. 14 | set POWERSHELL=powershell 15 | if exist %SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe ( 16 | set POWERSHELL=%SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe 17 | ) 18 | 19 | rem We assume the RMM copies this batch script and the Powershell script to the same directory 20 | %POWERSHELL% -executionpolicy bypass -f ./InstallHuntress.powershellv1.ps1 -acctkey %ACCTKEY% -orgkey %1 21 | -------------------------------------------------------------------------------- /Powershell/README.md: -------------------------------------------------------------------------------- 1 | ## Deploying the Huntress Agent using PowerShell 2 | 3 | This PowerShell script will install the Huntress Agent. The script will automatically download the installer from the Huntress servers and run it. The script does error checking and logging as well. (It will check to see if the agent is already installed and also verfiy the installation completed.) 4 | 5 | You have the option to hard code your Huntress account key, organization key, and tags (optional) in the script, or pass as arguments to the script. [Click here for more details regarding the Account Key and Organization Key.](https://support.huntress.io/hc/en-us/articles/4404012734227-Using-Account-Keys-Organization-Keys-and-Agent-Tags) 6 | 7 | The script supports the following mutually exclusive command-line switches: 8 | * `-reregister` - Force the agent to re-register (useful for clean install) 9 | * `-reinstall` - Re-install the agent (useful for "repairing" an agent; this will replace all the files are restart the services) 10 | * `-uninstall` - Forces the agent to uninstall itself; useful for corrupted installs 11 | 12 | Usage: 13 | ``` 14 | powershell -executionpolicy bypass -f ./InstallHuntress.powershellv2.ps1 [-acctkey ] [-orgkey ] [-tags ] [-reregister] [-reinstall] [-uninstall] 15 | ``` 16 | ### Batch File Wrapper 17 | 18 | We have also included a batch file, `InstallHuntress.bat`, to be used as a wrapper. This is useful if your RMM/SCCM application does not manage the PowerShell [`executionpolicy`.](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-3.0) 19 | 20 | You'll need to edit the batch file, adding your Huntress account key. Then you can run the batch file as follows: 21 | 22 | ``` 23 | InstallHuntress.bat 24 | ``` 25 | 26 | ### Using the script via a GPO 27 | 28 | We've had several of our partners use this PowerShell script with a GPO. The "startup script" is the best option because it will install with SYSTEM (local administrator) privileges before any user logs in. **The caveat is the system will need to be rebooted before the install will occur.** 29 | 30 | The startup script is located in Computer Configuration | Policies | Windows Settings | Scripts | Startup 31 | 32 | GPO 33 | 34 | GPO-script 35 | -------------------------------------------------------------------------------- /Powershell/gpo_startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Powershell/gpo_startup.png -------------------------------------------------------------------------------- /Powershell/gpo_startup_script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huntresslabs/deployment-scripts/e5efb0a70a571dd96bf3c6291195e9b006132c39/Powershell/gpo_startup_script.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Various deployment scripts for Huntress 2 | 3 | See for details. 4 | 5 | ## macOS 6 | 7 | macOS deployments require additional considerations and configuration before installing. [Please refer to this document for more information](https://support.huntress.io/hc/en-us/documents/25013857741331-Critical-Steps-for-Complete-macOS-EDR-Deployment) before planning your macOS deployment. 8 | 9 | The macOS mobileconfig can be found in the `Bash` folder. It is called `HuntressSystemExtensionProfile.mobileconfig`. 10 | -------------------------------------------------------------------------------- /SentinelOne/syslog_huntress_io.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIG5DCCBcygAwIBAgIQAlLeodn9H3RmRB+Fd/rBFTANBgkqhkiG9w0BAQsFADBZ 3 | MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMTMwMQYDVQQDEypE 4 | aWdpQ2VydCBHbG9iYWwgRzIgVExTIFJTQSBTSEEyNTYgMjAyMCBDQTEwHhcNMjUw 5 | MzA0MDAwMDAwWhcNMjYwNDA0MjM1OTU5WjByMQswCQYDVQQGEwJVUzERMA8GA1UE 6 | CBMITWFyeWxhbmQxFjAUBgNVBAcTDUVsbGljb3R0IENpdHkxGzAZBgNVBAoTEkh1 7 | bnRyZXNzIExhYnMgSW5jLjEbMBkGA1UEAxMSc3lzbG9nLmh1bnRyZXNzLmlvMIIB 8 | IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwqS3B1EmCkHuaqq6rA2KtThJ 9 | LdBIiyMfHeeQ5pfudF8181SjxhnvXF76FmXGV6nLiva0zZUicsvGOZNfzK7mq5Z+ 10 | pKXvPWrF7LlAzw7mP0txo6oU7HLMqzWm9mEKd5ZgVWeAtvoKGQnYnPYEpHNgZN95 11 | 0k4QueEfpwY4FH+UKYrS1zWDRf5nIWYgRXPFxIwU11So5Q2VCnPUaF4rdAg9X2Yt 12 | xzvvF03YqfCRE6dF0zALP159aRiZBDVaZLcYPE+q95nfOeBWfqtfyPS/lRzFz0Wq 13 | edrAhf8aJ4vwgQzdvX/PAGbNvhUOjmiCoz0g/SbEXcV/FPRDMENCzsQzVxuDyQID 14 | AQABo4IDjTCCA4kwHwYDVR0jBBgwFoAUdIWAwGbH3zfez70pN6oDHb7tzRcwHQYD 15 | VR0OBBYEFITAyQquc7GXUMMhEufBoiKdau9GMB0GA1UdEQQWMBSCEnN5c2xvZy5o 16 | dW50cmVzcy5pbzA+BgNVHSAENzA1MDMGBmeBDAECAjApMCcGCCsGAQUFBwIBFhto 17 | dHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDgYDVR0PAQH/BAQDAgWgMB0GA1Ud 18 | JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjCBnwYDVR0fBIGXMIGUMEigRqBEhkJo 19 | dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxHMlRMU1JTQVNI 20 | QTI1NjIwMjBDQTEtMS5jcmwwSKBGoESGQmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNv 21 | bS9EaWdpQ2VydEdsb2JhbEcyVExTUlNBU0hBMjU2MjAyMENBMS0xLmNybDCBhwYI 22 | KwYBBQUHAQEEezB5MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j 23 | b20wUQYIKwYBBQUHMAKGRWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp 24 | Q2VydEdsb2JhbEcyVExTUlNBU0hBMjU2MjAyMENBMS0xLmNydDAMBgNVHRMBAf8E 25 | AjAAMIIBfQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdgAOV5S8866pPjMbLJkHs/eQ 26 | 35vCPXEyJd0hqSWsYcVOIQAAAZViNnjXAAAEAwBHMEUCIFtadu07nwpkCc942nyB 27 | TzgTgOEXIUdP9+TEXu7SDmduAiEAp+zxwus67jJL1X3oVnXUuye/DsTnM+asIC0A 28 | CVj6BRAAdQBkEcRspBLsp4kcogIuALyrTygH1B41J6vq/tUDyX3N8AAAAZViNnkY 29 | AAAEAwBGMEQCIG5HhQfa7ebWIOuBQEtgahYUwGqB149jfnAYjrok+r2dAiB20t0F 30 | clqVEPZ9irIgYhPWH6T6LjjyRydfaQxT9QSmmAB2AEmcm2neHXzs/DbezYdkprhb 31 | rwqHgBnRVVL76esp3fjDAAABlWI2eSwAAAQDAEcwRQIgXqaixQgGt/m065pWoN3a 32 | 7SvyzsV2Miz2EovxER6fZ0oCIQDaEK9bm5emcQIhOJpX6PC3+k4K7S233jQWm76E 33 | KiscKDANBgkqhkiG9w0BAQsFAAOCAQEAb64CFKcXRaPvcYE23t/zK3gt7UlIT+gZ 34 | VIjHXMeXLfjqL2K8bG4W+bRCd0zY4iCj43nOEkn6+YnDlTPTaFZ/YXJUDbUAEarC 35 | LSlrYZpNxR5ZdAdlpbYGKg+3+vGtAaMdXu7GjHhXsb1/merHYbNR1ILet3Y3TYYY 36 | 90CtO14mqPDK1U1tzqaS96f82j/x3s7EsogEZymPxK+BfAdJtJ+oVx9pO7z8Mnhr 37 | 6olMU5WtCuZjuQc2hskvpgh9Z5StHOWck/nOsT1EGIjwaqeI+NxmCjdpMPD7tZdw 38 | RWtrqTdqQtAsAAJJCIlyfFp4KiM8zpAiYFrfpChDjQwT9rO7J2rTpw== 39 | -----END CERTIFICATE----- 40 | -------------------------------------------------------------------------------- /SolarwindsRMM/README.md: -------------------------------------------------------------------------------- 1 | SolarWinds RMM AMP for installing the Huntress agent. 2 | 3 | 4 | See https://support.huntress.io/hc/en-us/articles/4404012639379-Deploying-Huntress-with-N-able-Solarwinds-MSP-RMM for details. 5 | -------------------------------------------------------------------------------- /SolarwindsRMM/scripts/README.md: -------------------------------------------------------------------------------- 1 | PowerShell script used for installing the Huntress agent. The script is included in the SolarWindsRMM AMP. 2 | 3 | See https://support.huntress.io/hc/en-us/articles/4404012639379-Deploying-Huntress-with-N-able-Solarwinds-MSP-RMM for details. 4 | -------------------------------------------------------------------------------- /Syncro/InstallHuntress-macOS-Syncro.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #shellcheck disable=SC2181,SC2295,SC2116 3 | # 4 | 5 | # Copyright (c) 2022 Huntress Labs, Inc. 6 | # All rights reserved. 7 | # 8 | # Redistribution and use in source and binary forms, with or without 9 | # modification, are permitted provided that the following conditions are met: 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above copyright 13 | # notice, this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # * Neither the name of the Huntress Labs nor the names of its contributors 16 | # may be used to endorse or promote products derived from this software 17 | # without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | # DISCLAIMED. IN NO EVENT SHALL HUNTRESS LABS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 25 | # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | # The Huntress installer needs an Account Key and an Organization Key (a user 32 | # specified name or description) which is used to affiliate an Agent with a 33 | # specific Organization within the Huntress Partner's Account. These keys can be 34 | # pulled from Syncro using the variables defined below, or by using runtime variables. 35 | 36 | # For more details, see our KB article 37 | # https://support.huntress.io/hc/en-us/articles/10888685108627 38 | 39 | 40 | ############################################################################## 41 | ## Begin user modified variables 42 | ############################################################################## 43 | 44 | 45 | # By default, Syncro will pull from your HUNTRESS_API_KEY global variable. 46 | # Otherwise, you may specify your key inside the quotes below. 47 | defaultAccountKey="$HuntressAccountKey" 48 | 49 | # Syncro provides the CUSTOMER_NAME_LABEL as an variable that we use as the 50 | # Organization Name in Huntress. If you want to have customer names match Syncro, 51 | # leave the line below as-is. 52 | defaultOrgKey="$HuntressOrganizationKey" 53 | 54 | # Option to install the system extension after the Huntress Agent is installed. In order for this to happen 55 | # without security prompts on the endpoint, permissions need to be applied to the endpoint by an MDM before this script 56 | # is run. See the following KB article for instructions: 57 | # https://support.huntress.io/hc/en-us/articles/21286543756947-Instructions-for-the-MDM-Configuration-for-macOS 58 | install_system_extension=true 59 | 60 | ############################################################################## 61 | ## Do not modify anything below this line 62 | ############################################################################## 63 | dd=$(date "+%Y%m%d-%H%M%S") 64 | log_file="/tmp/HuntressInstaller.log" 65 | install_script="/tmp/HuntressMacInstall.sh" 66 | invalid_key="Invalid account secret key" 67 | pattern="[a-f0-9]{32}" 68 | rmm="Syncro macOS deployment component" 69 | version="1.1 - March 25, 2025" 70 | 71 | ## Using logger function to provide helpful logs within RMM tools in addition to log file 72 | logger() { 73 | echo "$dd -- $*"; 74 | echo "$dd -- $*" >> $log_file; 75 | } 76 | 77 | # Check for root 78 | if [ $EUID -ne 0 ]; then 79 | logger "This script must be run as root, exiting..." 80 | exit 1 81 | fi 82 | 83 | # Clean up any old installer scripts. 84 | if [ -f "$install_script" ]; then 85 | logger "Installer file present in /tmp; deleting." 86 | rm -f "$install_script" 87 | fi 88 | 89 | ## 90 | ## This section handles the assigning `=` character for options. 91 | ## Since most RMMs treat spaces as delimiters in Mac Scripting, 92 | ## we have to use `=` to assign the option value, but must remove 93 | ## it because, well, bash. https://stackoverflow.com/a/28466267/519360 94 | ## 95 | 96 | usage() { 97 | cat < --organization_key= 99 | 100 | -a, --account_key The account key to use for this agent install 101 | -o, --organization_key The org key to use for this agent install 102 | -h, --help Print this message 103 | 104 | EOF 105 | } 106 | 107 | while getopts a:o:h:-: OPT; do 108 | if [ "$OPT" = "-" ]; then 109 | OPT="${OPTARG%%=*}" # extract long option name 110 | OPTARG="${OPTARG#$OPT}" # extract long option argument (may be empty) 111 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 112 | else 113 | # the user used a short option, but we still want to strip the assigning `=` 114 | OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=` 115 | fi 116 | case "$OPT" in 117 | a | account_key) 118 | account_key="$OPTARG" 119 | ;; 120 | o | organization_key) 121 | organization_key="$OPTARG" 122 | ;; 123 | h | help) 124 | usage 125 | ;; 126 | ??*) 127 | logger "Illegal option --$OPT" 128 | exit 2 129 | ;; # bad long option 130 | \? ) 131 | exit 2 132 | ;; # bad short option (error reported via getopts) 133 | esac 134 | done 135 | shift $((OPTIND-1)) # remove parsed options and args from $@ list 136 | 137 | logger "=========== INSTALL START AT $dd ===============" 138 | logger "=========== $rmm | Version: $version ===============" 139 | 140 | # VALIDATE OPTIONS PASSED TO SCRIPT 141 | if [ -z "$organization_key" ]; then 142 | organizationKey=$(echo "$defaultOrgKey" | xargs) 143 | logger "--organization_key parameter not present, using defaultKey instead: $defaultOrgKey" 144 | else 145 | organizationKey=$(echo "$organization_key" | xargs) 146 | logger "--organization_key parameter present, set to: $organizationKey" 147 | fi 148 | 149 | if ! [[ $account_key =~ $pattern ]]; then 150 | logger "Invalid --account_key provided, checking defaultAccountKey..." 151 | accountKey=$(echo "$defaultAccountKey" | xargs) 152 | if ! [[ $accountKey =~ $pattern ]]; then 153 | logger "ERROR: Invalid --account_key. Please check Huntress support documentation." 154 | exit 1 155 | fi 156 | else 157 | accountKey=$(echo "$account_key" | xargs) 158 | fi 159 | 160 | # OPTIONS REQUIRED 161 | if [ -z "$accountKey" ] || [ -z "$organizationKey" ] 162 | then 163 | logger "Error: --account_key and --organization_key are both required" >> $log_file 164 | echo 165 | usage 166 | exit 1 167 | fi 168 | 169 | # Hide most of the account key in the logs, keeping the front and tail end for troubleshooting 170 | masked="$(echo "${accountKey:0:4}")" 171 | masked+="************************" 172 | masked+="$(echo "${accountKey: (-4)}")" 173 | 174 | logger "Provided Huntress key: $masked" 175 | logger "Provided Organization Key: $organizationKey" 176 | 177 | result=$(curl -w "%{http_code}" -L "https://huntress.io/script/darwin/$accountKey" -o "$install_script") 178 | 179 | if [ $? != "0" ]; then 180 | logger "ERROR: Download failed with error: $result" 181 | exit 1 182 | fi 183 | 184 | if grep -Fq "$invalid_key" "$install_script"; then 185 | logger "ERROR: --account_key is invalid. You entered: $accountKey" 186 | exit 1 187 | fi 188 | 189 | logger "=============== Begin Installer Logs ===============" 190 | if [ "$install_system_extension" = true ]; then 191 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -v --install_system_extension)" 192 | else 193 | install_result="$(/bin/bash "$install_script" -a "$accountKey" -o "$organizationKey" -v)" 194 | fi 195 | 196 | if [ $? != "0" ]; then 197 | logger "Installer Error: $install_result" 198 | exit 1 199 | fi 200 | 201 | logger "$install_result" 202 | logger "=========== INSTALL FINISHED AT $dd ===============" 203 | exit 204 | -------------------------------------------------------------------------------- /Syncro/README.md: -------------------------------------------------------------------------------- 1 | ## Deploying the Huntress Windows Agent using Syncro 2 | 3 | [The deployment script is already included with Syncro. See here for configuration details.](https://huntress.zendesk.com/hc/en-us/articles/4404005056275-Deploying-Huntress-with-Syncro-RMM) 4 | 5 | ## Deploying the Huntress macOS Agent using Syncro 6 | 7 | This script is in Syncro's Community Script library, and documentation is available [here](https://support.huntress.io/hc/en-us/articles/10888685108627). 8 | 9 | macOS deployments require additional considerations and configuration before installing. [Please refer to this document for more information](https://support.huntress.io/hc/en-us/documents/25013857741331-Critical-Steps-for-Complete-macOS-EDR-Deployment) before planning your macOS deployment. 10 | --------------------------------------------------------------------------------