
Manage Exhange Online Mailbox Quotas based on group membership through Powershell
If you need to change Office365 mailbox quotas the only way to do so is via Powershell. In addition there is not way to control quotas via groups for example or any policy to assign in order to assisgn for example X GBs quota to sales department .
For that reason I created the Powershell script below .
Feel free to change / share / comment .
Script contains parts of the script originally posted by
Johan Dahlbom from 365lab.net so credits to Johan :D
Script Logic :
- Checks if the script was run under admin privileges otherwise informs the user to rerun with admin privs.
- Checks if MSOnline and Exchange Online Modules are installed .
- If they are not it tries to install them .
- Checks if there are active MSOnline and Exchange Online Sessions. If there are not it prompts you to enter credentials to connect .
- Asks the user to provide the name of the group which will get the following quota policy (of course you can change the values to suit your needs) : ProhibitSendQuota 4.5gb -ProhibitSendReceiveQuota 5gb -IssueWarningQuota 3.9gbAsks the user to provide the script output folder (usefull when you run it against multiple users) .
- Then it changes all group's members quota to the one mentioned above
- And also changes all other users quotas to ProhibitSendQuota 75gb -ProhibitSendReceiveQuota 80gb -IssueWarningQuota 74gb
The Script :
function EditMailboxQuotas { $OutPutFolder = "c:\temp\EditMailboxQuotas.txt" $SpecificUserQuota=$null $ConvertedQuotaToKB = $null Write-Host "Please input the name of the group members of which will be assigned 5GB Quota" $ADGroup = Read-Host -Prompt 'Input the group name' Write-Host "Input the folder to export all script output - Please include file name as well" -ForegroundColor Green $OutPutFolder = Read-Host -Prompt 'Folder path and file name to export output to "Example:c:\filename.txt"' Write-Host "Searching for Group " $ADGroup Write-Output "Searching for Group " $ADGroup | Out-File $OutPutFolder -Append Import-Module AzureAD Import-Module MSOnline Import-Module ExchangeOnlineManagement #Connect-MsolService $MSOLAccountSku = Get-MsolAccountSku -ErrorAction Ignore -WarningAction Ignore if (-not($MSOLAccountSku)) { Connect-MsolService } $getsessions = Get-PSSession | Select-Object -Property State, Name #Connect-ExchangeOnline $IsconnectedToEOL = (@($getsessions) -like '@{State=Opened; Name=ExchangeOnlineInternalSession*').Count -gt 0 If ($IsconnectedToEOL -ne "True") { Connect-ExchangeOnline } #Connect-ExchangeOnline $MSOLGroup = Get-MsolGroup -SearchString $ADGroup Write-Host "Group's id is " $MSOLGroup.ObjectId Write-Output "Group's id is " $MSOLGroup.ObjectId | Out-File $OutPutFolder -Append write-host "------------- Configuring quotas for all users who are members of the group " $ADGroup "-------------" -ForegroundColor Magenta Write-Output "------------- Configuring quotas for all users who are members of the group " $ADGroup "-------------" | Out-File $OutPutFolder -Append Read-Host -Prompt "Press any key to continue configuring quotas for all users who are members of the group to 5GB or CTRL+C to quit" Start-Sleep -Seconds 3 $UsersWithinGroup = Get-JDMsolGroupMember($MSOLGroup.ObjectId) if($null -ne $UsersWithinGroup) {#Check if mailbox quota more than 5gb foreach ($UserWithinGroup in $UsersWithinGroup) { $UserWithinGroup.EmailAddress $SpecificUserQuota = Get-Mailbox $UserWithinGroup.EmailAddress | Select-Object ProhibitSendReceiveQuota $ConvertedQuotaToKB = Convert-QuotaStringToKB($SpecificUserQuota) If($ConvertedQuotaToKB -gt 5242880 ) {#quota is more than 5gb Write-Host "CurrentUser" $UserWithinGroup.EmailAddress "has" $ConvertedQuotaToKB "KB Quota more than 5gb will check mailbox size" -ForegroundColor Cyan Write-Output "CurrentUser" $UserWithinGroup.EmailAddress "has" $ConvertedQuotaToKB "KB Quota more than 5gb will check mailbox size" | Out-File $OutPutFolder -Append ##Check if mailbox size is more than 4.5 $MailboxSize = Get-MailboxStatistics $UserWithinGroup.EmailAddress | Select-Object TotalItemSize $MailboxSizeInKB = Convert-QuotaStringToKB($MailboxSize) if ($MailboxSizeInKB -gt 4718592){#If user mailbox size is more than 4.5 GB Write-Host "Mailbox size is more than 4.5 GB No changes will be made " -ForegroundColor Red Write-Output "Mailbox size is more than 4.5 GB No changes will be made " -Append #do Nothing } #If user mailbox size is more than 4.5 GB if ($MailboxSizeInKB -lt 4718592) {#Mailbox size is less than 4.5 GB Write-Host "CurrentUser" $UserWithinGroup.EmailAddress "has" $MailboxSizeInKB "KB mailbox size mailbox quota will be changed" -ForegroundColor Green Write-Output "CurrentUser" $UserWithinGroup.EmailAddress "has" $MailboxSizeInKB "KB mailbox size mailbox quota will be changed" | Out-File $OutPutFolder -Append set-Mailbox $UserWithinGroup.EmailAddress -ProhibitSendQuota 4.5gb -ProhibitSendReceiveQuota 5gb -IssueWarningQuota 3.9gb $SpecificUserQuota = $null } #Mailbox size is less than 4.5 GB } elseif ($ConvertedQuotaToKB -eq 5242880 ) { #quota is 5gb ##Do nothing Write-Host "CurrentUser" $UserWithinGroup.EmailAddress "has" $ConvertedQuotaToKB "KB Quota 5gb Nothing will be changed" -ForegroundColor Red Write-Output "CurrentUser" $UserWithinGroup.EmailAddress "has" $ConvertedQuotaToKB "KB Quota 5gb Nothing will be changed" | Out-File $OutPutFolder -Append $SpecificUserQuota = $null } elseIf ($UserWithinGroup.UseDatabaseQuotaDefaults) #quota used from db defaults { Write-Host "CurrentUser" $UserWithinGroup.EmailAddress "has" $ConvertedQuotaToKB "uses defaults changing" -ForegroundColor Red Write-Output "CurrentUser" $UserWithinGroup.EmailAddress "has" $ConvertedQuotaToKB "uses defaults changing" | Out-File $OutPutFolder -Append set-Mailbox $UserWithinGroup.EmailAddress -ProhibitSendQuota 4.5gb -ProhibitSendReceiveQuota 5gb -IssueWarningQuota 3.9gb } elseif ($ConvertedQuotaToKB -lt 5242880) #quota is less than 5gb and not db defaults { Write-Host "CurrentUser" $UserWithinGroup.EmailAddress "has" $ConvertedQuotaToKB "KB Quota less than 5gb Quotas will be changed" -ForegroundColor Green Write-Output "CurrentUser" $UserWithinGroup.EmailAddress "has" $ConvertedQuotaToKB "KB Quota less than 5gb Quotas will be changed" | Out-File $OutPutFolder -Append set-Mailbox $UserWithinGroup.EmailAddress -ProhibitSendQuota 4.5gb -ProhibitSendReceiveQuota 5gb -IssueWarningQuota 3.9gb } }#ForEach }#If else { #GroupIsEmpty } write-host "------------- Configuring quotas for all users EXCLUDING those who are members of the group " $ADGroup "-------------" -ForegroundColor Magenta Write-Output write-host "------------- Configuring quotas for all users EXCLUDING those who are members of the group " $ADGroup "-------------" | Out-File $OutPutFolder -Append Read-Host -Prompt "Press any key to continue configuring quotas for ALL usersof the organization who are not members of the group to 80GB or CTRL+C to quit" Start-Sleep -Seconds 3 $UsersWithinGroup = Get-JDMsolGroupMember($MSOLGroup.ObjectId) $EXOMailboxes = Get-EXOMailbox -RecipientTypeDetails UserMailbox foreach($EXOMailbox in $EXOMailboxes) {write-host "For mailbox "$EXOMailbox.primarySMtpaddress -ForegroundColor White Write-Output "For mailbox "$EXOMailbox.primarySMtpaddress | Out-File $OutPutFolder -Append if(!(Get-MsolGroupMember -GroupObjectId $MSOLGroup.ObjectId | Where-Object {$_.EmailAddress -eq $EXOMailbox.primarySMtpaddress})) {write-host "Configuring Quota For mailbox "$EXOMailbox.primarySMtpaddress " to 80GB" -ForegroundColor Green Write-Output "Configuring Quota For mailbox "$EXOMailbox.primarySMtpaddress " to 80GB" | Out-File $OutPutFolder -Append set-Mailbox $EXOMailbox.primarySMtpaddress -ProhibitSendQuota 75gb -ProhibitSendReceiveQuota 80gb -IssueWarningQuota 74gb }#if elseif (Get-MsolGroupMember -GroupObjectId $MSOLGroup.ObjectId | Where-Object {$_.EmailAddress -eq $EXOMailbox.primarySMtpaddress}) { write-host "For mailbox "$EXOMailbox.primarySMtpaddress "Nothing will be changed because user is a member of the group" $ADGroup -ForegroundColor red Write-Output "For mailbox "$EXOMailbox.primarySMtpaddress "Nothing will be changed because user is a member of the group" $ADGroup | Out-File $OutPutFolder -Append } }#ForEachEXOMailbox Write-Host "All quotas configuration is finished . If you need to change quotas again re-run the script." -ForegroundColor Gray Write-Output "All quotas configuration is finished . If you need to change quotas again re-run the script." | Out-File $OutPutFolder -Append}#FunctionEditMailboxQuotas Function Convert-QuotaStringToKB() { Param([string]$CurrentQuota) [string]$CurrentQuota = ($CurrentQuota.Split("("))[1] [string]$CurrentQuota = ($CurrentQuota.Split(" bytes)"))[0] $CurrentQuota = $CurrentQuota.Replace(",","") [int]$CurrentQuotaInKB = "{0:F0}" -f ($CurrentQuota/1024) return $CurrentQuotaInKB}Function Get-JDMsolGroupMember { param( [CmdletBinding(SupportsShouldProcess=$true)] [Parameter(Mandatory=$true, ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0)] [ValidateScript({Get-MsolGroup -ObjectId $_})] $ObjectId, [switch]$Recursive ) begin { $MSOLAccountSku = Get-MsolAccountSku -ErrorAction Ignore -WarningAction Ignore if (-not($MSOLAccountSku)) { throw "Not connected to Azure AD, run Connect-MsolService" } } process { Write-Verbose -Message "Enumerating group members in group $ObjectId" [array]$UserMembers = Get-MsolGroupMember -GroupObjectId $ObjectId -MemberObjectTypes User -All if ($PSBoundParameters['Recursive']) { $GroupsMembers = Get-MsolGroupMember -GroupObjectId $ObjectId -MemberObjectTypes Group -All if ($GroupsMembers) { Write-Verbose -Message "$ObjectId have $($GroupsMembers.count) group(s) as members, enumerating..." $GroupsMembers | ForEach-Object -Process { Write-Verbose "Enumerating nested group $($_.Displayname) ($($_.ObjectId))" $UserMembers += Get-JDMsolGroupMember -Recursive -ObjectId $_.ObjectId } } } Write-Output ($UserMembers | Sort-Object -Property EmailAddress -Unique) } end { } }if (Get-Module -Name ExchangeOnlineManagement) { Write-Host "Exchange online Module installed proceeding to next steps" #Write-Output "Exchange online Module installed proceeding to next steps"| Out-File $OutPutFolder -Append Start-Sleep -Seconds 2}else { Write-Host "Exchange online Module does not exist needs to be installed to proceed " #Write-Output "Exchange online Module does not exist needs to be installed to proceed " | Out-File $OutPutFolder -Append Start-Sleep -Seconds 2 $isadmin = (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if ($isadmin) { Write-Host "Installing Exchange online Module .... " #Write-Output "Installing Exchange online Module .... " | Out-File $OutPutFolder -Append Install-module ExchangeOnlineManagement -Force } else { Write-Host "It Appears you did not run the script with administrative rights please run the script with administrative rights to proceed" # Write-Output "It Appears you did not run the script with administrative rights please run the script with administrative rights to proceed" | Out-File $OutPutFolder -Append Pause }}if (Get-Module -Name MSOnline) { Write-Host "MSOnline online Module installed proceeding to next steps" # Write-Output "MSOnline online Module installed proceeding to next steps" | Out-File $OutPutFolder -Append Start-Sleep -Seconds 2 }else { Write-Host "MSOnline does not exist needs to be installed to proceed " # Write-Output "MSOnline does not exist needs to be installed to proceed " | Out-File $OutPutFolder -Append $isadmin = (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if ($isadmin) { Install-module MSOnline -Force } else { Write-Host "It Appears you did not run the script with administrative rights please run the script with administrative rights to proceed" # Write-Output "It Appears you did not run the script with administrative rights please run the script with administrative rights to proceed" | Out-File $OutPutFolder -Append Pause } } EditMailboxQuotasThe script is provided “AS IS” with no guarantees, no warranties, and it confer no rights.






