Scroll Top
Evotec Services sp. z o.o., ul. Drozdów 6, Mikołów, 43-190, Poland

Office 365 – Using dynamic variable as prefix for Office 365 commands

Import-PSSession

One of the nice features of an Import-PSSession is Prefix parameter. If you have never used one let me try to show you an example that should clear things up for you. Let's assume You want to get mailbox from Office 365 and Exchange On-Premises during the same session. Usually, you would do something like

# Connect to Exchange Online
$Mailbox2 = Get-Mailbox -Identity 'MyMailbox1'
# Disconnect from Exchange Online
# Connect to Exchange On-Premises
$Mailbox2 = Get-Mailbox -Identity 'MyMailbox2'
# Disconnect from Exchange On-Premises

While this code would most likely work it's pretty inefficient and in more complicated scenarios not really useful. That's why Import-PSSession has a parameter called Prefix. This gives you a way to connect to Office 365 and Exchange Online at the same time!

$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session -Prefix O365

# Get-Mailbox from Exchange On-Premises
Get-Mailbox -Identity 'MyMailbox1'

# Get-Mailbox from Exchange Online
Get-O365Mailbox -Identity 'MyMailbox2'

Isn't that cool? It is. But this is pretty common so there's probably 50 pages with information on how to use this. What I actually wanted to write about is the ability to dynamically define that prefix for a command.

So what about that Prefix?

What if one wanted to have a function that you can allow the user to define prefix?

function Connect-WinExchange {
    [CmdletBinding()]
    param(
        [string] $SessionName = 'Exchange',
        [string] $ConnectionURI = 'http://ex2013x3.ad.evotec.xyz/Powershell', # https://outlook.office365.com/powershell-liveid/
        [ValidateSet("Basic", "Kerberos")][String] $Authentication = 'Kerberos',
        [string] $Username,
        [string] $Password,
        [switch] $AsSecure,
        [switch] $FromFile,
        [string] $Prefix,
        [switch] $Output
    )
   # Some Code
    if ($Prefix) {
        #Write-Verbose "Prefix used $Prefix"
        Import-Module (Import-PSSession -Session $Session -AllowClobber -DisableNameChecking -Prefix $Prefix -Verbose:$false) -Global -Prefix $Prefix
    } else {
        #Write-Verbose "Prefix used - None"
        Import-Module (Import-PSSession -Session $Session -AllowClobber -DisableNameChecking -Verbose:$false) -Global
    }
}

Now notice how Prefix in the code above is available as a parameter and how I had to use Import-Module to be able to use Import-PSSession in a separate module. Because of that Prefix has to be also defined for the Import-Module. Otherwise, Prefix within Import-Module gets lost, and all commands work as if there was no prefix at all. But back to the topic. Now that we passed a Prefix to Connect-WinExchange we can try to use it in code.

# Connect to Exchange and set dynamic prefix
Connect-WinExchange -Prefix 'Something'

# After we're connected we now needs to use
Get-SomethingMailbox 

Is this a problem? No, not really. But what if there is another function taking this as a parameter? Things get complicated.

function Get-WinExchangeMailbox {
    [CmdletBinding()]
    param(
        [string] $UserName,
        [string] $Prefix
    )
   # Normally you would do it like 
   Get-SomeMailbox

   # But how to use prefix?
   Get-$PrefixMailbox 
  
   # Or maybe?
   Get-$($Prefix)Mailbox 
}

Well, the code above won't work. I did try it. If only it were that simple right?

I want my answer now

The only way that worked for me (maybe not the only one out there thou) was to use it with Call operator

& "get-$($prefix)mailbox"

Prefix

Call operator allows you to execute string (among other things) which is what I wanted in this case.

Related Posts