My Powershell Scripts to update Computers & Contacts with Computername, Username, Fullname
Hello!
I have been using Teamviewer for years I finally found a way to solve an old problem that had been bugging me for years. I am posting this here as I am sure this will benefit others.
Basically, we have 4000-5000 computers in our Computers & Contacts list, across various clients that we provide IT support for - We typically deploy Teamviewer through Group Policy / with a "Design & Deploy" MSI . This method when done correctly automatically adds the computer to the Contact List in the Group we want.
We then typically rename the contacts with perhaps the users name, or whatever - but over time, users change, and this information becomes old, and we end up with a mess in the contact list.
Another thing that bugs me, is that computers sometimes end up in the wrong group.
I discovered the Teamviewer API the other day, and started messing about with it, and wrote a few scripts in powershell which solves the above two issues by updating the Contact in the Computers and Contact List with the format "COMPUTERNAME (username) (Full Name)"
The API documentation is here: https://dl.tvcdn.de/integrate/TeamViewer_API_Documentation.pdf
The method consists of:
1) A Group Policy User Logon Script to generate a file on a file share which contains the Teamviewer ID, username and Full Name
2) A Scheduled Task which runs a batch file, which combines all the generated files into a powershell script, which is then run. It uses the Teamviewer API to update your Computers and Contacts list. The script looks to see if there are any updates to make, and if there are none, it simply ends. However, if there are updates to be made, it will continue and run the process.
A few points to make before we get into it (Surgeons General Health Warning)
1. I will say from the outset, that I am not an expert on Powershell Scripting - and these scripts have no error checking (not that it really needs it, it either works, or it doesnt!)
2. The API Token is stored in plain text, however, the script which runs the API commands is not and should not be visible to your end users. Obviously this is a fairly sensitive piece of information, so be sure to keep it safe and secure.
3. This is my own convoluted way of doing it, and I am welcome to any ideas or suggestions from those here with ideas or better scripting knowledge.
4. My scheduled task runs every minute - however, please be sure to read the API documentation, and note in particular the section about Rate Limits on Page 10. I am using Teamviewer Corporate, so its fine for me, but might not be fine for you if you're on a Free license for example. Just something to consider when creating your Scheduled Task later.
With the above out of the way, here goes.
Step 1 - Obtain / Create an API Token
1. Log into Teamviewer Management Console https://login.teamviewer.com
2. Click on your Login Name / Avatar at the top right hand side and select Edit Profile
3. Click on Apps
4. Create Script Token.
Name: UpdateTool
Description: API Key for updating ComputerList
Group Management: View
Computer & Contacts: View, add, edit & delete
Leave the rest as default (No Access)
5. Save it, and make a note of the API Token - you'll need it later.
Step 2 - Set up the folder structure for your scripts and put files in place.
Note: For simplicity, im going to use C:\TVUpdate - you can modify this to suit your own setup.
1. Download the RAR file containing the powershell scripts from (https://mega.nz/#!f2IBECKC!oGcYbcqd1ESHuBopRRqj2oGN740g8P1aUhR9o3EmuNo)
2. From the RAR, extract the contents so that the RAR contents are in C:\TVUpdate
The RAR contains 5 files & 1 folder.
- README.TXT (Read this!)
- RetrieveGroupsInfo.ps1 (This connects to Teamviewer via the API and creates a CSV of all your groups, and their Group IDs)
- RetrieveTVInfo.ps1 (This connects to Teamviewer, and create a Global Powershell variable containing literally all of the information from Computers & Contacts)
- UpdateTeamviewerDevice.ps1 (This, when fed parameters, updates a specific device with a new Alias, and Group ID)
- Run.bat (This is the file which runs on a schedule which kicks off the whole process)
- TV (This is the folder you're going to share, for the Logon Script to dump its instructions into)
3. Share the folder "C:\TVUpdate\TV" with the sharename "\\SERVERNAME\TV$"
(I like to use the $ to keep the share hidden)
4. Ensure that the Share Permissions are "Everyone - Full Control"
5. Ensure that the NTFS Permissions are "Everyone - Full Control"
6. Edit the 3x Powershell files and replace "INSERT_TOKEN_HERE" with your API Key.
Step 3 - Determine the correct Group ID, and update the script to use it.
1. Right Click on "RetrieveGroupsInfo.ps1" and run it.
All going well, groups.csv should open in notepad with a list of groups, and their "group_id" -
2. Find and make a note of the Group ID you want use.
3. Edit the file "UpdateTeamviewerDevice.ps1" and replace the text "INSERT_GROUPID_HERE" with the ID you made a note of (e.g. g92342)
Step 4 - Create the Group Policy Logon Script
1. Open up Group Policy Management and create a new GPO in the OU containing your Users.
2. Call it "Update Teamviewer Contacts" or whatever.
3. Edit it, and navigate to User Configuration -> Policies -> Windows Settings -> Scripts (Logon/Logoff)
4. Double Click on Logon
5. Switch to the Powershell Scripts Tab! (easy to miss this one)
6. Click Add
Script Name: \\servername\tv$\CreateUpdateFile.ps1
Script Parameters: \\servername\tv$\
(N.B. Make sure you include the backslash at the end)
7. Click Ok, and Ok again.
Now when users log on, the script will create e.g. (\\servername\tv$\6868686.bat)
Step 5 - Schedule the Task to Run every minute.
It's in the README.txt, but I use the following command, to schedule it under the logged in user, you may prefer to create a dedicated service account for it. This is up to yourself.
schtasks /create /sc minute /mo 1 /tn "Update Teamviewer Contacts" /tr c:\TVUpdate\run.bat /RU %USERNAME% /RP
That's it! Run gpupdate /force on a client computer, log off and on again, and watch as the entry on "Computers & Contacts" magically updates itself.
Hope this helps, let me know how you get on with it!
Denis Mc Auliffe
Systems Engineer @ Everything IT
[removed per Community Guidelines]
Comments
-
One thing I just noticed, is that within "run.bat" the path c:\TVUpdate is hard coded. You might need to update that if you decide to put it on a different drive letter or path.
1 -
Hi,
Many thanks, we have been looking for something like this for a long time, as TeamViewer seems incapable of implementing this kind of basic and a MUST feature on their own software.
We will test and see how it works.
Ps. might want to consider hosting the script files on some other site, all my browsers on Win10 gave a TLS error on that mega.nz site. I was however able to download the package through an Android phone's browser.0 -
First impressions; it works, but some observations below:
- Running the script requires a newer version of PowerShell (not sure which, maybe 3.x or newer?). We first tried on a Windows Server 2008 R2 and it didn't work, but it does work on Windows Server 2016, so it's not an issue (unless all the servers are from stone age).
- The script provided only works on 64-bit Teamviewer hosts. We have still some old 32-bit Windows 7 hosts, so we made a 32-bit version of it and narrowed it down with WMI filters, so we can read the registry correctly from both 32-bit hosts and 64-bit hosts. Otherwise it just creates .bat files without names and TV ID's. This was the easiest solution for us. Another option might be to directly modify the PS script to choose between 32/64-bit hosts inside the script.
Will report back any further observations, but so far it's looking very good.
0 -
Hey tvuser,
I was beginning to wonder if anyone would ever actually try this out!
You're right, it's a pity the functionality is not built into Teamviewer - since using this, it has made my life so much easier.
I have it running on Server 2012 R2 and above - I havent tried it on any 2008/2008 R2 servers but your theory is probably correct on that one about the Powershell Versions.
I have also since had to make some minor changes to locate the Teamviewer ID from the WOW6432Node for 32 bit machines.
It's a bit rough, but it works!
I am glad it's working out for you
0 -
It's working out, but a few more comments after initial testing.
- We have a lot of VPN users, that rarely log on to computers inside our internal network, which means the logon script doesn't run for them. We made a scheduled task to run the update script every hour, so when the user has a VPN connection the script will run and the information can be gathered.
- There is an issue with TeamViewer, it apparently cannot accept Nordic/Skandinavian characters (ä, ö, å, etc). So if the username has these kind of characters within the generated .bat file , it will not update any information to the management console. We will need to get around this somehow, maybe one solution could be to convert inside the PS script the characters "ä > a" and "ö > o". It's only a workaround, we run into the same issue before with the AD connector. Not sure how to implement it within the PS script though.
0 -
Hi, Denis!
That's what I've been looking for!
Unfortunately, I do not have enough knowledge to make this decision in the form of a single script.
Maybe you made a new version of these great scripts?0 -
We have used this successfully with some minor additions:
- Added separate scripts for 32-bit and 64-bit hosts and focused to run them as logon scripts through WMI filtering.
- Added a replace funtion to scripts to replace Skandinavian letters with "generic" letters, otherwise TeamViewer API refures to update information.
- Removed the username information from the update script, as the maximum number of accepted characters is 50 in the API command, we had some names that were longer than that, so the update script failed.
- Added scheduled tasks through GPP to run scripts on a regular basis on hosts that are mostly connected via VPN (logon scripts not running).
It's not perfect, but works okay. A big thanks to Denis for the original work and scripts!
1 -
Hi TeamAI-IT,
Im not really sure what you're asking? I havent updated the scripts much since I originally posted them as they're working.
Are you having difficulty getting them working?
Thanks,
Denis0 -
Hi Denis,
I think they are referring to a post where you mentioned that you did modifications to WOWnode to distinguish between 64bit and 32 bit.
I have just tested this script with the download link you posted and it does not work with 32 bit OS.
Can you or someone else post a link with the updated version for us that are not very skilled in scripting ?
Thank you.
0 -
Here are our modifed scripts for both 32-bit and 64-bit. We have added an exclude rule for AD users (group membership) for those user accounts we don't want the autoupdate to include. Also added a replace rule for Scandinavian characters in the user's display name, might be unnecessary for other environments.
32-bit:
Param( [string]$ServerShare = "\\SERVER\SHARE$\")
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ct = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$GroupName = "TeamViewer_EXCLUDE_user_autoupdater"
$user = [System.DirectoryServices.AccountManagement.UserPrincipal]::Current
$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($ct,$GroupName)
if(!$user.IsMemberOf($group))
{
$dom = $env:userdomain
$usr = $env:username
$Fullname = ([adsi]"WinNT://$dom/$usr,user").fullname
$TVID = (Get-ItemProperty "HKLM:\SOFTWARE\TeamViewer").ClientID
if (!$TVID) { $TVID = (Get-ItemProperty "HKLM:\SOFTWARE\TeamViewer\Version9").ClientID }
if (!$TVID) { $TVID = (Get-ItemProperty "HKLM:\SOFTWARE\TeamViewer\Version10").ClientID }
if (!$TVID) { $TVID = (Get-ItemProperty "HKLM:\SOFTWARE\TeamViewer\Version11").ClientID }
if (!$TVID) { $TVID = (Get-ItemProperty "HKLM:\SOFTWARE\TeamViewer\Version12").ClientID }
if (!$TVID) { $TVID = (Get-ItemProperty "HKLM:\SOFTWARE\TeamViewer\Version13").ClientID }
if (!$TVID) { $TVID = (Get-ItemProperty "HKLM:\SOFTWARE\TeamViewer\Version14").ClientID }
$FilePath = $ServerShare + $TVID + ".bat"
$FileCommand = ".\UpdateTeamviewerDevice.ps1 " + $TVID + " """ + $ENV:Computername + " (" + $Fullname +")" + """ " + "groupid" -replace "ä","a" -replace "ö","o"
echo $FileCommand
echo $FilePath
Add-Content $FilePath $FileCommand
}
else
{
}64-bit:
Param( [string]$ServerShare = "\\SERVER\SHARE$\")
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ct = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$GroupName = "TeamViewer_EXCLUDE_user_autoupdater"
$user = [System.DirectoryServices.AccountManagement.UserPrincipal]::Current
$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($ct,$GroupName)
if(!$user.IsMemberOf($group))
{
$dom = $env:userdomain
$usr = $env:username
$Fullname = ([adsi]"WinNT://$dom/$usr,user").fullname
$TVID = (Get-ItemProperty "HKLM:\SOFTWARE\WOW6432Node\TeamViewer").ClientID
if (!$TVID) { $TVID = (Get-ItemProperty "HKLM:\SOFTWARE\WOW6432Node\TeamViewer\Version9").ClientID }
if (!$TVID) { $TVID = (Get-ItemProperty "HKLM:\SOFTWARE\WOW6432Node\TeamViewer\Version10").ClientID }
if (!$TVID) { $TVID = (Get-ItemProperty "HKLM:\SOFTWARE\WOW6432Node\TeamViewer\Version11").ClientID }
if (!$TVID) { $TVID = (Get-ItemProperty "HKLM:\SOFTWARE\WOW6432Node\TeamViewer\Version12").ClientID }
if (!$TVID) { $TVID = (Get-ItemProperty "HKLM:\SOFTWARE\WOW6432Node\TeamViewer\Version13").ClientID }
if (!$TVID) { $TVID = (Get-ItemProperty "HKLM:\SOFTWARE\WOW6432Node\TeamViewer\Version14").ClientID }
$FilePath = $ServerShare + $TVID + ".bat"
$FileCommand = ".\UpdateTeamviewerDevice.ps1 " + $TVID + " """ + $ENV:Computername + " (" + $Fullname +")" + """ " + "groupid" -replace "ä","a" -replace "ö","o"
echo $FileCommand
echo $FilePath
Add-Content $FilePath $FileCommand
}
else
{
}0 -
And here are some screenshots how we have deployed the scripts to our users, with WMI filter rules (focusing Windows Desktops only) and logon/logoff scripts for both users inside LAN and users outside LAN, such as VPN users. We have rules for both 32-bit and 64-bit separately, these examples are from 32-bit.
0 -
When I try to run the bat file I get the error below
Invoke-RestMethod : {"Message":"The requested resource does not support http method 'PUT'."}
At C:\TVUpdate\UpdateTeamviewerDevice.ps1:40 char:13
+ $Response = Invoke-RestMethod -Header $header -Method PUT -ContentTyp ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
eption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
 : The term '' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\TVUpdate\WorkingPS.ps1:3 char:1
+ 
+ ~
+ CategoryInfo : ObjectNotFound: (:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException0 -
Looks like something got messed up when you Copy & Pasted the code.
I'd have a good look at it, make sure there are no special characters - check the inverted commas and make sure all of them look right.I come to this conclusion based on the error:
"The term '' is not recognized as the name of a cmdlet, function, script file, or operable program. "Best of luck,
Denis0 -
Param(
[string]$TVID,
[string]$Alias,
[string]$GroupID
)
#Override Group ID by Entering it below.
$GroupID = 'g1659*****'
#Define Auth Token
$token = "8745336-O42pRf5p************"
$bearer = "Bearer",$token
$header = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$header.Add("authorization", $bearer)
#Define rID
$Global:RemoteControlID = "r" + $TVID
#Determine Device ID from Teamviewer ID
$Global:Device = $Global:TeamviewerDeviceList.devices | where {$_.remotecontrol_id -eq $Global:RemoteControlID}
$Global:DeviceID = $Global:Device.device_id
$Global:DeviceID
#Define URL For Request.
$ReqURI = 'https://webapi.teamviewer.com/api/v1/devices/' + $Global:DeviceID
#Define Body For Request.
$Jsonbody= @{
'alias' = $Alias
'groupid' = $GroupID
} | ConvertTo-Json
#Send Request
$Response = Invoke-RestMethod -Header $header -Method PUT -ContentType 'application/json' -Uri $ReqURI -Body $Jsonbody -Verbose| fl *I only edited the code from the downloaded rar. This is the error in Powershell
PS C:\Windows\system32> C:\TVUpdate\UpdateTeamviewerDevice.ps1
VERBOSE: PUT https://webapi.teamviewer.com/api/v1/devices/ with -1-byte payload
Invoke-RestMethod : {"Message":"The requested resource does not support http method 'PUT'."}
At C:\TVUpdate\UpdateTeamviewerDevice.ps1:40 char:13
+ $Response = Invoke-RestMethod -Header $header -Method PUT -ContentTyp ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
PS C:\Windows\system32>0 -
This worked perfectly and was exactly the kind of thing I was looking for. Thank you!
0 -
I started from scratch and only have edited the required fields. It worked once on my test PC and updated the contact in Teamviewer. Now when I run the bat file I am getting same error again.
0 -
Would anyone be available to assist that has this working. I am still getting the same error every time.
VERBOSE: PUT https://webapi.teamviewer.com/api/v1/devices/ with -1-byte payload
Invoke-RestMethod : {"Message":"The requested resource does not support http method 'PUT'."}
At C:\TVUpdate\UpdateTeamviewerDevice.ps1:40 char:13
+ $Response = Invoke-RestMethod -Header $header -Method PUT -ContentTyp ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
eption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
 : The term '' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\TVUpdate\WorkingPS.ps1:3 char:1
+ 
+ ~
+ CategoryInfo : ObjectNotFound: (:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException0 -
Sure, i'll help you with this - Email me directly **Do Not Post Email Addresses** and i'll give you some guidance on it.
0 -
Did you every figure this problem out? I'm having the same issue
0 -
We have had this script working well for quite some time now but now trying to get it working with Teamviewers new device groups and having some issues as put doesn't seem to be supported in the api for devices under managed groups TeamViewer API Documentation. Anyone able to update this script to work with managed device groups?
0 -
I am lloking for a script to update all of our TV clients with %computername% from each remote client. That's all I need. Will this do that? I have many different companies I support, so I would like it to just run and connect to every client and pull the info. Can this script do that? Can it be done? Thanks!
0 -
Wrote this for powershell for post installation endpoint profiling in a shared computers group. Hope this saves someone some time!
User Name (HostName) format.
This is submitted as is, for other sysadmins, not for commercial gain.
# Teamviewer dynamic device alias generator - sgroom 4 Jan 2023
# LastUpdated 10 October 2023
Write-Host "`n"
Write-Host "Discovering Environment to build desired Alias..."
Write-Host "`n"
$UserName = $env:USERNAME
$FirstName,$LastName = $Username.split('.')
$FirstName = (Get-Culture).TextInfo.ToTitleCase($FirstName)
$LastName = (Get-Culture).TextInfo.ToTitleCase($LastName)
$ComputerName = $env:COMPUTERNAME
Write-Host "Computer Name: $ComputerName"
Write-Host "Current UserName: $UserName"
Write-Host "First Name: $FirstName"
Write-Host "Last Name: $LastName"
Write-Host "`n"
Write-Host "TeamViewer API: Acquiring Workstations device from ComputerName: $ComputerName"
$token = '*** PutYourUserTokenHere ***'
$header = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$header.Add("authorization", "Bearer $token")
$GetDevice = Invoke-RestMethod -Uri "https://webapi.teamviewer.com/api/v1/devices?full_list=true" -Method GET -Headers $header -ContentType application/json
$DeviceInformation = $GetDevice.devices | Where-Object { $_.alias -eq "$ComputerName" }
$DeviceInformation
$ThisDeviceID = $DeviceInformation.device_id
$NewAlias = "$FirstName $LastName ($ComputerName)"
$header2 = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$header2.Add("authorization", "Bearer $token")
$body = (@{
alias = $NewAlias
}) | ConvertTo-Json
$SetAlias = (Invoke-RestMethod -Uri "https://webapi.teamviewer.com/api/v1/devices/$ThisDeviceID" -Method PUT -Headers $header2 -ContentType application/json -Body $body)
$SetAlias
0 -
Thanks again for this script. Works well when ran the 1st time. The moment there's a new user on the same device, im getting the same error as others described:
Invoke-RestMethod : {"Message":"The requested resource does not support http method 'PUT'."}
At line:79 char:14
+ ... SetAlias = (Invoke-RestMethod -Uri "
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
I think the PUT method only works once and can not be re-used but really unsure about this. Checked the API docs, no luck.
Asked TV support and received a "API and CUSTOM script are not supported".
Is there anyone else having success with this?
0 -
Anyone have an updated script for the Managed Device Groups? If you look at the API documentation there is a new section "Device Groups"
https://webapi.teamviewer.com/api/v1/docs/index#!/Device32Groups/ManagedGroups_List
0 -
Anyone have found a solution for the new Managed Device Groups
0 -
This function works with Managed Device Groups.
It is part of my program which stays in sync with the primary owner in Intune.
Function Set-TVDeviceName {
Param (
[Parameter(Mandatory)]
[string]$TVid,
[Parameter(Mandatory)]
[string]$TVname
)
Begin {
$body = @"
{
"name": "$TVname"
}
"@
}
Process {
$request = @{
Method = "PUT"
Uri = "$APIUri/managed/devices/$TVid"
ContentType = "application/json"
Headers = @{ Authorization = "Bearer $($APIKey)" }
Body = $body
}
}
End {
Invoke-RestMethod @request
}
}0