Public/Invoke-SpecTeamViewerConfig.ps1

function Invoke-specTeamViewerConfig {

    # Requires -Modules @{ ModuleName="spec.azure.tables"; ModuleVersion="1.0.4" }
    # Requires -Modules @{ ModuleName="spec.base.utilities"; ModuleVersion="1.1.7" }

    <#
        .SYNOPSIS
            Configures TeamViewer groups dynamically based on the detected device persona and Azure table data.
 
        .DESCRIPTION
            The Invoke-specTeamViewerConfig function automates TeamViewer configuration by assigning devices to specific groups
            based on the detected device persona. It first detects the device persona by extracting the prefix from the computer name
            (the part before the '-'). It then looks up the relevant group information from the specified Azure table. After obtaining
            the required groups, the function queries the TeamViewer API to retrieve all available groups and matches them with the
            required groups. It adds the device identified by its Management ID to the corresponding groups in TeamViewer.
 
        .PARAMETER MachineName
            Specifies the name of the machine. Default value is the local computer's name ($env:COMPUTERNAME).
 
        .PARAMETER TableName
            Specifies the name of the Azure table containing the device persona and associated groups. This parameter is mandatory.
 
        .PARAMETER StorageAccount
            Specifies the Azure Storage Account containing the Azure table. This parameter is mandatory.
 
        .PARAMETER SASToken
            Specifies the Shared Access Signature (SAS) token for authenticating access to the Azure Storage Account. This parameter is mandatory.
 
        .PARAMETER TVAPIKey
            Specifies the TeamViewer API key for authentication. This parameter is mandatory.
 
        .EXAMPLE
            Invoke-specTeamViewerConfig -TableName "DeviceGroupsTable" -StorageAccount "YourAzureStorageAccount" -SASToken "YourSASToken" -TVAPIKey "YourTeamViewerAPIKey"
            Configures TeamViewer groups dynamically based on the device persona detected from the machine name and the specified Azure table data.
 
        .NOTES
            Author : owen.heaume
            Version : 1.0
 
        #>



    [cmdletbinding()]

    param (
        [parameter (mandatory = $false)]
        [string]$MachineName = $env:COMPUTERNAME,

        [parameter (mandatory = $true)]
        [string]$TableName,

        [parameter (mandatory = $true)]
        [string]$StorageAccount,

        [parameter (mandatory = $true)]
        [string]$SASToken,

        [parameter (mandatory = $true)]
        [string]$TVAPIKey
    )

    Write-specLogMessage "Detecting computer name" -Colour Darkcyan
    Write-specLogMessage "$machineName`n" -Colour DarkGreen

    # Determine the device persona based on the machine name prefix (the part before the '-' in the computer name)
    # The prefix will be used to lookup the relevant group info from the Azure table
    Write-specLogMessage "Determining the device persona" -Colour DarkCyan

    $persona = Get-specComputerNamePrefix -ComputerName $MachineName

    if ($persona -eq 1) {
        Write-specLogMessage "Computername does not contain a - in the hostname. Will not be able to detetermine persona so script will exit" -Colour DarkYellow -DoNotUseWriteHost
        throw "Computername does not contain a - in the hostname. Will not be able to detetermine persona so script will exit"
    } else {
        Write-specLogMessage "$persona`n" -Colour DarkGreen
    }

    # Get the row data from the Azure table
    $params = @{
        value          = $persona
        Key            = 'RowKey'
        tableName      = $TableName
        StorageAccount = $StorageAccount
        SASToken       = $SasToken
    }

    Write-specLogMessage "Getting data from Azure table [$TableName]" -Colour Darkcyan
    $tblResult = Get-SpecAzTableRowUsingSAS @params

    # If there is no data returned, then it means that there is no matching persona found under RowKey in the Azure table
    if ($null -eq $tblResult) {
        Write-specLogMessage "No matching persona found in the Azure table. This machines persona is [$persona]. Script will now exit." -DoNotUseWriteHost
        throw "No matching persona found in the Azure table. This machines persona is [$persona]. Script will now exit."
    }

    #Convert the groups string to an array for processing
    $requiredGroups = $tblResult.groups -split ','

    Write-specLogMessage "Found assigned required groups based on persona: $($requiredGroups -join ', ')`n" -Colour DarkGreen

    # Fetch all managed groups
    Write-specLogMessage "Querying Team Viewer API to get all groups" -Colour DarkCyan
    $allGroups = Get-specAllTVGroups -APIKey $TVAPIKey

    if ($allGroups -eq 1) {
        Write-specLogMessage "Failed to retrieve all groups from TeamViewer. Script will now exit." -DoNotUseWriteHost
        throw "Failed to retrieve all groups from TeamViewer. Script will now exit."
    }
    Write-specLogMessage "OK - got the groups`n" -Colour DarkGreen


    # Match the required groups with their IDs
    $groupIDsToAdd = $requiredGroups | ForEach-Object {
        $groupName = $_
        ($allGroups.resources | Where-Object { $_.name -eq $groupName }).id
    }

    # Add the device to each group
    Write-specLogMessage "Querying registry for ManagementID" -Colour DarkCyan

    if ([Environment]::Is64BitOperatingSystem) {
        Write-specLogMessage "This is a 64-bit device" -Colour DarkGray
        Write-specLogMessage "Querying [HKLM:\SOFTWARE\TeamViewer\DeviceManagementV2]" -Colour DarkGray
        $RegistryPath = "HKLM:\SOFTWARE\TeamViewer\DeviceManagementV2"
    } else {
        Write-specLogMessage "This is a 32-bit device" -Colour DarkGray
        Write-specLogMessage "Querying [HKLM:\SOFTWARE\WOW6432Node\TeamViewer\DeviceManagementV2]" -Colour DarkGray
        $RegistryPath = "HKLM:\SOFTWARE\WOW6432Node\TeamViewer\DeviceManagementV2"
    }

    $managementID = Get-specRegistryValue -RegistryPath $RegistryPath

    # Check if $managementID is null or empty
    if ($managementID -eq 1) {
        throw "ManagementId not found in the registry, or is empty. Exiting script."
    }

    # Sanitize the ManagementId by removing curly braces
    $managementID = $managementID -replace '[{}]', ''

    # Log the retrieved $managementID
    Write-specLogMessage "Retrieved: $managementID`n" -Colour DarkGreen

    foreach ($groupID in $groupIDsToAdd) {
        Write-specLogMessage "Processing management ID: [$managementID]" -Colour DarkCyan

        $addResult = Add-specComputerToTVGroup -GroupID $groupID -ManagementID $managementID -APIKey $TVAPIKey

        if ($addResult -eq 1) {
            Write-specLogMessage "Failed to add device to group with ID [$groupID]" -DoNotUseWriteHost
            throw "Failed to add device to group with ID [$groupID]"
        }

        Write-specLogMessage "Added device to group with ID: $groupID`n" -Colour DarkGreen

    }

    Write-specLogMessage "Device addition to groups completed" -Colour DarkGray
}