Exchange Server 2010 Portable Command Guide: Advanced Techniques

Date: Jul 7, 2011

Return to the article

This chapter provides information and commands covering working with pipelines, running programs, creating and running scripts, registry modifications with PowerShell, and understanding quotes in Exchange Server 2010.

This chapter provides information and commands concerning the following topics:

Working with Pipelines

When you pipeline, you take the output of one cmdlet and use it in a subsequent cmdlet to perform another operation. This simple act ensures that you can string together very simple cmdlets into complex operations. Some of the reasons you may wish to pipeline include the following:

You can use pipelining to pass data from the output of one cmdlet to a subsequent cmdlet in order to perform another operation. This operation might work like what's shown in the following table.

Get-User
-OrganizationalUnit OUName
| Enable-Mailbox
-Database "DatabaseName"
PS C:\UsersAdministrator>Get-User
-OrganizationalUnit
Assemblers |
Enable-Mailbox
-Database "AssemblyDB"
               

After acquiring a new assembly plant in Philadelphia, you need to create mailboxes in the AssemblyDB database for all users in the Assemblers OU, which is a child of the Philadelphia OU.

This pipelined cmdlet retrieves a list of all users in the Assemblers OU and passes the resultset to the Enable-Mailbox cmdlet, which creates the mailboxes for those users.

In Figure 3-1, you can see that there are two users in the Assemblers OU in Active Directory Users and Computers. However, in Figure 3-2, there are no mailboxes present for these users.

Figure 3-3 demonstrates the cmdlet used for creating mailboxes for existing users using a Get-User cmdlet piped to an Enable-Mailbox cmdlet. Finally, in Figure 3-4, you can see that the mailboxes have been created.

Figure 3-1 Users in the Assemblers OU in Active Directory Users and Computers

Figure 3-2 No mailboxes present in the Exchange Management Console for the Assemblers OU users

Figure 3-3 Mailboxes for users in the Assemblers OU created with the Enable-Mailbox cmdlet

Figure 3-4 Mailboxes now present in the Exchange Management Console for the Assemblers OU users

You can also use pipelining to combine several actions. In that way, you can use one cmdlet to gather the mailboxes for all managers, VPs, and anyone in the Assembly department in your organization who has an Exchange mailbox and then a second cmdlet to set multiple quota values on those distinct groups of mailboxes. Performing multiple actions on Exchange objects might work like what's shown in the following table.

                  Get-User -Filter {((Title -like
                  Title1Name) -or (Title -like Title2Name)

                  -or (Department -eq DepartmentName
                  ))


                  -and (RecipientTypeDetails -eqRecipientType
                  )} | Set-Mailbox


                  -IssueWarningQuota size1

                  -ProhibitSendQuota size2


                  -ProhibitSendReceiveQuota size3


                  -UseDatabaseQuotaDefaults $boolean value

                  PS C:\Users\Administrator>Get-User

                  -Filter {((Title -like "*Manager*") -or

                  (Title -like "*VP*") -or (Department -eq

                  "Assembly")) -and (RecipientTypeDetails

                  -eq "UserMailbox")} |

                  Set-Mailbox -IssueWarningQuota

                  900MB -ProhibitSendQuota 1GB

                  -ProhibitSendReceiveQuota unlimited

                  -UseDatabaseQuotaDefaults $false

               

You have very distinct groups of users who need unique quotas applied to their mailboxes. You cannot use a quota at the database level because these users are spread across multiple databases.

All managers, VPs, and users in the Assembly department need these quotas applied to their mailboxes regardless of the server or database where their mailbox is located.

You can combine the collecting of the distinct groups of users with the application of the unique quotas on the mailboxes with a piped cmdlet, as shown.

You can pipe data between dissimilar nouns. You might find that you want to use the data from one cmdlet within another cmdlet, but the object types do not match. This can happen if one cmdlet references one noun (such as by importing information from a .csv file with an Import-CSV cmdlet, where "CSV" is the noun) and you then want to use that imported data to create a new user account as well as an Exchange mailbox, which you can do with the New-Mailbox cmdlet, where "Mailbox" is the noun. Finally, you might wish to add title and department attributes to the user account (not the mailbox), which references the "User" noun. Passing data output between dissimilar nouns might work like what's shown in the following table.

                  Import-CSV "C:\filename.csv" |

                  ForEach-Object -Begin {
                  $Pass =

                  ConvertTo-SecureString password
                  -asPlainText -force} -Process
                  {New-Mailbox -Name $_.Name
                  -UserPrincipalName
                  "$($_.UserName)@
                  DomainName"
                  -OrganizationalUnit "OUName" -Database
                  "DatabaseName" -Password $Pass
                  -ResetPasswordOnNextLogon $true |
                  Set-User
                  -Title $_.Title -Department
                  $_.Department}
                  PS C:\Users\Administrator>Import-CSV
                  "C:\FileFromHR.csv" |
                  ForEach-Object -Begin {$Pass =
                  ConvertTo-SecureString "Pa$$w0rd"
                  
                  -asPlainText -force} -Process
                  {New-Mailbox -Name $_.Name
                  -UserPrincipalName "$($_.UserName)
                  @DomainName"
                  -OrganizationalUnit "OUName" -Database
                  "DatabaseName"
                  -Password $Pass
                  -ResetPasswordOnNextLogon $true |
                  Set-User
                  -Title $_.Title -Department
                  $_.Department}
               

You need to import several users from a .csv file given to you by the HR department. The noun initially used is "CSV".

You then wish to create the user and the mailbox at the same time, but that requires setting a password for each user. You create a password and save it as a secure string, which the Active Directory will accept. You use a variable ($Pass) to store the secure string password. This involves the New-Mailbox cmdlet, which utilizes the "Mailbox" noun.

Finally, you want to add values to title and department, which are properties of the user, so you need to reference the "User" noun to do that.

You can also report errors or warnings though pipelining, which might work like what's shown in the following table.

                  $Name = "Custom Text"
                   PS C:\Users                   Administrator>
                   $Warn
                  = "This is an example
                  of a custom warning
                  that you might create that could provide
                  an onscreen warning
                  when some condition
                  exists."
                  $Name | Write-Warning
                  PS C:\Users                  Administrator>
                     $Warn |
                  Write-Warning
               

This illustrates how you could pipe a string to the Write-Warning cmdlet.

You could save the string in a variable, as shown in the first pair of cmdlets, and then pipe the string to Write-Warning, as shown in the second pair of cmdlets.

Running Programs

Unlike cmd.exe, Exchange Management Shell (EMS) can process cmdlets in one of two ways. It analyzes what you have typed and decides whether it should be interpreted as an expression (Typing 1 + 1 produces a result of 2 in Expression mode) or as a command, which works similarly to the way that cmd.exe works. In Command mode, if what you have typed has no errors, it will be executed. If you begin a line of code with a number, a quote, or a dollar sign ($), EMS will function in Expression mode. This can be observed when you type $compute = 1+1 and press Enter. When you subsequently type $computer and press Enter, the output will be the number "2".

What if you are interested in running a program and you have defined the variable $Prog to run it—how can you tell EMS to execute $Prog as a command and not display it as a value? The use of the ampersand (&) character is how you can do this, as shown in the following table.

PS C:\UsersAdministrator>$Prog=
C:\Windows\System32\
calc.exe
PS C:\UsersAdministrator>$Prog
PS C:\UsersAdministrator>&$Prog

               

If you define the variable $Prog as shown in the example, the Windows Calculator will not launch when you subsequently type $Prog, but the result that is displayed will be C:\Windows\System32\calc.exe.

EMS is displaying the value of the variable, not executing it.

However, if you type &$Prog, the Windows Calculator will launch successfully.

To run a batch file, you need cmd.exe to launch first, so you could do something like what's shown in the following table.

PS C:\UsersAdministrator>cmd.exe /c
MyTest.bat
               

Here, /c tells the batch file to carry out the command and then terminate cmd.exe It is not necessary to use & with cmd.exe.

For a VBScript executable, you also need cmd.exe to launch first, so you could do something like what's shown in the following table.

PS C:\Users\Administrator>
&"cscript.exe MyVBScript.vbs
param1 param2"
               

Because you are launching another executable, & is required.

To run PowerShell scripts from a cmd.exe prompt, you need to use powershell.exe. In previous versions of PowerShell, you used msh.exe. Powershell.exe is run as shown in the following table.

PS C:\UsersAdministrator>
powershell.exe-noexit
"C:\MyScripts\MyTest.ps1"

               

Powershell.exe is the Windows PowerShell executable.

The -noexit switch is an optional parameter that tells the PowerShell console to remain open after the script finishes.

This technique will be illustrated in the section that follows.

Creating and Running Scripts

In most cases, you will run individual cmdlets to achieve your desired result, and with the use of pipelining you can combine cmdlets together to allow for creative results. However, just like from a Windows command prompt, a single line of code may not be able to provide you with the ability to do everything you desire. From the Windows command prompt, it is common to use a .bat file to group multiple commands into a single file, but that will not work in Exchange Management Shell. But, do not fear. PowerShell offers support for a scripting language, based on the Microsoft .NET Framework, and those scripts can be used to automate tasks or run multiple cmdlets together when pipelining is not appropriate. The Shell lets you create scripts, assign variables in the scripts, perform looping operations, and use conditional logic in the scripts. This is all done within a text file using PowerShell cmdlets. When you save the text file with a .ps1 extension, it is executable from Exchange Management Shell.

By creating your own library of these .ps1 scripts, you can automate tasks and efficiently run your scripts on any computer that has Exchange Management Shell installed on it. The following example illustrates how to create a script to perform the five steps necessary to configure Messaging Records Management.

Create a text file with a .ps1 extension.

In the example that follows, the file will be called C:\Users\Administrator\MRM_Retention.ps1.

Five steps are involved in configuring Messaging Records Management.

This is commonly configured from Exchange Management Console (prior to Service Pack 1) because each step is performed in a unique place and no single cmdlet will perform all five steps. However, in the Console, there is no single wizard that will perform all five steps either. Therefore, you want to create a script to perform all five steps together in a PowerShell script.

New-ManagedFolder
-Name "ObjectName" -FolderName "FolderName"

PS C:\Users\Administrator>
New-ManagedFolder
-Name "Retention" -FolderName "Retention"
               

Step 1: Create a new managed custom folder.

$AgeLimit = New-TimeSpan
-Day ValueInDays
PS C:\Users\Administrator>
$AgeLimit
 =
New-TimeSpan
-Day 1100

               

Create a variable to use in step 2.

New-ManagedContentSettings
-Name "ContentSettingsName" -FolderName
"FolderName"
-MessageClass "MessageClassType"
-RetentionEnabled $boolean value
-AgeLimitForRetention $AgeLimit
-RetentionAction RetentionActionType
PS C:\Users\Administrator>
New-ManagedContentSettings
-Name "Retention Settings for Retention
Folder"
-FolderName "Retention" -MessageClass *
-RetentionEnabled: $true
-AgeLimitForRetention $AgeLimit
-RetentionAction PermanentlyDelete

Step 2: Create managed content settings for the 3 Year Retention Folder, which permanently deletes all items after 3 years or 1,100 days.

New-ManagedFolderMailboxPolicy
-Name "PolicyName"
-ManagedFolderLinks "Folder(s)ToBeLinked
ToPolicy"
PS C:\Users\Administrator>New-
ManagedFolderMailboxPolicy
-Name "Executives Mailbox Policy"
-ManagedFolderLinks "Retention"
               

Step 3: Create a managed folder mailbox policy.

Set-Mailbox -Identity MailboxUsername
-ManagedFolderMailboxPolicy "PolicyName"
PS C:\Users\Administrator>Set-Mailbox
-Identity Administrator
-ManagedFolderMailboxPolicy "Executives
Mailbox Policy"
               

Step 4: Apply the managed folder mailbox policy to a mailbox.

PS C:\Users\Administrator>$ServerName =
cmd /c echo %computername%
PS C:\Users\Administrator>Set-
MailboxServer -ID $ServerName
-ManagedFolderAssistantSchedule "Schedule"
PS C:\Users\Administrator>Set-
MailboxServer -ID $ServerName
-ManagedFolderAssistantSchedule
"Sun.12:00-Sun.11:00"
               

Step 5: Schedule the Managed Folder Assistant to run each day.

PS C:\Users\Administrator>
Start-ManagedFolderAssistant
               

Alternate step 5: Start the Managed Folder Assistant manually.

# Step 1: Create a new managed custom
folder.
New-ManagedFolder -Name "Retention"
-FolderName "Retention"
# Create a variable, "$AgeLimit," to use
in Step Number 2.
$AgeLimit = New-TimeSpan -Day 1100
# Step 2: Create managed content settings
for the 3 Year Retention Folder that
permanently deletes all items after 3 years
or 1100 days.
New-ManagedContentSettings
-Name "Retention Settings for Retention
Folder"
-FolderName "Retention" -MessageClass *
-RetentionEnabled:$true
-AgeLimitForRetention $AgeLimit
-RetentionAction PermanentlyDelete
# Step 3: Create a managed folder mailbox
policy.
New-ManagedFolderMailboxPolicy
-Name "Executives Mailbox Policy"
-ManagedFolderLinks "Retention"
# Step 4: Apply the managed folder mailbox policy to a mailbox.
Set-Mailbox -Identity Administrator
-ManagedFolderMailboxPolicy "Executives
Mailbox Policy"
# Step 5: Start the Managed Folder
Assistant manually.
Start-ManagedFolderAssistant
               

The completed script with all steps combined in a file.

The # sign indicates a remark, and that line will not be executed.

Save this file with a name such as C:\Users\Administrator>MRM_Retention.ps1.

PS C:\Users\Administrator>.\
MRM_Retention.ps1
               

Run the script as shown in Figure 3-5.

Figure 3-5 Running the MRM_Retention.ps1 script created in the example

Figures 3-6, 3-7, 3-8, and 3-9 show the results after the script has been run.

Figure 3-6 Custom folder and content settings on a folder viewed from the Exchange Management Console

Figure 3-7 Managed folder mailbox policy viewed from the Exchange Management Console

Figure 3-8 Executives mailbox policy linked to a user, as viewed from the Exchange Management Console

Figure 3-9 Retention folder viewed on user's Outlook Web App client

Registry Modifications with PowerShell

It is very easy to modify the registry of a server by using Exchange Management Shell and the Set-ItemProperty cmdlet. Performing the registry change from within Exchange Management Shell means that you can incorporate the change into a .ps1 script, and you can also pipeline it to multiple servers as needed. You must have permission to make this change or your attempt will fail. The examples in the following table illustrate how to change the timeout values for the OWA cookies used by forms-based authentication on a Client Access Server.

Use the following cmdlets at your own risk.

Set-ItemProperty RegistryPath
-Name TimeoutType -Value
TimeInMinutes -Type
RegistryValueType
PS C:\Users\Administrator>
Set-ItemProperty "HKLM:\SYSTEM\
CurrentControlSet\Services\
MSExchange OWA"
-Name PrivateTimeout -Value 360
-Type Dword
               

This example sets the Private Computer cookie timeout value to 360 minutes, or 6 hours, for the Outlook Web App client.

Set-ItemProperty RegistryPath
-Name TimeoutType -Value
TimeInMinutes -Type
RegistryValueType
PS C:\Users\Administrator>
Set-ItemProperty "HKLM:\SYSTEM\
CurrentControlSet\Services\
MSExchange OWA"
-Name PublicTimeout -Value 30
-Type Dword
              

This example sets the Public Computer cookie timeout value to 30 minutes for the Outlook Web App client.

Understanding Quotes

PowerShell uses four different types of quotes. As an administrator, you are most interested in single ordinary and double ordinary quotes. A developer would be more interested in the here-strings. The four types of quotes are explained in the following table.

Single ordinary quotes:

$a="Champs"

'World $a' => World $a

               

In single quotes, variable names are not expanded and escape sequences are not interpreted.

Double ordinary quotes:
$a="Champs""World $a" =>

World Champs

               

Inside double quotes, variable names are replaced with their values and PowerShell escape sequences are interpreted.

Single here-strings:
$b="Two"

$x = @'

"

Easy as

One

$b

Three

!

"

'@

$x produces:

"

Easy as

One

$b

Three

!

"

               

In single here-strings, variable names are not expanded and escape sequences are not interpreted. A single here-string begins with @' and ends with '@.

PowerShell here-strings are similar to here-documents in Perl.

Double here-strings:
$b="Two"

$x = @"

"

Easy as

One

Two

Three

!

"

"@

$x produces:

"

Easy as

One

Two

Three

!

"

               

Inside double here-strings, variable names are replaced with their values and PowerShell escape sequences are interpreted. A double here-string begins with @" and ends with "@.

PowerShell here-strings are similar to here-documents in Perl.

800 East 96th Street, Indianapolis, Indiana 46240

sale-70-410-exam    | Exam-200-125-pdf    | we-sale-70-410-exam    | hot-sale-70-410-exam    | Latest-exam-700-603-Dumps    | Dumps-98-363-exams-date    | Certs-200-125-date    | Dumps-300-075-exams-date    | hot-sale-book-C8010-726-book    | Hot-Sale-200-310-Exam    | Exam-Description-200-310-dumps?    | hot-sale-book-200-125-book    | Latest-Updated-300-209-Exam    | Dumps-210-260-exams-date    | Download-200-125-Exam-PDF    | Exam-Description-300-101-dumps    | Certs-300-101-date    | Hot-Sale-300-075-Exam    | Latest-exam-200-125-Dumps    | Exam-Description-200-125-dumps    | Latest-Updated-300-075-Exam    | hot-sale-book-210-260-book    | Dumps-200-901-exams-date    | Certs-200-901-date    | Latest-exam-1Z0-062-Dumps    | Hot-Sale-1Z0-062-Exam    | Certs-CSSLP-date    | 100%-Pass-70-383-Exams    | Latest-JN0-360-real-exam-questions    | 100%-Pass-4A0-100-Real-Exam-Questions    | Dumps-300-135-exams-date    | Passed-200-105-Tech-Exams    | Latest-Updated-200-310-Exam    | Download-300-070-Exam-PDF    | Hot-Sale-JN0-360-Exam    | 100%-Pass-JN0-360-Exams    | 100%-Pass-JN0-360-Real-Exam-Questions    | Dumps-JN0-360-exams-date    | Exam-Description-1Z0-876-dumps    | Latest-exam-1Z0-876-Dumps    | Dumps-HPE0-Y53-exams-date    | 2017-Latest-HPE0-Y53-Exam    | 100%-Pass-HPE0-Y53-Real-Exam-Questions    | Pass-4A0-100-Exam    | Latest-4A0-100-Questions    | Dumps-98-365-exams-date    | 2017-Latest-98-365-Exam    | 100%-Pass-VCS-254-Exams    | 2017-Latest-VCS-273-Exam    | Dumps-200-355-exams-date    | 2017-Latest-300-320-Exam    | Pass-300-101-Exam    | 100%-Pass-300-115-Exams    |
http://www.portvapes.co.uk/    | http://www.portvapes.co.uk/    |