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 (
[Parameter(Mandatory=$true)][string]$host_msi_url,
[Parameter(Mandatory=$true)][string]$configuration_id,
[Parameter(Mandatory=$true)][string]$assingment_tool_url,
[Parameter(Mandatory=$true)][string]$api_token
)
$tv_msi_path = $env:TEMP + "\TeamViewer_Host-idc$configuration_id.msi"
$assign_path = $env:TEMP + "\tvassign.exe"
if (Test-Path("C:\Program Files\TeamViewer\")) {
#32
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")) {
#64
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)"))) {
#32
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 {
#64
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
-
# Get script parameters.
Param (
[string]$customer_name = $(Read-Host "Customer name"),
[string]$device_alias = $env:computername,
[string]$msi_url = "https://yourwebhost.com/TeamViewer_Host.msi",
[string]$assignment_tool_url = "https://yourwebhost.com/TeamViewer_Assignment.exe"
)
# Assignment variables. - MAKE SURE YOU SET THESE
$config_id = ""
$assign_token = ""
$policy_id = ""
# API variables.
$api_token = ""
$user_id = "" # Token must belong to this user.
$base_url = "https://webapi.teamviewer.com/"
$headers = @{"Authorization" = "Bearer $api_token"}
# Check to see if device already exists, prompt to delete it if it does
$devices = Invoke-RestMethod -Uri "$base_url/api/v1/devices" -Headers $headers
$existing_device = $devices.devices | where { $_.alias -eq $device_alias }
if ($existing_device) {
$title = "Delete Device"
$message = "A device with the name $device_alias already exists. Do you wish to delete it?"
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", `
"Deletes the device $device_alias."
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", `
"Cancels the current installation."
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 0)
switch ($result) {
0 {
try {
Invoke-RestMethod -Method Delete `
-Uri "$base_url/api/v1/devices/$($existing_device.device_id)" `
-Headers $headers
}
catch {
throw "Error deleting device"
}
}
1 {
throw "Device already exists"
}
}
}
# 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 12 Host (MSI Wrapper)'"
if ($msi_wrapper) {
echo "Removing existing TeamViewer installation"
$msi_wrapper.Uninstall()
}
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 = @(
"/I"
('"{0}"' -f $tv_msi_path)
"/quiet"
)
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)
"-verbose"
)
Start-Process -NoNewWindow -Wait -FilePath $assign_path -ArgumentList $AssignArguments
echo "Cleaning up"
Remove-Item $base_path -Force -RecurseHi,
Thanks for your follow up - this script in the original solution is pretty old though. Here is the updated script.
6
Answers
-
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!0 -
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"
0 -
Awesome, this was exactly what I was looking for. Tested it out, and it works perfectly. Thank you!!
0 -
Line 19 should be
Start-Process -Wait -FilePath "C:\Program Files (x86)\TeamViewer\uninstall.exe" -ArgumentList "/S"
0 -
# Get script parameters.
Param (
[string]$customer_name = $(Read-Host "Customer name"),
[string]$device_alias = $env:computername,
[string]$msi_url = "https://yourwebhost.com/TeamViewer_Host.msi",
[string]$assignment_tool_url = "https://yourwebhost.com/TeamViewer_Assignment.exe"
)
# Assignment variables. - MAKE SURE YOU SET THESE
$config_id = ""
$assign_token = ""
$policy_id = ""
# API variables.
$api_token = ""
$user_id = "" # Token must belong to this user.
$base_url = "https://webapi.teamviewer.com/"
$headers = @{"Authorization" = "Bearer $api_token"}
# Check to see if device already exists, prompt to delete it if it does
$devices = Invoke-RestMethod -Uri "$base_url/api/v1/devices" -Headers $headers
$existing_device = $devices.devices | where { $_.alias -eq $device_alias }
if ($existing_device) {
$title = "Delete Device"
$message = "A device with the name $device_alias already exists. Do you wish to delete it?"
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", `
"Deletes the device $device_alias."
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", `
"Cancels the current installation."
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 0)
switch ($result) {
0 {
try {
Invoke-RestMethod -Method Delete `
-Uri "$base_url/api/v1/devices/$($existing_device.device_id)" `
-Headers $headers
}
catch {
throw "Error deleting device"
}
}
1 {
throw "Device already exists"
}
}
}
# 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 12 Host (MSI Wrapper)'"
if ($msi_wrapper) {
echo "Removing existing TeamViewer installation"
$msi_wrapper.Uninstall()
}
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 = @(
"/I"
('"{0}"' -f $tv_msi_path)
"/quiet"
)
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)
"-verbose"
)
Start-Process -NoNewWindow -Wait -FilePath $assign_path -ArgumentList $AssignArguments
echo "Cleaning up"
Remove-Item $base_path -Force -RecurseHi,
Thanks for your follow up - this script in the original solution is pretty old though. Here is the updated script.
6 -
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?
0 -
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.
0 -
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"
0 -
The Customer Name is what you want it to show up as in your Computers & Contacts
1 -
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 devicePlease advise.
0 -
"BUMP"
0 -
"BUMP", "BUMP"
0 -
Anyone?
0 -
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.StartProcessCommandPlease advise.
0 -
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"
$msi_wrapper.Uninstall()
}echo "Downloading TeamViewer MSI"
Invoke-WebRequest -Uri $msi_url -OutFile $tv_msi_pathecho "Downloading assignment tool"
Invoke-WebRequest -Uri $assignment_tool_url -OutFile $assign_pathecho "Installing TeamViewer"
$MSIArguments = @(
"/I"
('"{0}"' -f $tv_msi_path)
"/quiet"
)
Start-Process msiexec.exe -Wait -ArgumentList $MSIArgumentsecho "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.idecho "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)
"-verbose"
)
Start-Process -NoNewWindow -Wait -FilePath $assign_path -ArgumentList $AssignArgumentsecho "Cleaning up"
Remove-Item $base_path -Force -Recurse0 -
Where do you get some of your parameters?
I.E.assign_token, policy_id, user_id, base_url
0 -
Hi
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]
Try
{
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
}
Catch
{
$ErrorM = $PSItem.Exception.Message
$ErrorM | out-file $ErrorLog -append
}
0 -
Blank post....
0