Public/Functions/Session/Skype/Enable-CsOnlineSessionForReconnection.ps1
# Module: TeamsFunctions # Function: Session # Author: Andrés Gorzelany # Updated: 19-JAN-2021 # Status: Live function Enable-CsOnlineSessionForReconnection { <# .SYNOPSIS Enables the Skype Online Session to reconnect .DESCRIPTION Enables the Skype Online Session to reconnect .EXAMPLE Enable-CsOnlineSessionForReconnection Enables the Skype Online Session to reconnect .INPUTS System.Void .OUTPUTS System.Void .NOTES With special thanks to Andres for providing the code for this wonderful command .COMPONENT Session .ROLE Session Reconnection .FUNCTIONALITY Enables the Skype Online Session to reconnect .LINK https://github.com/DEberhardt/TeamsFunctions/tree/master/docs/ .LINK about_TeamsSession .LINK Enable-CsOnlineSessionForReconnection .LINK Connect-SkypeOnline #> [CmdletBinding()] param() #param begin { Show-FunctionStatus -Level Live #Write-Verbose -Message "[BEGIN ] $($MyInvocation.MyCommand)" } #begin process { $global:CsOnlineSessionInputParams = $UserCredential $modules = Get-Module tmp_* $csModuleUrl = '/OcsPowershellOAuth' $isSfbPsModuleFound = $false; foreach ($module in $modules) { [string] $moduleUrl = $module.Description [int] $queryStringIndex = $moduleUrl.IndexOf('?') if ($queryStringIndex -gt 0) { $moduleUrl = $moduleUrl.SubString(0, $queryStringIndex) } if ($moduleUrl.Contains($csModuleUrl)) { $isSfbPsModuleFound = $true & $module { ${function:Get-PSImplicitRemotingSession} = ` { param( [Parameter(Mandatory = $true, Position = 0)] [string] $commandName ) if (($null -eq $script:PSSession) -or ($script:PSSession.Runspace.RunspaceStateInfo.State -ne 'Opened')) { Set-PSImplicitRemotingSession ` (& $script:GetPSSession ` -InstanceId $script:PSSession.InstanceId.Guid ` -ErrorAction SilentlyContinue ) } if (($null -ne $script:PSSession) -and ($script:PSSession.Runspace.RunspaceStateInfo.State -eq 'Disconnected')) { # If we are handed a disconnected session, try re-connecting it before creating a new session. Set-PSImplicitRemotingSession ` (& $script:ConnectPSSession ` -Session $script:PSSession ` -ErrorAction SilentlyContinue) } if (($null -eq $script:PSSession) -or ($script:PSSession.Runspace.RunspaceStateInfo.State -ne 'Opened')) { Write-PSImplicitRemotingMessage ('Recreating a new remote powershell session (implicit) for command: "{0}" ...' -f $commandName) if ((Test-Path variable:global:CsOnlineSessionInputParams) -ne $true) { throw 'Unable find input parameters from global scope, will not be able to recreate session' } if ((Test-Path variable:global:CsOnlineSessionRetryAttempt) -ne $true) { $global:CsOnlineSessionRetryAttempt = 1 } else { $global:CsOnlineSessionRetryAttempt = $global:CsOnlineSessionRetryAttempt + 1 } $session = New-CsOnlineSession -Credential @global:CsOnlineSessionInputParams if ($null -ne $session) { Set-PSImplicitRemotingSession -CreatedByModule $true -PSSession $session } #note - this magic string has to be same as above, search for this string above, it will become clear #because this will be in callback handler, I am not putting this into const variable #$sfbPsSessionPrefix = 'SfBPowerShellSession_' $sfbPsSessionPrefix = 'SfBPowerShellSession' #Changed to allow capture of Session Name with MicrosoftTeams #sessions originally created will have the below one $sfbPsSessionRegEx1 = $sfbPsSessionPrefix + '*' #sessions created later will get their name changed by powershell during Set-PSImplicitRemotingSession #and so it will have names like "Session for implicit remoting module at C:\Users\<user>\AppData\Local\Temp\tmp_tsdvdhga.20e\tmp_tsdvdhga.20e.psm1" #tmp_tsdvdhga.20e being the module name $sfbPsSessionRegEx2 = Get-PSImplicitRemotingModuleName $sfbPsSessionRegEx2 = '*' + $sfbPsSessionRegEx2 + '*' #delete broken sessions - begin $psBroken = Get-PSSession | Where-Object { ($_.Name -like $sfbPsSessionRegEx1 -or $_.Name -like $sfbPsSessionRegEx2) -and $_.State -like '*Broken*' } $psClosed = Get-PSSession | Where-Object { ($_.Name -like $sfbPsSessionRegEx1 -or $_.Name -like $sfbPsSessionRegEx2) -and $_.State -like '*Closed*' } $psBroken | Remove-PSSession; $psClosed | Remove-PSSession; #delete broken sessions - end } if (($null -eq $script:PSSession) -or ($script:PSSession.Runspace.RunspaceStateInfo.State -ne 'Opened')) { throw 'No session has been associated with this implicit remoting module' } return [Management.Automation.Runspaces.PSSession]$script:PSSession } } } } } end { Write-Verbose -Message "[END ] $($MyInvocation.MyCommand)" } #end } # Enable-CsOnlineSessionForReconnection |