Module that connects to o365 Exchange and op Exchange not working

Hello,

I have created a simple module that connects me to my on-prem and o365 exchange servers and imports the commands with a prefix. The code works fine if I paste it into my PowerShell session, however if I run it as the module while the code all seems to work the commands from the PSSessions doesn’t work.

I do get tab completion of the commands, so PowerShell seems aware they are there, however if I try to actually run the command I get told that the term is not recognized as the name of cmdlet, function etc.

I have pasted the code I am using below, I have tried searching bing and google and so far am not sure what I am missing.

Thank you for any help,

Eric

[hr]

function Connect-Cloud {

[CmdletBinding()]
Param(
    [Parameter(Mandatory=$True, ValueFromPipeline=$True)]
    [string]$UserToConnectAs
)
PROCESS {
    $host.ui.RawUI.WindowTitle = "$UsertoConnectAs Credential"
    $Cred = Get-Credential -UserName $UserToConnectAs -Message 'Enter your password...'
    Write-Verbose "The Cred is $cred"
    $opExchange = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://myopexchangeserver/PowerShell/ -Authentication Kerberos
    Import-PSSession $opExchange -Prefix 'op'
    $O365Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $Cred -Authentication Basic -AllowRedirection
    Import-PSSession $O365Session -Prefix 'o365'

    Import-Module MSOnline
    Connect-MsolService –Credential $Cred
    Export-ModuleMember -Function * -Alias *
    }
}

First, I’m not sure why you’ve specified ValueFromPipeline or PROCESS{}; were you to actually pipe multiple strings to this, which you’ve allowed, I don’t think this would work as intended.

Second, all functions in PowerShell run in their own private scope. So the sessions you create within the function will “go away” once the function finishes running. Because the O365 session that you import relies upon the PSSession being valid, once the session stops being valid, that module stops working. You might want to re-think how you’re doing this. Is the goal to simply make it easier to get your current console session connected up to the cloud, and all the appropriate modules loaded?

Hello,

I had left valuefrompipeline simply because I had used it in other modules, I’d be happy to do it another way if that is better.

I was hoping that by exporting the module members I would be able to take the commands I had pulled from the PSSession into my general session. After I run the module if I run get-pssession I can still see both session open and available.

I initially had this as a couple of commands that I would just paste into PowerShell when I was actually going to need them, but after that had happened enough times I thought that turning it into a module might make more sense. I use PowerShell as my normal way of doing things so want to keep the launch time as quick as possible and connecting to the sessions takes long enough that I don’t want to have to wait for it to load from my profile. I also was hoping that if I could get this to run well as a module I could share it with other team members to make things easier for them.

I’m certainly happy to look at a better way to achieve this if there is a better way to make these connections when needed.

Thank you.

Generally, you don’t want stuff in functions that isn’t doing useful work; if you don’t actually deal with pipeline input, don’t tell the function to accept it, and you have less risk of something weird happening.

So, here’s what you want to do.

In the module, outside a function, declare variable(s) to hold your sessions. Inside your function, when you set those variables, you’ll have to use the $script:variable modifier so that you explicitly put the session into the module-level variable. Use Export-ModuleMember to explicitly export those variables when the module is loaded. That’ll keep the sessions open in the console even when the function finishes running. That’s the basic starting point.

Generally, you don’t want stuff in functions that isn’t doing useful work; if you don’t actually deal with pipeline input, don’t tell the function to accept it, and you have less risk of something weird happening.

So, here’s what you want to do.

In the module, outside a function, declare variable(s) to hold your sessions. Inside your function, when you set those variables, you’ll have to use the $script:variable modifier so that you explicitly put the session into the module-level variable. Use Export-ModuleMember to explicitly export those variables when the module is loaded. That’ll keep the sessions open in the console even when the function finishes running. That’s the basic starting point.