Install, update and remove checkmk agent

Install, update and remove checkmk Agent on Windows or Linux with automated scripts. Furthermore these scripts are adding or removing the client-object in the checkmk-Server (via API calls).

Prerequisites

  1. No pending changes open in checkmk instance before running a script.
  2. Open web interface from checkmk server and log-in with admin account.
  3. Create a new User (if not already existent) with the following name: automation
  4. Asign the Role Administrator to the automation-User.

automation%20user%20%28assign%20Administrator%20role%29


Linux

  1. For all scripts please edit the following variuables:

  2. After creating or downloading the script please make it executable:

    chmod +x <SCRIPTNAME.sh>
  3. Execute the script with root-rights:

    sudo ./<SCRIPTNAME.sh>

All scripts are running ca. 3 minutes (do to some API calls.) !!!

install-checkmk.sh

#!/bin/bash

# parameters needed to be set site-specific.
SERVER_NAME="v-u-checkmk-p"
SITE_NAME="cmk" # More infos: https://docs.checkmk.com/latest/de/intro_setup.html#create_site
API_URL="http://$SERVER_NAME/$SITE_NAME/check_mk/api/1.0"
USERNAME="automation"
PASSWORD="<PASSWORD_OF_THE_AUTOMATION_USER>"
FOLDER="/" # (Optional) More infos: https://docs.checkmk.com/latest/de/hosts_structure.html?#folder
# End specific parameters
##### below should not be changed unless you are absolutely sure in what you are doing !

# check if running as root
if [ "$EUID" -ne 0 ]; then
  printf "$(tput setaf 1)%s$(tput sgr0)\n" "Please run as root!"
  exit
fi

# Function to display a message and a spinner while a background command is running
spinner() {
  # Arguments
  # 1. Message
  local message=$1
  # 2. additional delay in secounds
  local additionaldelay=$2
  additionaldelay=$(($additionaldelay*10))

  local pid=$!
  local delay=0.1
  local spinChars="/-\|"

  while ps -p $pid > /dev/null; do
    local spinChar=${spinChars:0:1}
    spinChars=${spinChars:1}${spinChar}
        printf "$(tput setaf 6)%s : %s$(tput sgr0)\r" "$message" "$spinChar"
    sleep $delay
  done

  for ((i = 1 ; i <= $additionaldelay; i++ )); do
    local spinChar=${spinChars:0:1}
    spinChars=${spinChars:1}${spinChar}
    printf "$(tput setaf 6)%s : %s$(tput sgr0)\r" "$message" "$spinChar"
    sleep $delay
  done

  # Wait for the background process to finish
  wait $pid

  # Check the exit status of curl
  if [ $? -ne 0 ]; then
    error_message=$(cat error.log)
    printf "\n$(tput setaf 1)%s$(tput sgr0)\n" "$error_message"
    rm error.log
    exit 1
  fi

  printf "$(tput setaf 2)%s : OK$(tput sgr0)\n" "$message"
}

# Check if there are any pending changes on the checkmk server
temp_file=$(mktemp)
# Get Content-Length from "pending changes" object via REST-API
curl -s -S -I -H "Authorization: Bearer $USERNAME $PASSWORD" -X GET "$API_URL/domain-types/activation_run/collections/pending_changes" > "$temp_file" 2> error.log &
spinner "Get Content-Length from 'pending changes' object via REST-API" 0
# Extract the ETag value from the file content
result=$(grep -iE '^Content-Length: ' "$temp_file" | awk '{print $2}' | tr -d '"' | tr -cd '[:alnum:]')
# Delete the temporary file
rm "$temp_file"
if [ "$result" -gt 350 ]; then
  printf "$(tput setaf 1)%s$(tput sgr0)\n" "Please revert or accept pending change(s) on the checkmk server before running the script! Install aborted!"
  exit
fi

# Check if rpm or dpkg package manager is installed
if command -v dpkg &> /dev/null; then
  # Download check_mk_agent.deb file from checkmk-server via REST-API
  curl -s -S -H "Accept: application/octet-stream" -H "Authorization: Bearer $USERNAME $PASSWORD" -X GET -H "Content-Type: application/json" -o "/tmp/check_mk_agent.deb" "$API_URL/domain-types/agent/actions/download/invoke?os_type=linux_deb" 1> /dev/null 2> error.log &
  spinner "Download check_mk_agent.deb file from checkmk-server via REST-API" 0

  # Install check_mk_agent
  dpkg -i /tmp/check_mk_agent.deb 1> /dev/null 2> error.log &
  spinner "Install check_mk_agent" 0

  # Download mk_apt plugin from checkmk server
  wget http://$SERVER_NAME/$SITE_NAME/check_mk/agents/plugins/mk_apt --no-check-certificate 1> /dev/null 2> error.log &
  spinner "Download mk_apt plugin from checkmk server" 0
  mv -f mk_apt /usr/lib/check_mk_agent/plugins
  chmod +x /usr/lib/check_mk_agent/plugins/mk_apt

elif command -v rpm &> /dev/null; then
  # Download check_mk_agent.rpm file from checkmk-server via REST-API
  curl -s -S -H "Accept: application/octet-stream" -H "Authorization: Bearer $USERNAME $PASSWORD" -X GET -H "Content-Type: application/json" -o "/tmp/check_mk_agent.rpm" "$API_URL/domain-types/agent/actions/download/invoke?os_type=linux_rpm" 1> /dev/null 2> error.log &
  spinner "Download check_mk_agent.rpm file from checkmk-server via REST-API" 0

  # Install check_mk_agent
  rpm -i /tmp/check_mk_agent.rpm 1> /dev/null 2> error.log &
  spinner "Install check_mk_agent" 0

else
  printf "$(tput setaf 1)%s$(tput sgr0)\n" "Neither dpkg nor rpm is installed! Install aborted!"
  exit
fi

# Create a checkmk local script to check for pending reboots
cat << EOF > /usr/lib/check_mk_agent/local/reboot
#!/bin/bash

[[ -f /etc/os-release ]] && source /etc/os-release

if [[ -f /var/run/reboot-required ]]; then
  if [[ -f /var/run/reboot-required.pkgs ]]; then
    echo "1 Reboot_needed - A system reboot is needed due to updated packages: \$(cat /var/run/reboot-required.pkgs | tr '\n' ' ')"
  else
    echo "1 Reboot_needed - A system reboot is needed"
  fi
else
  echo "0 Reboot_needed - No system reboot needed"
fi
EOF
chmod +x /usr/lib/check_mk_agent/local/reboot 1> /dev/null 2> error.log &
spinner "Create a checkmk local script to check for pending reboots" 0

# Get the host IP-Address
HostIP=$(ip -4 route get 8.8.8.8 | awk 'NR==1 {print $7}')

# Create Host via REST-API
BODY="{\"folder\": \"$FOLDER\", \"host_name\": \"$(hostname | tr '[:upper:]' '[:lower:]')\", \"attributes\": {\"ipaddress\": \"$HostIP\"}}"
curl -s -S -H "Accept: application/json" -H "Authorization: Bearer $USERNAME $PASSWORD" -X POST -H "Content-Type: application/json" -d "$BODY" "$API_URL/domain-types/host_config/collections/all" 1> /dev/null 2> error.log &
spinner "Create Host via REST-API" 0

# Get ETag from "pending changes" object via REST-API
temp_file=$(mktemp)
curl -s -S -I -H "Authorization: Bearer $USERNAME $PASSWORD" -X GET "$API_URL/domain-types/activation_run/collections/pending_changes" 1> "$temp_file" 2> error.log &
spinner "Get ETag from 'pending changes' object via REST-API" 0
# Extract the ETag value from the file content
etag=$(grep -iE '^ETag: ' "$temp_file" | awk '{print $2}' | tr -d '"' | tr -cd '[:alnum:]')
rm "$temp_file"

# Start activating the pending changes via REST-API
temp_file=$(mktemp)
BODY="{\"force_foreign_changes\": \"false\", \"redirect\": \"false\", \"sites\": [\"$SITE_NAME\"]}"
curl -s -S -H "Accept: application/json" -H "Authorization: Bearer $USERNAME $PASSWORD" -H "If-Match: \"$etag\"" -X POST -H "Content-Type: application/json" -d "$BODY" "$API_URL/domain-types/activation_run/actions/activate-changes/invoke"  1> "$temp_file" 2> error.log &
spinner "Start activating the pending changes via REST-API" 60
# Extract the id value from the file content
activation_id=$(cat $temp_file | grep -oP '(?<="id": ")[^"]+' | head -n1)
rm "$temp_file"

# Register the Agent1> /dev/null 2> error.log
cmk-agent-ctl register --hostname $(hostname | tr '[:upper:]' '[:lower:]') --server $SERVER_NAME --site $SITE_NAME --user $USERNAME --password $PASSWORD --trust-cert 1> /dev/null 2> error.log &
spinner "Register the Agent (Wait 60 secounds for host-lables to be assigned to host-object)" 60

# Start service discovery for the newly created host via REST-API
BODY="{\"host_name\": \"$(hostname | tr '[:upper:]' '[:lower:]')\", \"mode\": \"only_host_labels\"}"
curl -s -S -H "Accept: application/json" -H "Authorization: Bearer $USERNAME $PASSWORD" -X POST -H "Content-Type: application/json" -d "$BODY" "$API_URL/domain-types/service_discovery_run/actions/start/invoke" 1> /dev/null 2> error.log &
spinner "Start service discovery for the newly created host via REST-API (Wait 120 secounds)" 120

# Get ETag from "pending changes" object via REST-API
temp_file=$(mktemp)
curl -s -S -I -H "Authorization: Bearer $USERNAME $PASSWORD" -X GET "$API_URL/domain-types/activation_run/collections/pending_changes" > "$temp_file" 2> error.log &
spinner "Get ETag from 'pending changes' object via REST-API" 0
# Extract the ETag value from the file content
etag=$(grep -iE '^ETag: ' "$temp_file" | awk '{print $2}' | tr -d '"' | tr -cd '[:alnum:]')
rm "$temp_file"

# Start activating the pending changes via REST-API
BODY="{\"force_foreign_changes\": \"false\", \"redirect\": \"false\", \"sites\": [\"$SITE_NAME\"]}"
curl -s -S -H "Accept: application/json" -H "Authorization: Bearer $USERNAME $PASSWORD" -H "If-Match: \"$etag\"" -X POST -H "Content-Type: application/json" -d "$BODY" "$API_URL/domain-types/activation_run/actions/activate-changes/invoke" 1> /dev/null 2> error.log &
spinner "Start activating the pending changes via REST-API" 0

# Script deletes itself
echo "Script deletes itself"
currentscript=$0
shred -u ${currentscript}

uninstall-checkmk.sh

#!/bin/bash

# parameters needed to be set site-specific.
SERVER_NAME="v-u-checkmk-p"
SITE_NAME="cmk" # More infos: https://docs.checkmk.com/latest/de/intro_setup.html#create_site
API_URL="http://$SERVER_NAME/$SITE_NAME/check_mk/api/1.0"
USERNAME="automation"
PASSWORD="<PASSWORD_OF_THE_AUTOMATION_USER>"
# End specific parameters
##### below should not be changed unless you are absolutely sure in what you are doing !

# check if running as root
if [ "$EUID" -ne 0 ]; then
  printf "$(tput setaf 1)%s$(tput sgr0)\n" "Please run as root!"
  exit
fi

# Function to display a message and a spinner while a background command is running
spinner() {
  # Arguments
  # 1. Message
  local message=$1
  # 2. additional delay in secounds
  local additionaldelay=$2
  additionaldelay=$(($additionaldelay*10))

  local pid=$!
  local delay=0.1
  local spinChars="/-\|"

  while ps -p $pid > /dev/null; do
    local spinChar=${spinChars:0:1}
    spinChars=${spinChars:1}${spinChar}
        printf "$(tput setaf 6)%s : %s$(tput sgr0)\r" "$message" "$spinChar"
    sleep $delay
  done

  for ((i = 1 ; i <= $additionaldelay; i++ )); do
    local spinChar=${spinChars:0:1}
    spinChars=${spinChars:1}${spinChar}
    printf "$(tput setaf 6)%s : %s$(tput sgr0)\r" "$message" "$spinChar"
    sleep $delay
  done

  # Wait for the background process to finish
  wait $pid

  # Check the exit status of curl
  if [ $? -ne 0 ]; then
    error_message=$(cat error.log)
    printf "\n$(tput setaf 1)%s$(tput sgr0)\n" "$error_message"
    rm error.log
    exit 1
  fi

  printf "$(tput setaf 2)%s : OK$(tput sgr0)\n" "$message"
}

# Check if there are any pending changes on the checkmk server
temp_file=$(mktemp)
# Get Content-Length from "pending changes" object via REST-API
curl -s -S -I -H "Authorization: Bearer $USERNAME $PASSWORD" -X GET "$API_URL/domain-types/activation_run/collections/pending_changes" 1> "$temp_file" 2> error.log &
spinner "Get Content-Length from 'pending changes' object via REST-API" 0
# Extract the ETag value from the file content
result=$(grep -iE '^Content-Length: ' "$temp_file" | awk '{print $2}' | tr -d '"' | tr -cd '[:alnum:]')
# Delete the temporary file
rm "$temp_file"
if [ "$result" -gt 350 ]; then
  printf "$(tput setaf 1)%s$(tput sgr0)\n" "Please revert or accept pending change(s) on the checkmk server before running the script! Uninstall aborted!"
  exit
fi

# Check if rpm or dpkg package manager is installed
if command -v dpkg &> /dev/null; then
  # Download check_mk_agent.deb file from checkmk-server via REST-API
  curl -s -S -H "Accept: application/octet-stream" -H "Authorization: Bearer $USERNAME $PASSWORD" -X GET -H "Content-Type: application/json" -o "/tmp/check_mk_agent.deb" "$API_URL/domain-types/agent/actions/download/invoke?os_type=linux_deb" 1> /dev/null 2> error.log &
  spinner "Download check_mk_agent.deb file from checkmk-server via REST-API" 0

  # Uninstall check_mk_agent
  apt-get remove -y check-mk-agent 1> /dev/null 2> error.log &
  spinner "Uninstall check_mk_agent" 0
  rm -r /usr/lib/check_mk_agent
  rm -r /var/lib/check_mk_agent
  rm -r /var/lib/cmk-agent
  rm -r /etc/check_mk

elif command -v rpm &> /dev/null; then
  # Download check_mk_agent.rpm file from checkmk-server via REST-API
  curl -s -S -H "Accept: application/octet-stream" -H "Authorization: Bearer $USERNAME $PASSWORD" -X GET -H "Content-Type: application/json" -o "/tmp/check_mk_agent.rpm" "$API_URL/domain-types/agent/actions/download/invoke?os_type=linux_rpm" 1> /dev/null 2> error.log &
  spinner "Download check_mk_agent.rpm file from checkmk-server via REST-API" 0

  # Uninstall check_mk_agent
  dnf remove -y check_mk_agent 1> /dev/null 2> error.log &
  spinner "Uninstall check_mk_agent" 0
  rm -r /usr/lib/check_mk_agent
  rm -r /var/lib/check_mk_agent
  rm -r /var/lib/cmk-agent
  rm -r /etc/check_mk

else
  printf "$(tput setaf 1)%s$(tput sgr0)\n" "Neither dpkg nor rpm is installed! Uninstall aborted!"
  exit
fi

# Delete Host via REST-API
curl -s -S -H "Accept: application/json" -H "Authorization: Bearer $USERNAME $PASSWORD" -X DELETE -H "Content-Type: application/json" -d "$BODY" "$API_URL/objects/host_config/$(hostname | tr '[:upper:]' '[:lower:]')" 1> /dev/null 2> error.log &
spinner "Delete Host via REST-API" 0

# Get ETag from "pending changes" object via REST-API
temp_file=$(mktemp)
curl -s -S -I -H "Authorization: Bearer $USERNAME $PASSWORD" -X GET "$API_URL/domain-types/activation_run/collections/pending_changes" 1> "$temp_file" 2> error.log &
spinner "Get ETag from 'pending changes' object via REST-API" 0
# Extract the ETag value from the file content
etag=$(grep -iE '^ETag: ' "$temp_file" | awk '{print $2}' | tr -d '"' | tr -cd '[:alnum:]')
rm "$temp_file"

# Start activating the pending changes via REST-API
BODY="{\"force_foreign_changes\": \"false\", \"redirect\": \"false\", \"sites\": [\"$SITE_NAME\"]}"
curl -s -S -H "Accept: application/json" -H "Authorization: Bearer $USERNAME $PASSWORD" -H "If-Match: \"$etag\"" -X POST -H "Content-Type: application/json" -d "$BODY" "$API_URL/domain-types/activation_run/actions/activate-changes/invoke" 1> /dev/null 2> error.log &
spinner "Start activating the pending changes via REST-API" 0

# Script deletes itself
echo "Script deletes itself"
currentscript=$0
shred -u ${currentscript}

update-checkmk.sh

#!/bin/bash

# parameters needed to be set site-specific.
SERVER_NAME="v-u-checkmk-p"
SITE_NAME="cmk" # More infos: https://docs.checkmk.com/latest/de/intro_setup.html#create_site
API_URL="http://$SERVER_NAME/$SITE_NAME/check_mk/api/1.0"
USERNAME="automation"
PASSWORD="<PASSWORD_OF_THE_AUTOMATION_USER>"
# End specific parameters
##### below should not be changed unless you are absolutely sure in what you are doing !

# check if running as root
if [ "$EUID" -ne 0 ]; then
  printf "$(tput setaf 1)%s$(tput sgr0)\n" "Please run as root!"
  exit
fi

# Function to display a message and a spinner while a background command is running
spinner() {
  # Arguments
  # 1. Message
  local message=$1
  # 2. additional delay in secounds
  local additionaldelay=$2
  additionaldelay=$(($additionaldelay*10))

  local pid=$!
  local delay=0.1
  local spinChars="/-\|"

  while ps -p $pid > /dev/null; do
    local spinChar=${spinChars:0:1}
    spinChars=${spinChars:1}${spinChar}
        printf "$(tput setaf 6)%s : %s$(tput sgr0)\r" "$message" "$spinChar"
    sleep $delay
  done

  for ((i = 1 ; i <= $additionaldelay; i++ )); do
    local spinChar=${spinChars:0:1}
    spinChars=${spinChars:1}${spinChar}
    printf "$(tput setaf 6)%s : %s$(tput sgr0)\r" "$message" "$spinChar"
    sleep $delay
  done

  # Wait for the background process to finish
  wait $pid

  # Check the exit status of curl
  if [ $? -ne 0 ]; then
    error_message=$(cat error.log)
    printf "\n$(tput setaf 1)%s$(tput sgr0)\n" "$error_message"
    rm error.log
    exit 1
  fi

  printf "$(tput setaf 2)%s : OK$(tput sgr0)\n" "$message"
}

# Check if there are any pending changes on the checkmk server
temp_file=$(mktemp)
# Get Content-Length from "pending changes" object via REST-API
curl -s -S -I -H "Authorization: Bearer $USERNAME $PASSWORD" -X GET "$API_URL/domain-types/activation_run/collections/pending_changes" > "$temp_file" 2> error.log &
spinner "Get Content-Length from 'pending changes' object via REST-API" 0
# Extract the ETag value from the file content
result=$(grep -iE '^Content-Length: ' "$temp_file" | awk '{print $2}' | tr -d '"' | tr -cd '[:alnum:]')
# Delete the temporary file
rm "$temp_file"
if [ "$result" -gt 350 ]; then
  printf "$(tput setaf 1)%s$(tput sgr0)\n" "Please revert or accept pending change(s) on the checkmk server before running the script! Install aborted!"
  exit
fi

# Check if rpm or dpkg package manager is installed
if command -v dpkg &> /dev/null; then
  # Download check_mk_agent.deb file from checkmk-server via REST-API
  curl -s -S -H "Accept: application/octet-stream" -H "Authorization: Bearer $USERNAME $PASSWORD" -X GET -H "Content-Type: application/json" -o "/tmp/check_mk_agent.deb" "$API_URL/domain-types/agent/actions/download/invoke?os_type=linux_deb" 1> /dev/null 2> error.log &
  spinner "Download check_mk_agent.deb file from checkmk-server via REST-API" 0

  # Install check_mk_agent
  dpkg -i /tmp/check_mk_agent.deb 1> /dev/null 2> error.log &
  spinner "Install check_mk_agent" 0

  # Download mk_apt plugin from checkmk server
  wget http://$SERVER_NAME/$SITE_NAME/check_mk/agents/plugins/mk_apt --no-check-certificate 1> /dev/null 2> error.log &
  spinner "Download mk_apt plugin from checkmk server" 0
  mv -f mk_apt /usr/lib/check_mk_agent/plugins
  chmod +x /usr/lib/check_mk_agent/plugins/mk_apt

elif command -v rpm &> /dev/null; then
  # Download check_mk_agent.rpm file from checkmk-server via REST-API
  curl -s -S -H "Accept: application/octet-stream" -H "Authorization: Bearer $USERNAME $PASSWORD" -X GET -H "Content-Type: application/json" -o "/tmp/check_mk_agent.rpm" "$API_URL/domain-types/agent/actions/download/invoke?os_type=linux_rpm" 1> /dev/null 2> error.log &
  spinner "Download check_mk_agent.rpm file from checkmk-server via REST-API" 0

  # Install check_mk_agent
  rpm -i /tmp/check_mk_agent.rpm 1> /dev/null 2> error.log &
  spinner "Install check_mk_agent" 0

else
  printf "$(tput setaf 1)%s$(tput sgr0)\n" "Neither dpkg nor rpm is installed! Update aborted!"
  exit
fi

# Register the Agent
cmk-agent-ctl register --hostname $(hostname | tr '[:upper:]' '[:lower:]') --server $SERVER_NAME --site $SITE_NAME --user $USERNAME --password $PASSWORD --trust-cert 1> /dev/null 2> error.log &
spinner "Register the Agent" 0

# Script deletes itself
echo "Script deletes itself"
currentscript=$0
shred -u ${currentscript}

Windows

  1. For all scripts please edit the following variuables:

  2. Execute the script with administrator-rights:

    powershell ./<SCRIPTNAME.ps1>

All scripts are running ca. 3 minutes (do to some API calls.) !!!

install-checkmk.ps1

# check if running as administrator
#Requires -RunAsAdministrator

# parameters needed to be set site-specific.
$SERVER_NAME="v-u-checkmk-p"
$SITE_NAME="cmk" # More infos: https://docs.checkmk.com/latest/de/intro_setup.html#create_site
$API_URL="http://$SERVER_NAME/$SITE_NAME/check_mk/api/1.0"
$USERNAME="automation"
$PASSWORD="<PASSWORD_OF_THE_AUTOMATION_USER>"
$FOLDER="/" # (Optional) More infos: https://docs.checkmk.com/latest/de/hosts_structure.html?#folder
# End specific parameters
##### below should not be changed unless you are absolutely sure in what you are doing !

# Function to display a message and a spinner while a background job is running
function Spinner {
    param (
        [Parameter(Mandatory=$true)][int]$JobId,
        [Parameter(Mandatory=$true)][String]$Message,
        [Parameter(Mandatory=$true)][int]$AdditionalDelay
    )
    $AdditionalDelay=$AdditionalDelay*10

    $spinChars = "/-\|"

    while ($true) {
        if ($job.State -eq 'Completed' -or $job.State -eq 'Failed' -or $job.State -eq 'Stopped') {
            break
        }
        $spinChar = $spinChars[0]
        $spinChars = $spinChars.Substring(1) + $spinChar
        Write-Host -NoNewline ($Message+": " + $spinChar) -ForegroundColor Cyan
        Start-Sleep -Milliseconds 100
        Write-Host -NoNewline "`r"  # Clear the line
    }

    if ($job.ChildJobs[0].Error -ne "") {
        Write-Host `r`n($job.ChildJobs[0].Error) -ForegroundColor Red
        exit 1
    }

    for ($i = 1; $i -le $AdditionalDelay; $i++) {
        $spinChar = $spinChars[0]
        $spinChars = $spinChars.Substring(1) + $spinChar
        Write-Host -NoNewline ($Message+": " + $spinChar) -ForegroundColor Cyan
        Start-Sleep -Milliseconds 100
        Write-Host -NoNewline "`r"  # Clear the line
    }

    Write-Host ($Message+": OK") -ForegroundColor Green
}

# Check if there are any pending changes on the checkmk server
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD -ScriptBlock {
    $headers = @{
        'Accept' = 'application/json'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
    }
    $result = Invoke-WebRequest -Method GET -Uri "$($args[0])/domain-types/activation_run/collections/pending_changes" -Headers $headers -UseBasicParsing
    Write-Output $result.RawContentLength
}
Spinner -JobId $job.Id -Message "Get Content-Length from 'pending changes' object via REST-API" -AdditionalDelay 0
$result = Receive-Job -Id $job.Id
Remove-Job -Id $job.Id
if ($result -gt 350) {
    Write-Host "Please revert or accept pending change(s) on the checkmk server before running the script! Install aborted!" -ForegroundColor Red
    exit
}

# Download check_mk_agent.msi file from checkmk-server via REST-API
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD -ScriptBlock {
    $headers = @{
        'Accept' = 'application/octet-stream'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
    }
    $BODY = @{
        'os_type' = 'windows_msi'
    }
    Invoke-RestMethod -Method GET -Uri "$($args[0])/domain-types/agent/actions/download/invoke" -Headers $headers -Body $BODY -ContentType 'application/json' -OutFile "C:\Windows\Temp\check_mk_agent.msi"
}
Spinner -JobId $job.Id -Message "Download check_mk_agent.msi file from checkmk-server via REST-API" -AdditionalDelay 0
Remove-Job -Id $job.Id

# Install check_mk_agent
$job = Start-Job -ScriptBlock {
    $installpathcheckmk = "/i C:\Windows\Temp\check_mk_agent.msi /qn"
    Start-Process C:\Windows\System32\msiexec.exe -ArgumentList $installpathcheckmk -wait
    Copy-Item 'C:\Program Files (x86)\checkmk\service\plugins\windows_updates.vbs' -Destination C:\ProgramData\checkmk\agent\plugins
    Copy-Item 'C:\Program Files (x86)\checkmk\service\plugins\mk_inventory.vbs' -Destination C:\ProgramData\checkmk\agent\plugins
}
Spinner -JobId $job.Id -Message "Install check_mk_agent" -AdditionalDelay 0
Remove-Job -Id $job.Id

# Get the host IP-Address
$env:HostIP = (
    Get-NetIPConfiguration |
    Where-Object {
        $_.IPv4DefaultGateway -ne $null -and
        $_.NetAdapter.Status -ne "Disconnected"
    }
).IPv4Address.IPAddress

# Create Host via REST-API
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD,$FOLDER -ScriptBlock {
    $headers = @{
        'Accept' = 'application/json'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
    }
    $BODY = -join( '{"folder": "' , $args[3] , '", "host_name": "' , $($env:computername.ToLower()) , '", "attributes": {"ipaddress": "' , $env:HostIP , '"}}' )
    Invoke-RestMethod -Method Post -Uri "$($args[0])/domain-types/host_config/collections/all" -Headers $headers -Body $BODY -ContentType "application/json"
}
Spinner -JobId $job.Id -Message "Create Host via REST-API" -AdditionalDelay 0
Remove-Job -Id $job.Id

# Get ETag from "pending changes" object via REST-API
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD -ScriptBlock {
    $headers = @{
        'Accept' = 'application/json'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
    }
    $result = Invoke-WebRequest -Method GET -Uri "$($args[0])/domain-types/activation_run/collections/pending_changes" -Headers $headers -UseBasicParsing
    Write-Output $result.Headers.ETag
}
Spinner -JobId $job.Id -Message "Get ETag from 'pending changes' object via REST-API" -AdditionalDelay 0
$result = Receive-Job -Id $job.Id
Remove-Job -Id $job.Id

# Start activating the pending changes via REST-API
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD,$SITE_NAME,$result -ScriptBlock {
    $headers = @{
        'Accept' = 'application/json'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
        'If-Match' = $args[4]
    }
    $BODY= -join( '{"force_foreign_changes": "false", "redirect": "false", "sites": ["' , $args[3] , '"]}' )
    $result = Invoke-RestMethod -Method Post -Uri "$($args[0])/domain-types/activation_run/actions/activate-changes/invoke" -Headers $headers -Body $BODY -ContentType "application/json"
    Write-Output $result.Id
}
Spinner -JobId $job.Id -Message "Start activating the pending changes via REST-API" -AdditionalDelay 60
$activation_id = Receive-Job -Id $job.Id
Remove-Job -Id $job.Id

# Register the Agent
$job = Start-Job -ArgumentList $SERVER_NAME,$SITE_NAME,$USERNAME,$PASSWORD -ScriptBlock {
    Start-Process "C:\Program Files (x86)\checkmk\service\cmk-agent-ctl.exe" -ArgumentList "register --hostname $($env:computername.ToLower()) --server $($args[0]) --site $($args[1]) --user $($args[2]) --password $($args[3]) --trust-cert" -Wait -WindowStyle Hidden
}
Spinner -JobId $job.Id -Message "Register the Agent (Wait 60 secounds for host-lables to be assigned to host-object)" -AdditionalDelay 60
Remove-Job -Id $job.Id

# Start service discovery for the newly created host via REST-API
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD -ScriptBlock {
    $headers = @{
        'Accept' = 'application/json'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
    }
    $BODY = -join( '{"host_name": "' , $($env:computername.ToLower()) , '", "mode": "only_host_labels"}' )
    Invoke-RestMethod -Method Post -Uri "$($args[0])/domain-types/service_discovery_run/actions/start/invoke" -Headers $headers -Body $BODY -ContentType "application/json" -TimeoutSec 120
}
Spinner -JobId $job.Id -Message "Start service discovery for the newly created host via REST-API (Wait 120 secounds)" -AdditionalDelay 120
Remove-Job -Id $job.Id

# Get ETag from "pending changes" object via REST-API
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD -ScriptBlock {
    $headers = @{
        'Accept' = 'application/json'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
    }
    $result = Invoke-WebRequest -Method GET -Uri "$($args[0])/domain-types/activation_run/collections/pending_changes" -Headers $headers -UseBasicParsing
    Write-Output $result.Headers.ETag
}
Spinner -JobId $job.Id -Message "Get ETag from 'pending changes' object via REST-API" -AdditionalDelay 0
$result = Receive-Job -Id $job.Id
Remove-Job -Id $job.Id

# Start activating the pending changes via REST-API
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD,$SITE_NAME,$result -ScriptBlock {
    $headers = @{
        'Accept' = 'application/json'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
        'If-Match' = $args[4]
    }
    $BODY= -join( '{"force_foreign_changes": "false", "redirect": "false", "sites": ["' , $args[3] , '"]}' )
    Invoke-RestMethod -Method Post -Uri "$($args[0])/domain-types/activation_run/actions/activate-changes/invoke" -Headers $headers -Body $BODY -ContentType "application/json"
}
Spinner -JobId $job.Id -Message "Start activating the pending changes via REST-API" -AdditionalDelay 0
Remove-Job -Id $job.Id

# Script deletes itself
Write-Output "Script deletes itself"
Remove-Item -Path $MyInvocation.MyCommand.Source -Force

uninstall-checkmk.ps1

# check if running as administrator
#Requires -RunAsAdministrator

# parameters needed to be set site-specific.
$SERVER_NAME="v-u-checkmk-p"
$SITE_NAME="cmk" # More infos: https://docs.checkmk.com/latest/de/intro_setup.html#create_site
$API_URL="http://$SERVER_NAME/$SITE_NAME/check_mk/api/1.0"
$USERNAME="automation"
$PASSWORD="<PASSWORD_OF_THE_AUTOMATION_USER>"
# End specific parameters
##### below should not be changed unless you are absolutely sure in what you are doing !

# Function to display a message and a spinner while a background job is running
function Spinner {
    param (
        [Parameter(Mandatory=$true)][int]$JobId,
        [Parameter(Mandatory=$true)][String]$Message,
        [Parameter(Mandatory=$true)][int]$AdditionalDelay
    )
    $AdditionalDelay=$AdditionalDelay*10

    $spinChars = "/-\|"

    while ($true) {
        if ($job.State -eq 'Completed' -or $job.State -eq 'Failed' -or $job.State -eq 'Stopped') {
            break
        }
        $spinChar = $spinChars[0]
        $spinChars = $spinChars.Substring(1) + $spinChar
        Write-Host -NoNewline ($Message+" : " + $spinChar) -ForegroundColor Cyan
        Start-Sleep -Milliseconds 100
        Write-Host -NoNewline "`r"  # Clear the line
    }

    if ($job.ChildJobs[0].Error -ne "") {
        Write-Host `r`n($job.ChildJobs[0].Error) -ForegroundColor Red
        exit 1
    }

    for ($i = 1; $i -le $AdditionalDelay; $i++) {
        $spinChar = $spinChars[0]
        $spinChars = $spinChars.Substring(1) + $spinChar
        Write-Host -NoNewline ($Message+" : " + $spinChar) -ForegroundColor Cyan
        Start-Sleep -Milliseconds 100
        Write-Host -NoNewline "`r"  # Clear the line
    }

    Write-Host ($Message+" : OK") -ForegroundColor Green
}

# Check if there are any pending changes on the checkmk server
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD -ScriptBlock {
    $headers = @{
        'Accept' = 'application/json'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
    }
    $result = Invoke-WebRequest -Method GET -Uri "$($args[0])/domain-types/activation_run/collections/pending_changes" -Headers $headers -UseBasicParsing
    Write-Output $result.RawContentLength
}
Spinner -JobId $job.Id -Message "Get Content-Length from 'pending changes' object via REST-API" -AdditionalDelay 0
$result = Receive-Job -Id $job.Id
Remove-Job -Id $job.Id
if ($result -gt 350) {
    Write-Host "Please revert or accept pending change(s) on the checkmk server before running the script! Uninstall aborted!" -ForegroundColor Red
    exit
}

# Download check_mk_agent.msi file from checkmk-server via REST-API
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD -ScriptBlock {
    $headers = @{
        'Accept' = 'application/octet-stream'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
    }
    $BODY = @{
        'os_type' = 'windows_msi'
    }
    Invoke-RestMethod -Method GET -Uri "$($args[0])/domain-types/agent/actions/download/invoke" -Headers $headers -Body $BODY -ContentType 'application/json' -OutFile "C:\Windows\Temp\check_mk_agent.msi"
}
Spinner -JobId $job.Id -Message "Download check_mk_agent.msi file from checkmk-server via REST-API" -AdditionalDelay 0
Remove-Job -Id $job.Id

# Uninstall check_mk_agent
$job = Start-Job -ScriptBlock {
    $installpathcheckmk = "/x C:\Windows\Temp\check_mk_agent.msi /qn"
    Start-Process C:\Windows\System32\msiexec.exe -ArgumentList $installpathcheckmk -wait
    Remove-Item "C:\Program Files (x86)\checkmk" -Recurse -Force -ErrorAction SilentlyContinue
    Remove-Item "C:\ProgramData\checkmk" -Recurse -Force -ErrorAction SilentlyContinue
    Remove-Item "C:\ProgramData\cmk_agent_uninstall.txt" -Force -ErrorAction SilentlyContinue
}
Spinner -JobId $job.Id -Message "Uninstall check_mk_agent" -AdditionalDelay 0
Remove-Job -Id $job.Id

# Delete Host via REST-API
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD -ScriptBlock {
    $headers = @{
        'Accept' = 'application/json'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
    }
    Invoke-RestMethod -Method DELETE -Uri "$($args[0])/objects/host_config/$($env:computername.ToLower())" -Headers $Headers -ContentType "application/json"
}
Spinner -JobId $job.Id -Message "Delete Host via REST-API" -AdditionalDelay 0
Remove-Job -Id $job.Id

# Get ETag from "pending changes" object via REST-API
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD -ScriptBlock {
    $headers = @{
        'Accept' = 'application/json'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
    }
    $result = Invoke-WebRequest -Method GET -Uri "$($args[0])/domain-types/activation_run/collections/pending_changes" -Headers $headers -UseBasicParsing
    Write-Output $result.Headers.ETag
}
Spinner -JobId $job.Id -Message "Get ETag from 'pending changes' object via REST-API" -AdditionalDelay 0
$result = Receive-Job -Id $job.Id
Remove-Job -Id $job.Id

# Start activating the pending changes via REST-API
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD,$SITE_NAME,$result -ScriptBlock {
    $headers = @{
        'Accept' = 'application/json'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
        'If-Match' = $args[4]
    }
    $BODY= -join( '{"force_foreign_changes": "false", "redirect": "false", "sites": ["' , $args[3] , '"]}' )
    Invoke-RestMethod -Method Post -Uri "$($args[0])/domain-types/activation_run/actions/activate-changes/invoke" -Headers $headers -Body $BODY -ContentType "application/json"
}
Spinner -JobId $job.Id -Message "Start activating the pending changes via REST-API" -AdditionalDelay 0
Remove-Job -Id $job.Id

# Script deletes itself
Write-Output "Script deletes itself"
Remove-Item -Path $MyInvocation.MyCommand.Source -Force

update-checkmk.ps1

# check if running as administrator
#Requires -RunAsAdministrator

# parameters needed to be set site-specific.
$SERVER_NAME="v-u-checkmk-p"
$SITE_NAME="cmk" # More infos: https://docs.checkmk.com/latest/de/intro_setup.html#create_site
$API_URL="http://$SERVER_NAME/$SITE_NAME/check_mk/api/1.0"
$USERNAME="automation"
$PASSWORD="<PASSWORD_OF_THE_AUTOMATION_USER>"
# End specific parameters
##### below should not be changed unless you are absolutely sure in what you are doing !

# Function to display a message and a spinner while a background job is running
function Spinner {
    param (
        [Parameter(Mandatory=$true)][int]$JobId,
        [Parameter(Mandatory=$true)][String]$Message,
        [Parameter(Mandatory=$true)][int]$AdditionalDelay
    )
    $AdditionalDelay=$AdditionalDelay*10

    $spinChars = "/-\|"

    while ($true) {
        if ($job.State -eq 'Completed' -or $job.State -eq 'Failed' -or $job.State -eq 'Stopped') {
            break
        }
        $spinChar = $spinChars[0]
        $spinChars = $spinChars.Substring(1) + $spinChar
        Write-Host -NoNewline ($Message+": " + $spinChar) -ForegroundColor Cyan
        Start-Sleep -Milliseconds 100
        Write-Host -NoNewline "`r"  # Clear the line
    }

    if ($job.ChildJobs[0].Error -ne "") {
        Write-Host `r`n($job.ChildJobs[0].Error) -ForegroundColor Red
        exit 1
    }

    for ($i = 1; $i -le $AdditionalDelay; $i++) {
        $spinChar = $spinChars[0]
        $spinChars = $spinChars.Substring(1) + $spinChar
        Write-Host -NoNewline ($Message+": " + $spinChar) -ForegroundColor Cyan
        Start-Sleep -Milliseconds 100
        Write-Host -NoNewline "`r"  # Clear the line
    }

    Write-Host ($Message+": OK") -ForegroundColor Green
}

# Check if there are any pending changes on the checkmk server
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD -ScriptBlock {
    $headers = @{
        'Accept' = 'application/json'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
    }
    $result = Invoke-WebRequest -Method GET -Uri "$($args[0])/domain-types/activation_run/collections/pending_changes" -Headers $headers -UseBasicParsing
    Write-Output $result.RawContentLength
}
Spinner -JobId $job.Id -Message "Get Content-Length from 'pending changes' object via REST-API" -AdditionalDelay 0
$result = Receive-Job -Id $job.Id
Remove-Job -Id $job.Id
if ($result -gt 350) {
    Write-Host "Please revert or accept pending change(s) on the checkmk server before running the script! Uninstall aborted!" -ForegroundColor Red
    exit
}

# Download check_mk_agent.msi file from checkmk-server via REST-API
$job = Start-Job -ArgumentList $API_URL,$USERNAME,$PASSWORD -ScriptBlock {
    $headers = @{
        'Accept' = 'application/octet-stream'
        'Authorization' = "Bearer $($args[1]) $($args[2])"
    }
    $BODY = @{
        'os_type' = 'windows_msi'
    }
    Invoke-RestMethod -Method GET -Uri "$($args[0])/domain-types/agent/actions/download/invoke" -Headers $headers -Body $BODY -ContentType 'application/json' -OutFile "C:\Windows\Temp\check_mk_agent.msi"
}
Spinner -JobId $job.Id -Message "Download check_mk_agent.msi file from checkmk-server via REST-API" -AdditionalDelay 0
Remove-Job -Id $job.Id

# Install check_mk_agent
$job = Start-Job -ScriptBlock {
    $installpathcheckmk = "/i C:\Windows\Temp\check_mk_agent.msi /qn"
    Start-Process C:\Windows\System32\msiexec.exe -ArgumentList $installpathcheckmk -wait
    Copy-Item 'C:\Program Files (x86)\checkmk\service\plugins\windows_updates.vbs' -Destination C:\ProgramData\checkmk\agent\plugins
    Copy-Item 'C:\Program Files (x86)\checkmk\service\plugins\mk_inventory.vbs' -Destination C:\ProgramData\checkmk\agent\plugins
}
Spinner -JobId $job.Id -Message "Install check_mk_agent" -AdditionalDelay 0
Remove-Job -Id $job.Id

# Register the Agent
$job = Start-Job -ArgumentList $SERVER_NAME,$SITE_NAME,$USERNAME,$PASSWORD -ScriptBlock {
    Start-Process "C:\Program Files (x86)\checkmk\service\cmk-agent-ctl.exe" -ArgumentList "register --hostname $($env:computername.ToLower()) --server $($args[0]) --site $($args[1]) --user $($args[2]) --password $($args[3]) --trust-cert" -Wait -WindowStyle Hidden
}
Spinner -JobId $job.Id -Message "Register the Agent" -AdditionalDelay 0
Remove-Job -Id $job.Id

# Script deletes itself
Write-Output "Script deletes itself"
Remove-Item -Path $MyInvocation.MyCommand.Source -Force

Previous Post Next Post

Add a comment


Comments

Thanks a lot!!!
That was the solution.

Written on Mon, 08 Apr 2024 09:13:07 by Berni
1. Does your automation user have the "Administrator"-Role?
2. Do you have any pending changes in checkmk?

Written on Thu, 04 Apr 2024 19:37:48 by SuitDeer
Hi, I get on the install-checkmk.ps1 following error: Waiting for changes to be applied: -
{"title": "Method Not Allowed", "status": 405, "detail": "405 Method Not Allowed: The method is not allowed for the requested URL."}.

Did you have an idea why it is not working?

Written on Wed, 03 Apr 2024 08:31:47 by Berni