Skip to content

Instantly share code, notes, and snippets.

@chrisbrownie
Last active December 11, 2017 22:35
Show Gist options
  • Save chrisbrownie/cd706d35284e9b2348a0022ec9f15374 to your computer and use it in GitHub Desktop.
Save chrisbrownie/cd706d35284e9b2348a0022ec9f15374 to your computer and use it in GitHub Desktop.
Automatically discovers newest EXOPS module in the user's profile
function UpdateImplicitRemotingHandler {
$modules = Get-Module tmp_*
foreach ($module in $modules)
{
[bool]$moduleProcessed = $false
[string] $moduleUrl = $module.Description
[int] $queryStringIndex = $moduleUrl.IndexOf("?")
if ($queryStringIndex -gt 0)
{
$moduleUrl = $moduleUrl.SubString(0,$queryStringIndex)
}
if ($moduleUrl.EndsWith("/PowerShell-LiveId", [StringComparison]::OrdinalIgnoreCase) -or $moduleUrl.EndsWith("/PowerShell", [StringComparison]::OrdinalIgnoreCase))
{
& $module { ${function:Get-PSImplicitRemotingSession} = `
{
param(
[Parameter(Mandatory = $true, Position = 0)]
[string]
$commandName
)
if (($script:PSSession -eq $null) -or ($script:PSSession.Runspace.RunspaceStateInfo.State -ne 'Opened')) {
Set-PSImplicitRemotingSession `
(& $script:GetPSSession `
-InstanceId $script:PSSession.InstanceId.Guid `
-ErrorAction SilentlyContinue )
}
if (($script:PSSession -ne $null) -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 (($script:PSSession -eq $null) -or ($script:PSSession.Runspace.RunspaceStateInfo.State -ne 'Opened')) {
Write-PSImplicitRemotingMessage ('Creating a new Remote PowerShell session using MFA for implicit remoting of "{0}" command ...' -f $commandName)
$session = New-ExoPSSession -UserPrincipalName $global:UserPrincipalName -ConnectionUri $global:ConnectionUri -AzureADAuthorizationEndpointUri $global:AzureADAuthorizationEndpointUri -PSSessionOption $global:PSSessionOption -Credential $global:Credential
if ($session -ne $null)
{
Set-PSImplicitRemotingSession -CreatedByModule $true -PSSession $session
}
RemoveBrokenOrClosedPSSession
}
if (($script:PSSession -eq $null) -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
}}
}
}
}
function Test-Uri {
[CmdletBinding()]
[OutputType([bool])]
Param
(
# Uri to be validated
[Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)]
[string]
$UriString
)
[Uri]$uri = $UriString -as [Uri]
$uri.AbsoluteUri -ne $null -and $uri.Scheme -eq 'https'
}
function Connect-EXOPSSession {
<#
.SYNOPSIS
To connect in other Office 365 offerings, use the following settings:
- Office 365 operated by 21Vianet: -ConnectionURI https://partner.outlook.cn/PowerShell-LiveID -AzureADAuthorizationEndpointUri https://login.chinacloudapi.cn/common
- Office 365 Germany: -ConnectionURI https://outlook.office.de/PowerShell-LiveID -AzureADAuthorizationEndpointUri https://login.microsoftonline.de/common
- PSSessionOption accept object created using New-PSSessionOption
.DESCRIPTION
This PowerShell module allows you to connect to Exchange Online service
.LINK
https://go.microsoft.com/fwlink/p/?linkid=837645
#>
param(
# Connection Uri for the Remote PowerShell endpoint
[string] $ConnectionUri = 'https://outlook.office365.com/PowerShell-LiveId',
# Azure AD Authorization endpoint Uri that can issue the OAuth2 access tokens
[string] $AzureADAuthorizationEndpointUri = 'https://login.windows.net/common',
# User Principal Name or email address of the user
[string] $UserPrincipalName = '',
# PowerShell session options to be used when opening the Remote PowerShell session
[System.Management.Automation.Remoting.PSSessionOption] $PSSessionOption = $null,
# User Credential to Logon
[System.Management.Automation.PSCredential] $Credential = $null
)
# Validate parameters
if (-not (Test-Uri $ConnectionUri))
{
throw "Invalid ConnectionUri parameter '$ConnectionUri'"
}
if (-not (Test-Uri $AzureADAuthorizationEndpointUri))
{
throw "Invalid AzureADAuthorizationEndpointUri parameter '$AzureADAuthorizationEndpointUri'"
}
try
{
# Cleanup old ps sessions
Get-PSSession | Remove-PSSession
$ExoPowershellModule = "Microsoft.Exchange.Management.ExoPowershellModule.dll";
# Find the latest version of the module installed
$ExoPowerShellModules = Get-ChildItem -Path $env:LOCALAPPDATA -Filter $ExoPowershellModule -Recurse -ErrorAction SilentlyContinue | Select-Object -ExpandProperty VersionInfo
$ModulePath = $ExoPowerShellModules | Sort-Object -Property FileVersion -Descending | Select-Object -First 1 -ExpandProperty FileName
Write-Verbose "Discovered module path $ModulePath"
$global:ConnectionUri = $ConnectionUri;
$global:AzureADAuthorizationEndpointUri = $AzureADAuthorizationEndpointUri;
$global:UserPrincipalName = $UserPrincipalName;
$global:PSSessionOption = $PSSessionOption;
$global:Credential = $Credential;
Import-Module $ModulePath;
$PSSession = New-ExoPSSession -UserPrincipalName $UserPrincipalName -ConnectionUri $ConnectionUri -AzureADAuthorizationEndpointUri $AzureADAuthorizationEndpointUri -PSSessionOption $PSSessionOption -Credential $Credential
if ($PSSession -ne $null)
{
Import-PSSession $PSSession -AllowClobber
UpdateImplicitRemotingHandler
}
}
catch
{
throw $_
}
}
Connect-EXOPSSession
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment