Save on Office 365 Licensing Costs with PowerShell

In my last PowerShell blog, I explained how to automate user mailbox logon stats reports for Office 365 by utilizing PowerShell and the Windows Task Scheduler. In this post, I’ll illustrate how to use PowerShell to reveal accounts that don’t need to be assigned a license and save on Office 365 licensing costs. Shared mailboxes in Office 365 are useful for a number of reasons:

  • They make it easy for a group of people to monitor and send email from a common account
  • Replies to messages sent to shared mailboxes appear to be from the shared mailbox, not the individual user
  • They are a great place to store former employee accounts after they leave the company
  • Office 365 enterprise plans allow shared accounts to grow up to 10GB in size
  • THEY DON’T REQUIRE A LICENSE!

Converting a mailbox to shared status is oftentimes a standard procedure when an employee leaves. This allows a company to free up a license, retain historical information, and share the information with those who need it. I have detailed how to convert accounts in my blog post titled “Useful PowerShell commands for Office 365 Exchange Online.” Over time there is bound to be some shared accounts that have mistakenly not had their license removed. Maybe the accounts also had licenses for other Office 365 related products such as Windows Intune, or Project Online. You can use PowerShell and the Windows Task Scheduler can help automate reports on shared accounts using a license(s). The script below will query Office 365 shared mailboxes, correlate them to user accounts, list any accounts that are assigned a license(s), save the results to a .txt file and email the results to an address of your choosing:
[powershell]
################################################################################################################################################################
# SCRIPT NAME: Get-SharedAccountsWithLicense.ps1
# SCRIPT TYPE: PowerShell
# CREATED: 8/1/2014
# AUTHOR: Michael Joseph, TecFac Business Services Group (tecfac.net)
# CREATED FOR: Insert Company Here (company.com)
# PURPOSE: Query Office 365 Shared User Mailboxes for accounts assigned a license(s), save the results to
# a .txt file and email the results.
# PREREQUISITES: Windows OS with Powershell and WinRM installed and configured per http://help.outlook.com/en-us/140/cc952755.aspx and
# Windows Azure AD Module installed and configured per http://technet.microsoft.com/en-us/library/jj151815.aspx#bkmk_installmodule
# Office 365 administrative rights to the tenant the script is configured to query
# LAST MODIFIED: 8/1/2014
#
# NOTES:
#
# Script accepts 3 parameters from the command line
#
# Office365Username – Mandatory – Administrator login ID for the tenant we are querying
# Office365Password – Mandatory – Administrator login password for the tenant we are querying
#
#
#
# To run the script
#
# .Get-SharedAccountsWithLicense.ps1 -Office365Username [email protected] -Office365Password Password123
#
# To run this script on a schedule, use the Windows Task Scheduler
#
################################################################################################################################################################
#Accept input parameters
Param(
[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
[string] $Office365Username,
[Parameter(Position=1, Mandatory=$true, ValueFromPipeline=$true)]
[string] $Office365Password
)
#Main
Function Main {
#Remove all existing Powershell sessions
Get-PSSession | Remove-PSSession
#Call ConnectTo-ExchangeOnline function with correct credentials
ConnectTo-ExchangeOnline -Office365AdminUsername $Office365Username -Office365AdminPassword $Office365Password
#Import MSOnline Module and connect with defined credentials
Import-Module MSOnline
$SecureOffice365Password = ConvertTo-SecureString -AsPlainText $Office365Password -Force
$Office365Credentials = New-Object System.Management.Automation.PSCredential $Office365Username, $SecureOffice365Password
Connect-MsolService -Credential $Office365Credentials
#Call ConnectTo-ExchangeOnline function with correct credentials
ConnectTo-ExchangeOnline -Office365AdminUsername $Office365Username -Office365AdminPassword $Office365Password
#Search Office 365 Shared Mailboxes, correlate with user account, find out if a licence is assigned to the account, output results to a txt file
Get-Mailbox -Filter ‘(RecipientTypeDetails -eq "SharedMailbox")’ | Get-MsolUser | Where-Object {$_.isLicensed -eq "TRUE"} | Select userprincipalname,Licenses | Format-Table -AutoSize -Wrap >C:PathSharedAccountsWithLicense.txt
#Define OutputFile
$OutputFile = "C:PathSharedAccountsWithLicense.txt"
#Email the TXT file
$smtpServer = "Enter SMTP server IP address"
$att = new-object Net.Mail.Attachment ($OutputFile)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = "From email address"
$msg.To.Add("To email address")
$msg.Subject = "Office 365 Shared Mailboxes using a license(s)"
$msg.Body = "Attached is the latest Office 365 Shared Accounts with a license Report. Shared accounts do not require a license(s). Please remove them from any listed accounts."
$msg.Attachments.Add($att)
$smtp.Send($msg)
$att.Dispose()
#Clean up session
Get-PSSession | Remove-PSSession
}
###############################################################################
#
# Function ConnectTo-ExchangeOnline
#
# PURPOSE
# Connects to Exchange Online Remote PowerShell using the tenant credentials
#
# INPUT
# Tenant Admin username and password.
#
# RETURN
# None.
#
###############################################################################
function ConnectTo-ExchangeOnline
{
Param(
[Parameter(
Mandatory=$true,
Position=0)]
[String]$Office365AdminUsername,
[Parameter(
Mandatory=$true,
Position=1)]
[String]$Office365AdminPassword
)
#Encrypt password for transmission to Office365
$SecureOffice365Password = ConvertTo-SecureString -AsPlainText $Office365AdminPassword -Force
#Build credentials object
$Office365Credentials = New-Object System.Management.Automation.PSCredential $Office365AdminUsername, $SecureOffice365Password
#Create remote Powershell session
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $Office365credentials -Authentication Basic –AllowRedirection
#Import the session
Import-PSSession $Session -AllowClobber | Out-Null
}
# Start script
. Main
[/powershell]
To set the script to run as a scheduled task, just copy the file to a server or workstation with PowerShell and the Windows Azure AD Module installed. Call the script to start a program. Enter PowerShell as the program/script, and setup the arguments like this: -file “C:Location of Script Get-SharedAccountsWithLicense.ps1″ -Office365Username your o365 admin username -Office365Password corresponding password