Before you start...
This article is a part of a collection of articles.&nbation-list-footer">
Office 365 Reporting via PowerShell for Syndication Partners to understand the audience this article is intended for, the background, what's in scope and out of scope, assumptions and limitations.
Scenario
The Syndication Partner needs to contact some or all of its customers to share a communication with technical information related to the Office 365 service. The communication requires that the customer's company administrator(s) performs administrative actions.
The Syndication Partner must retrieve from MOP the Technical Contact Email which the customer provides in the Company's Profile. The partner also needs to identify in MOP the users who have been granted administrator permissions as Global Administrators.
The Syndication Partner can obtain this information using Windows Azure Active Directory Module for Windows PowerShell cmdlets (previously known as the Microsoft Online Services Module for Windows PowerShell cmdlets).
A Syndication Partner may need to get this information for all of its customers or for some of its customers. Both options are covered in this article.
Option 1: Get Report for All Customers
None. The script will retrieve information for all customer tenants of the partner
Three CSV files located in C:\Scripts named:
- TechNotList.csv => List of Technical Notification Email address provided by the customer
- CompanyAdminList.csv => List of users and their alternate e-mail address who have a Company Admin role
- InvalidTenants.csv => List of tenants that at some point had one or more subscription, all of which are now deprovisioned. The file may not always contain information if the partner does not have customers with all subscriptions deprovisioned.
One txt file located in C:\Scripts named:
- TenantList.txt => List of all tenants for the partner with active, in grace period, disabled or deprovisioned subscriptions
*** NOTE: The folder C:\Scripts must exist prior to running the script
Clear-Host
Write-Progress -Id 1 -Activity "Get tenant list" -Status "Retrieving... this may take several minutes"
$tenantList = Get-MsolpartnerContract -All | Format-Table -Property TenantID -AutoSize -HideTableHeaders | Out-file "C:\Scripts\TenantList.txt"
(get-content "C:\Scripts\TenantList.txt") | where {$_ -ne ""} | out-file "C:\Scripts\TenantList.txt"
$myTechNotOutput=@()
$myAdminOutput =@()
$myInvalidOutput =@()
$inputFile = get-content "C:\Scripts\TenantList.txt"
$totTenants = $inputfile.count
foreach ($tenantItem in $inputFile)
{
$tenantCount = $tenantItem.readcount
Write-Progress -Id 1 -Activity "Get tenant list" -Status "Completed" -PercentComplete 100
Write-Progress -Id 2 -Activity "Validating tenant list and retrieving data" -PercentComplete (($tenantCount/ $totTenants)*100) -CurrentOperation " processing $tenantCount of $totTenants" -status "Please wait"
$Company = Get-MsolCompanyInformation -TenantID $tenantItem -ErrorAction SilentlyContinue
If (!$?)
{
$objInvalid = New-Object system.object
$objInvalid | Add-Member -Type NoteProperty -Name TenantID -value $tenantItem
$myInvalidOutput += $objInvalid
}
Else
{
$Company = Get-MsolCompanyInformation -TenantID $tenantItem | Select DisplayName, @{Name='TechnicalNotificationEmails'sp; $objInvalid | Add-Member -Type NoteProperty -Name TenantID -value $tenantItem
$myInvalidOutput += $objInvalid
}
Else
&nbs;;Expression={[string]::join(";", ($_.TechnicalNotificationEmails))}}
$InitialDomain = Get-MsolDomain -TenantID $tenantItem | where {$_.IsInitial -Eq $true}
$CompanyAdmins = Get-MsolRoleMember -TenantID $tenantItem -roleobjectID 62e90394-69f5-4237-9190-012177145e10
$objTechNot = New-Object system.object
$objTechNot | Add-Member -Type NoteProperty -Name TenantID -value $tenantItem
$objTechNot | Add-Member -Type NoteProperty -Name CompanyName -value $Company.DisplayName
$objTechNot | Add-Member -Type NoteProperty -Name OnMicrosoftDomain -value $InitialDomain.Name
$objTechNot | Add-Member -Type NoteProperty -Name CompanyTechnicalNotificationEmails -value $Company.TechnicalNotificationEmails
$myTechNotOutput += $objTechNot
foreach($caItem in $CompanyAdmins)
{
$Email =Get-MsolUser -TenantID $tenantItem -ObjectID $caItem.ObjectID | Select UserPrincipalName, PhoneNumber, MobilePhone, @{Name='AlternateEmailAddresses';Expression={[string]::join(";", ($_.AlternateEmailAddresses))}}
$objAdmin = New-Object system.object
$objAdmin | Add-Member -Type NoteProperty -Name TenantID -value $tenantItem
$objAdmin | Add-Member -Type NoteProperty -Name CompanyName -value $Company.DisplayName
$objAdmin | Add-Member -Type NoteProperty -Name OnMicrosoftDomain -value $InitialDomain.Name
$objAdmin | Add-Member -Type NoteProperty -Name AdminUserUPN -value $Email.UserPrincipalName
$objAdmin | Add-Member -Type NoteProperty -Name AdminUserAltEmail -value $Email.AlternateEmailAddresses
$objAdmin | Add-Member -Type NoteProperty -Name AdminUserPhone -value $Email.PhoneNumber
$objAdmin | Add-Member -Type NoteProperty -Name AdminUserMobilePhone -value $Email.MobilePhone
$myAdminOutput += $objAdmin
}
}
}
$myInvalidOutput | export-csv -Path "C:\Scripts\InvalidTenants.csv" -NoTypeInformation
$myTechNotOutput | export-csv -Path "C:\Scripts\TechNotList.csv" -NoTypeInformation
$myAdminOutput | export-csv -Path "C:\Scripts\CompanyAdminList.csv" -NoTypeInformation
|
Click image for better quality
TechNotList.csv
CompanyAdminList.csv
InvalidTenants.csv
TenantList.txt
Option 2: Get Report for Some Customers (provide list of TenantIDs)
A txt file located in C:\Scripts named TenantList.txt with the TenantID GUIDs of those customers that you want to retrieve data for. Provide data as displayed below.
*** NOTE: The folder C:\Scripts must exist prior to running the script
Three CSV files located in C:\Scripts named:
- TechNotList.csv => List of Technical Notification Email address provided by the customer
- CompanyAdminList.csv => List of users and their alternate e-mail address who have a Company Admin role
- InvalidTenants.csv => List of tenants that at some point had one or more subscription, all of which are now deprovisioned. The file may not always contain information if the partner does not have customers with all subscriptions deprovisioned.
*** NOTE: The folder C:\Scripts must exist prior to running the script
Clear-Host
Write-Progress -Id 1 -Activity "Get tenant list" -Status "Retrieving... this may take several minutes"
$myTechNotOutput=@()
$myAdminOutput =@()
$myInvalidOutput =@()- CompanyAdminList.csv => List of users and their alternate e-mail address who have a Company Admin role
- InvalidTenants.csv => List of tenants that at some point had one or more subscription, all of which are now deprovisioned. The file may not always contain information if the partner does not have customers with all subscriptions deprovisioned.
*** NOTE: The folder C:\Scripts must exist prior to running the script
Clear-Host
Write-Progress -Id 1 -Activity "Get tenant list" -Status "Retrieving... this may take several minutes"
$myTecr />
$inputFile = get-content "C:\Scripts\TenantList.txt"
$totTenants = $inputfile.count
foreach ($tenantItem in $inputFile)
{
$tenantCount = $tenantItem.readcount
Write-Progress -Id 1 -Activity "Get tenant list" -Status "Completed" -PercentComplete 100
Write-Progress -Id 2 -Activity "Validating tenant list and retrieving data" -PercentComplete (($tenantCount/ $totTenants)*100) -CurrentOperation " processing $tenantCount of $totTenants" -status "Please wait"
$Company = Get-MsolCompanyInformation -TenantID $tenantItem -ErrorAction SilentlyContinue
If (!$?)
{
$objInvalid = New-Object system.object
$objInvalid | Add-Member -Type NoteProperty -Name TenantID -value $tenantItem
$myInvalidOutput += $objInvalid
}
Else
{
$Company = Get-MsolCompanyInformation -TenantID $tenantItem | Select DisplayName, @{Name='TechnicalNotificationEmails';Expression={[string]::join(";", ($_.TechnicalNotificationEmails))}}
$InitialDomain = Get-MsolDomain -TenantID $tenantItem | where {$_.IsInitial -Eq $true}
$CompanyAdmins = Get-MsolRoleMember -TenantID $tenantItem -roleobjectID 62e90394-69f5-4237-9190-012177145e10
$objTechNot = New-Object system.object
$objTechNot | Add-Member -Type NoteProperty -Name TenantID -value $tenantItem
$objTechNot | Add-Member -Type NoteProperty -Name CompanyName -value $Company.DisplayName
$objTechNot | Add-Member -Type NoteProperty -Name OnMicrosoftDomain -value $InitialDomain.Name
$objTechNot | Add-Member -Type NoteProperty -Name CompanyTechnicalNotificationEmails -value $Company.TechnicalNotificationEmails
$myTechNotOutput += $objTechNot
foreach($caItem in $CompanyAdmins)
{
$Email =Get-MsolUser -TenantID $tenantItem -ObjectID $caItem.ObjectID | Select UserPrincipalName, PhoneNumber, MobilePhone, @{Name='AlternateEmailAddresses';Expression={[string]::join(";", ($_.AlternateEmailAddresses))}}
$objAdmin = New-Object system.object
$objAdmin | Add-Member -Type NoteProperty -Name TenantID -value $tenantItem
$objAdmin | Add-Member -Type NoteProperty -Name CompanyName -value $Company.DisplayName
$objAdmin | Add-Member -Type NoteProperty -Name OnMicrosoftDomain -value $InitialDomain.Name
$objAdmin | Add-Member -Type NoteProperty -Name AdminUserUPN -value $Email.UserPrincipalName
$objAdmin | Add-Member -Type NoteProperty -Name AdminUserAltEmail -value $Email.AlternateEmailAddresses
$objAdmin | Add-Member -Type NoteProperty -Name AdminUserPhone -value $Email.PhoneNumber
$objAdmin | Add-Member -Type NoteProperty -Name AdminUserMobilePhone -value $Email.MobilePhone
$myAdminOutput += $objAdmin
}
 sp; $objAdmin | Add-Member -Type NoteProperty -Name AdminUserAltEmail -value $Email.AlternateEmailAddresses
$objAdmin | Add-Member -Type NoteProperty -Name AdminUserPhone -value $Email.PhoneNumber
$objAdmin | Add-Member -Type NoteProperty -Name AdminUserMobilePhone -value $Email.MobilePhone
&; }
}
$myInvalidOutput | export-csv -Path "C:\Scripts\InvalidTenants.csv" -NoTypeInformation
$myTechNotOutput | export-csv -Path "C:\Scripts\TechNotList.csv" -NoTypeInformation
$myAdminOutput | export-csv -Path "C:\Scripts\CompanyAdminList.csv" -NoTypeInformation
|
Click image for better quality
TechNotList.csv
CompanyAdminList.csv
InvalidTenants.csv
|