Using Delegated Access Permissions in PowerShell to Manage all Microsoft 365 Services

I recently posted about how we can use Delegated Access Permissions via a partner relationship to connect to an Exchange Online organization through PowerShell. This is a fantastic piece of functionality for MSPs and CSPs to manage multiple tenancies securely without having managing a set of admin identities for all of their customers.

To expand on the previous post, I thought I would put together each of the PowerShell modules that support delegated admin permissions in one place and also highlight any that I feel are missing.

In this post I will go through the connection methods (where available) using DAP for each of the below modules:

  • ExchangeOnline
  • MSOnline
  • Azure AD
  • MicrosoftTeams
  • Skype for Business
  • SharePoint Online
  • Security & Compliance Center

Exchange Online Module (v2)

I’ve gone through this one recently in another post so full information is available there. In short, we cann connect to Exchange Online Powershell using the Exchange Online (v2) PowerShell Module by specifying the tenant domain in our connection command.

First, install the module as normal:

Install-Module ExchangeOnline

Once installed, restart PowerShell and connect using the customer tenancy domain:

Connect-ExchangeOnline -DelegatedOrganization <>

MS Online Module

The MS Online Module works a little differently in that we don’t connect directly to our customer tenancy, we specify the tenancy in our commands.

We install the module with:

Install-Module MSOnline

Then we connect to our own service as normal:


Once we are connected, we need to locate the Tenant ID of our target organization. If we don’t have it to hand we can find it using the tenant domain in the below command:

Get-MsolPartnerContract -DomainName <> | Select-Object TenantID

Once we have the TenantID output (which will be a GUID), we can run commands against the tenant as below, using the -TenantID flag:

Get-MsolUser -All -TenantId <TenantID>

Azure AD Module

To connect to Azure AD, we need the Tenant ID from above to use in our connection. We can install the AzureADPreview Module:

Install-Module AzureADPreview

We then connect using our Tenant ID with the below command:

Connect-AzureAD -TenantId <TenantID>

Microsoft Teams Module

For Microsoft Teams we use the Tenant ID again. Install with:

Install-Module MicrosoftTeams

And then we connect with the Tenant ID as below:

Connect-MicrosoftTeams -TenantId <TenantID>

Skype for Business Module

The Skype for Business Module is interesting in that a lot of organizations have moved off Skype to use Microsoft Teams. The Skype module is still required to manage certain aspects of Teams though. The connection to the module is equally as strange. Once we have connected to Teams as above, we then new to create out connection to Skype using the below commands to create the session and then import it:

$session = New-CsOnlineSession
Import-PSSession $session

This will connect our existing Teams session to the Skype for Business module!

SharePoint Online Module

Unfortunately the SharePoint Online Module does not support DAP at the moment. I will update this post when/if it becomes available.

Security & Compliance Center Module

The Security and Compliance Center Module is installed as part of the Exchange Online (v2) module and allows connection to services such as DLP and Information Protection.

To connect to the Security & Compliance Center we can install the Exchange Online (v2) module as above and use the -DelegatedOrganization flag to specify our customer domain:

Connect-IPPSSession -DelegatedOrganization <CustomerDomain>

And that’s it, that’s pretty much all the modules I use on a daily basis, I will update this post as/when more updates or modules are available.

PowerShell Script To Migrate Users From Skype On Premises to Microsoft Teams

With the functionality available in Microsoft Teams, lot of organizations are focusing moving from an on-premises Skype for Business server to full Microsoft Teams Voice. This requires user accounts to be migrated to Teams and assigned Full Teams Only Mode.

I’ve put together a handy script to allow the migration from Skype to be user friendly and seamless from a admin perspective. The below script will give an export of all users and allow an admin to select one or more users and process them for migration. The script should be imported using “import-module TeamsMove.ps1” into the Skype for Business PowerShell Module and then the process can be kicked off by running the function “Move-ToTeams”. The script can be found on GitHub here.

Warning: This script may not run as expected in your environment and is used for illustration. It may need to be modified for your exact use case. Ensure you understand the steps and test before running in your environment.

##This function allows us to select users who are still homed in Skype for business
function move-toTeams-selectusers{
    $i = 1
    ##Allow selection of one or multiple users
    $users = (Get-CsUser -ResultSize unlimited | ?{$_.registrarPool -notlike $null} | Out-GridView -PassThru -Title "Select One or more users to migrate")
    ##Writing Progress to Screen
    Write-host you selected $users.count users

    ##check if it's array
    if($users -is [array]){
        foreach($User in $users){
             write-host Moving user $i of $users.count : $user.SipAddress

             Move-ToTeams-performMove $user
            write-host Moving single user: $users.SipAddress
            Move-ToTeams-performMove $users


function Move-ToTeams-performMove{
    This function performs the move from Skype on Premises to Teams
    This function accepts a user account and moves the user to Teams
    .PARAMETER useridentity
    Takes a user in for processing by the migration process
    General notes

    ##Removes conferencing policy from user account
     Grant-CsConferencingPolicy -PolicyName "No Dial-in" -Identity $useridentity.identity
     ##Create Dialog
     $a = new-object -comobject 

     ##Prompt for if calling policy should be enabled
     $intAnswer = $a.popup("Should " + $useridentity.sipaddress + " be enabled for outbound calling", 0,"Outbound Calls",4) 
    ##IF yes
    If ($intAnswer -eq 6) { 
        ##warn admin to ensure license is assigned
       $a.popup("Enabling Calling Policy for " + $useridentity.sipaddress + ", make sure they are licensed for Calling or this will fail!") 
        ##Enable outbound calling
        Set-CsUser -Identity $useridentity.identity -EnterpriseVoiceEnabled:$True
    }##Else no 
    else { 
        $a.popup("Removing Calling Policy from " + $useridentity.sipaddress + ", license can be removed if assigned") 
        ##Disable outbound calling
        Set-CsUser -Identity $useridentity.identity -EnterpriseVoiceEnabled:$False -Confirm:$false
        ##Moves user to Teams
        Move-CsUser -Identity $UserIdentity.identity -Target -MoveToTeams -Credential $credentials -HostedMigrationOverrideUrl $url -ErrorAction Stop -Confirm:$false
        write-host $UserIdentity.identity completed successfully -ForegroundColor Green

    #Catch and notify admin of error
    $ErrorMessage = $_.Exception.Message

    write-host Failed Migrating $useridentity.sip with error $ErrorMessage



function Move-toTeams{

    ##Adding Teams endpoint URL
    ##If credentials dont exist, prompt for them

        $credentials = Get-Credential -Message "Please enter credentials for an Office 365 admin with onmicrosoft UPN"




Setting up an Auto Attendant in Microsoft Teams

Microsoft Teams Calling Features have some great flexibility for standard calling requirements. For some more bespoke requirements there are great integrations available trough a number different contact center ISVs also. One of the cool built in features is the Microsoft Teams Auto Attendant. Auto Attendant has been around for a while now, coming from Skype for Business, and can help Organizations put a front end on customer facing numbers. In this post I’ll go through the steps to configure a Microsoft Teams Auto-Attendant.

Set up a Resource Account

The first requirement for an Auto Attendant is to create a resource account to act as the ‘entry point’ and have the associated front end phone number. Every Auto Attendant must have at least one Resource account associated and can have more than one if multiple numbers are required.

To set up a resource account, open the Teams Admin Center and go to ‘Org Settings‘ -> ‘Resource Accounts‘ and add a new account as below:

Next we assign a phone number to our resource account to enable it for dial-in. Depending on if you are using Dial Plans or Direct Routing this is slightly different.

For Dial Plans, hit the assign button and assign an Online number as below,

Screenshot of the Assign/unassign options

For Direct Routing, this currently needs to be done via the Skype For Business Online Management Shell. Use the command below to set this number on the resource account:

Set-CsOnlineVoiceApplicationInstance -Identity -TelephoneNumber +0000000000

Set up an Auto Attendant

Once we have our number set we can set up our Auto Attendant. Open the ‘Voice‘ -> ‘Auto Attendant‘ section of the Admin Center and create a new Auto Attendant.

On the creation page, select:

  • An Operator – The real person to get called if a user doesn’t want to speak to the Auto Attendant. This can be a real person, another Resource Account or an number that is external to Teams
  • Time Zone – this is for mapping opening hours to your current Time Zone
  • Language – The language the Auto Attendant should be in

On the next page, we can set up an initial greeting, this can be a recorded audio file or have the Teams system read out a typed message.

Next we choose what to do with our auto attendant. We can disconnect, reroute the call to another Resource Account or play a menu with associated triggers. If we choose to play menu options, we again have the option to record the message, or have the system read a written message.

We assign dial keys to trigger one of the below options, we can also add voice commands to each of the dial keys.

  • Operator – Speak to our chosen operator
  • Person in Organization – Search Directory (We’ll get to this in a later section)
  • Voice App – Another Resource Account linked to another Auto Attendant or Call Queue
  • Voicemail – Leave a Voicemail for an Office 365 Group
  • External Phone Number – A Number External to Teams

For our directory search option, we can allow users to search by name or extension.

Next we set our Business hours and choose what happens when we are outside business hours.

We can then set our settings for during holidays:

We configure who is accessible to directory search from this line, this can be a particular group of users or all users with particular excludions.

Finally, we link our resource account to our Auto Attendant and we’re all set. After a little time to propagate changes, our Resource Account number will route directly to our Auto Attendant flow.

Auto Attendants and Call Queues add some great functionality for receiving and routing calls for a lot of basic use cases. While more complex cases such as call center management can be fulfilled with Microsoft Partner integrations, the default functionality provides a lot of out of the box flexibility.

For more on Auto Attendants, Call Queues and licensing required see the Official Microsoft Documentation.

Microsoft Teams Meeting Settings

This week Microsoft are rolling out the Meeting Settings configuration to the Microsoft Teams & Skype for business Admin Center in Office 365! This configuration page will allow admins to define teams meeting settings such as Email Invitation URLs and Network and QoS configuration. This allows us to very easily mark real-time media traffic packets for QoS natively, rather than utilizing TCP port and network configuration. We can also define the Port ranges which will be used for different types of traffic.

View the Microsoft Teams & Skype for business Admin Center  at

Teams Meeting Options.png