Skip to main content
Markus_M
Staff & Editor
Staff & Editor
March 19, 2026

Technical Tip: Using a script for granular host aging

  • March 19, 2026
  • 0 replies
  • 153 views
Description

 

This article describes an alternate way to age out specific hosts that may not fall into the regular hosts aging due to their group structure. Aging refers here to removing the hosts from the database and, as a result, to clean them from the hosts' view on FortiNAC-F.

 

The regular Host aging is described in the documentation in different methods:

Globally: Aging out host or user records.

Per group: About Aging hosts in a group.

While group-based aging is more granular, it may produce erratic results if the hosts are being added to groups in an undefined order, as the documentation describes.

 

Scope

 

FortiNAC-F.

 

Solution

 

The following describes a method to age out hosts grouped by their assigned role.

Scripts are to be located in the '/home/cm/scripts' directory. New ones can be added and used. On FortiNAC CLI:

 

execute enter-shell

cd /home/cm/scripts

touch AgingHostsByRole.sh

chmod +x AgingHostsByRole.sh

vi -N AgingHostsByRole.sh

Paste the following content:

 

#!/usr/bin/env bash

ROLE="${1:-BYOD}"
MAX_MIN="${2:-60}"
DELETE="${3:-0}"

hostcmd() {
/bsc/campusMgr/bin/RunClient DumpHostRecords.class "$@"
}

NOW=$(date +%s)

echo "Role=$ROLE MaxAge=${MAX_MIN}min Delete=$DELETE"

hostcmd -all | awk -v now="$NOW" -v role="$ROLE" -v max="$MAX_MIN" '

function trim(s){gsub(/^[ \t]+|[ \t]+$/,"",s);return s}

function epoch(d,cmd,e){
cmd="date -d \"" d "\" +%s"
cmd|getline e
close(cmd)
return e
}

function check(){
if(id && r==role && poll!=""){
e=epoch(poll)
if(e && (now-e) > max*60)
print id
}
}

{
if($0~/Host Record Entity:/){check(); id=r=poll=""}

l=trim($0)

if(l~/^ID = /){sub(/^ID = /,"",l); id=l}
else if(l~/^role = /){sub(/^role = /,"",l); r=l}
else if(l~/^Last Successful Poll = /){sub(/^Last Successful Poll = /,"",l); poll=l}
}

END{check()}
' | while read -r id; do

[ -z "$id" ] && continue

if [ "$DELETE" = "1" ]; then
echo "Deleting host dbid=$id"

hostcmd -delete -dbid "$id"

logger "Custom script action: Deleted host dbid=$id"
else
echo "DRYRUN delete host dbid=$id"

logger "Custom Script DRYRUN: Would have deleted host dbid=$id"

fi

done

 

The custom script is initialized with variables in the header as follows:


ROLE="${1:-BYOD}"
MAX_MIN="${2:-60}"
DELETE="${3:-0}"

 

This means that by default, the Role that this script targets is 'BYOD'. The hosts would be deleted if older than 60 minutes. The last variable indicates the dry run.

Either dry-run or deletion will be logged in the system logs accessible via CLI (/var/log/messages).

 

Through the GUI script actions 'Arguments', the variables can be adapted to other requirements.

An example for the Arguments field would be:

 

Contractor 15 1

 

This would change the script's variable use to delete hosts that are older than 15 minutes (instead of the 60-minute default) and carry the role of 'Contractor', case-sensitive. This would not be a dry-run because of the boolean '1' at the end. '0' would be a dry-run.

The GUI would look to be set like this:

 

Script settingsScript settings

 

The script repetition should be set properly according to the defined aging of 15 minutes. In this example, the repetition rate might need to be set lower. Per the setting on the screen, the script would be re-run every 1 hour. When it runs, it deletes Hosts with Contractor-Role, older than 15 Minutes. A repetition rate of 5 Minutes may fit the use case better.