6. Identities
You
might have noticed the –Identity parameter in some of the cmdlets you
have explored so far. In many cases, a call to an Exchange cmdlet
results in a set of objects being returned (for example, all the
mailboxes on a server). In these instances, you might need to identify
a specific object within the chosen set with which to work. (Think of a
pointer to an item in an array.) For example, if you issue the
Get-ExchangeServer cmdlet, you retrieve a list of all the Exchange
servers in the organization. If you want to work with one server, you
have to tell EMS which server you want to select by passing its
identity. For example, to work with just the server named ExServer1:
Get-ExchangeServer –Identity 'ExServer1'
Apart
from its obvious use to identify the object with which you want to
work, –Identity has a special meaning within PowerShell because it is a
positional parameter. You can specify the parameter’s value without
specifying the parameter’s name, so the example previously used is just
as valid if you use:
Get-ExchangeServer 'ExServer1'
If you want, you can retrieve a
list of objects and store them in a variable and retrieve the values as
you wish. The variable holds the objects as an array. For example, to
populate a variable with a set of mailboxes hosted by a server:
$Mbx= Get-Mailbox –Server 'ExServer1'
To
retrieve the different objects in the array, pass the number of the
object with which you want to work, starting from zero. For example, to
fetch the first mailbox in the array:
$Mbx[0]
You
can be more specific and ask for one of the object’s properties. For
example, to get the identity of the first mailbox in the array:
$Mbx[0].Identity
IsDeleted : False
Rdn : CN=Eoin P. Redmond
Parent : contoso.com/Exchange Mailboxes
Depth : 3
DistinguishedName : CN=Eoin P. Redmond,OU=Exchange Mailboxes,DC=contoso,DC=com
IsRelativeDn : False
DomainId : contoso.com
ObjectGuid : 0bcd15b3-c418-43be-b678-2658614f732b
Name : Eoin P. Redmond
You
might be surprised by the amount of information returned here for the
mailbox’s identity (it’s all defined in the schema), but it contains
all the ways you can navigate to this object through its relative
distinguished name (shown here as the rdn property), distinguished
name, globally unique identifier (GUID), and name. Normally, you’ll
just use the name of a mailbox to find it, but you can use the other
methods, and Exchange will find the mailbox. There is no requirement to
parse out a specific piece of the identity you want to use or to trim
values; PowerShell does it all for you. For example, you can use an
identity to discover the groups to which a user belongs. Here’s the
code:
$U = (Get-User –Identity TRedmond).Identity; Get-Group | Where-Object {$_.Members –eq $U}
The
Get-User cmdlet loads the user’s identity into a variable, and then the
Get-Group and the Where-Object cmdlets scan all groups to discover any
that include the user in their membership. Scanning the membership list
of groups to discover string matches is never going to be as quick (and
will get slower as the number of groups in the forest grows) because a
string compare will never get close to the backward pointers that
consoles such as Active Directory Users and Computers or EMC use to
display group membership in terms of speed of access, so don’t be
surprised. Scanning for group membership in this way takes some time to
complete.
If you don’t like user-friendly forms such as email
addresses or mailbox names, Exchange also allows you to use GUIDs as
identifiers. Because they are obscure and long, GUIDs are difficult to
type, but you can still use them. One slightly complicating factor is
that you must know which GUID to use where. You might want the GUID
that points to a user’s mailbox, the GUID pointing to her Active
Directory account, or even the one pointing to her archive mailbox. For
example, this command displays all GUIDs registered for a mailbox:
Get-Mailbox –Identity 'Tony Redmond' | Format-List *Guid*
ExchangeGuid : c2c4a3b5-c1a6-5a17-971d-8549123a78d0
ArchiveGuid : 00000000-0000-0000-0000-000000000000
DisabledArchiveGuid : 00000000-0000-0000-0000-000000000000
Guid : 288617d1-4592-4211-bb20-26ab755458c8
The
ExchangeGuid property points to the user’s mailbox. This is a
tremendously important property because the GUID pointing to a mailbox
can be guaranteed to be unique across an Exchange organization, which
is why the Store uses this value to locate a user’s mailbox. It’s also
why Outlook users see the ExchangeGuid of their mailbox instead of the
server name when viewing the server name property shown when viewing
the server settings of an Exchange 2013 mailbox (Figure 3).
It
is confusing, but if you run Get-MailboxStatistics to retrieve summary
details of the contents of a mailbox, EMS returns a MailboxGuid
property. This is the same value as the ExchangeGuid when reported by
Get-Mailbox. Why Microsoft felt that two names were required for the
same GUID is beyond me.
The Guid property identifies the user’s
Active Directory account and thus provides the essential link between a
mailbox and an account. In this case, the ArchiveGuid is shown as all
zeros, so no archive mailbox is associated with this mailbox. The
DisabledArchiveGuid value is also all zeros. This GUID is used only
when a user has been assigned an archive mailbox that was subsequently
disabled for some reason. Exchange maintains the GUID so the archive
can be reconnected to the mailbox up to the point at which it is
permanently removed from a database after the expiry of the deleted
mailboxes’ retention period.
Now that you know what the GUIDs are, you could use them to reference a mailbox. For example:
$GUID = (Get-Mailbox –Identity 'Tony Redmond').Guid
Get-User | Where {$_.Guid –eq $GUID} | Format-Table Name
The
great thing about identities is that you sometimes don’t need to use
them. This situation occurs when you pipe information from one cmdlet
for processing by another because the shell understands that it needs
to operate on the current object that has been fetched through the
pipe. For example, this command pipes a list of mailbox identities
passed in strings to the Set-Mailbox cmdlet:
"TRedmond", "JSmith", "JDoe" | Set-Mailbox –Office "Dublin"
You’ll
pipe output from one cmdlet to another frequently as you work with
Exchange data. The important thing to remember is that PowerShell
outputs fully formed objects that can be manipulated when fed as input
to other cmdlets through the pipeline. This wouldn’t be possible if
PowerShell output text strings. For example, assume that you want to
change the value of the Office property for a set of users who have
moved to a new building. It would be tedious if you had to fetch the
identity of each user individually, determine each identity, and then
pass the value to make the change to each user’s properties. A simple
pipe works because PowerShell knows that it can use the stream of data
from one command to identify the objects it has to process with
another. Here’s how you might update the Office property for a complete
set of users without any mention of an identity. You’ll see that the
two cmdlets that do the work are separated by the pipe character, “|”.
This is the character that tells PowerShell to pipe the output from the
first cmdlet to become the input to the second.
Get-User –Filter {Office –eq 'Building A'} | Set-User –Office "Building B"