Deployment Adventures: TeamViewer

[Last Reviewed 2018-08-29]

[Note: These notes are a bit of a work in progress. Full scripts will be posted to GitHub once I’m more satisfied with their quality.]

TeamViewer’s a pretty recognizable name these days. The remote support software is used by family members, businesses, and more. It runs on Windows, macOS, Linux, and the more popular mobile platforms. It’s ease of use does come at a bit of a cost, however: If you don’t spend the time up front to ensure it’s reasonably secured, you could be opening yourself up for exploitation in the future.

While TeamViewer does have documentation on how to do mass deployments, the error-code-reporting capability it offered was a bit lack-luster. I wanted a bit more intelligence in my installer (and a bit more error handling). Without this extra level of checking, you could have deployments that report as successfully installed but didn’t assign to your account.

But before we cover TeamViewer deployments, it’s a good idea to review your TeamViewer environment’s security and client configurations.

Reasonably Secure: The Bare Minimum

There are a few simple yet powerful steps you can take to help lock down your TeamViewer environment–this is exceedingly important if you have many agents and/or many deployments

  1. Turn on Two Factor Authentication for every user that logs into the TeamViewer Client or the Management Console. 
  2. When deploying TeamViewer, associate the install with your account
  3. Use the TeamViewer whitelist, and allow only your company/user account
  4. Disable the random password for spontaneous access; use Easy Access instead
  5. Lock down the TeamViewer options window with a complex password

Some of these things can be set in the Management Console; others are set in the Client/Host. Be sure to review everything in both of these locations!

Deploying with Intelligence

Look around you, prequelmemes are everywhere.

For my TeamViewer deployments (Client for technicians, Host for everyone else), I chose to deploy using the venerable PowerShell App Deployment Toolkit. There’s a couple reasons for this:

  • When deploying the TeamViewer Client (not Host), there are several post-installation steps that you must take if you want the client to already be assigned to an account by the time someone signs into it the first time.
  • As of TeamViewer 13.2, the Host should automatically assign itself to your account. In the event that it doesn’t, we can use PSADT to return an error code letting ConfigMgr know it should try installing again.

The Host Module

When installing the Host module using the MSI, you can pass several switches to it to instruct TeamViewer to associate to your account when the install completes. An example of this in PSADT:

Execute-MSI -Action Install -Path "$dirFiles\TeamViewer_Host.msi" -Parameters '/qn IMPORTREGFILE=1 CUSTOMCONFIGID=**** APITOKEN=***-****** ASSIGNMENTOPTIONS="--group **** --reassign --grant-easy-access --alias %COMPUTERNAME%"'

In the above example, we’re importing our configuration registry file, entering our Configuration ID and API Token (both of which can be found in the Management Console), then marking which group we want to add this computer to and naming it. 

After the install completes, we can use the existence of the AssignmentData.json file to validate whether the client associated successfully. If it doesn’t automatically associate, we can run TeamViewer.exe and attempt to force it (and if it still doesn’t work, we can report this back to ConfigMgr as a failure).

Show-InstallationProgress -StatusMessage "Account assignment in progress..."
		
If ($Is64Bit) 
{
    $tvInstallPath = $envProgramFilesX86
}
else {
    $tvInstallPath = $envProgramFiles
}

$xCount = 0
Write-Log -Message "Waiting 30 seconds before attempting account assignment..." -Source 'Execute-Process' -LogType 'CMTrace'
		
While ((Test-Path "$tvInstallPath\TeamViewer\AssignmentData.json") -and ($xCount -ile 6))
{
    Start-Sleep -Seconds 5
    $xCount++
}

Write-Log -Message "Automatic account assignment timed out; attempting manual account assignment" -Source 'Execute-Process' -LogType 'CMTrace'
Execute-Process -Path "$tvInstallPath\TeamViewer\TeamViewer.exe" -Parameters "assign --api-token ***-***** --group **** --grant-easy-access --reassign --alias %COMPUTERNAME%"

While ((Test-Path "$tvInstallPath\TeamViewer\AssignmentData.json") -and ($xCount -ile 12))
{
    Start-Sleep -Seconds 5
    $xCount++
}

If (Test-Path "$tvInstallPath\TeamViewer\AssignmentData.json" ) 
{
    # Report back to ConfigMgr that the account assignment failed
    Exit-Script -ExitCode '69696'
}

The “Full” (Technician) Client

The Client installation/association is slightly different than the Host. The Client does not start automatically after installation, nor does it associate automatically.

Execute-MSI -Action Install -Path "$dirFiles\TeamViewer.msi" -Parameters '/qn IMPORTREGFILE=1 CUSTOMCONFIGID=**** APITOKEN=***-****** ASSIGNMENTOPTIONS="--group **** --reassign --grant-easy-access --alias %COMPUTERNAME%"'

For our account assignment process, we start TeamViewer and wait for the TeamViewer_Service to run (as it’s required for account assignment to complete). Then we run TeamViewer.exe assign to perform account assignment.

Show-InstallationProgress -StatusMessage "Preparing for TeamViewer Account Assignment`nDo not close or log in to TeamViewer."

If ($Is64Bit) 
{
    $tvInstallPath = $envProgramFilesX86
}
else {
    $tvInstallPath = $envProgramFiles
}

If (Test-Path "$tvInstallPath\TeamViewer") { Execute-Process -Path "$tvInstallPath\TeamViewer\TeamViewer.exe" -Parameters '--Minimize' -NoWait }
Else 
{
    # Report back that TeamViewer failed to start
    Write-Log -Message "TeamViewer installation completed, but TeamViewer.exe not found!" -Source 'Execute-Process' -LogType 'CMTrace' 
    Exit-Script -ExitCode '69695' 
}

Write-Log -Message "Waiting for the TeamViewer Service to start..." -Source 'Execute-Process' -LogType 'CMTrace'

$xSvcCheck = 0
Start-Sleep -Seconds 15
# TeamViewer_Service should start automatically when TeamViewer is launched, and is required for account assignment to work
While ((!(Get-Process -Name "TeamViewer_Service" -ErrorAction Continue)) -and ($xSvcCheck -ile 6))
{ 
    Start-Sleep 10 
    $xSvcCheck++
} 

If (!(Get-Process -Name "TeamViewer_Service")) 
{ 
    # Report back that TeamViewer_Service was unable to start
    Write-Log -Message "TeamViewer_Service failed to start. Will not attempt account assignment." -Source 'Execute-Process' -LogType 'CMTrace'
    Exit-Script -ExitCode '69697'
} 

Show-InstallationProgress -StatusMessage "Attempting TeamViewer Account Assignment`nDo not close or log in to TeamViewer."

If (Test-Path "$tvInstallPath\TeamViewer") { Execute-Process -Path "$tvInstallPath\TeamViewer\TeamViewer.exe" -Parameters "assign --api-token ***-***** --group GROUPNAME --grant-easy-access --reassign --alias %COMPUTERNAME%" }

Write-Log -Message "Waiting 30 seconds before attempting account assignment..." -Source 'Execute-Process' -LogType 'CMTrace'
Start-Sleep -Seconds 10
                
$xCount = 0

While ((Test-Path "$tvInstallPath\TeamViewer\AssignmentData.json") -and ($xCount -ile 6))
{
    Start-Sleep -Seconds 5
    $xCount++
}

Write-Log -Message "Automatic account assignment timed out; attempting manual account assignment" -Source 'Execute-Process' -LogType 'CMTrace'
Execute-Process -Path "$tvInstallPath\TeamViewer\TeamViewer.exe" -Parameters "assign --api-token ***-***** --group GROUPNAME --grant-easy-access --reassign --alias %COMPUTERNAME%"

While ((Test-Path "$tvInstallPath\TeamViewer\AssignmentData.json") -and ($xCount -ile 12))
{
    Start-Sleep -Seconds 5
    $xCount++
}

If (Test-Path "$tvInstallPath\TeamViewer\AssignmentData.json" ) 
{
    # Report back to ConfigMgr that the account assignment failed
    Exit-Script -ExitCode '69696'
}

# Kill our running TeamViewer process since it was started with elevated rights
Write-Log -Message "Killing any running TeamViewer processes as they were started with elevated rights." -Source 'Execute-Process' -LogType 'CMTrace'
Stop-Process -Name "TeamViewer" -Force

The Follow-Up

Using a simple check of “Is TeamViewer installed?” is not quite enough to validate that you’ve got a working install. You’ll also want to check one of the following registry keys and make sure they match your account’s information–this will help validate that your install was successfully associated with your account:

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\TeamViewer\OwningManagerAccountName
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\TeamViewer\OwningManagerCompanyName

Even then, you may find that an install passes these checks, but your technicians still can’t connect because they’re prompted for a password. This means that Easy Access isn’t enabled–and unfortunately there isn’t an easy programmatic way to check for this (yet! But I have submitted an enhancement request to TeamViewer about it).

Here’s to continued deployment improvements in 13.3!

Jacob

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.