TeamViewer Assignment not working reliable

z-bckr
New Contributor

Hey,

I have a problem with my TeamViewer Installation script.
The download and installation part works great, but the assignment isnt working reliable.
I have followed the steps from here: https://community.teamviewer.com/English/kb/articles/50739-mass-deployment-on-macos

I have added a 'sleep' and increased the '-wait' parameter, both without success.
Sometimes it works, sometimes it does not.

Is there a more reliable way to assign the device in TeamViewer?

Here is my script:

#!/bin/zsh
#
# Downloads and installs latest TeamViewer Host with custom configuration
# Runs the TeamViewer Assignment Tool after the installation
# Provide configuration details via jamf parameter:#
#   Parameter $4 = Teamviewer configuration ID
#   Parameter $5 = Teamviewer assignment API token
#
# Created 16. March 2021
# 
# 
#

# Precheck - configuration id
if [[ -z $4 ]]; then
    echo "$(date): No teamviewer configuration id provided."
    exit 1
else
    tv_customID="$4"
fi

# Precheck - assignment api token
if [[ -z $5 ]]; then
    echo "$(date): No teamviewer api token provided."
    exit 1
else
    tv_apiToken="$5"
fi


# Generate url with confiugration id
downloadUrl="https://dl.teamviewer.com/download/version_15x/CustomDesign/Install%20TeamViewerHost-idc$tv_customID.pkg"


# Choices xml for silent installation
choices_xml=$(
    cat <<EOF
<?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">
<array>
  <dict>
    <key>attributeSetting</key>
    <integer>1</integer>
    <key>choiceAttribute</key>
    <string>selected</string>
    <key>choiceIdentifier</key>
    <string>com.teamviewer.teamviewerSilentInstaller</string>
  </dict>
</array>
</plist>
EOF
)

# Create working directory
# stolen from here: https://gist.github.com/talkingmoose/a16ca849416ce5ce89316bacd75fc91a
echo "$(date): Creating working directory"
workDirectory=$( /usr/bin/basename $0 )
tempDirectory=$( /usr/bin/mktemp -d "/private/tmp/$workDirectory.XXXXXX" )
downloadFilePath="TeamviewerHost-idc$tv_customID.pkg"

# change directory to temporary working directory
echo "Changing directory to working directory "$tempDirectory""
cd "$tempDirectory"

# Download
echo "$(date): Downloading Teamviewer Host Application"
/usr/bin/curl --location --silent -o "$downloadFilePath" "$downloadUrl"

# Preparation
echo "$(date): Creating choices.xml"
echo "$choices_xml" > "choices.xml"

# Installation
echo "$(date): Installing Teamviewer Host Application"
echo "$(date): .pkg path: $downloadFilePath"
/usr/sbin/installer -pkg "$downloadFilePath" -applyChoiceChangesXML "choices.xml" -target /

sleep 30

# Assignment
echo "$(date): Run Teamviewer assignment"
tv_assignmentHelper="/Applications/TeamViewerHost.app/Contents/Helpers/TeamViewer_Assignment"
tv_hostname="$(hostname -s) | $(id -P $(stat -f%Su /dev/console) | cut -d : -f 8)"
${tv_assignmentHelper} -api-token "$tv_apiToken" -alias "$tv_hostname" -wait 60

# clean up
echo "$(date): Cleanup"
/bin/rm -Rf "$tempDirectory"

Any help is appreciated,
Greetings
Martin

10 REPLIES 10

SanduQi
New Contributor

Hello, I am using this easy script and working fine.

!/bin/bash

cd /tmp

Download and Install custom host

echo "Downloading and Installing custom host"
cd /tmp
curl -L https://download.teamviewer.com/download/version_15x/CustomDesign/Install%20TeamViewerHost-XXXXXXpkg -o /Users/account/Downloads/TeamViewerHost-XXXXX.pkg
Sudo Installer -pkg /Users/account/Downloads/TeamViewerHost-XXXXX.pkg -target /

echo "10 seconds wait"

sleep 10

Assignment

echo "Running the account assignment"
computername=$(hostname -s)
sudo /Applications/TeamViewerHost.app/Contents/Helpers/TeamViewer_Assignment -api-token XXXXXXXX -group "ALL | Macbooky" -grant-easy-access

echo "10 seconds wait"

sleep 10

z-bckr
New Contributor

Hey,

thanks for the input.
It looks like your script uses the same logic to run the TeamViewer assignment, does this really works 100% of the time?

I have tried some additional things with my script, all without success:
- I have added some logic to wait with the assignment until the TeamViewer host service is running
- I found this doc article which uses a different syntax for the assignment helper:

#!/bin/sh
sudo /Applications/TeamViewerHost.app/Contents/Helpers/TeamViewer_Assignment assign YES -api-token 12345678 -group SomeGroup

note the 'assign YES'

I think i will have to open a ticket with teamviewer support

SanduQi
New Contributor

Yes, it works everytime

z-bckr
New Contributor

Update:
I have asked the TeamViewer support about this and it looks like you have to sperate the installation and assignment.
According to TeamViewer there is no known way to combine the installation and assignment in one script.

But i did some digging with composer and found a plist which can be used to determine whether the assignment has run, and to which account the app is assigned.
Here is a Extension attribute which returns the same values you can see under "Account Assignment" in the teamviewer preferences.

#!/bin/sh
RESULT='Not installed'
if [[ -e '/Applications/TeamViewer.app' || -e '/Applications/TeamViewerHost.app' ]]; then
    RESULT='Not assigned'
    AccountName=$(defaults read /Library/Preferences/com.teamviewer.teamviewer.preferences.plist OwningManagerAccountName 2>/dev/null)
    CompanyName=$(defaults read /Library/Preferences/com.teamviewer.teamviewer.preferences.plist OwningManagerCompanyName 2>/dev/null)

    if [[ -n "$AccountName" && -n "$CompanyName" ]]; then
        RESULT="$AccountName,$CompanyName"
    fi
fi
/bin/echo "<result>$RESULT</result>"

I think i will use this to find devices without a device assignment to run the assignment policy more efficiently.

macservit
New Contributor II

I realize this is an older thread, not sure if anyone is still watching... I'm having assignment issues using multiple variations of the scripts in this thread. The issues so far are only with Big Sur (this is all I've tested so far). The script runs perfectly when I run it directly on the target machine, but it fails to assign when I run it through my RMM tool. I'm considering trying to run it from Jamf, but want to make sure it's not an OS issue first...

ryan_ball
Valued Contributor

@macservit This worked for me the last time I worked on a TeamViewer assignment project:

#!/bin/bash

api="API-STRING-GOES-HERE"
group="GROUP-YOU-WANT-TO-ASSIGN-TO"
serial=$(system_profiler SPHardwareDataType | awk '/Serial Number/ {print $4}')
assignmentTool="/Applications/TeamViewerHost.app/Contents/Helpers/TeamViewer_Assignment"
count="1"

echo "Pausing for a few seconds..."
sleep 5

# Set up the assignment
echo "Attempting to assign up to 5 times..."
while ! "$assignmentTool" -api-token "$api" -group "$group" -alias "$serial" -grant-easy-access -verbose; do
    echo "Assignment failed."
    (( count++ ))
    if [[ "$count" -ge "5" ]]; then
        echo "Assignment failed 5 times; exiting."
        exit 1
    fi
    sleep 5
done

echo "Successfully assigned TeamViewerHost."

exit 0

Note that this was done immediately after installation so I paused for a few seconds before I proceeded with the assignment.

Levi_
Contributor

@macservit - A little old but everything here is still gold. Believe me, I used this thread and few others to put together the pieces to get this done.

The one call out which I do not believe is called out here is the account assignment and might be the problem. If you look at @ryan.ball post he is running the account assignment up to 5 times until it's complete with a short 5-second pause before it attempts it. The reason for this is the TeamViewer services need to be started and if you try before that it won't work. If you don't have a sleep period long enough(I personally use 60 seconds) or have a retry statement the account assignment will fail. You can read more about some of that here - Teamviewer Account Assignment

I hope this helps you.

macservit
New Contributor II

Thanks @Levi_ and @ryan.ball . I'm really scratching my head with this one, as I have a bunch of endpoints that have had TV Host on them for some time now (months), so clearly the service is running. Or maybe it's not... I'll try to leverage pieces of the script on the page above to check for the service running and go from there.

z-bckr
New Contributor

Hey @macservit ,

I ended up with this assignment script.
This runs as a second policy after the teamviewer installation.
In addition to this i have created a smart group for the clients where the assignment did not completed yet. (The extension attribute used for this is a few posts up). The assignment script is scoped to this smart group and runs daily.

#!/bin/bash
#
# Script to run the TeamViewer Assignment Helper
# works for the full client and the host version
#
# Parameter $4 = reassign ( true | false )
# Parameter $5 = API-Token
# Parameter $6 = TeamViewer Group name
#

# precheck - reassignment
REASSIGN=false
if [ "$4" == "true" ]; then
    REASSIGN=true
fi
# precheck - api token
if [[ -z $5 ]]; then
    echo "$(date): No teamviewer API Token provided."
    exit 1
else
    tv_apiToken="$5"
fi
# precheck - group
if [[ -z $6 ]]; then
    echo "$(date): No teamviewer group provided."
    exit 1
else
    tv_group="$6"
fi

# precheck - installed TeamViewer Version
if [ -f '/Applications/TeamViewerHost.app/Contents/Helpers/TeamViewer_Assignment' ]; then
    echo "$(date): TeamViewer Host installed"
    tv_service="/Applications/TeamViewerHost.app/Contents/MacOS/TeamViewer_Service"
    tv_assignmentHelper="/Applications/TeamViewerHost.app/Contents/Helpers/TeamViewer_Assignment"
elif [ -f '/Applications/TeamViewer.app/Contents/Helpers/TeamViewer_Assignment' ]; then
    echo "$(date): TeamViewer Full Client installed"
    tv_service="/Applications/TeamViewer.app/Contents/MacOS/TeamViewer_Service"
    tv_assignmentHelper="/Applications/TeamViewer.app/Contents/Helpers/TeamViewer_Assignment"
else
    echo "$(date): No TeamViewer Assignment helper found. TeamViewer might not be installed"
    exit 1
fi

# teamviewer processes
# get all running teamviewer related processes and count them
processCount=$(pgrep -f "$tv_service" | wc -l)
counter=0
serivceStarted="false"
startTeamViewerService() {
    echo "$(date): Start TeamViewer Service"
   /bin/launchctl load /Library/LaunchDaemons/com.teamviewer.teamviewer_service.plist
   serivceStarted="true"
}

# timeout after 3 minutes (36x sleep for 5 sec)
while [[ $counter -le 36 ]]; do
    if [[ $processCount -eq 1 ]]; then
        echo "$(date): TeamViewer is running, run assignment"
        tv_hostname="$(hostname -s) | $(id -P $(stat -f%Su /dev/console) | cut -d : -f 8)"
        if [ "$REASSIGN" == "true" ]; then
            echo "$(date): Run TeamViewer Assignment with reassign parameter"
            ${tv_assignmentHelper} -api-token "$tv_apiToken" -alias "$tv_hostname" -group "$tv_group" -reassign
            break
        else
            echo "$(date): Run TeamViewer Assignment"
            ${tv_assignmentHelper} -api-token "$tv_apiToken" -alias "$tv_hostname" -group "$tv_group"
            break
        fi
    else
        echo "$(date): Waiting for TeamViewer to start"
        if [[ "$serivceStarted" == "false" ]]; then
            startTeamViewerService
        fi
        sleep 5
        ((counter++))
    fi
done
# Script to run the TeamViewer Assignment Helper
# works for the full client and the host version
#
# Parameter $4 = reassign ( true | false )
# Parameter $5 = API-Token
# Parameter $6 = TeamViewer Group
#
# Created 06. April 2021
#
#

# precheck - reassignment
REASSIGN=false
if [ "$4" == "true" ]; then
    REASSIGN=true
fi
# precheck - api token
if [[ -z $5 ]]; then
    echo "$(date): No teamviewer API Token provided."
    exit 1
else
    tv_apiToken="$5"
fi
# precheck - group
if [[ -z $6 ]]; then
    echo "$(date): No teamviewer group provided."
    exit 1
else
    tv_group="$6"
fi

# precheck - installed TeamViewer Version
if [ -f '/Applications/TeamViewerHost.app/Contents/Helpers/TeamViewer_Assignment' ]; then
    echo "$(date): TeamViewer Host installed"
    tv_service="/Applications/TeamViewerHost.app/Contents/MacOS/TeamViewer_Service"
    tv_assignmentHelper="/Applications/TeamViewerHost.app/Contents/Helpers/TeamViewer_Assignment"
elif [ -f '/Applications/TeamViewer.app/Contents/Helpers/TeamViewer_Assignment' ]; then
    echo "$(date): TeamViewer Full Client installed"
    tv_service="/Applications/TeamViewer.app/Contents/MacOS/TeamViewer_Service"
    tv_assignmentHelper="/Applications/TeamViewer.app/Contents/Helpers/TeamViewer_Assignment"
else
    echo "$(date): No TeamViewer Assignment helper found. TeamViewer might not be installed"
    exit 1
fi

# teamviewer processes
# get all running teamviewer related processes and count them
processCount=$(pgrep -f "$tv_service" | wc -l)
counter=0
serivceStarted="false"
startTeamViewerService() {
    echo "$(date): Start TeamViewer Service"
   /bin/launchctl load /Library/LaunchDaemons/com.teamviewer.teamviewer_service.plist
   serivceStarted="true"
}

# timeout after 3 minutes (36x sleep for 5 sec)
while [[ $counter -le 36 ]]; do
    if [[ $processCount -eq 1 ]]; then
        echo "$(date): TeamViewer is running, run assignment"
        tv_hostname="$(hostname -s) | $(id -P $(stat -f%Su /dev/console) | cut -d : -f 8)"
        if [ "$REASSIGN" == "true" ]; then
            echo "$(date): Run TeamViewer Assignment with reassign parameter"
            ${tv_assignmentHelper} -api-token "$tv_apiToken" -alias "$tv_hostname" -group "$tv_group" -reassign
            break
        else
            echo "$(date): Run TeamViewer Assignment"
            ${tv_assignmentHelper} -api-token "$tv_apiToken" -alias "$tv_hostname" -group "$tv_group"
            break
        fi
    else
        echo "$(date): Waiting for TeamViewer to start"
        if [[ "$serivceStarted" == "false" ]]; then
            startTeamViewerService
        fi
        sleep 5
        ((counter++))
    fi
done

This has worked for the most clients, but unfortunately not for those clients with a different custom host installed and assigned to a different account. In this case, the existing assignment was removed, but i found no way to assign them to the new account without removing the existing client first and installing the new custom client.

i hope this helps

macservit
New Contributor II

To close the loop on this, I spent a fair amount of time on the phone with TeamViewer support and came up with the script below. Seems to work consistently. FYI, I install this using my RMM tool instead of Jamf, so there might be some extra code that's not relevant to Jamf. Many thanks to all those who posted answers previously...

!/bin/bash

if [ "$usrUninstallFirst" == "true" ]; then

Uninstall TeamViewer first

#Terminates TeamViewer app echo "Stopping TeamViewer" osascript -e 'quit app "TeamViewer*"' launchctl remove com.teamviewer.Helper

#Delete app & configuration files. echo "Removing TeamViewer app & configuration files" rm -R /Applications/TeamViewer rm -f /Library/PrivilegedHelperTools/com.teamviewer.Helper rm -f /Library/Preferences/com.teamviewer rm -f ~/Library/Preferences/com.teamviewer*
fi

Set working directory to /tmp

current_path=$(pwd)

cd /tmp

cp "${current_path}/choices.xml" .

Move choices.xml to /tmp

mv choices.xml /tmp
echo "choices.xml moved to /tmp"

Download and Install custom host

echo "Downloading and Installing custom host"
cd /tmp
curl -O https://dl.teamviewer.com/download/version_15x/CustomDesign/Install%20TeamViewerHost-xxxxxxxx.pkg
installer -applyChoiceChangesXML choices.xml -pkg Install%20TeamViewerHost-xxxxxxx.pkg -target /

sleep 20

Start and confirm the app is running

tvStatus=$(pgrep -x TeamViewerHost)

if [[ "$tvStatus" == "" ]]; then user=$(stat -f%Su /dev/console) sudo -u $user open "/Applications/TeamViewer Host.app/Contents/MacOS/TeamViewerHost"
fi

while [[ "$tvStatus" == "" ]]; do sleep 5 tvStatus=$(pgrep -x TeamViewerHost) echo "Waiting for the app to start"
done

Assignment

echo "Running the account assignment"
computername=$(hostname -s)

sudo /Applications/TeamViewerHost.app/Contents/Helpers/TeamViewer_Assignment -api-token xxxxxxxxxxx -group-id $TVGroupID -alias $computername -grant-easy-access

echo "10 second wait"

sleep 10

Get the TeamViewer ID

tvID=$(/usr/libexec/PlistBuddy -c "Print :ClientID" /Library/Preferences/com.teamviewer.teamviewer.preferences.plist)

Get the TeamViewer app type

if [ -d "/Applications/TeamViewerHost.app" ] ; then
appType=Host
else
appType=Full
fi

Check for assignment

AccountName=$(defaults read /Library/Preferences/com.teamviewer.teamviewer.preferences.plist OwningManagerCompanyName 2>/dev/null)

if [ "$AccountName" == "" ] ; then
Assigned=NONE
else
Assigned=$AccountName
fi

echo "ID: $tvID - App type: $appType - Assignment: $Assigned"