Function to connect to Exchange Online Powershell

Welcome Forums General PowerShell Q&A Function to connect to Exchange Online Powershell

This topic contains 6 replies, has 3 voices, and was last updated by

 
Participant
4 months ago.

  • Author
    Posts
  • #108383

    Participant
    Points: 0
    Rank: Member

    I'm trying to write a function that will connect me to Exchange Online PowerShell. I will then put this function in a module file (.psm1) that will load up each time I open PowerShell. I have found other functions that are supposed to do this very thing, however when I try them and call the function, it does not retain the open session with Exchange Online. After the cmdlets finish, it shows output that would indicate a successful import (showing ModuleType, Version, Name, and ExportedCommands) but none of the imported cmdlets are available. I'm thinking it might be an issue with the scope of the function but I don't know how to remedy that.

    I am using PS version 5.1 on a Windows 10 machine. Below is the function used.

    function Connect-ExchangeOnlinePowershell
    {
    
    
        [CmdletBinding()]
        Param
        (
            # Param1 help description
            [Parameter(Mandatory=$false,
                       Position=0)]
            [string]$Username="****"
        )
        Write-Output  "Connecting to Exchange Online Powershell..."
        $exchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ `
        -Credential (Get-Credential -UserName $Username -Message "Enter the password for $Username") -Authentication "Basic" -AllowRedirection
        Write-Output  "Importing Exchange Online Powershell session..."
        Import-PSSession $exchangeSession -AllowClobber -DisableNameChecking
    }
    
  • #108385

    Keymaster
    Points: 1,704
    Helping HandTeam Member
    Rank: Community Hero

    Well, not an “issue.” Magazines have issues :). Yes, this problem is caused by scope. Once the function ends, variables within it are out of scope and they vanish.

    The correct pattern would be for your function to output the session object (as opposed to outputting status messages, which is what Write-Verbose should be used for). You then capture that output in a variable:

    $mysession = Connect-ExchangeOnlinePowerShell

    That session can then be fed, via input parameter, to any other functions or commands you write or use, and they can use the session that way.

  • #108397

    Participant
    Points: 319
    Helping Hand
    Rank: Contributor

    Here is an approach you might want to look at, which is what you are after and provides a menu for it.

    Connect to Office 365/Exchange Services

    PowerShell script defining functions to connect to Office 365 online services or Exchange On-Premises. Makes it easy to connect to different Office 365 services using the same credentials.

    https://gallery.technet.microsoft.com/Connect-to-Office-53f6eb07

    An article on the topic

    'eightwone.com/2015/08/31/connecting-to-office-365exchange'

  • #108412

    Participant
    Points: 0
    Rank: Member

    Thanks Don and postanote, you hit on both uses I am looking for.

    I'd like to be able to call the function within other functions in the module, therefore reducing repeat code. Creating the New-PSSession then returning it from the function Connect-ExchangeOnlinePowershell would solve this.

    I'd also like to be able to call the function in an interactive environment to connect quickly for testing, without needing to recall each of the New-PSSession parameters and arguments. It looks like in order to do this I will need to set the scope of the function to global:Connect-ExchangeOnlinePowershell so that it remains in the shell until close. Does it sound like I am understanding that correctly?

    Could this be done with one function? I am thinking the function could be made global and a switch could be used. If the switch is present the function would call import-pssession internally and then because the function is global the session would be available in the interactive setting. If the switch is not there, the session would be created but instead of importing it, the session would be returned to be used by other functions/commands.

  • #108418

    Keymaster
    Points: 1,704
    Helping HandTeam Member
    Rank: Community Hero

    Yeah, you've got it.

    My broad approach to this kind of thing is to define a module-level variable, which I export, named something like $DJO365SessionPreference. I then capture my new session into that, and I make the value in that variable the default for other functions' -O365Session parameter.

  • #108616

    Participant
    Points: 0
    Rank: Member

    So I have adjusted the function to be global in scope but now I am finding it is not being automatically imported. I have edited $PSModulePath to include the directory where the module is saved. I have the module manifest file set to export all functions. All the other functions are imported automatically and will work fine. The global functions do not show up until I import manually with Import-Module. What other step do I need to take to have the global functions imported automatically?

    function global:Connect-ExchangeOnline
    {
    
    
    
        [CmdletBinding()]
        Param
        (
            # The default user is ****. Change the user by including this parameter.
            [Parameter(Mandatory=$false)]
            [string]$Admin="****",
    
            # To use this function to create an interactive connection with Exchange Online Powershell, include this switch
            [Parameter(Mandatory=$false)]
            [switch]$Interactive
        )
    
        $exchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange `
                                -ConnectionUri https://outlook.office365.com/powershell-liveid/ `
                                -Credential (Get-AdminCredentials $Admin) `
                                -Authentication "Basic" `
                                -AllowRedirection
    
        If($Interactive)
        {
            Write-Verbose  "Connecting to Exchange Online Powershell..."
            Write-Verbose "Importing Exchange Online Powershell session..."
            Import-PSSession $exchangeSession
        }
        Else
        {
            Return $exchangeSession
        }
    }
    
  • #108716

    Participant
    Points: 0
    Rank: Member

    I think my problem from my previous post was in using a wildcard to specify FunctionsToExport with the Update-ModuleManifest cmdlet. Explicitly stating the functions to export seems to have fixed it.

    Using the code above, calling Import-PSSession (Connect-ExchangeOnline) works successfully, I get the session commands I expect (Get-Mailbox, etc). However, calling Connect-ExchangeOnline -Interactive does not. It appears (with verbose output) that it imports all the commands, but they are not available in the local session.

    Any thoughts on why -Interactive is not working?

The topic ‘Function to connect to Exchange Online Powershell’ is closed to new replies.