Connect to Exchange Function in Module not persistent

I have a function in my profile to connect to Exchange and it works until I close powershell.
I put the same function in a module to redistribute with several other functions. I can run the function, and I see the connection to exchange, and the PSSession opened. However the cmdlets, like get-mailbox, are not recognized. I tried to dot source the function but still nothing.
If I call the connect function from within other functions in the same module, I get the cmdlets for the duration of those functions.
Any idea on how to make it persistent? Maybe I need something like “return PSSession”

I believe you are running into a scoping issue. I also ran into this awhile back. When you are doing implicit remoting which is what your are doing, if im understating of your question. This works when you put it in a script and dot source it because when you dot source a script into you console it is put in the same scope. When you call a function that calls implicit remoting inside of a module, those serialized cmdlets are only loaded into your modules scope and not your console session scope. This is a designed that way for nesting modules and limiting scopes. Windows PowerShell in Action 2nd Edition covers this in great detail if your interested (page 352). I have an example of what I did to work around this.

Page 352 from Windows PowerShell in Action 2nd Edition by Bruce Payette. Great Book

Import into the global environment with -Global
When one module loads another, by default it becomes a nested module. This is usu- ally what you want, but perhaps you want to write a module that manipulates mod- ules. In this scenario, you need to be able to import the module into a context other than your own. Although there isn’t a way to import directly into an arbitrary con- text, the -Global flag on Import-Module allows you to import into the global con- text.

function New-ExchangeSessionBasicAuth
{
    [CmdletBinding()]
    Param
    (
        # Param1 help description
        [Parameter(Mandatory=$true,Position=0)]
        [String]$ComputerName,
        [Parameter(Mandatory=$true,Position=1)]
        $Credential = (Get-Credential)
    )

    Process
    {
        $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$ComputerName/powershell -Credential $Credential -Authentication Basic
        Write-Verbose "Importing Exchange Cmdlets"
        Import-Module (Import-PSSession $session -DisableNameChecking -AllowClobber) -Global -DisableNameChecking -Force
        # The import-module part is needed for the -Global parameter, otherwise the pssession is imported into the current module and not the global scope, making this function useless if it is a part of a module it self.
        # for more explination refer to "Windows Powershell in Action 2nd Edition" page 352
    }
 
}

Thank you so very much !!!

Something odd that happens is that when I do a “get-mailbox xxxx”, the result is shown as if I had added “| fl” and shows every attribute. Not a problem though.

And I will definitely check out that book.

I can’t test it right now but I believe that is because the PowerShell formatting files are not pulled over for those cmdlets when implicit remoting. If i remembered right Jeffery Snover mentions this in one of the JumpsStart MVA videos, this is due to security concerns because you can put in executable code in the format files. And when you are implicit remoting you don’t want to automatically trust the code that could potentially be altered in the remote system format files to do something you don’t want.

If this important to you, you can probably create your own format files for those cmdlets on your local system . But I have never done so.

https://technet.microsoft.com/en-us/\library/Dd878339(v=VS.85).aspx