I'm sure this is a pretty normal scenario, but I have a few situations where I need to loop through my clients and connect to their Exchange Online infrastructure via PowerShell. Currently, I do this:
# Specifying credentials and connecting to Office 365 module
$Credential = Get-Credential
Connect-MsolService -Credential $Credential
# Getting a list of tenant IDs (clients) used to connect to their environment
$Tenants = (Get-MsolPartnerContract).TenantID.Guid
# Running command against all tenants
ForEach ($Tenant in $Tenants) {
# Get primary domain for the tenant
$Domain = (Get-MsolDomain -TenantId $Tenant `
| Where-Object { `
$_.Name -NotLike "*onmicrosoft.com" -and `
$_.Name -NotLike "*microsoftonline.com" })[0].Name
# Authenticating to Exchange Online for the tenant
$Session = New-PSSession `
-ConfigurationName Microsoft.Exchange `
-ConnectionUri https://outlook.office365.com/powershell-liveid?DelegatedOrg=$Domain `
-Credential $Credential `
-Authentication Basic `
-AllowRedirection
Import-PSSession $Session -ErrorAction 'silentlycontinue'
# Logic goes here...
Remove-PSSession $Session
}
This may have been something I just missed in the docs, but is there a faster way to run commands against multiple sessions? Currently, it's taking a long time to just connect, which of course adds up when connecting to a lot of different tenants.
I won't write full code here, but you might want to try creating different Jobs for each client/connection. See Start-Job
and similar cmdlets. The aim would be to spin a number of these in parallel and wait for them to finish.
For each of your tenants you can start a job and keep track of the Job object that is created, e.g.
$jobs = @{}
# create the jobs
foreach($tenant in $tenants) {
$jobs[$tenant] = Start-Job ...
}
Once you have started the jobs, find a way to wait for them to finish and collect any output the code may have spat out.