Deployment of Zluri Mac Agent using Kandji

Mac Agent Version3.2.3


Mac Versions tested on: Ventura[13.4], Big Sur[11.0], Monterey[12.6]


Permissions: Screen Recording Permissions - Optional Permission


Notifications to end users: “Login Item Added- zluri” might come up in some systems; it is a behaviour in control of MacOS


 Creation of Blueprint and adding the scripts

1. Click ‘Blueprints’ from the left navigation menu.


2. Click ‘New Blueprint’

3. Click ‘start from scratch’


4. Enter name & description


5. Click ‘Library’


6. Click ‘Add New’

7. Select ‘Mac’ & Click ‘Custom Apps’


8. Click ‘Add & Configure’


9. Add Title; select the Blueprint created above.


10. In the installation, select ‘Audit & Enforce.’

Audit script:


#!/bin/bash


# version comparison logic


function version_compare { printf "%03d%03d%03d%03d" $(echo "$1" | tr '.' ' '); }




# perform version comparision


function perf_comparison {


installedVersion=$(defaults read /Applications/zluri.app/Contents/Info.plist CFBundleShortVersionString) # ask installed version of the app from system


echo "installed zluri app version: $installedVersion"


expectedVersion="3.2.3" # admin should update the expectedVersion value to the latest version available


[ $(version_compare $installedVersion) -lt $(version_compare $expectedVersion) ] && echo "1"


[[ $(version_compare $installedVersion) -gt $(version_compare $expectedVersion) || $(version_compare $installedVersion) -eq $(version_compare $expectedVersion) ]] && echo "0"


}




shouldUpdate="0"


finalResult="0"


ZLURI_APP="/Applications/zluri.app"


if [ -e $ZLURI_APP ]


  then


     echo "zluri app found in /Applications/ dir"


    finalResult="0"


    perf_comparison


    shouldUpdate=$?


    echo "shouldUpdate again $shouldUpdate"


  else


    echo "zluri app NOT found in /Applications/ dir"


    finalResult="1"


fi




if [[ $shouldUpdate -eq "1" ]] || [[ $finalResult -eq "1" ]]


  then


  echo "it should update or exit with code 1"


  # first kill the app if running


  # needed for auto-update


  ZLURI_PROCESS=$(ps aux | grep -v grep | grep -ci zluri)


  OSQUERY_PROCESS=$(ps aux | grep -v grep | grep -ci osquery)


  if [[ $ZLURI_PROCESS -gt 0 ]] && [[ $OSQUERY_PROCESS -gt 0 ]]


    then


    echo "trying to kill the process"


      pkill -x "zluri"


      pkill -x "osquery"


  fi


  exit 1


fi




if [[ $finalResult -eq 0 ]] || [[ $shouldUpdate -eq 0 ]]


    then


    echo "all ok"


    exit 0


fi


11. Add the pre-install script and upload the package and post-install script.

Pre-install:

#!/bin/bash


CURRENT_USER=$( echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }' )


HOMEDIR=$(/usr/bin/dscl . -read /Users/"$CURRENT_USER" NFSHomeDirectory | /usr/bin/cut -d' ' -f2)


ORG_TOKEN=<orgToken>


INTERVAL= 3600000


SCREEN_RECORD=off


echo "$ORG_TOKEN"


echo "$CURRENT_USER"


echo "$HOMEDIR"




# Deleting App components from Application folder


echo "Deleting zluri Logs"


logsPath=$HOMEDIR/Library/Logs/zluri


if [ -d "$logsPath" ]


then


rm -rf $HOMEDIR/Library/Logs/zluri


echo "***Deleted Zluri Logs Successfully***"


fi




echo "Deleting Zluri Application Support"


applicationSupportPath=$HOMEDIR/Library/Application\ Support/zluri


if [ -d "$applicationSupportPath" ]


then


rm -rf $HOMEDIR/Library/Application\ Support/zluri


echo "***Deleted Zluri Application Support Successfully***"


fi




echo "Finished:preflight"




echo "writing zluri generic-MDM config file"




if [ ! -d /tmp/zluritemp ]; then


    mkdir -p /tmp/zluritemp


else


    echo "zluritemp dir exists"


fi


echo "{\"org_token\": \"$ORG_TOKEN\", \"interval\": \"$INTERVAL\", \"screen_recording\": \"$SCREEN_RECORD\", \"silent_auth\": \"on\"}" > /tmp/zluritemp/client-config.json


echo "====written the client config json file required configurations in temp directory===="




# Handle the rosetta-related issues in preinstall script


# Determine the processor brand


processor_brand=$(/usr/sbin/sysctl -n machdep.cpu.brand_string)




# Determine the processor brand


if [[ "$processor_brand" == *"Apple"* ]]; then


    /bin/echo "Apple Processor is present..."




    # Check if the Rosetta service is running


    check_rosetta_status=$(/usr/bin/pgrep oahd)




    # Rosetta Folder location


    # Condition to check to see if the Rosetta folder exists. This check was added


    # because the Rosetta2 service is already running in macOS versions 11.5 and


    # greater without Rosseta2 actually being installed.


    rosetta_folder="/Library/Apple/usr/share/rosetta"




    if [[ -n $check_rosetta_status ]] && [[ -e $rosetta_folder ]]; then


        /bin/echo "Rosetta2 is installed... no action needed"


    else


        # Installs Rosetta


        /bin/echo "Rosetta is not installed... installing now"


        /usr/sbin/softwareupdate --install-rosetta --agree-to-license


    fi




elsex


    /bin/echo "Apple Processor is not present...Rosetta2 is not needed"


fi




sudo mkdir -p $HOMEDIR/Library/Application\ Support/zluri




echo "{\"org_token\": \"$ORG_TOKEN\", \"interval\": \"$INTERVAL\", \"screen_recording\": \"$SCREEN_RECORD\", \"silent_auth\": \"on\"}" > $HOMEDIR/Library/Application\ Support/zluri/client-config.json


echo "====written the client config json file required configurations in temp directory===="




exit 0

Post Install:

#!/bin/bash


# writing config json file to appData directory


# CURRENT_USER=$(/bin/ls -l /dev/console | awk '{print $3}')


CURRENT_USER=$( echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }' )


HOMEDIR=$(/usr/bin/dscl . -read /Users/"$CURRENT_USER" NFSHomeDirectory | /usr/bin/cut -d' ' -f2)


ORG_TOKEN=<orgToken>


INTERVAL= 3600000


SCREEN_RECORD=off




echo "ORG TOKEN: $ORG_TOKEN"


echo "API INTERVAL: $INTERVAL"


echo "SCREEN RECORD: $SCREEN_RECORD"


echo "CURRENT USER: $CURRENT_USER"


echo "HOMEDIR: $HOMEDIR"




sleep 300




ZLURIDIR="$HOMEDIR/Library/Application Support/zluri"




echo "ZLURIDIR: $ZLURIDIR"


# cd $ZLURIDIR




if [ -d "$ZLURIDIR" ]; then


    echo "{\"org_token\": \"$ORG_TOKEN\", \"interval\": \"$INTERVAL\", \"screen_recording\": \"$SCREEN_RECORD\", \"silent_auth\": \"on\"}" > "$ZLURIDIR"/client-config.json


    echo "===writing config json file to appData directory==="


    else


        echo "zluri folder doesn't exist, cannot write config json file"


fi


Replace <orgToken> with your Organisation Token


12. Save the Blueprint.

13. Assign the Blueprint to the devices you want to install the Zluri agent

User Experience

  • The Zluri Agent will silently install and authenticate and sit on the system tray

  • On some systems, the notification for the addition of a login item might come up [Under the control of MacOS]

  • After authentication, the agent will start sending the data to the Zluri servers silently

Authentication:

On installation of the scripts first and then the application, all the devices are {org_token} authenticated and are listed in the Sources → Agents → Desktop Agents Page



The mapping of the device to the user can be done in 3 ways:

  1. Integration with Kandji: 
    We will get the user to device mapping, and the user authentication is handled with this data by Zluri

  2. Manually

  3. In development: 
    An option to Bulk Upload a CSV with user-to-device mapping on the UI. For the time being, we can handle the bulk mapping from Zluri’s support team.


Once the User is authenticated with the Organization Token, the agent looks something like this until the user authentication is complete by the admin:


  • An admin mode is introduced, which is activated with a hotkey; only then logout, quit, and force restart the agent is possible → preferred not to be shared with all the users.






Can’t find what you are looking for? Let us help you!

Deployment of Zluri Mac Agent using Kandji

Modified on Mon, 01 Apr 2024 at 08:52 PM

Mac Agent Version3.2.3


Mac Versions tested on: Ventura[13.4], Big Sur[11.0], Monterey[12.6]


Permissions: Screen Recording Permissions - Optional Permission


Notifications to end users: “Login Item Added- zluri” might come up in some systems; it is a behaviour in control of MacOS


 Creation of Blueprint and adding the scripts

1. Click ‘Blueprints’ from the left navigation menu.


2. Click ‘New Blueprint’

3. Click ‘start from scratch’


4. Enter name & description


5. Click ‘Library’


6. Click ‘Add New’

7. Select ‘Mac’ & Click ‘Custom Apps’


8. Click ‘Add & Configure’


9. Add Title; select the Blueprint created above.


10. In the installation, select ‘Audit & Enforce.’

Audit script:


#!/bin/bash


# version comparison logic


function version_compare { printf "%03d%03d%03d%03d" $(echo "$1" | tr '.' ' '); }




# perform version comparision


function perf_comparison {


installedVersion=$(defaults read /Applications/zluri.app/Contents/Info.plist CFBundleShortVersionString) # ask installed version of the app from system


echo "installed zluri app version: $installedVersion"


expectedVersion="3.2.3" # admin should update the expectedVersion value to the latest version available


[ $(version_compare $installedVersion) -lt $(version_compare $expectedVersion) ] && echo "1"


[[ $(version_compare $installedVersion) -gt $(version_compare $expectedVersion) || $(version_compare $installedVersion) -eq $(version_compare $expectedVersion) ]] && echo "0"


}




shouldUpdate="0"


finalResult="0"


ZLURI_APP="/Applications/zluri.app"


if [ -e $ZLURI_APP ]


  then


     echo "zluri app found in /Applications/ dir"


    finalResult="0"


    perf_comparison


    shouldUpdate=$?


    echo "shouldUpdate again $shouldUpdate"


  else


    echo "zluri app NOT found in /Applications/ dir"


    finalResult="1"


fi




if [[ $shouldUpdate -eq "1" ]] || [[ $finalResult -eq "1" ]]


  then


  echo "it should update or exit with code 1"


  # first kill the app if running


  # needed for auto-update


  ZLURI_PROCESS=$(ps aux | grep -v grep | grep -ci zluri)


  OSQUERY_PROCESS=$(ps aux | grep -v grep | grep -ci osquery)


  if [[ $ZLURI_PROCESS -gt 0 ]] && [[ $OSQUERY_PROCESS -gt 0 ]]


    then


    echo "trying to kill the process"


      pkill -x "zluri"


      pkill -x "osquery"


  fi


  exit 1


fi




if [[ $finalResult -eq 0 ]] || [[ $shouldUpdate -eq 0 ]]


    then


    echo "all ok"


    exit 0


fi


11. Add the pre-install script and upload the package and post-install script.

Pre-install:

#!/bin/bash


CURRENT_USER=$( echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }' )


HOMEDIR=$(/usr/bin/dscl . -read /Users/"$CURRENT_USER" NFSHomeDirectory | /usr/bin/cut -d' ' -f2)


ORG_TOKEN=<orgToken>


INTERVAL= 3600000


SCREEN_RECORD=off


echo "$ORG_TOKEN"


echo "$CURRENT_USER"


echo "$HOMEDIR"




# Deleting App components from Application folder


echo "Deleting zluri Logs"


logsPath=$HOMEDIR/Library/Logs/zluri


if [ -d "$logsPath" ]


then


rm -rf $HOMEDIR/Library/Logs/zluri


echo "***Deleted Zluri Logs Successfully***"


fi




echo "Deleting Zluri Application Support"


applicationSupportPath=$HOMEDIR/Library/Application\ Support/zluri


if [ -d "$applicationSupportPath" ]


then


rm -rf $HOMEDIR/Library/Application\ Support/zluri


echo "***Deleted Zluri Application Support Successfully***"


fi




echo "Finished:preflight"




echo "writing zluri generic-MDM config file"




if [ ! -d /tmp/zluritemp ]; then


    mkdir -p /tmp/zluritemp


else


    echo "zluritemp dir exists"


fi


echo "{\"org_token\": \"$ORG_TOKEN\", \"interval\": \"$INTERVAL\", \"screen_recording\": \"$SCREEN_RECORD\", \"silent_auth\": \"on\"}" > /tmp/zluritemp/client-config.json


echo "====written the client config json file required configurations in temp directory===="




# Handle the rosetta-related issues in preinstall script


# Determine the processor brand


processor_brand=$(/usr/sbin/sysctl -n machdep.cpu.brand_string)




# Determine the processor brand


if [[ "$processor_brand" == *"Apple"* ]]; then


    /bin/echo "Apple Processor is present..."




    # Check if the Rosetta service is running


    check_rosetta_status=$(/usr/bin/pgrep oahd)




    # Rosetta Folder location


    # Condition to check to see if the Rosetta folder exists. This check was added


    # because the Rosetta2 service is already running in macOS versions 11.5 and


    # greater without Rosseta2 actually being installed.


    rosetta_folder="/Library/Apple/usr/share/rosetta"




    if [[ -n $check_rosetta_status ]] && [[ -e $rosetta_folder ]]; then


        /bin/echo "Rosetta2 is installed... no action needed"


    else


        # Installs Rosetta


        /bin/echo "Rosetta is not installed... installing now"


        /usr/sbin/softwareupdate --install-rosetta --agree-to-license


    fi




elsex


    /bin/echo "Apple Processor is not present...Rosetta2 is not needed"


fi




sudo mkdir -p $HOMEDIR/Library/Application\ Support/zluri




echo "{\"org_token\": \"$ORG_TOKEN\", \"interval\": \"$INTERVAL\", \"screen_recording\": \"$SCREEN_RECORD\", \"silent_auth\": \"on\"}" > $HOMEDIR/Library/Application\ Support/zluri/client-config.json


echo "====written the client config json file required configurations in temp directory===="




exit 0

Post Install:

#!/bin/bash


# writing config json file to appData directory


# CURRENT_USER=$(/bin/ls -l /dev/console | awk '{print $3}')


CURRENT_USER=$( echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }' )


HOMEDIR=$(/usr/bin/dscl . -read /Users/"$CURRENT_USER" NFSHomeDirectory | /usr/bin/cut -d' ' -f2)


ORG_TOKEN=<orgToken>


INTERVAL= 3600000


SCREEN_RECORD=off




echo "ORG TOKEN: $ORG_TOKEN"


echo "API INTERVAL: $INTERVAL"


echo "SCREEN RECORD: $SCREEN_RECORD"


echo "CURRENT USER: $CURRENT_USER"


echo "HOMEDIR: $HOMEDIR"




sleep 300




ZLURIDIR="$HOMEDIR/Library/Application Support/zluri"




echo "ZLURIDIR: $ZLURIDIR"


# cd $ZLURIDIR




if [ -d "$ZLURIDIR" ]; then


    echo "{\"org_token\": \"$ORG_TOKEN\", \"interval\": \"$INTERVAL\", \"screen_recording\": \"$SCREEN_RECORD\", \"silent_auth\": \"on\"}" > "$ZLURIDIR"/client-config.json


    echo "===writing config json file to appData directory==="


    else


        echo "zluri folder doesn't exist, cannot write config json file"


fi


Replace <orgToken> with your Organisation Token


12. Save the Blueprint.

13. Assign the Blueprint to the devices you want to install the Zluri agent

User Experience

  • The Zluri Agent will silently install and authenticate and sit on the system tray

  • On some systems, the notification for the addition of a login item might come up [Under the control of MacOS]

  • After authentication, the agent will start sending the data to the Zluri servers silently

Authentication:

On installation of the scripts first and then the application, all the devices are {org_token} authenticated and are listed in the Sources → Agents → Desktop Agents Page



The mapping of the device to the user can be done in 3 ways:

  1. Integration with Kandji: 
    We will get the user to device mapping, and the user authentication is handled with this data by Zluri

  2. Manually

  3. In development: 
    An option to Bulk Upload a CSV with user-to-device mapping on the UI. For the time being, we can handle the bulk mapping from Zluri’s support team.


Once the User is authenticated with the Organization Token, the agent looks something like this until the user authentication is complete by the admin:


  • An admin mode is introduced, which is activated with a hotkey; only then logout, quit, and force restart the agent is possible → preferred not to be shared with all the users.






Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select atleast one of the reasons

Feedback sent

We appreciate your effort and will try to fix the article