Active Directory is a huge dependency for Exchange, and it
makes a lot of sense to be able to manage Active Directory through
PowerShell. This was not always possible, but on Windows Server 2008 R2
SP1 servers, all you need to do is load the Active Directory Module for
PowerShell that’s installed under Administrative Tools. Assuming that
the Active Directory module is available on a server or client, you can
load it into any PowerShell session by using the following command:
PS C:\> Import-Module ActiveDirectory
The
Active Directory module is loaded automatically into EMS on Windows
2012 servers, so you can execute commands against Active Directory data
immediately. To get a list of the Active Directory cmdlets, type:
PS C:\> Get-Help *-AD*
In
terms of navigation through the directory structure, Active Directory
is represented to PowerShell like files on a hard drive that is
referenced as the AD: drive. If your system is joined to a domain, you
can then navigate Active Directory. For example, here’s how to create a
new organizational unit (OU) called Marketing after navigating to the
desired location in Active Directory. You can see the same in Figure 1.
PS C:\> CD AD:
PS AD:\> CD "DC=contoso,DC=com"
PS AD:\DC=contoso, DC=com> MD "OU=Marketing"
To
compare how much easier it is to access Active Directory data by using
the new module, the command to retrieve a list of domain controllers is:
PS C:\> Get-ADDomainController | Format-Table Name, OperatingSystem
Name Operatingsystem
---- ---------------
CONTOSO-DC07 Windows Server 2012 Standard
CONTOSO-DC01 Windows Server 2012 Standard
CONTOSO-DC02 Windows Server 2008 R2 Enterprise
Another
useful example is when you want to scan for inactive Active Directory
accounts so that you can clean up the directory. In this command, you
scan for any account that has not been logged on to in the past 120
days and report the account name and the date the user last logged on.
Search-ADAccount –UsersOnly –AccountInActive –TimeSpan 120 | Format-Table Name, LastLogonDate
You
could then disable these accounts by piping the discovered list to the
Disable-ADAccount cmdlet. However, this is a dangerous thing to do in
an Exchange environment because so many accounts are never logged on to
because they are used for purposes such as room and discovery mailboxes.
Another
one-liner that is extremely useful on test systems searches for all
Active Directory accounts that have an email address and sets the
accounts so that the passwords never expire. This gets rid of a lot of
annoying prompts you might otherwise encounter because passwords expire!
Get-ADUser –Filter {EmailAddress –Like "*@contoso.com"} | Set-ADUser –PasswordNeverExpires $True
Setting the right scope for objects in a multi-domain forest
When you start EMS, Exchange sets the default scope for
queries performed against Active Directory to the domain to which the
server belongs. This is fine if you operate a single-domain forest, but
it is definitely not if you have to manage objects in a multi-domain
forest because it means that any query you perform will return only
objects from the local domain. To control the scope for Active
Directory objects, use the Set-ADServerSettings cmdlet. Set the
ViewEntireForest parameter to be $True (to see the entire forest) or
$False (to see just the objects owned by the default domain). The
logical place to do this is in your personal PowerShell profile. For
example:
Set-ADServerSettings -ViewEntireForest $True
You can also use this command to point to a particular domain controller to retrieve Active Directory data. For example:
Set-ADServerSettings –PreferredServer 'DC1.contoso.com'
If
you do not want to set your scope to the entire forest, a partial
workaround is to specify a global catalog server in the remote domain
to use for the query. Another way of forcing EMS to operate on a
forest-wide basis is to specify the –IgnoreDefaultScope parameter for
cmdlets such as Get-Mailbox. This parameter tells EMS to ignore the
default recipient scope setting for EAC (typically the domain into
which a server is installed) and use the entire forest instead. For
example, if you wanted to set up a batch of mailboxes to move from an
Exchange 2007 server to Exchange 2013 that used accounts in multiple
domains, you could use a command like this:
Get-Mailbox –Server 'Exchange2007' –ResultSize Unlimited –IgnoreDefaultScope | New-MoveRequest -TargetDatabase 'Mailbox Database 1002' –BatchName 'Move Group from Exchange 2007'
The
natural question at this point is whether changing the scope for Active
Directory queries will affect how you work with EMS. The answer is yes
because when you set a forest-wide scope, EMS fetches data from across
the forest rather than from the local domain. Unless you use parameters
to focus on particular groups of objects, such as specifying that you
want to work with the mailboxes from one server, you will probably have
to wait longer for a response. This is because you will ask EMS to
process cmdlets that deal with servers, mailboxes, databases, or other
objects across a complete forest rather than with just one domain, but
in most cases, the wait is worthwhile because you see the complete
picture and do not run the risk of missing something.