Manage Multiple Office 365 Tenants from PowerShell
July 28, 2016 14 Comments
Yep, another PowerShell themed post.
This is something I cobbled together a few years back, never thought it was worth sharing, but sitting here this evening with nothing much to do decided to write it up.
At it’s core it is not much more than a method of automating entering credentials to your various Office 365 ‘Clients’. I say ‘’clients” because I do not know if that is the correct terminology. If you are the Partner of Record or even if you are supporting more than one tenant on 365 this may be useful to you.
First, in PowerShell ISE we can define some functions.
function connect
{
Import-Module MSOnline
$pwd = Read-Host -AsSecureString -Prompt "Enter Password for Client $clientName"
$cred = New-Object System.Management.Automation.PSCredential($username,$pwd)
Connect-MSolService -credential $cred
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $cred -Authentication Basic -AllowRedirection
Import-PSSession $Session
Write-Output "Connected to Office 365 & Exchange"
}
function disconnect
{
Remove-Module MSOnline
Get-PSSession | Remove-PSSession
}
These are pretty straight forward, with Connect, connecting us to 365 and Disconnect removing all of our current sessions.
Next we can set our credentials for our various tenants.
# Client A
$clientAName = "Company A"
$clientAUserName = "userAAdmin@companyA.onMicrosoft.com"
# Client B
$clientBName = "Company B"
$clientBUserName = "userBAdmin@companyB.onMicrosoft.com"
Again, reasonably straight forward, we have defined the usernames for our two tenants.
Next we have a small menu to build.
function menu
{
Write-Host "Office 365 Management Connect to PowerShell"
Write-Host ""
Write-Host "Enter Client ID.."
Write-Host ""
Write-Host "1. Client A"
Write-Host "2. Client B"
Write-Host "D. Disconnect"
Write-Host "0. Quit"
$client = Read-Host
if (($client) -eq "1")
{
$clientName = $clientAName
$userName = $clientAUserName
Connect
}
if (($client) -eq "2")
{
$clientName = $clientBName
$userName = $clientBUserName
Connect
}
if (($client) -eq "d")
{
Disconnect
}
}
Menu
The menu will give us the option of choosing Client A (1) or Client B (2) it then prompts us for the password for that account and connects us to Office 365.
Of course you can keep adding more clients and expand the menu to include the additional Clients.
Save it as something memorable, like 365.ps1 and fire it up.
Not ground breaking by any means, but something i find useful.
Following some useful comments below from Mark Watson, i created this today for using Delegated Admin Credentials.
Import-Module MSOnline
Write-Output "Enter Office 365 Credentials.."
$cred = Get-Credential
Connect-MSolService -credential $cred
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $cred -Authentication Basic -AllowRedirection
Import-PSSession $Session
Write-Output "Connected to Office 365 & Exchange"
$clients = Get-MSOLPartnerContract
$clientObj = @()
$clientNum = 0
foreach ( $client in $clients )
{
$clO = New-Object System.Object
$clO | Add-Member -Type NoteProperty -Name "Number" -Value $clientNum
$clO | Add-Member -Type NoteProperty -Name "ClientName" -Value $client.Name
$clO | Add-Member -Type NoteProperty -Name "TenantID" -Value $client.TenantID
$clO | Add-Member -Type NoteProperty -Name "DomainName" -Value $client.DefaultDomainName
$clientObj += $clO
$clientNum++
}
$clientObj | ft -AutoSize
$clientChoice = Read-Host -Prompt "Select Your Client"
$clientTenant = $clientObj[$clientChoice]
$TenantId = $clientTenant.TenantID.Guid
$Global:TenantID = $TenantId.Guid
$Domain = Get-MsolDomain -TenantId $TenantId | Where {$_.IsInitial -eq $true}
$ConnectionURL = “https://ps.outlook.com/powershell-liveid?DelegatedOrg=” + $clientTenant.DomainName
$ConnectionURL
$s = New-PSSession -ConnectionUri $ConnectionURL -Credential $Cred -Authentication Basic -ConfigurationName Microsoft.Exchange -AllowRedirection
Import-PSSession $s -AllowClobber
Once the script finished the $tenantID variable is loaded with your chosen clients TenantID Guid.
Nice script. It will be very handy. Thank you.
I do get a warning when running the script. Its because userBAdmin@companyB.onMicrosoft.com needs quotation marks:
$clientBUserName = “userBAdmin@companyB.onMicrosoft.com”
Thats probably just my bad cut and paste job! – fixed.
Nice share, we did something similar but opted to use our delegated admin rights coupled with the TenantID, we supply the Org Name and build the connection from there. Doing it this way means you don’t need to lookup/remember the clients admin credentials, you just use yours.
$TenantId=(Get-MsolPartnerContract | ?{$_.Name -eq $OrgName}).TenantId
$Domain = Get-MsolDomain -TenantId $TenantId | Where {$_.IsInitial -eq $true}
$ConnectionURL = “https://outlook.Office365.com/powershell-liveid?DelegatedOrg=” + $Domain.Name
$s = New-PSSession -ConnectionUri $ConnectionURL -Credential $Credential -Authentication Basic -ConfigurationName Microsoft.Exchange -AllowRedirection
$Output = Import-PSSession $s -AllowClobber
Thats cool!
$clients = Get-MSOLPartnerContract
$clientObj = @()
$clientNum = 0
foreach ( $client in $clients )
{
$clO = New-Object System.Object
$clO | Add-Member -Type NoteProperty -Name "Number" -Value $clientNum
$clO | Add-Member -Type NoteProperty -Name "ClientName" -Value $client.Name
$clO | Add-Member -Type NoteProperty -Name "TenantID" -Value $client.TenantID
$clO | Add-Member -Type NoteProperty -Name "DomainName" -Value $client.DefaultDomainName
$clientObj += $clO
$clientNum++
}
$clientObj
$clientChoice = Read-Host -Prompt "Select Your Client"
$clientObj[$clientChoice]
How about this?
Nice mod!!
You have totally sent me down a rabbit hole now, when will this end! (fun for a friday though)
You should see what my colleague Simon has done, whole modules for managing our clients, I’ll try and get him to blog it on our site. Have fun :)
I tried this modification but the script just continues to run with no output.
I am trying to use this mod so we can continue to use our credentials but it doesn’t seem to work. when I connect using my credentials and perform a get-msoluser or get-mailbox, both cmdlets report my own domain for my MSP credentials. Never the remove client even though I select an option. I run the $client variable and like I mentioned in another post, it seems like it automatically defaults to the very last entry on my list of 39 entries. I would really love to manag our tenants properly with PowerShell but so far none of these work and I have no idea why.
Is each set of credentials defined as a unique variable?
Robert,
Do you mean am I using the very first script where he built a menu and has client A with this admin logon and client B with this admin logon? If so, no… Although that is the only one that is working as I would like it to. I was really hoping to take advantage of the delegated admin rights but the connection context is different as I have mentioned in a different reply below.
Hello, I have been using your script to manage our tenants. Something I have noticed is when it provides us our list of tenants. I enter a number, say “30”. It uses my delegated credentials and connects to that tenant. However, when i try to run commands for that tenant like get-msoluser, it is listing my organizations people and not the tenant. If I do get-mailbox, it is the tenant, however the wrong tenant. It automatically for some reason defaults to the very last tenant on the list. Something is wrong with this script. Has nobody else experienced this?
Please someone get back to me. I am having issues with your scripts and we are an MSP with many clients and these would be so helpful if they worked like we thought they would. If I use the script at the very top of the page where you specify the respective admin account for each tenant (which would take forever btw), it works perfectly. If I do get-msoluser or get-mailbox, both report users in the tenant I want to work in. The dynamic scripts below don’t seem to do that where I use my partner credentials. It seems to connect to Office 365 with my MSP domain but connects to Exchange as the tenant, however it is the wrong tenant, it seems to pick the very last one in the msolpartercontract list. I am very close but something just isn’t quite right. I really hope someone can guide me in the right direction here. Thanks a million.