PSTeamViewer.psm1
<# Description: TeamViewer API Module Author: Marco Micozzi Requires Powershell 5 #> #region Module Variables [string] $script:fmt_AuthBearer = "Bearer {0}" [string] $script:TOKEN_MISSING_ERROR = 'No AccessToken found, please supply the token or run Initialize-TeamViewerAPI with a valid token first' [string] $script:TOKEN_INVALID = 'Invalid Token' [hashtable] $script:TVConfig = @{ BaseUrl = 'https://webapi.teamviewer.com' LoginUrl = 'https://login.teamviewer.com' ApiVersion = 'v1' AccessToken = '' TokenValid = $false Header = @{ Authorization = '' } } #endregion #region Classes class TVToken{ [ValidateNotNullOrEmpty()][string] $Access [ValidateNotNullOrEmpty()][string] $Type [ValidateNotNullOrEmpty()][string] $Refresh [ValidateNotNullOrEmpty()][int] $ExpiresIn [System.DateTime] $ExpireTime [bool] $Expired = $true [System.Timers.Timer] $Timer = $null TVToken($Access, $Type, $Refresh, $ExpiresIn){ $this.Expired = $false $this.ExpireTime = (Get-Date).AddSeconds($ExpiresIn) $this.Access = $Access $this.ExpiresIn = $ExpiresIn $this.Refresh = $Refresh $this.Type = $Type $this.Timer = New-Object -TypeName System.Timers.Timer -Property @{Interval=$ExpiresIn*1000;AutoReset=$false} Register-ObjectEvent -InputObject $this.Timer -EventName 'Elapsed' -MessageData $this -Action { Write-Verbose -Message ('The Elapsed event was raised at {0}' -f $EventArgs.SignalTime) [TVToken] $token = $Event.MessageData $token.Expired = $true } $this.Timer.Enabled = $true } } class TVUserBase { [ValidateNotNullOrEmpty()][string]$ID [ValidateNotNullOrEmpty()][string]$Name TVUserBase($ID, $Name){ $this.ID = $ID $this.Name = $Name } } class TVUser : TVUserBase { [ValidateNotNullOrEmpty()][string[]]$Permissions [ValidateNotNullOrEmpty()][bool]$Active [bool]$LogSessions [bool]$ShowCommentWindow [string]$QuickSupportID [string]$QuickJoinID TVUser( $ID, $Name, $Permissions, $Active, $LogSessions, $ShowCommentWindow, $QuickSupportID, $QuickJoinID ) : base ($ID, $Name) { $this.Permissions = $Permissions $this.Active = $Active $this.QuickSupportID = $QuickSupportID $this.QuickJoinID = $QuickJoinID $this.ShowCommentWindow = $ShowCommentWindow $this.LogSessions = $LogSessions } TVUser( $ID, $Name, $Permissions, $Active, $LogSessions, $ShowCommentWindow ) : base ($ID, $Name) { $this.Permissions = $Permissions $this.Active = $Active $this.ShowCommentWindow = $ShowCommentWindow $this.LogSessions = $LogSessions } } Class TVAccount : TVUserBase { [string] $Email [string] $CompanyName TVAccount ( [string] $ID, [string] $Name, [string] $Email, [string] $CompanyName ) : base ($ID, $Name) { $this.Email = $Email $this.CompanyName = $CompanyName } } Class TVGroupUser : TVUserBase { [string] $Permissions = [string]::Empty [bool] $Pending = $false TVGroupUser ( $ID, $Name, $Permissions, $Pending) : base ( $ID, $Name) { $this.Permissions = $Permissions $this.Pending = $Pending } TVGroupUser ( $ID, $Name, $Permissions) : base ( $ID, $Name) { $this.Permissions = $Permissions } } Class TVGroup { [ValidateNotNullOrEmpty()][string]$ID [ValidateNotNullOrEmpty()][string]$Name [TVUserBase] $Owner [ValidateNotNullOrEmpty()][string]$Permissions [ValidateNotNullOrEmpty()][string]$PolicyID [TVGroupUser[]] $SharedWith TVGroup ( [string] $ID, [string] $Name, [TVUserBase] $Owner, [string] $Permissions, [TVGroupUser[]] $SharedWith ) { $this.ID = $ID $this.Name = $Name $this.Owner = $Owner $this.Permissions = $Permissions $this.SharedWith = $SharedWith } } Class TVDevice { [string] $RemoteControlID [string] $DeviceID [string] $Alias [string] $GroupID [string] $OnlineStatus [bool] $AssignedTo [string] $SupportedFeatures TVDevice ( [string] $RemoteControlID, [string] $DeviceID, [string] $Alias, [string] $GroupID, [string] $OnlineStatus, [bool] $AssignedTo, [string] $SupportedFeatures ) { $this.Alias = $Alias $this.AssignedTo = $AssignedTo $this.DeviceID = $DeviceID $this.GroupID = $GroupID $this.OnlineStatus = $OnlineStatus $this.RemoteControlID = $RemoteControlID $this.SupportedFeatures = $SupportedFeatures } } #endregion #region Helpers function Initialize-TVUserObject { [CmdLetBinding()] [OutputType([TVUser])] param( [Parameter(Mandatory = $true)] [psobject] $Json ) [string] $QuickSupportID = [System.String]::Empty if( $Json.custom_quicksupport_id -ne $null) { $QuickSupportID = $Json.custom_quicksupport_id } [string] $QuickJoinID = [System.String]::Empty if( $Json.custom_quickjoin_id -ne $null) { $QuickJoinID = $Json.custom_quickjoin_id } [string[]] $Permissions = $Json.permissions -split ',' [TVUser] $TVUser = New-Object TVUser -ArgumentList $Json.id, ` $Json.name, ` $Permissions, ` $Json.active, ` $Json.log_sessions, ` $Json.show_comment_window, ` $QuickSupportID, ` $QuickJoinID Write-Output -InputObject $TVUser } #endregion Helpers #region Initialization function Initialize-TVAPI { <# .SYNOPSIS Initialize the TeamViewer API wrapper .DESCRIPTION Initialize the TeamViewer API wrapper .PARAMETER Token The API token created on the management portal .EXAMPLE Initialize-TVAPI -Token "ABCD-1234" Initialize the TeamViewer API with the token "ABCD-1234" .NOTES Initializing the wrapper will allow all API call's to be made without having to specify the token in each call #> [CmdletBinding( HelpUri = 'http://psteamviewer.readthedocs.io/en/latest/cmdlets/Initialize-TVAPI/' )] [OutputType([bool])] param( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [Alias('t')] [string] $Token ) begin { [bool] $IsTokenValid = Test-TVToken -Token $Token if ( -not ( $IsTokenValid )) { throw (New-Object -TypeName System.Exception -ArgumentList $script:TOKEN_INVALID) } } process { $script:TVConfig.TokenValid = $IsTokenValid $script:TVConfig.AccessToken = $Token $script:TVConfig.Header.Authorization = ($script:fmt_AuthBearer -f $Token) } } #endregion #region Ping function Test-TVToken { <# .SYNOPSIS Test a TeamViewer API Token .DESCRIPTION Tests if a TeamViewer API token is valid .PARAMETER Token The token generated on the TeamViewer Management Console .EXAMPLE Test-TVToken -Token 'abc123def456ghi789' Tests if the token 'abc123def456ghi789' is valid .NOTES Author: Marco Micozzi #> [CmdletBinding( HelpUri = 'http://psteamviewer.readthedocs.io/en/latest/cmdlets/Test-TVToken/' )] [OutputType([bool])] param( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $Token ) begin { [string] $RequestUrl = ('{0}/api/{1}/ping' -f $script:TVConfig.BaseUrl, $script:TVConfig.ApiVersion) Write-Verbose -Message ('Compiled TV API request URI: "{0}".' -f $RequestUrl) } process { $TVResponse = Invoke-RestMethod -Method Get ` -Uri $RequestUrl ` -Headers @{ Authorization = ($script:fmt_AuthBearer -f $Token)} Write-Verbose -Message $TVResponse } end { Write-Verbose -Message ('TRUE: {0}' -f ($TVResponse.token_valid -eq 'true')) return ( $TVResponse.token_valid -eq 'true') } } #endregion #region Authorization function Get-TVOAuth2Authorization { [CmdletBinding( PositionalBinding = $false ) ] param( [Parameter( Mandatory = $true )] [string] $ClientID, [Parameter( Mandatory = $false )] [string] $RedirectURI = [string]::Empty ) begin{ Add-Type -AssemblyName PresentationFramework [string] $fmt_loginUtl = '{0}/oauth2/authorize?response_type=code&client_id={1}&redirect_url={2}&display=popup' [string] $Url = $fmt_loginUtl -f $script:TVConfig.LoginUrl, $ClientID, $RedirectURI } process { [System.Windows.Window] $Window = New-Object Windows.Window -Property @{Width=440;Height=640} $Window.Title = 'TeamViewer oAuth2' $window.WindowStartupLocation="CenterScreen" [System.Windows.Controls.Grid] $Grid = New-Object -TypeName System.Windows.Controls.Grid [System.Windows.Controls.WebBrowser] $Browser = New-Object -TypeName System.Windows.Controls.WebBrowser ` -Property @{Source=($Url -f ($Scope -join "%20")) } $Browser.HorizontalAlignment = [System.Windows.HorizontalAlignment]::Stretch $Browser.VerticalAlignment = [System.Windows.VerticalAlignment]::Stretch $Grid.AddChild($Browser) $Window.Content = $Grid $window.ShowDialog() | Out-Null } } function Revoke-TVOauth2Token { [OutputType([bool])] [CmdLetBinding()] param( [string] $Token ) } <# This function needs to be tested!!! #> function Get-TVOauth2Token { [OutputType([TVToken])] [CmdletBinding( HelpUri = 'http://psteamviewer.readthedocs.io/en/latest/cmdlets/Get-TVOauth2Token/' )] param( [Parameter( Mandatory=$true, HelpMessage = 'Authorization code acquired from the /oauth2/authorize page.', ParameterSetName = 'Grant' )] [string] $AuthorizationCode, [Parameter( Mandatory = $false, HelpMessage = 'Must be the same value as in the previous call to /oauth2/authorize', ParameterSetName = 'Grant' )] [string] $RedirectURI = [string]::Empty, [Parameter( Mandatory = $true, HelpMessage = 'Refresh-token from a previous call.', ParameterSetName = 'RefreshToken' )] [string] $RefreshToken, [Parameter( Mandatory = $true, HelpMessage = 'Client ID, a unique string that identifies the application.', ParameterSetName = 'Grant' )] [Parameter( Mandatory = $true, HelpMessage = 'Client ID, a unique string that identifies the application.', ParameterSetName = 'RefreshToken' )] [string] $ClientID, [Parameter( Mandatory = $true, HelpMessage = 'The client secret, which is known only to the creator of the application.', ParameterSetName = 'Grant' )] [Parameter( Mandatory = $true, HelpMessage = 'Client ID, a unique string that identifies the application.', ParameterSetName = 'RefreshToken' )] [string] $ClientSecret ) Write-Warning -Message 'The function "Get-TVOauth2Token" needs proper testing!!!' [string] $RequestUrl = ('{0}/api/{1}/oauth2/token' -f $script:TVConfig.BaseUrl, $script:TVConfig.ApiVersion) Try { [System.Net.WebRequest] $Request = [System.Net.WebRequest]::Create($RequestUrl) $Request.Method = 'POST' $Request.ContentType = 'application/x-www-form-urlencoded' [string] $Parameters = ('client_id={0}&client_secret={1}' -f $ClientID, $ClientSecret ) switch ( $PSCmdlet.ParameterSetName ){ 'Grant' { $Parameters += ('&grant_type=authorization_code&code={0}&redirect_uri={1}' -f $AuthorizationCode, $RedirectURI) } 'RefreshToken' { $Parameters += ('&grant_type=refresh_token&refresh_token={0}' -f $RefreshToken) } Default{ Write-Error -Message ('Unexpected ParameterSetname received: "{0}".' -f $PSCmdlet.ParameterSetName) } } Write-Verbose -Message ('Got Parameters: "{0}".' -f $Parameters) [byte[]] $Payload = [System.Text.Encoding]::UTF8.GetBytes($Parameters) Write-Verbose -Message ('Got Payload: "{0}".' -f $Payload) [System.IO.Stream] $RequestStream = $Request.GetRequestStream() $RequestStream.Write($Payload, 0, $Payload.Length) $RequestStream.Close() Write-Verbose -Message 'closing stream' [System.Net.WebResponse] $Response = $Request.GetResponse() Write-Verbose -Message 'Got repsonse' [string] $StatusString = $Response.StatusCode [int] $StatusCode = [int] $Response.StatusCode Write-Verbose -Message ('Got Status Code: "{0}" with message: "{1}".' -f $StatusCode, $StatusString) [System.IO.Stream] $ResponseStream = $Response.GetResponseStream() [System.IO.StreamReader] $StreamReader = New-Object -TypeName System.IO.StreamReader ` -ArgumentList $ResponseStream [string] $Result = $StreamReader.ReadToEnd() if ( $StatusCode -ne 200) { # false Write-Verbose -Message ( 'Status code {0}' -f $StatusCode) } else { $jsonResponse = ConvertFrom-Json -InputObject $result [TVToken] $Token = New-Object -TypeName TVToken -ArgumentList $jsonResponse.access_token, $jsonResponse.token_type, $jsonResponse.refresh_token, $jsonResponse.expires_in Write-Output -InputObject $Token } } catch { Write-Host ("Token: Request failed! The error was '{0}'" -f $_) $_.Exception #$resstream = $_.Exception.InnerException.Response.GetResponseStream() #$sr = new-object System.IO.StreamReader $resstream #$value = $sr.ReadToEnd() #Write-Host $value } finally { if ($Response) { Write-Verbose -Message ('Closing response') $Response.Close() Write-Verbose -Message ('Response closed') } } } #endregion Authorization #region Account function Get-TVAccount { [CmdletBinding( HelpUri = 'http://psteamviewer.readthedocs.io/en/latest/cmdlets/Get-TVAccount/' )] [OutputType([TVAccount])] param( [Parameter()] [string] $Token = $script:TVConfig.AccessToken ) begin { if ( [string]::IsNullOrEmpty($Token) ) { throw (New-Object -TypeName System.Exception -ArgumentList $script:TOKEN_MISSING_ERROR) } } process { [string] $RequestUrl = ('{0}/api/{1}/account' -f $script:TVConfig.BaseUrl, $script:TVConfig.ApiVersion) $Response = Invoke-RestMethod -Uri $RequestUrl ` -Headers $script:TVConfig.Header ` -Body $RequestBody ` -Method 'Get' [TVAccount] $Account = New-Object -TypeName TVAccount ` -ArgumentList $Response.userid, ` $Response.name, ` $Response.email, ` $Response.company_name Write-Output -InputObject $Account } } #endregion Account #region Users # TODO: Permissions # permissions (optional) – Comma-separated list of permissions that this user has. # See 1.6.2 for valid values and combinations. # If omitted the following default permissions will be set: ShareOwnGroups, ViewOwnConnections, EditConnections, EditFullProfile function New-TVUser { <# .SYNOPSIS Create a new Teamviewer user. .DESCRIPTION Create a new Teamviewer user .PARAMETER Token The Teamviewer API token generated on the Teamviewer Management console (https://login.teamviewer.com) .PARAMETER Name The name of the new Teamviewer user .PARAMETER Email The email address of the new user. .PARAMETER Password The password for the new user .PARAMETER Language 2 Letter language code for the new user .PARAMETER QuickSupportID The QuickSupportID for the new user .PARAMETER QuickJoinID The QuickJoinID for the new user .EXAMPLE New-TVUser -Token $Env:TeamViewerToken -Name 'John Doe' -Email 'john.doe@domain.com' -Passwprd (ConvertTo-SecureString -String "P4ssW0rd!" -AsPlainText -Force) Creates a new user John Doe with email address john.doe@domain.com and password: P4ssW0rd! .NOTES Author: Marco Micozzi .LINK Get-TVUser .LINK Set-TVUser #> [CmdletBinding( PositionalBinding = $false, HelpUri = 'http://psteamviewer.readthedocs.io/en/latest/cmdlets/New-TVUser/' )] [OutputType([TVUser])] param( [Parameter()] [string] $Token = $script:TVConfig.AccessToken, [Parameter( Mandatory = $true, HelpMessage = 'The name of the user to create.' )] [string] $Name, [Parameter( Mandatory = $true, HelpMessage = 'The email address of the user to create.' )] [ValidateScript({ if ($_ -match "^([0-9a-zA-Z]([-\.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$") { $true } else { Throw "$_ is not a valid email address" } })] [string] $Email, [Parameter( Mandatory = $true, HelpMessage = 'The password of the user to create.' )] [securestring]$Password, [Parameter( Mandatory = $false )] [ValidateSet('en', 'nl', 'fr', 'es')] [string] $Language = 'en', [Parameter( Mandatory = $false )] [ValidateNotNullOrEmpty()] [string] $QuickSupportID = [string]::Empty, [Parameter( Mandatory = $false )] [ValidateNotNullOrEmpty()] [string] $QuickJoinID = [string]::Empty ) begin { # Make sure to have a token if ( [string]::IsNullOrEmpty($Token) ) { throw (New-Object -TypeName System.Exception -ArgumentList $script:TOKEN_MISSING_ERROR) } [string] $RequestUrl = ('{0}/api/{1}/users' -f $script:TVConfig.BaseUrl, $script:TVConfig.ApiVersion) } process { [hashtable] $Params = @{ name = $Name email = $Email password = (New-Object PSCredential "user",$Password).GetNetworkCredential().Password language = $Language } if ( -not ( [string]::IsNullOrEmpty($QuickJoinID))) { $Params.custom_quickjoin_id = $QuickJoinID } if ( -not ( [string]::IsNullOrEmpty($QuickSupportID))) { $Params.custom_quicksupport_id = $QuickSupportID } # TODO: Add permission support Write-Verbose -Message ('Running Request URl: "{0}"' -f $RequestUrl) Try { $response = Invoke-RestMethod -Method Post ` -Uri $RequestUrl ` -Headers $script:TVConfig.Header ` -Body ( $Params | ConvertTo-Json ) ` -ContentType 'application/json' ` -ErrorAction SilentlyContinue -ErrorVariable respError # returns 204 on success Write-Verbose -Message "Fetching..." Get-TVUser -Email $Email -Token $Token } catch { Write-Output $_ #$ErrJsonoutWrite-Output $_.ErrorDetails.Message | convertFrom-json #Write-Error -Message $ErrJson.error_description } } } #TODO: User or company access token. Scope: Users.ModifyUsers or Users.ModifyAdministrators. function Set-TVUser { <# .SYNOPSIS Modify an existing Teamviewer user .DESCRIPTION Modify an existing Teamviewer User .PARAMETER Token The Teamviewer API token generated on the Teamviewer Management console (https://login.teamviewer.com) .PARAMETER Identity a TVUser Object fetched by Get-TVUser .PARAMETER UserID The userID of a Teamviewer user .PARAMETER Name The new name of the Teamviewer user .PARAMETER Email The new email address of the Teamviewer user .PARAMETER Permissions a list of Permissions to add to the user account .PARAMETER Active Indicates that the user should be active or not .PARAMETER Password The password for the Teamviewer user .PARAMETER QuickSupportID The QuickSupportID for the Teamviewer user .PARAMETER QuickJoinID The QuickJoinID for the Teamviewer user .EXAMPLE Set-TVUser -Token $Env:TeamViewerToken -UserID 'u123456789' -Name 'Doe, John' Sets the name of user with ID: u123456789 to 'Doe, John' .EXAMPLE Get-TVUser -Token $Env:TeamViewerToken -UserID 'u123456789' | Set-TVUser -Token $Env:TeamViewerToken -Name 'Solo, Han' Changes the name of user with ID: u123456789 to 'Solo, Han' .INPUTS TVUser. The output of the Get-TVUser CmdLet. .OUTPUTS TVUser. The TVUser object that was modified. .LINK Get-TVUser .LINK New-TVUser #> [CmdletBinding( HelpUri = 'http://psteamviewer.readthedocs.io/en/latest/cmdlets/Set-TVUser/' )] [OutputType([TVUser])] param( [Parameter( Mandatory = $false )] [string] $Token = $script:TVConfig.AccessToken, [Parameter( Mandatory = $true, ParameterSetName = 'ByIdentity', ValueFromPipeline = $true)] [ValidateNotNull()] [TVUser] $Identity, [Parameter( Mandatory = $true, ParameterSetName = 'ById')] [string] $UserID, [Parameter( Mandatory = $false )] [ValidateNotNullOrEmpty()] [string] $Name = $null, [Parameter( Mandatory = $false )] [ValidateNotNullOrEmpty()] [string] $Email = $null, [Parameter( Mandatory = $false )] [ValidateNotNullOrEmpty()] [ValidateSet('None', 'ManageAdmins', 'ManageUsers', 'ShareOwnGroups', 'ViewAllConnections', 'ViewOwnConnections', 'EditConnections', 'DeleteConnections', 'EditFullProfile', 'ManagePolicies', 'AssignPolicies', 'AcknowledgeAllAlerts', 'AcknowledgeOwnAlerts', 'ViewAllAssets', 'ViewOwnAssets', 'EditAllCustomModuleConfigs', 'EditOwnCustomModuleConfigs')] [string[]] $Permissions = $null, [Parameter( Mandatory = $false )] [ValidateNotNullOrEmpty()] [securestring] $Password = $null, [Parameter( Mandatory = $false )] [bool] $Active, [Parameter( Mandatory = $false )] [ValidateNotNullOrEmpty()] [string] $QuickJoinID = $null, [Parameter( Mandatory = $false )] [ValidateNotNullOrEmpty()] [string] $QuickSupportID = $null ) begin { # Make sure to have a token if ( [string]::IsNullOrEmpty($Token) ) { throw (New-Object -TypeName System.Exception -ArgumentList $script:TOKEN_MISSING_ERROR) } Write-Verbose -Message ('ParameterSet: {0}' -f $PSCmdlet.ParameterSetName) if ( $PSCmdlet.ParameterSetName -eq 'ById') { $Identity = Get-TVUser -UserID $UserID } } process { [string] $RequestUrl = ('{0}/api/{1}/users/{2}' -f $script:TVConfig.BaseUrl, $script:TVConfig.ApiVersion, $Identity.ID) [hashtable] $Params = @{} if ( -not ( [string]::IsNullOrEmpty($Name))) { $Params.name = $Name } if ( -not ( [string]::IsNullOrEmpty($Password))) { $Params.password = (New-Object PSCredential "user",$Password).GetNetworkCredential().Password } if ( -not ( [string]::IsNullOrEmpty($Email))) { $Params.email = $Email } if ( -not ( [string]::IsNullOrEmpty($QuickJoinID))) { $Params.custom_quickjoin_id = $QuickJoinID } if ( -not ( [string]::IsNullOrEmpty($QuickSupportID))) { $Params.custom_quicksupport_id = $QuickSupportID } if ( $PSBoundParameters.ContainsKey( "Active" ) ) { $Params.active = $Active } if ( $Permissions -ne $null ) { Write-Verbose -Message 'not supported yed' #$Params.permissions = $Permissions -join ',' } Write-Verbose -Message ('Running Request URl: "{0}"' -f $RequestUrl) Try { $response = Invoke-RestMethod -Method Put ` -Uri $RequestUrl ` -Headers $script:TVConfig.Header ` -Body ( $Params | ConvertTo-Json ) ` -ContentType 'application/json' ` -ErrorVariable respError Get-TVUser -UserID $Identity.ID -Token $Token } catch { # Write-Host -Object ('Error: "{0}". - Description: "{1}". - Code: "{2}".' -f $_.error, $response.error_description, $response.error_code) # Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__ # Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription # Write-Host "StatusCode:" ([int]$_.Exception.Response.StatusCode) $ErrJson = $_.ErrorDetails.Message | convertFrom-json Write-Error -Message ('Error: {0}' -f $ErrJson.error_description) #.Message.error_description } } end{} } function Get-TVUser { <# .SYNOPSIS Get Teamviewer user(s) .DESCRIPTION Get the details of one or more users from the Teamviewer management portal .PARAMETER Token The Teamviewer API token .PARAMETER UserID The ID of the user on the Teamviewer portal .PARAMETER Name The name of the user .PARAMETER Email The email address of the user .PARAMETER Permission Permissions assigned to a user .PARAMETER Simple minimize the output of the CmdLet .EXAMPLE Get-TVUser -Token $Env:TeamViewerToken Gets all Teamviewer Users .EXAMPLE Get-TVUser -Token $Env:TeamViewerToken -Name 'John Doe' Gets the user or all users with the name 'John Doe' .EXAMPLE Get-TVUser -Token $Env:TeamViewerToken -Email 'john.doe@domain.com' Gets the user with the specified email address. .INPUTS None. You can't pipe objects to the Get-TVUser CmdLet .OUTPUTS TVUser. a TVUser object or an array of TVUser Objects .NOTES Author: Marco Micozzi .LINK New-TVUSer .LINK Set-TVUser #> [CmdletBinding( HelpUri="http://psteamviewer.readthedocs.io/en/latest/cmdlets/Get-TVUser", PositionalBinding=$false, DefaultParameterSetName='All' )] [OutputType([TVUser[]])] param( [Parameter( Mandatory = $false )] [string] $Token = $script:TVConfig.AccessToken, [Parameter( Mandatory = $true, ParameterSetName = 'ByID' )] [string[]] $UserID, [Parameter( Mandatory = $true, ParameterSetName = 'ByName' )] [string] $Name, [Parameter( Mandatory = $true, ParameterSetName = 'ByEmail' )] [string[]] $Email, [Parameter( Mandatory = $true, ParameterSetName = 'ByPermission' )] [string[]] $Permission, [Parameter( Mandatory = $false )] [switch] $Simple ) begin { # Make sure to have a token if ( [string]::IsNullOrEmpty($Token) ) { throw (New-Object -TypeName System.Exception -ArgumentList $script:TOKEN_MISSING_ERROR) } [hashtable] $RequestBody = @{ full_list = (!$Simple.IsPresent) } [string] $RequestUrl = ('{0}/api/{1}/users' -f $script:TVConfig.BaseUrl, $script:TVConfig.ApiVersion) } process { Write-Debug -Message ('ParameterSetNamer: "{0}".' -f $PSCmdlet.ParameterSetName) switch ($PSCmdlet.ParameterSetName) { 'ByID' { Write-Debug -Message 'Checking by ID' foreach ( $User in $UserID) { Write-Verbose -Message ('Processing ID: "{0}".' -f $User) $Json = Invoke-RestMethod -Uri ('{0}/{1}' -f $RequestUrl, $User) -Headers $script:TVConfig.Header -Body $RequestBody -Method 'Get' Write-Verbose -Message ($Json | ConvertTo-Json) Write-Output -InputObject ( Initialize-TVUserObject -Json $Json ) } } { ( $_ -eq 'ByName' ) -or ( $_ -eq 'ByEmail' ) -or ( $_ -eq 'All') } { Write-Debug -Message 'The received parameters are Name, Email or none' if ( $PSCmdlet.ParameterSetName -eq 'ByName') { Write-Verbose -Message ('Checking by name: "{0}".' -f $Name) $RequestBody.name = $Name } if ( $PSCmdlet.ParameterSetName -eq 'ByEmail') { $RequestBody.email = @{$true = $Email -join ', '; $false = $Email -join ''}[ ($Email.Count -ge 2)] Write-Verbose -Message ('Checking by mail: "{0}".' -f $RequestBody.email ) } Write-Verbose -Message ('Get-TVUser: Processing URL: "{0}".' -f $RequestUrl) $Response = Invoke-RestMethod -Uri $RequestUrl -Headers $script:TVConfig.Header -Body $RequestBody -Method 'Get' Write-Verbose -Message $response $Response.users | ForEach-Object { Write-Verbose -Message $_ Write-Output -InputObject ( Initialize-TVUserObject -Json $_ ) } } 'ByPermission' { throw New-Object -TypeName System.NotImplementedException -ArgumentList 'Search by Permission has not been implemented yet.' } Default { throw New-Object -TypeName System.ArgumentException -ArgumentList ('Unexpected ParameterSet received: "{0}".' -f $PSCmdlet.ParameterSetName) } } } } #endregion Users #region Devices function Set-TVDevice { [CmdletBinding( )] [OutputType([TVDevice])] param( [Parameter( Position = 0 )] [string] $Token = $script:TVConfig.AccessToken, [Parameter( Mandatory = $true, Position = 1, ParameterSetName = 'ByDeviceIDPolicy' )] [Parameter( Mandatory = $true, Position = 1, ParameterSetName = 'ByDeviceIDGroup' )] [string] $DeviceID, [Parameter( Mandatory = $true, Position = 1, ParameterSetName = 'ByInputObjectPolicy' )] [Parameter(Mandatory = $true, Position = 1, ParameterSetName = 'ByInputObjectGroup' )] [ValidateNotNull()] [TVDevice] $InputObject, [Parameter()] [ValidateNotNullOrEmpty()] [string] $Alias, [Parameter()] [ValidateNotNullOrEmpty()] [string] $Description, [Parameter()] [ValidateNotNullOrEmpty()] [string] $Passwd, [Parameter(ParameterSetName = 'ByDeviceIDPolicy')] [Parameter(ParameterSetName = 'ByInputObjectPolicy')] [ValidateNotNullOrEmpty()] [string] $PolicyID, [Parameter(ParameterSetName = 'ByInputObjectGroup')] [Parameter(ParameterSetName = 'ByDeviceIDGroup')] [ValidateNotNullOrEmpty()] [string] $GroupID, [Parameter()] [switch] $PassThru ) begin { # Make sure to have a token if ( [string]::IsNullOrEmpty($Token) ) { throw (New-Object -TypeName System.Exception -ArgumentList $script:TOKEN_MISSING_ERROR) } Write-Verbose -Message ('ParameterSet: {0}' -f $PSCmdlet.ParameterSetName) if ( $PSCmdlet.ParameterSetName -eq 'ById') { $InputObject = Get-TVDevice | Where-Object { $_.DeviceID -eq $DeviceID} } } process { [string] $RequestUrl = ('{0}/api/{1}/devices/{2}' -f $script:TVConfig.BaseUrl, $script:TVConfig.ApiVersion, $InputObject.DeviceID) [hashtable] $Params = @{} if ( -not ( [string]::IsNullOrEmpty($Alias))) { $Params.alias = $Alias } if ( -not ( [string]::IsNullOrEmpty($Description))) { $Params.description = $Description } if ( -not ( [string]::IsNullOrEmpty($Passwd))) { $Params.password = $Passwd } if ( -not ( [string]::IsNullOrEmpty($PolicyID))) { $Params.policy_id = $PolicyID } if ( -not ( [string]::IsNullOrEmpty($GroupID))) { $Params.groupid = $GroupID } Try { Invoke-RestMethod -Method Put ` -Uri $RequestUrl ` -Headers $script:TVConfig.Header ` -Body ( $Params | ConvertTo-Json ) ` -ContentType 'application/json' ` -ErrorVariable respError #Get-TVUser -UserID $Identity.ID -Token $Token } catch { $ErrJson = $_.ErrorDetails.Message | convertFrom-json Write-Error -Message $ErrJson.error_description } } } function Get-TVDevice { <# .SYNOPSIS Get Device information fom the Teamviewer portal .DESCRIPTION Get Device information fom the Teamviewer portal .PARAMETER Token The API token generated on the portal .PARAMETER OnlineState include online or offline devices .PARAMETER GroupID Get all devices of a specific GroupID .PARAMETER RemoteControlID Get the device with a specific RemotecontrolID .EXAMPLE Get-TVDevice -OnlineState Online #> [CmdletBinding( HelpUri = 'http://psteamviewer.readthedocs.io/en/latest/cmdlets/Get-TVDevice/' )] [OutputType([TVDevice[]])] param( [Parameter()] [string] $Token = $script:TVConfig.AccessToken, [Parameter(Mandatory = $false)] [ValidateSet('Online', 'Offline')] [string] $OnlineState = [string]::Empty, [Parameter(Mandatory=$false)] [string] $GroupID = [string]::Empty, [Parameter(Mandatory=$false)] [string] $RemoteControlID = [string]::Empty ) begin { if ( [string]::IsNullOrEmpty($Token) ) { throw (New-Object -TypeName System.Exception -ArgumentList $script:TOKEN_MISSING_ERROR) } [string] $RequestUrl = ('{0}/api/{1}/devices' -f $script:TVConfig.BaseUrl, $script:TVConfig.ApiVersion) [hashtable] $RequestBody = @{} } process { if ( ! ( [string]::IsNullOrEmpty($OnlineState))) { $RequestBody.online_state = $OnlineState } if ( ! ( [string]::IsNullOrEmpty($GroupID))) { $RequestBody.groupid = $GroupID } if ( ! ( [string]::IsNullOrEmpty($RemoteControlID ) ) ) { $RequestBody.remotecontrol_id = $RemoteControlID } $Response = Invoke-RestMethod -Uri $RequestUrl -Headers $script:TVConfig.Header -Body $RequestBody $Response.devices | ForEach-Object { [TVDevice] $TVDevice = New-Object -TypeName TVDevice ` -ArgumentList $_.remotecontrol_id, $_.device_id, $_.alias, $_.groupid, $_.online_state, $_.assigned_to, $_.supported_features Write-Output $TVDevice } } } #endregion Devices #region Groups function Remove-TVGroup { <# .SYNOPSIS Remove a Teamviewer group .DESCRIPTION Remove a Teamviewer group .PARAMETER Token The Teamviewer API token generated on the Teamviewer Management console (https://login.teamviewer.com) .PARAMETER InputObject an instance of TVGroup returned by Get-TVGroup .PARAMETER Name The name of the TVGroup to be removed .PARAMETER GroupID The ID of the group to be removed .PARAMETER CompanyUserID The ID of the administrator to remove a company group instead of a user group. .EXAMPLE Remove-TVGroup -Name 'TestGroup' Removes the group "TestGroup" by name .EXAMPLE Get-TVGroup -Name 'TestGroup' | Remove-TVGroup Removes the group 'TestGroup' by InputObject .EXAMPLE Remove-TVGroup -GroupID 'GRP1' Removes the group with GroupID 'GRP1' .INPUTS TVGroup. The objects returned by the Get-TVGroup can be piped to the Remove-TVGroup CmdLet. .OUTPUTS None. This CmdLet doesn't produce any output .NOTES Author: Marco Micozzi .LINK Get-TVGroup .LINK New-TVGroup #> [CmdletBinding( SupportsShouldProcess=$true )] param( [Parameter()] [string] $Token = $script:TVConfig.AccessToken, [Parameter( Mandatory=$true, ValueFromPipeline = $true, ParameterSetName = 'ByInputObject' )] [ValidateNotNull()] [TVGroup] $InputObject, [Parameter( Mandatory=$true, HelpMessage = 'The name of the group to delete.', ParameterSetName = 'ByName' )] [string] $Name, [Parameter( Mandatory = $true, HelpMessage = 'The Group ID of the group to delete.', ParameterSetName = 'ByID' )] [string] $GroupID, [Parameter()] [string] $CompanyUserID = [string]::Empty ) begin{ # Check token if ( [string]::IsNullOrEmpty($Token) ) { throw (New-Object -TypeName System.Exception -ArgumentList $script:TOKEN_MISSING_ERROR) } [string] $AdminParam = @{$true=('/users/{0}' -f $CompanyUserID);$false=[string]::Empty}[(!( [string]::IsNullOrEmpty($CompanyUserID)))] [string] $RequestUrl = ('{0}/api/{1}{2}/groups' -f $script:TVConfig.BaseUrl, $script:TVConfig.ApiVersion, $AdminParam) } process{ switch ($PSCmdlet.ParameterSetName) { 'ByName' { $InputObject = Get-TVGroup -Name $Name } 'ByInputObject' {} 'ByID' { $InputObject = Get-TVGroup | Where-Object { $_.ID -eq $GroupID } } Default {} } if(!($InputObject)){ throw 'Invalid groupname received.' } $RequestUrl += ('/{0}' -f $InputObject.ID) Write-Verbose -Message ('Processing RequestURL: {0}' -f $RequestUrl) Try{ if ( $PSCmdlet.ShouldProcess($InputObject.Name, 'Remove Group') ){ $Response = Invoke-RestMethod -Method Delete ` -Uri $RequestUrl ` -Headers $script:TVConfig.Header ` -ContentType 'application/json' ` -ErrorAction SilentlyContinue -ErrorVariable respError return ( (Get-TVGroup -Token $Token -Name $InputObject.Name) -eq $null ) } } catch{ Write-Host $_ $ErrJson = $_ | convertFrom-json Write-Error -Message ("err: {0}" -f $ErrJson.message ) return $false } } } function New-TVGroup { <# .SYNOPSIS Create a new TeamViewer Group .DESCRIPTION Create a new TeamViewer Group .PARAMETER Token The Teamviewer API token generated on the Teamviewer Management console (https://login.teamviewer.com) .PARAMETER Name The name of the new group .PARAMETER CompanyUserID Administrator user ID .EXAMPLE New-TVGroup -Token $env:TeamviewerToken -Name 'MyTestGroup' Creates the group MyTestGroup .INPUTS None. You cannot pipe objects to New-TVGroup .OUTPUTS TVGroup. New-TVGroup will return the newly created TVGroup object .NOTES Author: Marco Micozzi .LINK Get-TVGroup .LINK Remove-TVGroup #> [CmdletBinding( HelpUri = 'http://psteamviewer.readthedocs.io/en/latest/cmdlets/New-TVGroup/' )] [OutputType([TVGroup])] param( [Parameter()] [string] $Token = $script:TVConfig.AccessToken, [Parameter(Mandatory=$true, HelpMessage = 'The name of the group to create.')] [string[]] $Name, [Parameter()] [string] $CompanyUserID = [string]::Empty ) begin{ # Make sure to have a token if ( [string]::IsNullOrEmpty($Token) ) { throw (New-Object -TypeName System.Exception -ArgumentList $script:TOKEN_MISSING_ERROR) } [string] $AdminParam = @{$true=('/users/{0}' -f $CompanyUserID);$false=[string]::Empty}[(!( [string]::IsNullOrEmpty($CompanyUserID)))] [string] $RequestUrl = ('{0}/api/{1}{2}/groups' -f $script:TVConfig.BaseUrl, $script:TVConfig.ApiVersion, $AdminParam) Write-Verbose -Message ('Processing RequestURL: {0}' -f $RequestUrl) } process { foreach ( $GroupName in $Name) { [hashtable] $Params = @{ name = $GroupName # policy_id = '' } Try{ $response = Invoke-RestMethod -Method Post ` -Uri $RequestUrl ` -Headers $script:TVConfig.Header ` -Body ( $Params | ConvertTo-Json ) ` -ContentType 'application/json' ` -ErrorAction SilentlyContinue -ErrorVariable respError Get-TVGroup -Name $response.name -Token $Token } catch{ } } } } function Get-TVGroup { <# .SYNOPSIS Get TeamViewer group information .DESCRIPTION Get information about a teamviewer group via the API .PARAMETER Token The Teamviewer API token generated on the Teamviewer Management console (https://login.teamviewer.com) .PARAMETER Name The name of the group to fetch .PARAMETER Shared Wether or not to list shared groups. .PARAMETER CompanyUserID The admin ID .EXAMPLE Get-TVGroup -Token $Env:TeamViewerToken Get all Teamviewer groups .EXAMPLE Get-TVGroup -Token $ENV:TeamviewerToken -Name "TestGrp" Get a group with the name 'TestGrp' .NOTES Author: Marco Micozzi .LINK New-TVGroup .LINK Remove-TVGroup #> [CmdletBinding( HelpUri = 'http://psteamviewer.readthedocs.io/en/latest/cmdlets/Get-TVGroup/' )] [OutputType([TVGroup])] param( [Parameter()] [string] $Token = $script:TVConfig.AccessToken, [Parameter()] [string] $Name, [Parameter()] [bool] $Shared, [Parameter(Mandatory = $false)] [string] $CompanyUserID = [string]::Empty ) begin { # Make sure to have a token if ( [string]::IsNullOrEmpty($Token) ) { throw (New-Object -TypeName System.Exception -ArgumentList $script:TOKEN_MISSING_ERROR) } [string] $AdminParam = @{$true=('/users/{0}' -f $CompanyUserID);$false=[string]::Empty}[(!( [string]::IsNullOrEmpty($CompanyUserID)))] [string] $RequestUrl = ('{0}/api/{1}{2}/groups' -f $script:TVConfig.BaseUrl, $script:TVConfig.ApiVersion, $AdminParam) Write-Verbose -Message ('Processing RequestURL: {0}' -f $RequestUrl) } process { [hashtable] $Params = @{} if ( -not ( [string]::IsNullOrEmpty($Name))) { $Params.name = $Name } if ( $PSBoundParameters.ContainsKey( "Shared" ) ) { $Params.shared = $Shared } # Fetch the groups from the API $Response = Invoke-RestMethod -Uri $RequestUrl -Headers $script:TVConfig.Header -Body $Params -ErrorVariable RestError -ErrorAction SilentlyContinue $RestError # Iterate over the groups $Response.groups | ForEach-Object { $CurrentGroup = $_ [TVGroupUser[]] $SharedWith = @() #Write-Verbose -Message ('not Shared?: "{0}".' -f [string]::IsNullOrEmpty($CurrentGroup.shared_with)) # Make sure that the group is shared first if ( -not ( [string]::IsNullOrEmpty($CurrentGroup.shared_with)) ) { $CurrentGroup.shared_with | ForEach-Object { [TVGroupUser] $CurrentUser = New-Object -TypeName TVGroupUser -ArgumentList $_.userid, $_.name, $_.permissions, $_.pending $SharedWith += $CurrentUser } } [TVUserBase] $Owner = $null if ($CurrentGroup.owner -ne $null) { $Owner = New-Object -TypeName TVUserBase -ArgumentList $CurrentGroup.owner.userid, $CurrentGroup.owner.name } [TVGroup] $Group = New-Object -TypeName TVGroup -ArgumentList $CurrentGroup.ID, $CurrentGroup.Name, $Owner, $CurrentGroup.permissions, $SharedWith Write-Output -InputObject $Group } } end {} } #endregion Groups #region Local function Get-TVClientID{ <# .SYNOPSIS Get the clientID from one or more (remote) computers .DESCRIPTION Retreives the CLientID registry value from one or more computers in the same LAN. .PARAMETER ComputerName The name(s) of the computer(s) to fetch the ClientID from. .EXAMPLE Get-TVClientID -ComputerName MarcoPC01 Retreives the ClientID from the computer MarcoPC01 in the current LAN .NOTES This CmdLet will only work on computers in the same LAN. A Test-Connection will check if the remote computer(s) is/are available. Remote Registry has to be enabled to make this work. Author: Marco Micozzi #> #TODO: Test the Get-TVClientID CmdLet [CmdLetBinding()] param( [Parameter( Mandatory = $false )] [string[]] $ComputerName = $env:COMPUTERNAME ) begin { [string] $KeyPath = 'SOFTWARE\\WOW6432Node\\TeamViewer' } process { foreach ( $Computer in $ComputerName ) { if ( Test-Connection -ComputerName $Computer -Count 1 -Quiet ) { [Microsoft.Win32.RegistryKey] $HKEY_LM = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer) [Microsoft.Win32.RegistryKey] $TeamViewerKey = $HKEY_LM.OpenSubKey($KeyPath) if ( $TeamViewerKey -ne $null ) { [hashtable] $Properties = @{ ComputerName = $Computer ClientID = $TeamViewerKey.GetValue('ClientID') } New-Object -TypeName PSObject -Property $Properties } else { Write-Error -Message ('The key: "HKLM:\{0}" was not found on computer: "{1}"!' -f $KeyPath, $Computer) } } else { Write-Error -Message ('The computer: "{0}" is offline!' -f $Computer) } } } } function Get-TVInstallDir { <# Get-Package -ProviderName Programs | Where-Object {$_.Name -like 'TeamViewer*'} #> [CmdletBinding()] param() $ProgramFilesX86 = @{$true=${env:ProgramFiles(x86)};$false=$env:ProgramFiles}[(${env:ProgramFiles(x86)} -ne $null)] "$ProgramFilesX86\TeamViewer\TeamViewer.exe" | ForEach-Object { if ( Test-Path -Path $_ ) { return $_ } else { return $null } } } function Start-TVRemoteControl { <# .SYNOPSIS Start a remote control session. .DESCRIPTION Start a remote control session. .PARAMETER RemoteControlID The remote control ID of a computer .PARAMETER InputObject The TVDevice Object returned by the Get-TVDevice CmdLet .PARAMETER Password The password to connect to this computer. .PARAMETER Mode The mode to connect to the remote computer. Defaults to 'Remote Control' if omitted. Valid values are 'vpn' or 'FileTransfer' .EXAMPLE Start-TVRemoteControl -RemoteControlID 'abc123' Starts a session to the device with remotecontrol ID abc123 and prompts for a password .EXAMPLE Get-TVDevice | Where-Object {$_.Alias -eq 'PC0001'} | Start-TVRemoteControl Start a remote control session to the computer with name PC0001 .NOTES Author: Marco Micozzi #> [CmdletBinding()] param( [Parameter( Mandatory = $true, ParameterSetName = 'ByRemoteControlID' )] [ValidateNotNullOrEmpty()] [string] $RemoteControlID, [Parameter( Mandatory = $true, ParameterSetName = 'ByInputObject' )] [ValidateNotNull()] [TVDevice] $InputObject, [Parameter( Mandatory = $false )] [securestring] $Password = $Null, [Parameter( Mandatory = $false )] [ValidateSet("FileTransfer", "vpn")] [ValidateNotNullOrEmpty()] [string] $Mode = $null ) $InstallDir = Get-TVInstallDir # Make sure Teamviewer is installed if ( $InstallDir -ne $null ) { # If the TVDevice was passed as an argument, get the RemoteControlID value. if ( $PSCmdlet.ParameterSetName -eq 'ByInputObject') { $RemoteControlID = $InputObject.RemoteControlID } # Create the argument string [string] $Arguments = ('-i {0}' -f $RemoteControlID) # Add the password if supplied if ( -not ( [string]::IsNullOrEmpty($Password))) { $Arguments += (' -P {0}' -f (New-Object PSCredential "user",$Password).GetNetworkCredential().Password) } # add the mode if supplied if ( -not ( [string]::IsNullOrEmpty($Mode))) { $Arguments += (' -m {0}' -f $Mode) } # Start the session Start-Process -FilePath $InstallDir -ArgumentList $Arguments # not sure about this one... #Invoke-WebRequest -Uri ('https://start.teamviewer.com/device/{0}' -f $RemoteControlID) } } #endregion |