Exchange Management Console contains many built-in
cmdlets. Administrators can create their own cmdlets using a common
text editor. In this instance, the cmdlet is a series of commands,
usually more than one line, stored in a text file with a .ps1 extension.
The
PowerShell common language runtime is an interpretive environment,
meaning that cmdlets, functions, and scripts are loaded into random
access memory (RAM) where they are validated and executed.
The
Exchange Management Shell and PowerShell define several types of
commands that administrators can use in development. These commands
include functions, filters, scripts, aliases, and executables
(applications). Small command called a cmdlet. Both EMS and PowerShell supply
sets of cmdlets and fully support cmdlet customization to suit the
organization’s environment. The PowerShell/EMS runtime processes all
cmdlets.
An EMS cmdlet is a simple set of
commands bundled together to interact with any managed application,
including the operating system. It is similar to a built-in command in
any other shell, such as Cmd.exe, Bash, or ksh.
A conventional shell processes most commands as separate executable
programs. Each program must parse the input and parameters, bind values
to the correct parameters, format the output, and display the output.
EMS,
in contrast, processes commands as instances of .NET classes,
concentrating on the simple cmdlet model. The administrator must
provide the necessary parameters and validate the values, and then
supply details of object types and formatting. EMS does the rest of the
work: parsing the parameters and binding them to their values,
formatting the output, and then displaying the output.
Demonstrating Cmdlet Examples
The
administrator can run a cmdlet singly or as one of several cmdlets
piped together on the command line. For example, the single cmdlet:
returns all attributes of an address list or set of address lists. The pipelined command:
Get-AddressList | export-csv "C:\AddressList.csv"
produces a collection of
address lists and pipelines it to the export-csv cmdlet, which requires
the file path and name parameter.
The
following example is a custom cmdlet that connects to the WMI provider
to display all public folders and their message counts in a table
format:
get-wmiobject -class Exchange_PublicFolder -Namespace ROOT\MicrosoftExchangev2 -
ComputerName SERVER1 | select-object name,messagecount,totalmessagesize |
format-table
Although
this is only a single-line command, it can be tedious to type every
time it is needed. It can be typed into a text editor and saved as a .ps1 file, PFSize.ps1 for example, in the system path so that it can easily be run again and again.
A
working knowledge of .NET is required to write more complex functions
that access objects and classes that are not exposed using the built-in
cmdlets. The following cmdlet example uses the system.net.mail.smtpClient class in the .NET 2.0 Framework to send Simple Mail Transfer Protocol (SMTP) email from the EMS command line:
$SmtpServer = "server1.companyabc.com"
$From = "[email protected]"
if ($args.Length -lt 1) {
$To = "[email protected]"
}
else {
$To = $args[0]
}
$Subject = "Greetings from EMS!"
$Body = "Hello, this is a test from the Exchange Management Shell."
$SmtpClient = new-object system.net.mail.smtpClient
$SmtpClient.host = $SmtpServer
$SmtpClient.Send($From, $To, $Subject, $Body)
This cmdlet takes an argument, or parameter. If the cmdlet is saved as TestMail.ps1, the administrator can issue the following command to send a test SMTP email:
Combining Functions to Create a Cmdlet Library
As
the administrators become more familiar with EMS and using and writing
cmdlets, they will begin to build a library of commonly used cmdlets
and scripts. It is common to “recycle” similar cmdlets to use for
different tasks. Over time, administrators will find useful scripts and
concepts from many resources: colleagues, scripting blogs, newsgroups,
and so on.
It is sometimes useful to put
all the cmdlets in a common area where other administrators, users, and
developers can peruse them and add to the knowledge base. Often, a
fellow administrator will need to perform the same task that another
administrator has already written. There is no reason to “reinvent the
wheel.”
A common practice is to create a
network share where administrators and cmdlet developers have modify
permissions and other users have read and execute access permissions.
Arrange the folder structure based on business needs and technical
requirements. It is also a
best practice to include a folder with the Exchange Server 2007 setup
bits, so that administrators can load the Exchange Management Shell
components to run the cmdlets.
Modifying and Applying Server Cmdlets to Other Systems
After
a cmdlet has been written and tested, it is often useful to run the
same cmdlet against many or all servers in the organization. For
example, consider the following cmdlet that sets the JournalRecipient
value for Mailbox Store 3 on SERVER1 to use the CompanyJournal mailbox:
set-MailboxDatabase "SERVER1\Mailbox Store 3" -JournalRecipient companyabc\ CompanyJournal
It is very easy to convert this cmdlet so it will run against all databases in the Exchange organization using pipelining:
Get-MailboxDatabase | set-MailboxDatabase -JournalRecipient companyabc\ companyjournal
In this example, Get-MailboxDatabase returns a collection of all the mailbox databases in the organization and pipes them to the Set-MailboxDatabase cmdlet, where it assigns the value.