9 Non-User Objects

________________________

In This Chapter

  • Shared Mailboxes
  • Resource Mailboxes
  • Public Folder Mailboxes
  • Distribution Groups
  • Group Moderation
  • Office 365 Groups
  • Putting It All Together

________________________

In the previous chapter, we covered user mailboxes and their management with PowerShell. While most Exchange Online operations involve these user mailboxes, there are other non-user objects that need to be managed as well. These objects serve a variety of purposes in Exchange Online and include objects like Shared Mailboxes, Resource Mailboxes, Public Folder Mailboxes and Distribution Groups.

Shared Mailboxes provide a common mailbox for a group of users to access. They also provide a common address for sending emails out as a single email address. They can be used by departments as a shared inbox or calendar for departmental operations.

Resource Mailboxes can be used for various reasons, from rooms, to equipment to other resources that an organization may want to keep track of. Examples of resources are Rooms and Equipment mailboxes. Room Lists can also be created and managed with PowerShell.

Public Folder Mailboxes are used by Exchange Online to store Public Folder data. Gone are the days of Public Folder databases with SMTP replicas and separate management. Public folders in Exchange Online are easier to manage and control with PowerShell or with the Exchange Online interface.

Distribution Groups are used for mass mailing, for updates meant for a group or for granting access to a group of people to mail objects in Exchange Online. With PowerShell we can manipulate the characteristics of these groups, add and remove members and more. Groups can also be moderated to control the flow of messages and to prevent information overload or improper emails from being sent to groups.

Office 365 Groups are a metamorphosis of the current Distribution Groups. This type of group provides more than just mail flow like Distribution Groups. A newly created group adds something in SharePoint, Exchange, One Note, and Planner. We'll explore the Exchange Online side of these groups.

Shared Mailboxes

Shared Mailboxes are commonly used by organizations as either a central place for group emails to be delivered or as a single mailbox to be used as a public customer facing presence where a group of users can send as a single user. Some examples are Customer Service mailboxes like 'Help Desk' where the customers are internal users and 'Support' where the clients are external people that have purchased a company's product. Another user would be a 'Faxes' mailbox that would be used as a central location for all faxes coming into an organization that could be received and then forwarded on to the appropriate internal recipients. Additionally a shared mailbox could be used for solely a group calendar which for example could be used by marketing management and users to keep track of when people will be in the office or maybe when marketing events are occurring.

PowerShell

Like the previous chapter explained, creating a new user in PowerShell is done using the New-Mailbox PowerShell cmdlet. When creating a new shared mailbox, a special parameter needs to be used in order for the mailbox to be designated as a shared mailbox. The '-Shared' parameter is all that is needed in order for this to occur.

Example

In this example, the IT Manager has decided he wants the Help Desk to respond to emails from a single mailbox so that all communications are funneled through a central mailbox. The manager wants this because this ensures that end users reply to the Help Desk emails and not individuals. Because schedules for Help Desk workers vary greatly, a central mailbox will allow for other Help Desk employees to be able to pick up an existing case if the original Help Desk employee was off work due to scheduling or sickness.

Now we need to create the mailbox and then assign Full Mailbox and Send-As rights to all users in the Help Desk Active Directory group. First, let's create the shared mailbox:

New-Mailbox -Shared -Name "Help Desk" -DisplayName "Help Desk"

The Help Desk shared mailbox is now in Exchange Online and we need to assign rights to the mailbox for the Help Desk users to be able to send as the shared mailbox. For this part, there are two options for assigning the correct permissions for the Help Desk users. Either the rights can be assigned on a per-user or a per-group basis. For a group like the Help Desk, it would be more appropriate to use a group as the Help Desk group is likely to have a higher turnover rate than other groups. The other reason to use a group is that it is far easier to assign rights with groups than users. That way when a new Help Desk user is hired, in order to grant rights to the Shared Mailbox, all the admin has to do is to add the user to the group instead of using PowerShell to assign the rights.

PowerShell

How can permissions be added to mailboxes in Exchange via PowerShell? First, let's check for appropriate PowerShell cmdlets with the 'Permissions' keyword in them:

Get-Command *Permission*

As we can see above, there are a few cmdlets that are useful for manipulating mailbox permissions. In particular, the Add-MailboxPermission cmdlet looks like what we need to handle this. Reviewing the examples for the cmdlet, Example 3 appears to be what is needed for this example.

Now if the Help Desk users are all in a group called "Help Desk Users", we can first add the FullAccess permission as seen above to the Help Desk Mailbox:

Add-MailboxPermission –Identity "Help Desk" –User "Help Desk" –AccessRights FullAccess –InheritanceType All

** Note ** The group needs to be a security type group, not a distribution type group. The object needs to be either pre-created in a non-synced environment or a synced object if you have Azure AD Connect in place.

The 'InheritanceType' parameter is used to make sure the permissions are applied to all folders in the mailbox. We now need to assign the Send-As permissions. However, the Add-MailboxPermission cmdlet does not have an option for that. The available permissions are:

FullAccess ExternalAccount DeleteItem

ReadPermission ChangePermission ChangeOwner

Notice that Send-As is not included in the above list. So if this is not a mailbox level permission, where else can rights be assigned? In Office 365 we need to use a cmdlet called 'Add-RecipientPermission' cmdlet like so:

Add-RecipientPermission -Identity 'Help Desk' -Trustee 'Help Desk Users' -AccessRights 'SendAs'

Now users from the Help Desk can send as the Help Desk and not themselves:

Example

In another scenario, the IT Department has received a request to produce a list of all shared mailboxes and a list of who has permissions for each mailbox. The rights that should be reported on are Send-As and Full Mailbox permissions. As we saw from the previous example, assigning these rights requires different PowerShell cmdlets (Add-ADPermission, Add-MailboxPermission and Add-RecipientPermission). We can safely assume that there are multiple cmdlets needed to query these. One more criteria we need to consider – whether or not the right was assigned directly (not inherited) by an Administrator or if the right was inherited and not assigned by an admin. From the request, it appears there is no distinction, just a report of the rights that are assigned on a mailbox. As such we will just look for 'Full Access' and 'Send-As' permission on the mailbox.

Let's start with the mailbox permission set with Add-MailboxPermission. From the previous page (top) we see a cmdlet called Get-MailboxPermission. For this environment, we will use a mailbox called "Help Desk" which has these permissions assigned to it, as our way to work out our PowerShell for all mailboxes.

First, let's see what PowerShell can reveal to us:

Get-Mailbox 'Help Desk' | Get-MailboxPermission | FT -Auto

From that one-liner we don't see the permissions assigned to the mailbox. Remember how we applied the Send-As permission with the Add-RecipientPermission? Well there is a corresponding cmdlet to query this with 'Get-RecipientPermission' to display those explicit rights:

Get-Mailbox "Help Desk" | Get-RecipientPermission

Now we can also go back to the Get-MailboxPermission cmdlet to filter down the results a bit. We need to remove any Organizational admins, NT Authority accounts and generally filter it down to users and groups that you care about. This one-liner should about do it:

Get-Mailbox "Help Desk" | Get-mailboxPermission | Select-Object Identity,User,AccessRights | Where {($_.User -NotLike "*SELF") -And ($_.User -NotLike "NT Auth*") -And ($_.User -NotLike "NAMPRD*")}

One of the filters that was use, filters for users like like NAMPRD. This abbreviation is specific to mailboxes in Noth AMerica and thus this filter will vary per region in Office 365. Notice at the bottom of the list there is a 'JitUsers'. This is a Built In group from Office 365. JIT stands for Just In Time Administration. If you want to exclude that from the list, you can use this:

Get-Mailbox "Help Desk" | Get-mailboxPermission | Select-Object Identity,User,AccessRights | Where {($_.User -NotLike "*SELF") -And ($_.User -NotLike "NT Auth*") -And ($_.User -NotLike "NAMPRD*") -and ($_.User -NotLike '*JITUsers')}

Resource Mailboxes

There are two types of Resource Mailboxes in Exchange Online – Room and Equipment. The room mailbox is generally used to designate rooms that will be used by more than two people for meeting purposes. Whether these are large or small conference rooms, stand up only spaces or maybe even the lunch room, the purpose of a room mailbox is to provide a central scheduling place for users within Exchange. Calendars on room mailboxes operate differently than calendars for regular users and can be tweaked to handle different booking scenarios (AutoBooking and restricted hours) in an organization. A resource mailbox is generally used for items that can be checked out for a certain time period like projects, or TVs or maybe even vehicles for a company.

Equipment Mailboxes

Examples of equipment mailboxes are projectors, cars, laptops and more. By creating a mailbox in Exchange your users will be able to use their own mailbox calendar to book or request the booking of equipment that may be used for example in a client presentation. By its definition equipment should be portable or something that one of your users can transport.

Example

For this example we have a sale department with a hundred sales people that constantly travel to client sites to help present new products or to inform potential clients about the services your company provides. These sales people use a series of projectors for their presentations. The projectors range from the small travel projectors to the larger, more professional and higher quality projectors. The sales people and IT management would like to create these as objects in Exchange so that the sales people can check them out. The idea is that instead of constantly asking about the availability of equipment, the sales people would be able to confirm availability and schedule meetings with the equipment to secure the projects for a certain amount of hours / days.

Some of the projectors (the larger ones) require the approval of Sales Managers. The reason is that the larger projectors are expensive company property and need to be properly tracked. Some have gone missing over the years due to mismanagement.

PowerShell

Creating a mailbox for the projects is the same as creating a user mailbox, with the exception of a –Equipment parameter being added to designate the mailbox as an equipment mailbox:

New-Mailbox –Name "Portable Projector 1" –Equipment

Now that the mailbox is in Exchange we can modify some settings. For the smaller projectors, we need to make sure that they are available for AutoBooking and restrict to only be bookable by the Sales Department. How do we do this? Set-CalendarProcessing. This cmdlet can be used with any mailbox. It is especially useful for Equipment, Shared and Room mailboxes.

Let's review some examples from the cmdlet:

From these examples, we can use the bottom example for our cmdlet to enable resource mailbox scheduling and make sure to include this parameter:

–AutomateProcessing AutoAccept

The request also stated that only users in the Sales Department can reserve the equipment. Reviewing examples from the same cmdlet we see that there is an option to do this as well:

Reviewing Get-Help for Set-CalendarProcessing, the BookInPolicy states that:

"The BookInPolicy parameter specifies a comma-separated list of users who are allowed to submit in-policy meeting requests to the resource mailbox. Any in-policy meeting requests from these users are automatically approved."

By default all users should be blocked from automatically booking a room. Putting together the two parameters, we get:

Set-CalendarProcessing "Portable Projector 1" –AutomateProcessing AutoAccept –BookInPolicy "Sales Dept"

Now when someone from the Sales Department wants to book this projector they can. Now, if we want to restrict all projectors with the word 'Projector' in the name to just the Sales Department we first need a way to get a list of all of these projectors:

Get-Mailbox -Filter {(RecipientTypeDetails -eq "EquipmentMailbox") -and (Name -Like "*projector*")}

The '–filter' parameter allows for the result set of 'Get-Mailbox' to be shrunk to only mailboxes that are Equipment and have 'projector' in the name.

Equipment Mailbox Management

When all the equipment mailboxes are created, a report on the equipment mailboxes can be generated with:

Get-Mailbox -Filter {RecipientTypeDetails -eq "EquipmentMailbox"}

Or:

Get-Mailbox -RecipientTypeDetails EquipmentMailbox

Using the above one-liner, we can now perform mass manipulation on a group of mailboxes based solely on the type of mailbox specified. For example, we can change the calendar processing for this. First, let's see what the default setting is on this new mailbox we created:

Get-Mailbox -Filter {RecipientTypeDetails -eq "EquipmentMailbox"} | Get-CalendarProcessing

Now if we want to change the setting to be AutoAccept using this one-liner, we can use this example:

Which gives us syntax we can apply with our filter above:

Get-Mailbox -Filter {RecipientTypeDetails -eq "EquipmentMailbox"} | Set-CalendarProcessing -AutomateProcessing AutoAccept

Room Mailboxes

Room mailboxes are by far the most used and configured of the resource mailboxes in Exchange. Room mailboxes need more care and maintenance to get them into useful order. Rooms can be large or small and designated as such in the capacity property. They can even be organized into lists. Let's see what we can do with rooms with PowerShell.

Example

Take for example a large organization that has a dozen locations in the US and Asia. Each of these locations has dozens of rooms. IT Management has been given the directive to create a series of rooms for each location. The naming of the rooms needs to be easy for end users to interpret which location and / or what floor a room is on. Groups of rooms should also be created if possible in order to help the end user find an appropriate room or even just an available room in a quick manner. First, we need to create all of the rooms. For this scenario we will use this list of locations:

US Asia

Orlando Tokyo

Dallas Taipei

San Diego Seoul

Denver Shanghai

New York Singapore

Seattle Hong Kong

For the sake of this book, we will concentrate on one site in the US and one site in Asia to work on creating and configuring these rooms per management's requirements. We will use PowerShell to create the rooms and then configure booking options for each room. In order to facilitate the creation of the rooms, a CSV file is prepopulated with details such as the region the room it's in, what city, the floor the room is on, a description, capacity and phone number. The same CSV file is below:

Region,City,Floor,Description,Capacity,Phone

US,Orlando,1,SW,20,"+1 (407) 220-1212"

US,Orlando,1,SE,20,"+1 (407) 220-1213"

US,Orlando,1,NW,20,"+1 (407) 220-1214"

US,Orlando,1,NE,25,"+1 (407) 220-1215"

US,Orlando,1,Large,50,"+1 (407) 220-1216"

US,Orlando,2,SW,20,"+1 (407) 220-2212"

US,Orlando,2,SE,15,"+1 (407) 220-2213"

US,Orlando,2,NW,20,"+1 (407) 220-2214"

US,Orlando,2,NE,20,"+1 (407) 220-2215"

US,Orlando,2,Large,40,"+1 (407) 220-2216"

US,Orlando,3,SW,20,"+1 (407) 220-3212"

US,Orlando,3,SE,20,"+1 (407) 220-3213"

US,Orlando,3,NW,20,"+1 (407) 220-3214"

US,Orlando,3,NE,20,"+1 (407) 220-3215"

US,Orlando,3,Small,5,"+1 (407) 220-3216"

US,Orlando,4,SW,15,"+1 (407) 220-4212"

US,Orlando,4,SE,15,"+1 (407) 220-4213"

US,Orlando,4,NW,25,"+1 (407) 220-4214"

US,Orlando,4,NE,20,"+1 (407) 220-4215"

US,Orlando,4,Small,10,"+1 (407) 220-4216"

US,Orlando,5,Amphitheater,100,"+1 (407) 220-5212"

US,Orlando,5,"Standing Room",75,"+1 (407) 220-5213"

US,Orlando,5,NW,25,"+1 (407) 220-5214"

US,Orlando,6,Executive,10,"+1 (407) 220-6212"

Asia,Seoul,10,SW,15,+82-02-505-1212

Asia,Seoul,10,SE,15,+82-02-505-1213

Asia,Seoul,10,NW,15,+82-02-505-1214

Asia,Seoul,10,NE,15,+82-02-505-1215

Asia,Seoul,10,Large,30,+82-02-505-1216

Asia,Seoul,10,Small,5,+82-02-505-1217

Asia,Seoul,15,SW,20,+82-02-505-2212

Asia,Seoul,15,SE,15,+82-02-505-2213

Asia,Seoul,15,NW,20,+82-02-505-2214

Asia,Seoul,15,NE,15,+82-02-505-2215

Asia,Seoul,15,Large,50,+82-02-505-2216

Asia,Seoul,16,SW,15,+82-02-505-3212

Asia,Seoul,16,SE,15,+82-02-505-3213

Now that a list of rooms is stored in a CSV file we can create a script that will read each line in the CSV file and create a room based off this information.

Sample Script

First section reads in the CSV we created above:

$Rooms = Import-CSV C:ScriptingRoomList.csv

Next, using a Foreach loop, the $Rooms variable is looped to go through each line:

Foreach ($Room in $Rooms) {

$Region = $Room.Region

$City = $Room.City

$Floor = $Room.Floor

$Location = "$Region-$City"

$Capacity = $Room.Capacity

$Phone = $Room.Phone

$Description = $Room.Description

$Roomname = "$City"+"-Floor-"+"$Floor"+"-"+"$Description"

Once the variable and values for the room are set, the New-Mailbox cmdlet is used to create the rooms as needed in the organization:

# Create mailbox with criteria from CSV file

New-Mailbox -Room -Name $RoomName -Phone $Phone -ResourceCapacity $Capacity -Office $Location

}

A sample run shows the rooms being created:

Room Lists

Once rooms have been created in Exchange, a new feature can be used called Room Lists. Think of Room Lists as groups of rooms that are logically put together by location.

PowerShell

Let's start out by looking for cmdlets that we can use to manage these lists. As a forewarning, it's not located where you think:

Get-Command *Room*

Get-Command *List*

Neither reveal any useful information. So how do I get the right cmdlet? Use a Search Engine.

Search Terms: Exchange PowerShell Room Lists

So according to the results list above, a Room List can be created as part of a Distribution Group creation. Reviewing the Get-Help for New-DistributionGroup you will see the 'RoomList' parameter:

So the Room List parameter allows for a group of rooms to be stored as members of a Distribution Group and seen by the client as a grouping of Rooms.

PowerShell

Using the rooms we created above, let's see if we can create a list of all room mailboxes in Orlando. Now, it would be nice if the New-DynamicDistributionGroup had a switch for Room Lists, but it does not. So any rooms added will be a manual process.

First, we can store all Rooms that start with Orlando in a variable called $Members:

$Members = Get-Mailbox -Filter {Name -Like "Orlando*"} | Where {$_.RecipientTypeDetails -eq"RoomMailbox"} | select -ExpandProperty Alias

After that, a new Distribution Group can be created with the –RoomList parameter and members added from the $Members variable:

New-DistributionGroup -Name "Orlando Meeting Rooms" -DisplayName "Orlando Meeting Rooms" -RoomList -Members $Members

Verifying that the group has all the room mailboxes in it:

Get-DistributionGroupMember -Identity "Orlando Meeting Rooms"

Now when a new meeting is created and 'Add Rooms' is chosen, the List appears instead of each individual room:

New room lists will begin to populate and display when the 'Add Rooms' button is used:

Clicking on the Seoul Room List, a list of available rooms appears for the user:

Room Lists can become very useful in organizations with either a lot of rooms, or a highly organized set of rooms and their names. Regular Distribution Groups can also be converted into Room Lists as well.

Public Folder Mailboxes

Exchange 2013 introduced a new paradigm for the way Public Folders operate. Instead of a database for Public Folders, a series of mailboxes in a regular mailbox database store all the Public Folder data, including the hierarchy. The reasoning was that Public Folder replication was notoriously problematic and used SMTP to make copies on other Public Folder Databases. This had the potential to clog up SMTP queues. Exchange Online takes the same approach. If you are creating Public Folder content in Exchange Online, then you will need to create Public Folder mailboxes and then Public Folders. Either Exchange on-premises or Exchange Online can host Public Folders, but not both.

PowerShell

First, we'll explore what PowerShell cmdlets are available for Public Folders:

Get-Command *PublicFolder*

What we see from the above is that there is no direct cmdlet for creating a Public Folder mailbox. We know that Public Folders require Public Folder mailboxes, so what about the New-Mailbox cmdlet? Is there a parameter for this?

Get-Help New-Mailbox –Full

Public Folder mailboxes can be created with a simple one-liner that requires only two parameters – the first is '-PublicFolder' and the second is '-name':

New-Mailbox –PublicFolder –Name "Public Folder 1"

To verify that the mailbox was created, simple run:

Get-Mailbox -PublicFolder

Once mailboxes have been created, Public Folder(s) can be created in order to store data. The cmdlet we need is New-PublicFolder. What examples are provided by Microsoft?

First, we will create a Root Public Folder to hold other Public Folders for the IT Department.

New-PublicFolder -Name 'IT Department' -Path ''

Then we can create sub-Public Folders under the root of 'IT Department'.

New-PublicFolder -Name 'Testing' -Path 'IT Department'

You can keep creating folders like, or via a script, as needed.

Distribution Groups

Distribution Groups in Exchange Online come in two different varieties – Dynamic and Static. Static groups are ones where the membership needs to be added or removed manually with PowerShell, Exchange EAC or Active Directory Users and Computers. A Dynamic Distribution Group builds its membership based on a set of criteria you define and thus the members that appear in the group are dynamic. This means that, based on the criteria for a group, if a user no longer meets that criteria, the user does not appear as a member of the group. If a user object is modified to meet the criteria again, it will then appear as a member of the group again. The distinction is also important in PowerShell as there exists two different sets of cmdlets for each group type.

PowerShell

First, let's review what cmdlets are available for distribution groups (dynamic or regular):

Get-Command *Distribution*

Now that we have a list of PowerShell cmdlets to use, let's use the New-DistributionGroup cmdlet to create some groups for Exchange:

Get-Help New-DistributionGroup –Examples

The examples given by PowerShell are rather basic and if more options are desired, then make sure to run:

Get-Help New-DistributionGroup -Full

Some sample options that can be chosen for the group are:

RequireSenderAuthenticationEnabled – This parameter determines if only internal users can send emails to the group or if external senders are allowed.

MemberJoinRestriction – If the group membership needs to be controlled, use this option to set 'ApprovalRequired' which will allow the membership to be managed.

MemberDepartRestriction – Conversely, the opposite of the above option, this is for users wishing to leave a group, the same controls can be put into place as those wishing/needing to join a group.

ManagedBy – Assigns a user the role of managing the group for approvals, removals, approve moderation requests and more.

Management

In Exchange, Distribution Groups can be used for many purposes. Whether they are used to represent parts of a company (e.g. All Users, North American Users and Paris Users). Or for a specific notification for IT (e.g. Alerts), they all need to be managed and maintained. In most organizations there will be group sprawl with groups going unused or forgotten and even completely emptied of all users without removal. Proper management and pruning of these extraneous groups allows for more efficient management. For the scenario below we'll explore a couple of items that can be managed for groups.

Example

In this scenario, we have an environment that has grown from Exchange 2000 and steadily updated Exchange and have now migrated to Exchange Online. The company has also grown from 50 users to well over 2,000 users through organic growth and acquisitions. Now the messaging team has decided to do some cleanup. There are 1,000 distribution groups that have been created over the past 15 years by various administrators. No one in the organization can say for sure which groups are needed and which are not.

In this scenario, we need to evaluate two criteria – number of members in a group and if any emails have gone to the group. The first is relatively easy as we simply need to query each group to see if it contains members. For the second, determining mail flow to groups requires a bit of legwork and keeping track of active groups. From the list of cmdlets above, we see there is a cmdlet specifically for distribution group members. What do the examples for this cmdlet provide to help us query for empty groups:

Not much to go on with the included examples for the cmdlet. However, when the cmdlet is run against a distribution group in Exchange, it reveals the members of that particular group. For our scenario, we have 1,000 distribution groups to query and get members from. This will require each group name to be piped from Get-DistributionGroup to the Get-DistributionGroupMember cmdlet in a Foreach loop. Two loops will be needed as each group type (dynamic and regular) need to be handled separately.

To determine which groups are empty, we first need to get a complete list of groups and store the groups in a variable:

$DistributionGroups = Get-DistributionGroup -ResultSize Unlimited

Once a list of groups is stored in $DistributionGroups we can now go through each group in a Foreach loop:

Foreach ($Group in $DistributionGroups) {

Notice the naming of variables was done for ease of keeping track of the current context, whether it's all groups ($DistributionGroups) or the current group in the list ($Group). In addition, we'll use a variable as a counter to keep track of distribution groups with no members ($N) – we'll set this to 0 before the Foreach loop.

For the next line we query the current Distribution Group in the loop for members:

$Members = Get-DistributionGroupMember -Identity $Group.DisplayName

Then, using an IF statement, the $Empty variable is checked to see if it is empty:

If ($Members -eq $Null) {

If this variable has no value assigned, then no members were found that are in the current group. This is reported to the PowerShell window with the Write-Host statement. The $N++ is an incremental counter:

Write-Host "The group $Group is an empty Distribution Group." -ForegroundColor Yellow

$N++

At the very end of the script we'll check to see if $N is equal to zero and if it is, then no empty groups have been found:

If ($N -eq 0) {

Write-Host "No empty Distribution Groups were found." -ForegroundColor Cyan

}

If there are no empty groups, then the script will report that:

When there are groups present with no members, the script will report them like so:

Dynamic Groups require a slightly different tactic. The line that queries for members has to be different because a dynamic group doesn't have actual members, virtual membership is calculated at query time for these groups.

Regular group members

$Members = Get-DistributionGroupMember -Identity $Group.DisplayName

Dynamic group members

$GroupDetails = Get-DynamicDistributionGroup $Group.DisplayName

$Members = Get-Recipient -RecipientPreviewFilter $GroupDetails.RecipientFilter

Note, the RecipientFilter is used to find all recipients that match the filter on the dynamic group.

Complete Script Code – Empty Distribution Groups

# Get a list of all empty distribution groups

$DistributionGroups = Get-DistributionGroup -ResultSize Unlimited

Write-Host "-- Empty Distribution Group report --" -ForegroundColor Green

Write-Host " "

$N = 0

Foreach ($Group in $DistributionGroups) {

$Members = Get-DistributionGroupMember -Identity $Group.DisplayName

If ($Members -eq $Null) {

Write-Host "The group $Group is an empty Distribution Group." -ForegroundColor Yellow

$N++

}

}

If ($N -eq 0) {

Write-Host "No empty Distribution Groups were found." -ForegroundColor Cyan

}

Script Code – Empty Dynamic Distribution Groups

CLS

$DynamicDistribution = Get-DynamicDistributionGroup

Write-Host "-- Empty Dynamic Distribution Group report --" -ForegroundColor Green

Write-Host " "

$N = 0

Foreach ($Group in $DynamicDistribution) {

$Members = Get-Recipient -RecipientPreviewFilter $Group.RecipientFilter

If ($Members -eq $Null) {

Write-Host "The group $Group is an empty Dynamic Distribution Group." -ForegroundColor Yellow

$N++

}

}

If ($N -eq 0) {

Write-Host "No empty Dynamic Distribution Groups were found." -ForegroundColor Cyan

}

Get-MessageTrace

If you are used to tracking messages for emails in Exchange on-premises, then you will have to retrain yourself for tracking messages for Exchange Online. This is because you don't have direct access to the log files, using Get-MessageTrackingLog, and instead have to use the Get-MessageTrace cmdlet. The Get-MessageTrace cmdlet behaves different because of these environmental differences. What we also discover is that because of what would appear to be throttling, adjustments may need to be made in how messages are traced based on the size and email volume of your environment.

First we need to review what Get-MessageTrace can do and what is available in the Get-Help for the cmdlet.

Get-Help Get-MessageTrace -Examples

Not too complicated. However, if we review the full help for the cmdlet there are a couple of options that appear peculiar at first. These are '-Page' and -'PageSize':

-Page

The Page parameter specifies the page number of the results you want to view. Valid input for this parameter is an integer between 1 and 1,000. The default value is 1.

-PageSize

The PageSize parameter specifies the maximum number of entries per page. Valid input for this parameter is an integer between 1 and 5,000. The default value is 1,000.

Each of these refers to how many results that can be pulled from the logs. This means by default, we can pull 1 full 'page' of results which provides up to 1,000 results. Other cmdlets in Exchange / Exchange Online have a '-ResultSize' parameter that could potentially be set to 'Unlimited'. However, there is no parameter for MessageTrace for Get-MessageTrace. As such, we need to use the 'Page' and 'PageSize' parameters to provide a larger result set. How can we do this? A sample trace for all messages from myself ([email protected]) to an external recipient ([email protected]) for the past month, could be done like so:

Get-MessageTrace -SenderAddress '[email protected]' -RecipientAddress '[email protected]' -StartDate '11/03/2017' -EndDate '12/03/2017'

** Note ** With Get-MessageTrace, we are limited to a max total of 30 days of data to pull results from.

On a relatively quiet tenant with a low number of messages, this might succeed. However, what you will find is that if the mail system is rather active, the search only actually reviews a very small portion of messages. For example, a university with 30,000 people with an EDU tenant might have students sending three emails a day on average and that gives us 90,000 potential emails per day. Imagine the limitations of 1,000 emails now. There is no way to review all of these emails with the default 'pagesize' and 'pages'.

What can we do to handle this number of messages? First we'll use the 'page' and 'pagesize' parameters to provide a larger window to review messages. The default 'pagesize' is 2,000 and has a maximum value of 5,000. For this PowerShell sample code we'll use 5,000:

$PageSize = 5000

Now we'll set the initial page to 1 since we'll want to start at the first page of results:

$Page = 1

We'll need a date range of a month, just like the first trace we ran above.

$StartDate = '11/03/17 12:01AM'

$EndDate = '12/03/17 11:59PM'

Using these parameters in a real world scenario we can examine how many messages were filtered as SPAM by EOP before they get delivered to these same 30,000 EDU users. For this I will run a loop of results. The other caveat you will find is that there is a maximum of 200 pages that can be examined as well. For a small environment that may not be an issue, but for a larger environment, it might make the date range a bit of an issue depending on number of messages processed.

In the below script, we use the values from the variables above and place them into a '# Variable Block' at the top of the script.

# Variable Block

$Page = 1

$PageSize = 5000

$TotalCount = 0

$Start = '11/29/17 12:01AM'

$End = '12/03/17 11:59PM'

A 'Do...While' loop is used to handle the 200 page limit. Inside the loop a Get-MessageTrace is run against each 'page' of 5,000 messages. Two variables are used, one ($Results) is used for filtering all messages for Spam and the second variable ($Results2). The $Count variable is used to keep track of the total number of Spam messages.
We also are filtering the results for a specific Status property value of 'FilteredAsSpam'.

Do {

$N = 1

$Results = Get-MessageTrace -StartDate $Start -EndDate $End -Page $Page -PageSize $PageSize | Where {$_.Status -eq 'FilteredAsSpam'}

$Results2 = Get-MessageTrace -StartDate $Start -EndDate $End -Page $Page -PageSize $PageSize

If ($Results2 -eq $Null) {

$Page = 201

} Else {

$Results2[0].Received

$Count = $Results.Count

Write-Host "Found $Count SPAM messages." -ForegroundColor Cyan

Write-Host "Page Number - $Page" -ForegroundColor Yellow

$Page++

}

} While ($Page -lt 200)

When run against a large amount of messages, expect to see results like this:

Notice there is about a two hour time difference between the pages, with hundreds of messages found between the timestamps. Another reason for the date/timestamp is to allow us to narrow down a date range if we need to. The difficulty becomes how to work with the two hundred page limit. If we know that each page is two hours and that there is a two hundred page limit, that means that we can work with a four hundred hour window for the script. Thats about a two week window.

This method could be used to find any sort of messages or even a lack of messages if we need to filter for a reverse scenario of missing messages.

Group Moderation

Emails to groups sometimes need to be moderated. Examples of this moderation occur with groups that contain C level management which may not want emails from just anyone in the company. Dynamic Groups such as 'All Employees' are also ones that should be controlled to prevent mass emails of 'ReplyAll' which can cause havoc or even embarrassment in the organization. Depending on the size of the organization, message approvers could be a single individual or a group of users responsible for this task.

PowerShell

To see what can be done in PowerShell, we can review the Get-Help for the Set-DistributionGroup:

Get-Help Set-DistributionGroup

From the above list of parameters we see there are two parameters for handling moderation of distribution groups. Reviewing the detailed description of these parameters we can get an understanding of what they are used for:

Combined, these two values enable control of message flow to a particular group. Below is an example of how to configure moderation on a Distribution Group called 'Sales Dept':

Note that when this is set, a Mail Tip might be displayed for users in OWA or Outlook depending on other configuration settings:

Controlling Group Mail Flow

If moderators are not desired, other controllers can be put in place such as restricting who can send to the group or if external senders can send to an internal group. Restrictions as to who can send to the group or who are blocked from sending to the group can also be set if so desired.

To control these settings we can review the list of parameters from the last section. The appropriate settings are as follows:

AcceptMessagesOnlyFrom AcceptMessagesOnlyFromDLMembers

AcceptMessagesOnlyFromSendersOrMembers RejectMessagesFrom

RejectMessagesFromDLMembers RejectMessagesFromSendersOrMembers

Depending on what the desired restrictions are for a group, we can pick from the above list to configure these restrictions.

Example 1

Take for example a company that has a group specifically for Sales. The Sales Department would like to restrict emails so that only users within the Sale Group can email the Sales Group distribution list. From the above parameters, it appears that either 'AcceptMessagesOnlyFrom' or 'AcceptMessagesOnlyFromDLMembers' would work. However, the restriction is for only group members so 'AcceptMessagesOnlyFromDLMembers' would be the ideal option for this scenario. Reviewing the parameter from Get-Help we can see that this acts like an Access Control List (ACL) on a distribution group:

Set-DistributionGroup "Sales Dept" –AcceptMessagesOnlyFromDLMembers "Sales Dept"

Prior to a message being sent to the group from someone outside the group they will now receive a Mail Tip:

The end user also received an NDR:

Users in the Sales Department group will not receive a Mail Tip and will be the only ones who can send to this distribution group.

Example 2

In another example a group has been created for C Level Executives and the directive from IT Management is that only direct reports may send emails to this new group. The group is called 'Company Executives' for this example.

We can then use PowerShell to get a list of the direct reports for each C Level executive:

First, we clear the array variable we will use to store the users allowed to send to this group:

$TeamMembers = @()

Next store the group name in a variable for use in the script:

$Group = "Company Executives"

Then all the members of the group are also stored in a variable. In order to do this, we use the Get-DistributionGroup and feed this to the Get-DistributionGroupMember command to get the members of $Group:

$Members = Get-DistributionGroup $Group | Get-DistributionGroupMember

Then a Foreach loop will read through each line in $Members to get all members and their direct reports:

Foreach ($Member in $Members) {

Within this loop, we first get the DistinguishedName of each member and add it to $TeamMembers:

$TeamMembers += $Member.DistinguishedName

Next, the DistinguishedName of all users with that manager are added to $TeamMembers:

$TeamMembers += (Get-User -Properties * -Filter {Manager -eq $Member.DistinguishedName}).DistinguishedName

}

With the $TeamMembers variable now storing all members of the group, their direct reports, and the loop finished, we need to remove any duplicates from $TeamMembers:

$TeamMembers = $TeamMembers | Select -Unique

Then the AcceptMessagesOnlyFrom parameter is set for the group with the $DirectReports:

Set-DistributionGroup $Group -AcceptMessagesOnlyFrom $DirectReports

Once set, we can verify the users are correctly configured:

Get-DistributionGroup $Group | FT AcceptMessagesOnlyFrom

Office 365 Groups

Office 365 Groups are the latest iteration of Distribution Groups with a twist. The group is not solely used in Exchange Online and functions similarly to Site Mailboxes from on-premises Exchange in that the historical content is accessible by a group of user. The group provides access to shared Yammer, SharePoint, Planner and Exchange resources. Make sure to verify licensing before activating this feature in Exchange Online.

The Group will be available for Outlook and OWA users. With either platform the group will allow be greater interaction, sharing and features than a typical Distribution List as it isn't all about email any more. More features are linked to a group to enhance their experience together as a group.

To make the most use of these new groups, great a test group and pilot them out to make that the features make sense before a roll-out to end users in your environment.

PowerShell

Office 365 Groups have their own set of PowerShell cmdlets, but the noun used for the cmdlets is not an obvious one. That's because we need to look for cmdlets with the phrase 'UnifiedGroup' in them. A Unified Group is an Office 365 Group.

Get-Command *UnifiedGroup*

By default, there are no Unified or Office 365 Groups in your Exchange Online tenant. That can be verified with the Get-UnifiedGroup cmdlet. Since we have not groups to explore initially, let's create a group so we can that review the object in Exchange Online.

Get-Help New-UnifiedGroup -Examples

Following the above basic example, we get this result while creating a group for the IT Department:

Great! Now we have an Office 365 Group. What Next? Let's check out it's properties:

In the properties there are a lot of options that could prove useful for this Office 365, depending on what the purpose of the group is, however these are not all exposed on PowerShell as of the writing of this book.

  • Hidden
  • Moderation settings

Converting Existing Group to Office 365 Group

As of the writing of this book, Microsoft is pushing to convert regular distribution groups to Office 365 groups:

This isn't necessarily a good or bad thing. Microsoft is a software company that would like it's end users to use all the features it spends time and money to create. The higher visibility will drive some customers to adopt this feature. However, the push to convert existing groups to Office 365 Groups may not be the wisest choices or even a necessary choice. A modern way to enable collaborate within organization groups. Office 365 Groups achieve this with the following elements:

  • Shared inbox
  • Shared files library
  • Shared calendar
  • Shared OneNote notebook
  • Guest access
  • Content is discoverable
  • Self-Service creation

As we can see, groups can be upgraded from the GUI with a couple of options. We can also do this with PowerShell. How can we do this? First we need to find groups that can be upgraded:

Get-EligibleDistributionGroupForMigration

If we had more than one group, it would show in this list above. Upgrade-DistributionGroup -DLIdentities @('[email protected]')

That's all it takes to convert an existing Distribution Group to an Office 365 Group.

Putting It All Together

Combining some knowledge from Chapter 8 and this chapter, we'll write a script that can provide a useful reporting script on mailboxes and groups within Exchange Online. Let's take a typical environment that has user, shared, room, equipment and public folder mailboxes. There are also regular and dynamic distribution groups. You'd like to have a quick report that was generated by PowerShell that was able to display the number of mailboxes of each type, number of groups by type and the sizes of each mailbox category.

In the below script, we can use Get-Mailbox, Get-DistributionGroup, Get-DynamicDistributionGroup and Get-MailboxStatistics to do this. For finding each mailbox type, we look for a value called "RecipientTypeDetails". Why use that? Because it provides the mailbox differentiation information we need.

Script Code

This first section uses the 'Get-Mailbox' cmdlet to get a list of mailboxes. The '-filter' parameter allows for a filter based on one mailbox property, which in our case is 'RecipientTypeDetails'. This attribute was chosen because it stores the type of mailbox the object is. Next, the ().Count bracket is used in order to get a count of whatever is returned from within the parentheses:

# Get mailbox and group counts per type

$DistributionGroupCount = (Get-DistributionGroup).Count

$DynDistributionGroupCount = (Get-DynamicDistributionGroup).Count

$AllMailboxCount = (Get-Mailbox).Count

$UserMailboxCount = (Get-Mailbox -Filter {RecipientTypeDetails -eq "UserMailbox"}).Count

$SharedMailboxCount = (Get-Mailbox -Filter {RecipientTypeDetails -eq "SharedMailbox"}).Count

$PublicFolderMailboxCount = (Get-Mailbox -PublicFolder).Count

$EquipmentMailboxCount = (Get-Mailbox -Filter {RecipientTypeDetails -eq "EquipmentMailbox"}).Count

$RoomMailboxCount = (Get-Mailbox -Filter {RecipientTypeDetails -eq "RoomMailbox"}).Count

For this last section of the script a visual report will be displayed in the PowerShell window which will give mailbox and group counts as well as the sizes of each type of mailbox in Exchange:

Write-Host "Number of Mailboxes found:" -ForegroundColor Green

Write-Host "-------------------------" -ForegroundColor Green

Write-Host "User Mailboxes: $UserMailboxCount." -ForegroundColor White

Write-Host "Shared Mailboxes: $SharedMailboxCount." -ForegroundColor White

Write-Host "Room Mailboxes: $RoomMailboxCount." -ForegroundColor White

Write-Host "Equipment Mailboxes: $EquipmentMailboxCount." -ForegroundColor White

Write-Host "Public Folder Mailboxes: $PublicFolderMailboxCount." -ForegroundColor White

Write-Host " " # Blank line for formatting

Write-Host "Number of Distribution Groups" -ForegroundColor Green

Write-Host "Distribution Groups: $DistributionGroupCount." -ForegroundColor White

Write-Host "Dynamic Distribution Groups: $DynDistributionGroupCount." -ForegroundColor White

Write-Host " " # Blank line for formatting

A quick run of the script generates a little concise report for Exchange:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.19.30.232