MyPSFunctions.Teams.ps1

<#
    ===========================================================================
     Created with: SAPIEN Technologies, Inc., PowerShell Studio 2021 v5.8.196
     Created on: 10/26/2023 7:16 PM
     Created by: John@MyPSFunctions.com
     Organization: MyPSFunctions
     Filename: MyPSFunctions.Teams.psm1
    -------------------------------------------------------------------------
     Module Name: MyPSFunctions.Teams
    ===========================================================================
#>

Function Assign-SingleTeamsAppPermissionPolicyUsingCSVFile
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $true,
                   Position = 2)]
        [String]$CSVFile
    )
    # List all Teams App Permission Policies
    Try
    {
        Write-Log warning -Message "The script is trying to find all Teams App Permission Policies"
        $AppPermissionPolicies = Get-CsTeamsAppPermissionPolicy
        Write-Log Info -Message "The script found all Teams App Permission Policies"
    }
    Catch
    {
        $ErrorMessage = $Error[0].Exception.Message
        $CMDLet = $Error[0].InvocationInfo.Line
        $FailedItem = $Error[0].Exception.ItemName
        Write-Log Error -Message "Failed to find all Teams App Permission Policies"
        Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet"
        Write-Log Error -Message "Failed with Error:$ErrorMessage"
        Read-Host "End of the Script"
        Exit
    }
    
    $SelectedAppPermissionPolicy = $AppPermissionPolicies | Select Identity, Description | Out-GridView -PassThru -Title "Select One App Permission Policy"
    $SelectedAppPermissionPolicy = ($SelectedAppPermissionPolicy.Identity).substring(4)
    #Import CSVFile
    Try
    {
        Write-Log warning -Message "The script is expected the CSV column Name :EmailAddress"
        Write-Log warning -Message "The script will try to import $CSVFile"
        $Users = Import-Csv $CSVFile
        Write-Log Info -Message "The script imported $CSVFile"
    }
    Catch
    {
        $ErrorMessage = $Error[0].Exception.Message
        $CMDLet = $Error[0].InvocationInfo.Line
        $FailedItem = $Error[0].Exception.ItemName
        Write-Log Error -Message "Failed to import $CSVFile"
        Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet"
        Write-Log Error -Message "Failed with Error:$ErrorMessage"
        Read-Host "End of the Script"
        Exit
    }
    
    #Assign Selected App Permission Policy
    [Int]$i = 1
    $Count = ($Users | Measure).count
    #Initiate the Hash Table
    $Table = $Null
    $Table = @()
    foreach ($User in $Users)
    {
        $Mail = $Null
        $Mailbox = $Null
        $WindowsLiveID = $Null
        $FoundMailbox = "Not Found"
        $GrantTeamsAppPermissionsPolicy = "Not Assigned"
        $Mail = $User.EmailAddress
        Write-Log warning -Message "Try to Assign $SelectedAppPermissionPolicy to $Mail --- $i/$Count"
        # Search for Mailbox
        Try
        {
            Write-Log warning -Message "The script is searching for $Mail"
            $Mailbox = Get-mailbox $Mail
            $WindowsLiveID = $Mailbox.WindowsLiveID
            Write-Log Info -Message "The script found $Mail"
            $FoundMailbox = "Yes"
            Try
            {
                Write-Log warning -Message "The script is trying to assign Teams App Permission Policy $SelectedAppPermissionPolicy To $Mail ($WindowsLiveID)"
                Grant-CsTeamsAppPermissionPolicy -Identity $WindowsLiveID -PolicyName $SelectedAppPermissionPolicy
                Write-Log Info -Message "The script assigned Teams App Permission Policy $SelectedAppPermissionPolicy To $Mail ($WindowsLiveID)"
                $GrantTeamsAppPermissionsPolicy = "Yes"
            }
            Catch
            {
                $ErrorMessage = $Error[0].Exception.Message
                $CMDLet = $Error[0].InvocationInfo.Line
                $FailedItem = $Error[0].Exception.ItemName
                Write-Log Error -Message "Failed to assign Teams App Permission Policy $SelectedAppPermissionPolicy To $Mail ($WindowsLiveID)"
                Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet"
                Write-Log Error -Message "Failed with Error:$ErrorMessage"
                $GrantTeamsAppPermissionsPolicy = "No - Failed with Error:$ErrorMessage"
            }
            
        }
        Catch
        {
            $ErrorMessage = $Error[0].Exception.Message
            $CMDLet = $Error[0].InvocationInfo.Line
            $FailedItem = $Error[0].Exception.ItemName
            Write-Log Error -Message "Failed to found $Mail"
            Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet"
            Write-Log Error -Message "Failed with Error:$ErrorMessage"
            $FoundMailbox = "No - Failed with Error:$ErrorMessage"
        }
        
        $Table += New-object PSobject -Property ([Ordered] @{
                Mail                           = $Mail;
                WindowsLiveID                   = $WindowsLiveID;
                SelectedAppPermissionPolicy    = $SelectedAppPermissionPolicy;
                FoundMailbox                   = $FoundMailbox;
                GrantTeamsAppPermissionsPolicy = $GrantTeamsAppPermissionsPolicy;
            })
        
        $i++
        
    }
    
    $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss"
    $ReportFilexlsx = ".\Report_TeamsAppPermissionPolicyAssignment_" + $DateFull + ".xlsx"
    $Table | Export-Excel $ReportFilexlsx -TableName "TeamsAppPermissionPolicyAssignment" -Title "Teams App Permission Policy Assignment" -TitleBold -WorksheetName "TeamsAppPermissionPolicyAssignment" -TableStyle Medium9 -AutoSize -AutoFilter
    Write-log INFO -Message "Generate the following Report: $ReportFilexlsx"
}

Function Enable-Office365GroupForTeams
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $true,
                   Position = 1)]
        [String]$EmailAddress
    )
    
    Try
    {
        $Office365Group = Get-UnifiedGroup -Identity $EmailAddress
        $Office365GroupExternalID = $Office365Group.ExternalDirectoryObjectId
        $Office365GroupDisplayName = $Office365Group.DisplayName
        Try
        {
            New-Team -GroupId $Office365GroupExternalID
            Write-Log -Level Info -Message "Office 365 Group $Office365GroupDisplayName ($EmailAddress) is enabled for Teams"    
            
        }
        Catch
        {
            $ErrorMessage = $Error[0].Exception.Message
            Write-Log -Level Error -Message "Failed to enable the Office 365 Group $Office365GroupDisplayName ($EmailAddress) for Teams with Error:$ErrorMessage"
        }
    }
    Catch
    {
        $ErrorMessage = $Error[0].Exception.Message
        $CMDLet = $Error[0].InvocationInfo.Line
        $FailedItem = $Error[0].Exception.ItemName
        Write-Log -Level Error -Message "Failed to Find the Office 365 Group with error: $ErrorMessage"
    }
    
    
    
}

Function Migrate-SkypeToTeamsMigrationBatch
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $true,
                   Position = 1)]
        [string]$TxtInputFile
    )
    $users_ids = Get-Content $TxtInputFile
    $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss"
    $OperationName = "MigrationBatch_" + $DateFull
    
    New-CsBatchPolicyAssignmentOperation -PolicyType TeamsUpgradePolicy -PolicyName UpgradeToTeams -Identity $users_ids -OperationName $OperationName
    sleep 5
    Get-CsBatchPolicyAssignmentOperation | where { $_.OperationName -eq $OperationName }
    
}

Function Check-SkypeToTeamsMigrationBatchStatus
{
    param
    (
        [Parameter(Mandatory = $true,
                   Position = 1)]
        [String]$MigrationBatchName
    )
    
    $MigrationBatches = Get-CsBatchPolicyAssignmentOperation | where { $_.OperationName -eq $OperationName }
    $MigrationBatchID = $MigrationBatches[0].OperationID
    $MigratedUsers = Get-CsBatchPolicyAssignmentOperation -Identity $MigrationBatchID | select -ExpandProperty UserState
    $MigratedUsers | group state | ft Count, Name
    $Response = Read-Host "Do you want to display the full List of Users? Press <Y>"
    If ($Response -eq "Y")
    {
        $MigratedUsers | ft
    }
}

Function Clear-TeamsCacheFolder
{
    [CmdletBinding()]
    param ()
    
    #Source:
    # From <https://commsverse.blog/2018/09/28/clear-the-microsoft-teams-client-cache/>
    # https://answers.microsoft.com/en-us/msoffice/forum/msoffice_other-mso_win10-mso_o365b/microsoft-teams-wont-open/24fcab1e-7c75-4f3e-9fd6-42c1ccb6004d#:~:text=the%20following%20steps.-, 1., and%20fully%20kill%20the%20process.&text=Once%20finally%20done%20clearing%2C%20you, check%20if%20the%20issue%20disappears.
    # Kill Teams Process
    $TeamsProcesses = get-process | where { $_.ProcessName -like "*Teams*" }
    $TeamsProcesses | foreach { Stop-Process $_.Id -ErrorAction SilentlyContinue | Out-Null }
    # Go to %appdata%\Microsoft\teams
    $TeamsAppData = $env:APPDATA + "\Microsoft\teams\"
    
    # Clear Folder: %appdata%\Microsoft\teams\application cache\cache"
    $TeamsAppDataAppCache = $TeamsAppData + "application cache\cache"
    Get-ChildItem -Path $TeamsAppDataAppCache -Recurse -ErrorAction SilentlyContinue | Remove-Item -Confirm:$false -Recurse | Out-Null
    
    # Clear Folder: %appdata%\Microsoft\teams\blob_storage
    $TeamsAppDataBlob_storage = $TeamsAppData + "blob_storage"
    Get-ChildItem -Path $TeamsAppDataBlob_storage -Recurse -ErrorAction SilentlyContinue | Remove-Item -Confirm:$false -Recurse | Out-Null
    
    # Clear Folder: %appdata%\Microsoft\teams\Cache
    $TeamsAppDataCache = $TeamsAppData + "Cache"
    Get-ChildItem -Path $TeamsAppDataCache -Recurse -ErrorAction SilentlyContinue | Remove-Item -Confirm:$false -Recurse | Out-Null
    # Clear Folder: %appdata%\Microsoft\teams\databases
    $TeamsAppDataDatabases = $TeamsAppData + "databases"
    Get-ChildItem -Path $TeamsAppDataDatabases -Recurse -ErrorAction SilentlyContinue | Remove-Item -Confirm:$false -Recurse | Out-Null
    # Clear Folder: %appdata%\Microsoft\teams\GPUcache
    $TeamsAppDataGPUcache = $TeamsAppData + "GPUcache"
    Get-ChildItem -Path $TeamsAppDataGPUcache -Recurse -ErrorAction SilentlyContinue | Remove-Item -Confirm:$false -Recurse | Out-Null
    # Clear Folder: %appdata%\Microsoft\teams\IndexedDB
    $TeamsAppDataIndexedDB = $TeamsAppData + "IndexedDB"
    Get-ChildItem -Path $TeamsAppDataIndexedDB -Recurse -ErrorAction SilentlyContinue | Remove-Item -Confirm:$false -Recurse | Out-Null
    # Clear Folder: %appdata%\Microsoft\teams\Local Storage
    $TeamsAppDataLocalStorage = $TeamsAppData + "Local Storage"
    Get-ChildItem -Path $TeamsAppDataLocalStorage -Recurse -ErrorAction SilentlyContinue | Remove-Item -Confirm:$false -Recurse | Out-Null
    # Clear Folder: %appdata%\Microsoft\teams\tmp
    $TeamsAppDataTmp = $TeamsAppData + "tmp"
    Get-ChildItem -Path $TeamsAppDataTmp -Recurse -ErrorAction SilentlyContinue | Remove-Item -Confirm:$false -Recurse | Out-Null
}

Function Get-Detailed_CSOnlineUsers_Report
{
    
    [Int]$i = 1
    $Table = $Null
    $Table = @()
    
    $CSOnlineUsers = Get-CsOnlineUser -ResultSize unlimited
    $Count = ($CSOnlineUsers | Measure).count
    ForEach ($CSOnlineUser in $CSOnlineUsers)
    {
        $CS_UserPrincipalName = $Null
        $CS_UserPrincipalName = $CSOnlineUser.UserPrincipalName
        $SIPAddress = $Null
        $SIPAddress = $CSOnlineUser.SIPAddress
        $SIPAddress = $SIPAddress.SubString(4)
        $DisplayName = $Null
        $DisplayName = $CSOnlineUser.DisplayName
        $LineURI = $Null
        $LineURI = $CSOnlineUser.LineURI
        $HostingProvider = $Null
        $HostingProvider = $CSOnlineUser.HostingProvider
        $TeamsUpgradeEffectiveMode = $Null
        $TeamsUpgradeEffectiveMode = $CSOnlineUser.TeamsUpgradeEffectiveMode
        Write-Log -Level Warning -message "The script is analyzing $DisplayName ($CS_UserPrincipalName)….. --- $i/$Count"
        $Recipient = Get-Recipient $CS_UserPrincipalName
        $UserPrincipalName = $Null
        $UserPrincipalName = $Recipient.WindowsLiveID
        $PrimarySmtpAddress = $Null
        $PrimarySmtpAddress = $Recipient.PrimarySmtpAddress
        $City = $Null
        $City = $Recipient.City
        $Department = $Null
        $Department = $Recipient.Department
        $FirstName = $Null
        $FirstName = $Recipient.FirstName
        $LastName = $Null
        $LastName = $Recipient.LastName
        $Office = $Null
        $Office = $Recipient.Office
        $Title = $Null
        $Title = $Recipient.Title
        $CustomAttribute5 = $Null
        $CustomAttribute5 = $Recipient.CustomAttribute5
        $CustomAttribute7 = $Null
        $CustomAttribute7 = $Recipient.CustomAttribute7
        $CustomAttribute13 = $Null
        $CustomAttribute13 = $Recipient.CustomAttribute13
        $CustomAttribute14 = $Null
        $CustomAttribute14 = $Recipient.CustomAttribute14
        $CustomAttribute15 = $Null
        $CustomAttribute15 = $Recipient.CustomAttribute15
        $Table += New-object PSobject -Property ([Ordered] @{
            FirstName = $FirstName;
            LastName = $LastName;
            DisplayName = $DisplayName;
            CS_UserPrincipalName = $CS_UserPrincipalName;
            UserPrincipalName = $UserPrincipalName;
            PrimarySmtpAddress = $PrimarySmtpAddress;
            SIPAddress = $SIPAddress;
            LineURI = $LineURI;
            HostingProvider = $HostingProvider;
            TeamsUpgradeEffectiveMode = $TeamsUpgradeEffectiveMode;
            Department = $Department;
            City = $City;
            Office = $Office;
            Title = $Title;
            CustomAttribute5 = $CustomAttribute5;
            CustomAttribute7 = $CustomAttribute7;
            CustomAttribute13 = $CustomAttribute13;
            CustomAttribute14 = $CustomAttribute14;
            CustomAttribute15 = $CustomAttribute15;
        })
        $i++
    }
    
    $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss"
    $ReportFile = ".\Report_Detailed_CSOnlineUsers_" + $DateFull + ".xlsx"
    $Table | Export-Excel $ReportFile -TableName "CSOnlineUsers" -Title "CSOnlineUsers" -TitleBold -WorksheetName "CSOnlineUsers" -TableStyle Medium9 -AutoSize -AutoFilter
    Write-log INFO -Message "Generate the following Report: $ReportFile"
}