Deployment script and command reference for the insider risk agent
- Last updated
- Save as PDF
Overview
When you create a deployment policy in the Code42 console, the process generates user-detection scripts and arguments for insider risk agent install commands. This article provides details about the scripts for Windows, Mac, and Linux devices.
Use the scripts for the agents in your Code42 environment. If you use scripts that are not made for the agents in your Code42 environment, they will break your deployment.
This article only applies to the insider risk agent.
For deployment scripts for the backup agent and legacy agent, see Deployment script and command reference for the backup and legacy agents.
For assistance, contact your Customer Success Manager (CSM) to engage the Code42 Professional Services team. If you don't know who your CSM is, contact our Technical Support Engineers.
Considerations
This article assumes you understand the introduction to deployment provided by the article Deploy Code42 agents.
- To use these deployment tools, you need to sign in to your Code42 console as a user with the Security Administrator role.
- In the Code42 federal environment, app installations must be deployed with a deployment policy to ensure the use of FIPS encryption in the Code42 agent. Users cannot download the installation package from the Code42 console or an email message.
Deployment is a secure process:
- During installation, device-server communications are encrypted.
- Devices can use a proxy to reach the Code42 cloud. See the PROXY_URL parameter.
- Deployment can run silently, with no intervention from users at devices.
About user detection scripts
Code42 relies on usernames having an email format, for instance, firstname.lastname@example.com. A user detection script detects the usernames in another system, such as a directory service, and transforms them to a username format that Code42 can use. When you create a user detection script, you must customize it for the system where you need to detect usernames.
To make it easier to create a user detection script that's right for your situation, we provide example scripts for Windows and Mac systems. You can use these examples as a starting place when creating your own user detection script.
Windows
For insider risk agents on Windows devices, a deployment policy provides:
- A user detection script to provide the insider risk agent with a username for the device. The script can also optionally specify the user's organization.
- Installation properties to serve as the arguments string to a insider risk agent install command.
- A code42.deployment.properties file to distribute along with the insider risk agent installer package.
Before insider risk agent installers can run properly, the code42.deployment.properties file must be in placed in the management tool or the device's file system.
Windows user detection script
When you create a deployment policy, you must also create a custom user detection script. A user detection script examines the host device and provides the insider risk agent with a username. The script resides on the Code42 cloud. The insider risk agent retrieves it during the install process.
Because user names in the Code42 cloud must be email addresses, deployments for connection to the Code42 cloud always require a customized user detection script.
You need to create a custom script because Code42 usernames must be email addresses. If you need help, contact your Customer Success Manager (CSM) to engage the Professional Services team.
How the Windows script works
The user detection script for Windows uses the device's operating system to determine the most recent logged-on username. The user detection script then reports this value to a standard output.
Tips to create a custom Windows script
Create a custom script and paste your script into your deployment policy. If you need help, contact your Customer Success Manager (CSM) for enterprise support.
When creating your custom script, be aware of the following:
- Every script must end by echoing the value for the username variable.
echo C42_USERNAME=<value>
- In the Code42 cloud, usernames must be email addresses.
echo C42_USERNAME=%current_user%@example.com
- Optionally, you can also specify the the organization for the user. Use the registration key for the organization. If the organization is not defined, the user registers to the organization specified in the deployment policy.
echo C42_ORG_REG_KEY=<value>
- You must provide values. Null values and empty strings will not work.
- The values cannot include either single (') or double (") quotation marks.
Windows command and arguments
Deployment policy command arguments need to be imported into your software management tool. To install a insider risk agent for all users of a device, sign in to an account with administrative rights and issue a command like the following:
<install-exe-name>.exe DEPLOYMENT_URL=<your deployment URL here> DEPLOYMENT_POLICY_TOKEN=<your token here> DEPLOYMENT_SECRET=<your secret here> /quiet /install /norestart
Windows deployment properties file
The code42.deployment.properties file uses values from your deployment policy and typically contains the following properties:
DEPLOYMENT_URL=<your deployment URL here> DEPLOYMENT_POLICY_TOKEN=<your token here> DEPLOYMENT_SECRET=<your secret here>
The file can also optionally contain a PROVIDED_USERNAME parameter that bypasses the user detection script altogether and simply registers with the provided username.
To deploy the properties file, see our instructions for deploying to devices.
Example Windows user detection scripts
Following are example user detection scripts for the Windows platform. For help with these scripts, contact your Customer Success Manager (CSM) to engage the Professional Services team.
General usage:
- Replace "domain.com" with your domain name.
- Add users you want to exclude from processing to the denylist in each script (look for "ExcludedUsers" or "Excluded Users"). This helps IT teams ensure that the Code42 installation is set up for the correct end users, and not the support staff setting up the Windows computers for the first time.
Domain-joined username detection
Professional Services filename: Win_Azure_ADSI_Combined_Userdetect.bat
This script detects users running explorer.exe and determines their email addresses from the directory. This script is the default Windows user detection script used by the Code42 Professional Services team. For Azure, the script looks at one of two registry keys. This script requires an active connection to a Windows domain and requires Powershell v.4.0 or later.
<# : batch script @echo off setlocal cd %~dp0 powershell -executionpolicy bypass -Command "Invoke-Expression $([System.IO.File]::ReadAllText('%~f0'))" endlocal goto:eof #> #Add users to this list that Code42 should not register with $ExcludedUsers = @( 'user1' 'user2' 'user3' 'admin' 'Administrator' 'admin-*' ) function Find-User { Write-Log "Starting user detection..." if (Check-Excluded-Users $username $C42_USERNAME) { Write-Log "Trying to grab the username from hybrid Azure reg key..." $username = (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Authentication\LogonUI | Select-Object -ExpandProperty LastLoggedOnDisplayName) Write-Log "Display name found: ($username)" $C42_USERNAME = (Get-ItemProperty HKLM:SOFTWARE\Microsoft\IdentityStore\LogonCache\*\Name2Sid\* | Where-Object {$_.DisplayName -eq $username} | Select-Object -Unique -ExpandProperty identityName) Write-Log "Username found via hybrid Azure reg key: ($C42_USERNAME)" } if (Check-Excluded-Users $username $C42_USERNAME) { Write-Log "Trying to find username from Azure Identity..." $username = (Get-Process -IncludeUserName -Name explorer | Select-Object -ExpandProperty UserName).Split('\')[1] Write-Log "Username found: ($username)" $C42_USERNAME = (Get-ItemProperty HKLM:SOFTWARE\Microsoft\IdentityStore\Cache\*\IdentityCache\* | Where-Object {$_.SAMName -eq $username} | Select-Object -Unique -ExpandProperty UserName) Write-Log "Email found in registry via Azure identity: ($C42_USERNAME)" } if (Check-Excluded-Users $username $C42_USERNAME) { Write-Log "Trying to grab the username from ADSI domain lookup key..." $username = (Get-Process -IncludeUserName -Name explorer | Select-Object -ExpandProperty UserName).Split('\')[1] Write-Log "Local username found ($username)" $searcher = [adsisearcher]"(samaccountname=$username)" ## Change attribute to userprincipalname, if required $C42_USERNAME = ($searcher.FindOne().Properties.mail) Write-Log "Username found via ADSI domain lookup: ($C42_USERNAME)" } if (Check-Excluded-Users $username $C42_USERNAME) { Write-Log "Excluded or null email address detected ($username). Will retry user detection after a period of time, or when reboot occurs." Write-Output "Excluded or null email address detected ($username). Will retry user detection after a period of time, or when reboot occurs." exit } Write-Log "Returning C42_USERNAME: $C42_USERNAME" Write-Host C42_USERNAME=$C42_USERNAME } <# Helper functions below this point.#> $PROC_LOG = "$env:HOMEDRIVE\ProgramData\Code42-AAT\Data\logs\userDetect_Result.log" function Check-Excluded-Users { [CmdletBinding()] Param ( [Parameter(Mandatory=$true, Position=0)] [AllowNull()] [AllowEmptyString()] [string]$username, [Parameter(Mandatory=$true, Position=1)] [AllowNull()] [AllowEmptyString()] [string]$C42_USERNAME ) $ExcludedUsers | ForEach-Object { if ([string]::IsNullOrEmpty($C42_USERNAME) -or $username -like $_ -or [string]::IsNullOrEmpty($username) -or $C42_USERNAME -like $_) { return $true } } return $false } function Write-Log { [CmdletBinding()] Param ( [Parameter(Mandatory=$true, Position=0)] [string]$LogMessage ) write-output $LogMessage Add-Content -Path $PROC_LOG -Value (Write-Output ("{0} - {1}" -f (Get-Date), $LogMessage)) } Find-User
Explorer.exe script
Professional Services filename: UserDetect_Explorer_AppendDomain.bat
The following script detects users running explorer.exe and appends the domain of the email address. This script requires PowerShell v.4.0 or later.
<# : batch script @echo off setlocal cd %~dp0 powershell -executionpolicy bypass -Command "Invoke-Expression $([System.IO.File]::ReadAllText('%~f0'))" endlocal goto:eof #> function Find-User { Write-Log "Starting user detection..." $username = (Get-Process -IncludeUserName -Name explorer | Select-Object -ExpandProperty UserName).Split('\')[-1].Split('@')[0] Write-Log "User name found ($username)" $C42_USERNAME = $username + '@domain.com' Write-Log "Email assembled by appending domain ($C42_USERNAME)" $ExcludedUsers = @( 'user1' 'user2' 'user3' 'admin' 'Administrator' 'admin-*' ) $ExcludedUsers | ForEach-Object { if ([string]::IsNullOrEmpty($username) -or $username -like $_) { Write-Log "Excluded or null email address detected ($username). Will retry user detection after a short period of time, or when reboot occurs." Write-Output "Excluded or null email address detected ($username). Will retry user detection after a short period of time, or when reboot occurs." exit } } Write-Log "Returning C42_USERNAME: $C42_USERNAME" Write-Host C42_USERNAME=$C42_USERNAME } <# Helper functions below this point. Most likely these will not need to be edited. #> $PROC_LOG = "$env:HOMEDRIVE\ProgramData\Code42-AAT\Data\logs\userDetect_Result.log" function Write-Log { [CmdletBinding()] Param ( [Parameter(Mandatory=$true, Position=0)] [string]$LogMessage ) Add-Content -Path $PROC_LOG -Value (Write-Output ("{0} - {1}" -f (Get-Date), $LogMessage)) } Find-User
Active Directory script
Professional Services filename: UserDetect_FirstLastName_ActiveDirectory.bat
The following script finds the real name of Active Directory users, joins the first name to the last name to create a username of firstname.lastname, and appends the domain of the email address. This script requires an active connection to a domain.
@echo off setlocal REM Gather user and home info. for /f "TOKENS=1,2,*" %%a in ('tasklist /FI "IMAGENAME eq explorer.exe" /FO LIST /V') do if /i "%%a %%b"=="User Name:" set _currdomain_user=%%c for /f "TOKENS=1,2 DELIMS=\" %%a in ("%_currdomain_user%") do set _currdomain=%%a & set currentuser=%%b for /f "tokens=2*" %%a in ('net user "%currentuser%" /domain ^| find /i "Full Name"') do set DisplayName=%%b set RealName=%DisplayName: =.% set Domain=@domain.com REM List of Excluded users that shouldn't be used for Code42 install. FOR %%G IN ("user1" "user2" "user3" "admin" "Administrator") DO ( IF /I "%currentuser%"=="%%~G" GOTO NOMATCH ) :MATCH REM Echo Values for Code42 Installer echo C42_USERNAME=%RealName%%DOMAIN% GOTO :EOF :NOMATCH echo Excluded or null user detected (%currentuser%). Will retry user detection after a short period of time, or when reboot occurs. GOTO :EOF
First name and last name script
Professional Services filename: UserDetect_FirstLastname_LastLoggedOnDisplayName.bat
The following script detects the locally logged-in users' first and last names and edits the string to create a username of firstname.lastname.
<# : batch script @echo off setlocal cd %~dp0 powershell -executionpolicy bypass -Command "Invoke-Expression $([System.IO.File]::ReadAllText('%~f0'))" endlocal goto:eof #> function Find-User { Write-Log "Starting user detection..." $username = (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Authentication\LogonUI | Select-Object -ExpandProperty LastLoggedOnUser).Split('\')[-1].Split('@')[0] $displayname = (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Authentication\LogonUI | Select-Object -ExpandProperty LastLoggedOnDisplayName) #Remove and start and end spaces on the string and force lowercase $displayname= $($displayname.Trim()).ToLower() if([string]::IsNullOrEmpty($displayname) -or $displayname -like ""){ Write-log "Regkey LastLoggedOnDisplayName not found or empty. Will retry user detection after a short period of time, or when reboot occurs." exit } Write-Log "User name found ($username)" Write-Log "DisplayName found ($displayname)" #Check for firstname lastname or lastname, firstname in the regkey LastLoggedOnDisplayName if($displayname -like "*,*"){ Write-Log "Lastname, Firstname Mode" $namearray= $displayname.Split(",") $lastname= $($namearray[0].Trim()).Trim(",") Write-Log "ln: ($lastname)" $firstname= $namearray[1].Trim() Write-Log "fn: ($firstname)" } else{ Write-Log "Firstname Lastname Mode" $namearray= $displayname.Split(" ") $lastname= $namearray[1].Trim() Write-Log "ln: ($lastname)" $firstname= $namearray[0].Trim() Write-Log "fn: ($firstname)" } $C42_USERNAME = $firstname + "." + $lastname + '@domain.com' Write-Log "Email assembled by appending domain ($C42_USERNAME)" $ExcludedUsers = @( 'user1' 'user2' 'user3' 'admin' 'Administrator' 'admin-*' ) $ExcludedUsers | ForEach-Object { if ([string]::IsNullOrEmpty($username) -or $username -like $_) { Write-Log "Excluded or null email address detected ($username). Will retry user detection after a short period of time, or when reboot occurs." Write-Output "Excluded or null email address detected ($username). Will retry user detection after a short period of time, or when reboot occurs." exit } } Write-Log "Returning C42_USERNAME: $C42_USERNAME" Write-Host C42_USERNAME=$C42_USERNAME } <# Helper functions below this point. Most likely these will not need to be edited. #> $PROC_LOG = "$env:HOMEDRIVE\ProgramData\Code42-AAT\Data\logs\userDetect_Result.log" function Write-Log { [CmdletBinding()] Param ( [Parameter(Mandatory=$true, Position=0)] [string]$LogMessage ) Add-Content -Path $PROC_LOG -Value (Write-Output ("{0} - {1}" -f (Get-Date), $LogMessage)) } Find-User
Local account script
Professional Services filename: UserDetect_FirstLastName_NoActiveDirectory.bat
The following script retrieves names from a local account, joins the first name to the last name to create a username of firstname.lastname, and appends the domain of the email address. This script needs the Full Name field for a local account to be populated with a user's first name and last name separated by a space. This script requires PowerShell v4.0 or later.
<# : batch script @echo off setlocal cd %~dp0 powershell -executionpolicy bypass -Command "Invoke-Expression $([System.IO.File]::ReadAllText('%~f0'))" endlocal goto:eof #> function Find-User { Write-Log "Starting user detection..." $username = (Get-Process -IncludeUserName -Name explorer | Select-Object -ExpandProperty UserName).Split('\')[-1].Split('@')[0] Write-Log "User name found ($username)" $fullname = (Get-CimInstance -Class Win32_UserAccount -Filter "LocalAccount='True'" | Where-Object -Property Name -like $username).FullName Write-Log "Full name found ($fullname)" $C42_USERNAME = ($fullname -replace " ",".") + '@domain.com' Write-Log "Email assembled from full name ($C42_USERNAME)" $ExcludedUsers = @( 'user1' 'user2' 'user3' 'admin' 'Administrator' 'admin-*' ) $ExcludedUsers | ForEach-Object { if ([string]::IsNullOrEmpty($username) -or $username -like $_) { Write-Log "Excluded or null email address detected ($username). Will retry user detection after a short period of time, or when reboot occurs." Write-Output "Excluded or null email address detected ($username). Will retry user detection after a short period of time, or when reboot occurs." exit } } Write-Log "Returning C42_USERNAME: $C42_USERNAME" Write-Host C42_USERNAME=$C42_USERNAME } <# Helper functions below this point. Most likely these will not need to be edited. #> $PROC_LOG = "$env:HOMEDRIVE\ProgramData\Code42-AAT\Data\logs\userDetect_Result.log" function Write-Log { [CmdletBinding()] Param ( [Parameter(Mandatory=$true, Position=0)] [string]$LogMessage ) Add-Content -Path $PROC_LOG -Value (Write-Output ("{0} - {1}" -f (Get-Date), $LogMessage)) } Find-User
Text file script
Professional Services filename: UserDetect_ReadFromFile_User.bat
The following script reads a text file (default location C:\Temp\C42_User.txt) for the user email addresses. This script requires PowerShell v4.0 or later.
<# : batch script @echo off setlocal cd %~dp0 powershell -executionpolicy bypass -Command "Invoke-Expression $([System.IO.File]::ReadAllText('%~f0'))" endlocal goto:eof #> function Find-User { Write-Log "Starting user detection..." $username = (Get-Process -IncludeUserName -Name explorer | Select-Object -ExpandProperty UserName).Split('\')[-1].Split('@')[0] Write-Log "User name found ($username)" $C42_USERNAME = Get-Content $env:HOMEDRIVE\temp\C42_User.txt Write-Log "Email read from file ($C42_USERNAME)" $ExcludedUsers = @( 'user1' 'user2' 'user3' 'admin' 'Administrator' 'admin-*' ) $ExcludedUsers | ForEach-Object { if ([string]::IsNullOrEmpty($C42_USERNAME) -or $username -like $_) { Write-Log "Excluded or null email address detected ($username). Will retry user detection after a short period of time, or when reboot occurs." Write-Output "Excluded or null email address detected ($username). Will retry user detection after a short period of time, or when reboot occurs." exit } } Write-Log "Returning C42_USERNAME: $C42_USERNAME" Write-Host C42_USERNAME=$C42_USERNAME } <# Helper functions below this point. Most likely these will not need to be edited. #> $PROC_LOG = "$env:HOMEDRIVE\ProgramData\Code42-AAT\Data\logs\userDetect_Result.log" function Write-Log { [CmdletBinding()] Param ( [Parameter(Mandatory=$true, Position=0)] [string]$LogMessage ) Add-Content -Path $PROC_LOG -Value (Write-Output ("{0} - {1}" -f (Get-Date), $LogMessage)) } Find-User
Last logged on user script
Professional Services filename: UserDetect_Registry_AppendDomain.bat
The following script detects which user last logged in using the LastLoggedOnUser registry value in HKLM, and appends the domain of the email address:
<# : batch script @echo off setlocal cd %~dp0 powershell -executionpolicy bypass -Command "Invoke-Expression $([System.IO.File]::ReadAllText('%~f0'))" endlocal goto:eof #> function Find-User { Write-Log "Starting user detection..." $username = (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Authentication\LogonUI | Select-Object -ExpandProperty LastLoggedOnUser).Split('\')[-1].Split('@')[0] Write-Log "User name found ($username)" $C42_USERNAME = $username + '@domain.com' Write-Log "Email assembled by appending domain ($C42_USERNAME)" $ExcludedUsers = @( 'user1' 'user2' 'user3' 'admin' 'Administrator' 'admin-*' ) $ExcludedUsers | ForEach-Object { if ([string]::IsNullOrEmpty($username) -or $username -like $_) { Write-Log "Excluded or null email address detected ($username). Will retry user detection after a short period of time, or when reboot occurs." Write-Output "Excluded or null email address detected ($username). Will retry user detection after a short period of time, or when reboot occurs." exit } } Write-Log "Returning C42_USERNAME: $C42_USERNAME" Write-Host C42_USERNAME=$C42_USERNAME } <# Helper functions below this point. Most likely these will not need to be edited. #> $PROC_LOG = "$env:HOMEDRIVE\ProgramData\Code42-AAT\Data\logs\userDetect_Result.log" function Write-Log { [CmdletBinding()] Param ( [Parameter(Mandatory=$true, Position=0)] [string]$LogMessage ) Add-Content -Path $PROC_LOG -Value (Write-Output ("{0} - {1}" -f (Get-Date), $LogMessage)) } Find-User
Mac
For insider risk agents on Mac devices, a deployment policy provides:
- A detection script to provide the insider risk agent with a username for the device. The script can also optionally specify the user's organization.
- A code42.deployment.properties file to distribute along with the insider risk agent installer package.
Before insider risk agent installers can run properly, the code42.deployment.properties file must be in placed in the management tool or the device's file system.
Mac user detection script
When you create a deployment policy, you must also create a custom user detection script. A user detection script examines the host device and provides the insider risk agent with a username. The script resides on the Code42 cloud. The insider risk agent retrieves it during the install process.
Because user names in the Code42 cloud must be email addresses, deployments for connection to the Code42 cloud always require a customized user detection script.
You need to create a custom script because Code42 usernames must be email addresses. If you need help, contact your Customer Success Manager (CSM) for enterprise support.
How the Mac script works
The user detection script for Mac uses the device's operating system to determine the most recent logged-on username. The detection script then reports the value to a standard output.
Python scripting language runtime is deprecated in macOS
According to the macOS Catalina 10.15 Release Notes, Apple deprecated bundling scripting language runtimes, including Python, in the Catalina release of macOS. This means that any Mac user detection script using Python may break in a future macOS.
To prevent this problem, if your user detection script uses Python, replace this:
/usr/bin/python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "\n");'
with this:
echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }'
Removing Python calls from your user detection script in this way ensures proper functioning of the script in future macOS versions.
Tips to create a custom Mac script
Create a custom script and paste your script into your deployment policy. If you need help, contact your Customer Success Manager (CSM) for enterprise support.
When creating your custom script, be aware of the following:
- Every script must end by echoing the value for the username variable:
echo "C42_USERNAME=<value>"
- In the Code42 cloud, usernames must be email addresses.
echo "C42_USERNAME=${user}@example.com"
- Optionally, you can also specify the the organization for the user. Use the registration key for the organization. If the organization is not defined, the user registers to the organization specified in the deployment policy.
echo C42_ORG_REG_KEY=<value>
- You must provide values. Null values and empty strings will not work.
- The values cannot include either single (') or double (") quotation marks.
Mac commands
Deployment policy command arguments need to be imported into your software management tool. Commands and arguments are detailed here in case you need to modify them for some reason, or to help you deploy without a device management tool.
To install a insider risk agent for all users of a device, sign in to an account with administrative rights and issue a command like the following:
hdiutil attach Code42_n.n.n_Mac.dmg installer -package "/Volumes/Code42/Install Code42-AAT.pkg" -target LocalSystem hdiutil detach /Volumes/Code42
Individual parts of the commands are as follows:
Element | Description |
hdiutil attach Code42_n.n.n_Mac.dmg |
Mount the insider risk agent disk image. You must update the name of the installer file to match the exact name and version number being deployed. |
installer -package "/Volumes/Code42/Install Code42-AAT.pkg" |
Run the install program. |
-target LocalSystem |
Install the insider risk agent for all users of the device. |
hdiutil detach /Volumes/Code42 |
Unmount the insider risk agent disk image. |
Mac deployment properties file
The code42.deployment.properties file uses values from your deployment policy and typically contains the following properties:
DEPLOYMENT_URL=<your deployment URL here> DEPLOYMENT_POLICY_TOKEN=<your token here> DEPLOYMENT_SECRET=<your secret here>
The file can also optionally contain a PROVIDED_USERNAME parameter that bypasses the user detection script altogether and simply registers with the provided username.
To deploy the properties file, see our instructions for deploying to devices.
To write the deployment properties to a local machine, you can use a script. For example:
#!/bin/bash echo "DEPLOYMENT_URL=<your deployment URL here> DEPLOYMENT_POLICY_TOKEN=<your token here> DEPLOYMENT_SECRET=<your secret here>" > /tmp/code42.deployment.properties
Example Mac user detection scripts
Following are example user detection scripts for the Mac platform. For help with these scripts, contact your Customer Success Manager (CSM) to engage the Professional Services team.
General usage:
- Replace "domain.com" with your domain name.
- Add users you want to exclude from processing to the denylist in each script (look for "admin1|admin2|admin3"). This helps IT teams ensure that the Code42 installation is set up for the correct users, and not the support staff setting up the Mac computers for the first time.
First initial and last name script
Professional Services filename: UserDetect_and_modify_firstinitial_dot_lastname.sh
The following script detects the locally logged-in users' first and last names and edits the string to create a username of firstinitial.lastname:
function main() { writeLog "Starting user detection..." local user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }') writeLog "User name found ($user)" if [[ "$user" =~ ^(admin1|admin2|admin3)$ ]] || [[ -z "$user" ]]; then writeLog "Excluded or null username detected ($user). Will retry user detection after a short period of time, or when reboot occurs." exit else realname="$(dscl . -read /Users/$user RealName | cut -d: -f2)" if [[ ($realname =~ ',') ]]; then writeLog "Real name contains a comma, assuming last, first format." realname="$(echo $realname | sed -e 's/[[:space:]]*//g' | grep -v "^$" | tr '[:upper:]' '[:lower:]' | awk -F , '{print substr($2,1,1) "." $1}')" else realname="$(echo $realname | sed -e 's/^[[:space:]]*//; s/[[:space:]]*$//; s/^\(.\)[^ ]* /\1./' | grep -v "^$" | tr '[:upper:]' '[:lower:]')" fi local C42_USERNAME="$realname@domain.com" writeLog "Email assembled from real name: $C42_USERNAME" writeLog "Returning C42_USERNAME=$C42_USERNAME" echo "C42_USERNAME=$C42_USERNAME" fi } function writeLog () { echo "$(date) - $@" >> /Library/Application\ Support/Code42-AAT/Data/logs/userDetect_Result.log } main "$@"
First name and last name script
Professional Services filename: UserDetect_and_modify_firstname_dot_lastname.sh
The following script detects the locally logged-in users' first and last names and edits the string to create a username of firstname.lastname:
function main() { writeLog "Starting user detection..." local user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }') writeLog "User name found ($user)" if [[ "$user" =~ ^(admin1|admin2|admin3)$ ]] || [[ -z "$user" ]]; then writeLog "Excluded or null username detected ($user). Will retry user detection after a short period of time, or when reboot occurs." exit else realname="$(dscl . -read /Users/$user RealName | cut -d: -f2)" if [[ ($realname =~ ',') ]]; then writeLog "Real name contains a comma, assuming last, first format." realname="$(echo $realname | sed -e 's/[[:space:]]*//g' | grep -v "^$" | tr '[:upper:]' '[:lower:]' | awk -F , '{print $2 "." $1}')" else realname="$(echo $realname | sed -e 's/^[[:space:]]*//; s/[[:space:]]*$//; s/ /./' | grep -v "^$" | tr '[:upper:]' '[:lower:]')" fi local C42_USERNAME="$realname@domain.com" writeLog "Email assembled from real name: $C42_USERNAME" writeLog "Returning C42_USERNAME=$C42_USERNAME" echo "C42_USERNAME=$C42_USERNAME" fi } function writeLog () { echo "$(date) - $@" >> /Library/Application\ Support/Code42-AAT/Data/logs/userDetect_Result.log } main "$@"
Text file script
Professional Services filename: UserDetect_from_text.sh
The following script reads the username from a text file (located by default at /tmp/Code42test.txt). Use when no other logical way of finding the username can be determined and no user interaction is desired.
function main() { writeLog "Starting user detection..." local user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }') writeLog "User name found ($user)" if [[ "$user" =~ ^(admin1|admin2|admin3)$ ]] || [[ -z "$user" ]]; then writeLog "Excluded or null username detected ($user). Will retry user detection after a short period of time, or when reboot occurs." exit else local C42_USERNAME=$(cat /tmp/Code42test.txt) writeLog "Email read from file: $C42_USERNAME" writeLog "Returning C42_USERNAME=$C42_USERNAME" echo "C42_USERNAME=$C42_USERNAME" fi } function writeLog () { echo "$(date) - $@" >> /Library/Application\ Support/Code42-AAT/Data/logs/userDetect_Result.log } main "$@"
Last logged on user script
Professional Services filename: UserDetect_last_plus_domain.sh
The following script checks the last known logged in users and narrows down the list to the currently logged-in user:
function main () { writeLog "Starting user detection..." local user=$(last | egrep 'console.*still' | egrep -v 'root|admin|reboot|shutdown|local|_mbsetupuser' | awk '{print $1}' | sort -u | head -n1) writeLog "User name found ($user)" if [[ "$user" =~ ^(admin1|admin2|admin3)$ ]] || [[ -z "$user" ]]; then writeLog "Excluded or null username detected ($user). Will retry user detection after a short period of time, or when reboot occurs." exit else local C42_USERNAME="${user}@domain.com" writeLog "Username assembled by appending domain ($C42_USERNAME)" writeLog "Returning C42_USERNAME=$C42_USERNAME" echo "C42_USERNAME=$C42_USERNAME" fi } function writeLog () { echo "$(date) - $@" >> /Library/Application\ Support/Code42-AAT/Data/logs/userDetect_Result.log } main "$@"
Scutil script
Professional Services filename: UserDetect_scutil_user_plus_domain.sh
The following script uses the system configuration utility (scutil) to detect the logged-in user. The client's email domain needs to be appended to the resulting username to get a valid Code42 username.
function main () { writeLog "Starting user detection..." local user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }') writeLog "User name found ($user)" if [[ "$user" =~ ^(admin1|admin2|admin3)$ ]] || [[ -z "$user" ]]; then writeLog "Excluded or null username detected ($user). Will retry user detection after a short period of time, or when reboot occurs." exit else local C42_USERNAME="${user}@domain.com" writeLog "Username assembled by appending domain ($C42_USERNAME)" writeLog "Returning C42_USERNAME=$C42_USERNAME" echo "C42_USERNAME=$C42_USERNAME" fi } function writeLog () { echo "$(date) - $@" >> /Library/Application\ Support/Code42-AAT/Data/logs/userDetect_Result.log } main "$@"
DSCL script
Professional Services filename: UserDetect_using_DSCL.sh
The following script obtains the user's email address from the domain records stored on the client using the Directory Service command line utility (DSCL). The Mac must be domain-bound.
function main() { writeLog "Starting user detection..." local user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }') writeLog "User name found ($user)" if [[ "$user" =~ ^(admin1|admin2|admin3)$ ]] || [[ -z "$user" ]]; then writeLog "Excluded or null username detected ($user). Will retry user detection after a short period of time, or when reboot occurs." exit else local C42_USERNAME=$(dscl . -read /Users/${user} EMailAddress | cut -d ' ' -f 2) writeLog "Username read from dscl ($C42_USERNAME)" writeLog "Returning C42_USERNAME=$C42_USERNAME" echo "C42_USERNAME=$C42_USERNAME" fi } function writeLog () { echo "$(date) - $@" >> /Library/Application\ Support/Code42-AAT/Data/logs/userDetect_Result.log } main "$@"
Jamf plist script
Professional Services filename: macuserdetection-plist.sh
The following script is helpful if you use Jamf for device management. The script places a plist on the local machine that is populated with the username associated with the device from Jamf. This script is a good option if you have a username associated with a specific device in JAMF, but you do not have assurance that the usernames on the local device match the username part of the email address. This script requires additional setup in Jamf.
function main () { writeLog "Starting user detection..." local user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }') writeLog "User name found ($user)" if [[ "$user" =~ ^(admin1|admin2|admin3)$ ]] || [[ -z "$user" ]]; then writeLog "Excluded or null username detected ($user). Will retry user detection after a short period of time, or when reboot occurs." exit else local C42_USERNAME=$(defaults read /Library/Managed\ Preferences/com.code42.email.plist code42ActivationEmail) writeLog "Username read from plist ($C42_USERNAME)" writeLog "Returning C42_USERNAME=$C42_USERNAME" echo "C42_USERNAME=$C42_USERNAME" fi } function writeLog () { echo "$(date) - $@" >> /Library/Application\ Support/Code42-AAT/Data/logs/userDetect_Result.log } main "$@"
- Place the script into your deployment policy.
You may need to update the script depending on your Jamf version and configuration. Earlier versions of Jamf put the plist in~/Library/Preferences/
, but later versions put it in/Library/Managed Preferences/
. - In Jamf, create a new configuration profile or edit an existing one.
- Go to Custom Settings (or Application & Custom Settings, depending on your Jamf version), and upload the following com.code42.email.plist file.
This is a sample plist file. If you prefer, you can create your own, as long as the EMAIL variable is present as a key that matches what the deployment policy is set up to read.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>code42ActivationEmail</key> <string>$EMAIL</string> </dict> </plist>
- Scope the Privacy Preferences Policy Control (PPPC) to the users.
Use appropriate scoping. Whether you scope to users or machines depends on your environment. JAMF must have an email on file for whatever you scope the profile to. - Deploy as normal.
Linux
For insider risk agents on Linux devices, a deployment policy provides:
- A custom-written detection script to provide the insider risk agent with a username. The script can also optionally specify the user's organization.
- Installation properties to serve as the arguments string to a insider risk agent install command.
Linux user detection script
A user detection script examines the host device and provides the insider risk agent with a username. The script resides on the Code42 cloud. The insider risk agent retrieves it during the install process.
Tips to create a custom Linux script
Create a custom script and paste your script into your deployment policy. If you need help, contact your Customer Success Manager (CSM) for enterprise support.
When creating your custom script, be aware of the following:
- Every script must end by echoing the value for the username variable:
echo C42_USERNAME=<value>;
- In the Code42 cloud, usernames must be email addresses.
- Optionally, you can also specify the the organization for the user. Use the registration key for the organization. If the organization is not defined, the user registers to the organization specified in the deployment policy.
echo C42_ORG_REG_KEY=<value>
- You must provide values. Null values and empty strings will not work.
- The values cannot include either single (') or double (") quotation marks.
Linux commands and arguments
Deployment policy command arguments need to be imported into your software management tool. Commands and arguments are detailed here in case you need to modify them for some reason, or to help you deploy without a device management tool.
To install a insider risk agent for all users of a device, sign in to an account with root access and issue a command like the following:
- Ubuntu
sudo apt install /path/to/<installer file>.deb
- Red Hat
sudo yum install /path/to/<installer file>.rpm
Linux deployment properties file
The code42.deployment.properties file uses values from your deployment policy and typically contains the following properties:
DEPLOYMENT_URL=<your deployment URL here> DEPLOYMENT_POLICY_TOKEN=<your token here> DEPLOYMENT_SECRET=<your secret here>
The file can also optionally contain a PROVIDED_USERNAME parameter that bypasses the user detection script altogether and simply registers with the provided username.
To deploy the properties file, see our instructions for deploying to devices.
To write the deployment properties to a local machine, you can use a script. For example:
#!/bin/bash echo "DEPLOYMENT_URL=<your deployment URL here> DEPLOYMENT_POLICY_TOKEN=<your token here> DEPLOYMENT_SECRET=<your secret here>" > /tmp/code42.deployment.properties