PowerShell Based Host Deployment (.msi)

Step 1) Go to your Design & Deploy page and click Add Host>Host, do all your site/client settings and make sure Allow account assignment without confirmation is checked. Then download the Assignment Tool, click Save.

Step 2) Click the Edit button next to your newly created client host, copy the Configuration ID and the API token. Save those for later, now click Download MSI. (note: if you keep you're using the same configuration (logo, colors) for all of your MSI's you won't have to repeat this step for other sites/clients.)

Step 3) Uploaded your TeamViewer_Host.msi and your TeamViewer_Assignment.exe somewhere which will be accessible from where you want to deploy.
(e.g. http://mywebsite.com/TV/TeamViewer_Host.msi, http://mywebiste.com/TV/TeamViewer_Assignment.exe)

Step 4) Save those urls, now we're ready to run the script, you will have to find a way to bypass executionpolicy on PowerShell (it's pretty easy..), when you run the script use it as such (make sure you run as Admin)

.\Download-TV.ps1 -host_msi_url "http://mywebsite.com/TV/TeamViewer_Host.msi" -configuration_id "$config_id" -assingment_tool_url "http://mywebiste.com/TV/TeamViewer_Assignment.exe" -api_token "$api_token"

param (

$tv_msi_path = $env:TEMP + "\TeamViewer_Host-idc$configuration_id.msi"
$assign_path = $env:TEMP + "\tvassign.exe"

if (Test-Path("C:\Program Files\TeamViewer\")) {
Start-Process -Wait -FilePath "C:\Program Files\TeamViewer\uninstall.exe" -ArgumentList "/S"
Remove-Item "C:\Program Files\TeamViewer\" -Force -Recurse
echo "Removing existing TeamViewer install (32)"
} elseif (Test-Path("C:\Program Files (x86)\TeamViewer\uninstall.exe")) {
Start-Process -Wait -FilePath "C:\Program Files (x86)\TeamViewer\" -ArgumentList "/S"
Remove-Item "C:\Program Files (x86)\TeamViewer" -Force -Recurse
echo "Removing existing TeamViewer install (64)"

$client = New-Object System.Net.WebClient
$client.DownloadFile($host_msi_url, $tv_msi_path)
$client.DownloadFile($assingment_tool_url, $assign_path)

echo "installing TV"
Start-Process -Wait -FilePath $tv_msi_path -ArgumentList "/qn"

if (! (Test-Path("C:\Program Files (x86)"))) {
Start-Process -Wait -FilePath $assign_path -ArgumentList "-apitoken $([char]34)$api_token$([char]34) -datafile $([char]34)C:\Program Files\TeamViewer\AssignmentData.json$([char]34)"
echo "Running configuration utility (32)"
} else {
Start-Process -Wait -FilePath $assign_path -ArgumentList "-apitoken $([char]34)$api_token$([char]34) -datafile $([char]34)C:\Program Files (x86)\TeamViewer\AssignmentData.json$([char]34)"
echo "Running configuration utility (64)"

Best Answer


  • Aaron_Boshers
    Aaron_Boshers Posts: 47 Staff member 🤠


    Thank you very much for your post here.

    Could you please also provide the parameters you passed to the powershell script so that others can see how the whole script works.

    Thanks once again for your excellent post!


    Aaron Boshers
    Senior Enterprise Solutions Engineer

    If my reply answered your question, help out other users and click the Accept as a Solution button below.
    You can also say thanks by clicking on the Thumbs Up button! Thanks for being an active member of our Community!
  • @Aaron_Boshers

    Yea sure, it's right on the bottom of step 4:

    .\Download-TV.ps1 -host_msi_url "http://mywebsite.com/TV/TeamViewer_Host.msi" -configuration_id "$config_id" -assingment_tool_url "http://mywebiste.com/TV/TeamViewer_Assignment.exe" -api_token "$api_token"

  • Awesome, this was exactly what I was looking for. Tested it out, and it works perfectly. Thank you!!

  • Line 19 should be

    Start-Process -Wait -FilePath "C:\Program Files (x86)\TeamViewer\uninstall.exe" -ArgumentList "/S"
  • Nfoster
    Nfoster Posts: 53 ✭✭

    BigNuggets, your post has Smiley Tongues at lines 65 and 69. It looks like it should be,

    $program_files = ${envProgramFiles(x86)}

    Howver to create a Smiley Tongue you would need to type : P (no space).

    Can you please clarify what line 65 and 69 should be?

  • Nfoster
    Nfoster Posts: 53 ✭✭

    I am attempting to run this script but it does not work. I get prompted for "Customer name" which I am assuming is the registered company name with our license. Either way, it does not appear to matter what I type in as the script proceeds to the next line and starts downloading my shared Temaviewer files, but stops at 24KB and just sits there waiting for the "AssignmentData.json" file.


    Please advise.

  • Nfoster
    Nfoster Posts: 53 ✭✭

    Ok got past the download issue. It will download and install, assign it to my TeamViewer account. However, if I try to run this again it fails to delete the device in my account and throws the following error,

    "Error deleting device"

    Line in referance:  throw "Error deleting device"


  • The Customer Name is what you want it to show up as in your Computers & Contacts

  • Nfoster
    Nfoster Posts: 53 ✭✭

    Ok makes sense. I was able to pass that pawameter. However, I am not able to delete.

    Error deleting device
    At C:\temp\Download-TV.ps1:45 char:17
    + throw "Error deleting device"
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : OperationStopped: (Error deleting device:String) [], RuntimeException
    + FullyQualifiedErrorId : Error deleting device

    Please advise.

  • Nfoster
    Nfoster Posts: 53 ✭✭


  • Nfoster
    Nfoster Posts: 53 ✭✭

    "BUMP", "BUMP"

  • Nfoster
    Nfoster Posts: 53 ✭✭


  • Nfoster
    Nfoster Posts: 53 ✭✭

    This script appears to hang on the "Waiting for AssignmentData.json" and then fails with the following,

    Start-Process : This command cannot be run due to the error: This version of %1 is not compatible with the version of
    Windows you're running. Check your computer's system information and then contact the software publisher.
    At C:\temp\DTV12v1.ps1:146 char:1
    + Start-Process -NoNewWindow -Wait -FilePath $assign_path -ArgumentList ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException
    + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand

    Please advise.

  • Nfoster
    Nfoster Posts: 53 ✭✭

    Do you recall what might be causing the file download to stop at 256Kb?. It is an odd one for sure. The files names are correct but it only downloads the first 256Kb of both files. I have recreated everything from scratch and even have a support ticket in with MSFT. 

    This script has been work for a while;

    # Get script parameters.
    Param (
    [string]$customer_name = "TEST",
    [string]$device_alias = $env:computername,
    [string]$msi_url = "https://host/file",
    [string]$assignment_tool_url = "https://host/file"

    # Assignment variables. - MAKE SURE YOU SET THESE
    $config_id = "CONFIG_ID_NUMBER"
    $assign_token = "TOKEN_NUMBER"
    $policy_id = "TEST"

    # API variables.
    $api_token = "TOKEN_NUMBER"
    $user_id = "USER_ID" # Token must belong to this user.
    $base_url = "https://webapi.teamviewer.com/"
    $headers = @{"Authorization" = "Bearer $api_token"}

    # Create a temporary directory at the root of the current drive.
    $base_path = "$($pwd.drive.name):\TeamViewer_Install"
    New-Item $base_path -type directory -Force

    # Set download paths for MSI and assignment tool.
    $tv_msi_path = "$base_path\TeamViewer_Host-idc$config_id.msi"
    $assign_path = "$base_path\tvassign.exe"

    # Determine if this is a 32-bit or a 64-bit machine.
    if (${env:ProgramFiles(x86)}) {
    # 64-bit
    $program_files = ${env:ProgramFiles(x86)}
    else {
    # 32-bit
    $program_files = $env:ProgramFiles

    # Uninstall TeamViewer if it is currently installed.
    $msi_wrapper = Get-WmiObject -Class Win32_Product -Filter "Name = 'TeamViewer 13 Host (MSI Wrapper)'"
    if ($msi_wrapper) {
    echo "Removing existing TeamViewer installation"

    echo "Downloading TeamViewer MSI"
    Invoke-WebRequest -Uri $msi_url -OutFile $tv_msi_path

    echo "Downloading assignment tool"
    Invoke-WebRequest -Uri $assignment_tool_url -OutFile $assign_path

    echo "Installing TeamViewer"
    $MSIArguments = @(
    ('"{0}"' -f $tv_msi_path)
    Start-Process msiexec.exe -Wait -ArgumentList $MSIArguments

    echo "Waiting for AssignmentData.json"
    while (!(Test-Path "$program_files\TeamViewer\AssignmentData.json")) {
    Start-Sleep 10

    $JSON_File = "$program_files\TeamViewer\AssignmentData.json"

    # Get contents of AssignmentData.json
    $JSON_Data = Get-Content $JSON_File -raw | ConvertFrom-Json

    # Replace default TeamViewer group name with customer name and output to new file
    $JSON_Data.group_name = $customer_name
    $JSON_Data | ConvertTo-Json -Compress | Out-File "$base_path\assign.json" -Encoding Ascii

    # Create and share the customer group if it doesn't already exist
    $groups = Invoke-RestMethod -Uri "$base_url/api/v1/groups?name=$customer_name" -Headers $headers
    if (!$groups.groups) {
    $payload = @{
    name = $customer_name
    policy_id = $policy_id

    echo "Creating $customer_name group"

    # Create group and get group ID
    $response = Invoke-RestMethod -Method Post -ContentType 'application/json' `
    -Uri "$base_url/api/v1/groups" -Body ($payload | ConvertTo-Json) `
    -Headers $headers
    $gid = $response.id

    echo "Sharing group to consultants"

    # Get list of TeamViewer users and exclude superuser.
    $users = Invoke-RestMethod -Uri "$base_url/api/v1/users?full_list=true" -Headers $headers
    $consultants = $users.users | where { $_.id -ne $user_id -and $_.active }

    # Create a mapping of user IDs to permissions.
    $uids = $consultants | foreach { @{userid = $_.id; permissions = "full"} }

    # Perform request to give users permissions on the group.
    $response = Invoke-RestMethod -Method Post -ContentType 'application/json' `
    -Uri "$base_url/api/v1/groups/$gid/share_group" `
    -Body (@{users = $uids} | ConvertTo-Json) `
    -Headers $headers

    # Run the assignment tool
    echo "Running assignment tool"
    $AssignArguments = @(
    ('-apitoken "{0}"' -f $assign_token)
    ('-datafile "{0}\assign.json"' -f $base_path)
    Start-Process -NoNewWindow -Wait -FilePath $assign_path -ArgumentList $AssignArguments

    echo "Cleaning up"
    Remove-Item $base_path -Force -Recurse

  • Where do you get some of your parameters?

    assign_token, policy_id, user_id, base_url


  • BBAY_ITAdmin
    BBAY_ITAdmin Posts: 2 ✭✭


    Just wanted to say this helped me to get my deploy script working but I reduced and retooled so the below works for me

    if you know your API keys and COnfigID and have the install already downloaded

    $ErrorLog = [PATH TO where you want to save your errorlog]



            Unblock-File -Path '[PATH TO MSI]\TeamViewer_Host.msi'

            Start-Process -Wait -FilePath '[PATH TO MSI]\TeamViewer_Host.msi'"  -ArgumentList "ASSIGNMENTOPTIONS=--grant-easy-access CUSTOMCONFIGID=[CONFIGID] APITOKEN=[APITOKEN] /qn"-PassThru




            $ErrorM = $PSItem.Exception.Message

            $ErrorM | out-file $ErrorLog -append


  • BBAY_ITAdmin
    BBAY_ITAdmin Posts: 2 ✭✭
    edited April 24

    Blank post....