December 23, 2014

Check SMTP address validity with only command prompt

Recently I had an interview question that was not Exchange or Powershell based. This is an important thing for every exchange admin to know as this is something that can be done quickly and on the fly.

The question:
If you were on a Windows box and you only had access to command prompt. How would you check if an smtp address was valid on an exchange system?

Dont forget:
You can't use Powershell
You can't use the Exchange GUI

This is a telnet question.

As we all know telnet is a part of an exchange admins role when checking whether servers are talking to each other.

Start with the communication with the server, then try to send an email.

You can start a Telnet session by using the Telnet command in the following format:

Note Press ENTER after you type each line. 

telnet servername portnumber

For example, type: 
telnet 25

NB: You can replace servername with the IP address or the FQDN of the SMTP server that you want to connect to. 

If the command works, you receive a response from the SMTP server that is similar to the following: 
220 Microsoft Exchange Internet Mail Connector <version number of the IMC>

Start communication by typing the following command: 

If the command is successful, you receive the following response: 

250 OK

Type the following command to tell the receiving SMTP server who the message is from: 

Note This address can be any SMTP address that you want, but it is a good idea to use a valid e-mail address possibly your own for testing. Using a non-valid smtp address will result in an NDR (non-delivery receipt).

If you do not use a valid e-mail address when you send a message, you cannot determine if the message had a delivery problem, because the non-delivery report (NDR) cannot reach an IP address that is not valid. If you use a valid e-mail address, you receive the following response from the SMTP server: 

Type the following command with the SMTP address of the person you want to send to: 

RCPT TO: User@Domain.Com

You receive the following response: 
250 OK - Recipient User@ Domain.Com

Type the following command to tell the SMTP server that you are ready to send data: 

You receive the following response: 
354 Send data. End with CRLF.CRLF

You are now ready to start typing the 822/2822 section of the message. The user will see this part of the message in their inbox. Type the following command to add a subject line: 
Subject: test message
Press ENTER two times. You do not receive a response from this command.

Note The two ENTER commands comply with Request for Comments (RFC) 822 and 2822. 822 commands must be followed by a blank line. 

Type the following command to add message body text: 
This is a test message.

Type a period (.) at the next blank line, and then press ENTER. You receive the following response: 
250 OK

Close the connection by typing the following command: 



telnet 25
RCPT TO: User@Domain.Com
Subject: test
Test test


November 22, 2014

Powershell storage analysis

So on a daily basis we have a report emailed to us with the current total storage and a percentage of that storage that is free.
It’s definitely easier than logging into servers and calculating the amount of storage on every mount point.

The powershell script works in 2 ways.
1) The powershell script itself (storagereport.ps1) and the server list (serverlist.txt) that it references. If you are adding or subtracting servers from the environment, just add or subtract them from the serverlist.txt and save the file in the same directory as the powershell script.

I suggest creating a folder on the server that this report will run from and putting in a text file with a list of servers, then referencing this list in your script.

Script (storagereport.ps1)
$TotalGB = @{Name="Capacity(GB)";expression={[math]::round(($_.Capacity/ 1073741824),2)}}
$FreeGB = @{Name="FreeSpace(GB)";expression={[math]::round(($_.FreeSpace / 1073741824),2)}}
$FreePerc = @{Name="Free(%)";expression={[math]::round(((($_.FreeSpace / 1073741824)/($_.Capacity / 1073741824)) *


function get-mountpoints {
$volumes =Get-WmiObject -computer $server win32_volume | Where-object {$_.DriveLetter -eq $null -and $ -like

"*Indexvol*" }
$volumes | Select SystemName, Label, $TotalGB, $FreeGB, $FreePerc |ConvertTo-HTML -head $a | add-content



remove-item C:\<user>\<ServerStorage>.htm
$servers = (Get-Content c:\<user>\serverlist.txt)

foreach ($server in $servers){
Invoke-Expression C:\<user>\<ServerStorage>.htm

# Send email as a HTML body.
$smtpServer = "smtp.<domain>.com"
$mailto = "<username>@<domain>.com,"

$msg = new-object Net.Mail.MailMessage  
$smtp = new-object Net.Mail.SmtpClient($smtpServer) 
$msg.From = $MailFrom
$msg.IsBodyHTML = $true
$msg.Subject = "My exchange Storage Report."
$MailTextT =  Get-Content  -Path C:\<user>\<ServerStorage>.htm
$msg.Body = $MailTextT

Server list (serverlist.txt)

As you add and remove servers from your environment, update the serverlist.txt to ensure it will appear on your report.

To add/remove recipients to the email report, amend the $mailto = section in the script to reflect your new addition (eg),,

# Send email as a HTML body.
$smtpServer = "smtp.<domain>.com"
$mailto = "<username>@<domain>.com,"

Once all have been configured. Create a scheduled task to run the report daily. This will automatically send the report out via email daily as a result.

November 21, 2014

Moving mass Mailboxes from Exchange 2003 to Exchange 2010

Assuming you already have Exchange 2003 and Exchange 2010 working in co-existence in your large single forest environment. These are the following steps you need to take when moving mailboxes in bulk from exchange 2003 to exchange 2010.

1) You need to take a look at your .config file on your target Exchange 2010 CAS server. By default the maximum number of mailboxes you can move at a given time is 2. If you are moving mailboxes in bulk you will need to increase it to your desired number of mailbox moves, in this example, we'll make it 50.

In a normal installation of exchange, you will find the .config file located here to edit in notepad:

C:\Program Files\Microsoft\ExchangeServer\V14\Bin\MSExchangeMailboxReplication.exe.config

MaxActiveMovesPerSourceMDB = "50"
MaxActiveMovesPerTargetMDB = "50"
MaxActiveMovesPerSourceServer = "50"
MaxActiveMovesPerTargetServer = "50"

After making the above changes, you will need to restart Microsoft Exchange Mailbox Replication service. 

Note: I recommend making these changes afterhours in any environment. Restarting this service will not disrupt mailflow during the business day but it is ideal practise to make these changes after hours in your environment.

2) Create a .csv file having the Alias or Displayname in the format below and save it as batchusers.csv


Then you need to run the command from the Exchange Management Shell on your Exchange 2010 server.

Import-CSV "C:\Batchusers.csv" | foreach {New-MoveRequest -Identity $_.alias -TargetDatabase $_.TargetDatabase}

With a baditemlimit parameter in there as well:

Import-CSV "C:\Batchusers.csv" | foreach {New-MoveRequest -Identity $_.alias -TargetDatabase $_.TargetDatabase -BadItemLimit 100}

You can also use the Get-Content switch to move mailboxes in bulk. Some may say this is easier. Using the Display Name or alias of Users and in notepad, save the notepad file as a .txt file like batchusers.txt
In Exchange Management Shell type this command:

Get-Content -Path C:\MoveMailbox\batchusers.txt | New-MoveRequest -TargetDatabase "NameOfMailboxDatabase" 

August 2, 2014

Recreating failed content index state on multiple databases.

This can be used if you find that multiple or all databases are in failed content index state. This is especially handy if you have many databases (for example 50 databases) and lag copy servers and databases.

.\RedistributeActiveDatabases.ps1 -DagName USDAG001 -BalanceDbsByActivationPreference –Confirm:$false” -ShowFinalDatabaseDistribution               
Restart the indexer service on all of the MBX servers if it is complaining about failed content state for multiple (or all) databases           
Check that they are mounted correctly and index is in a healthy state for each MBX server.        
Get-MailboxDatabaseCopyStatus -Server NYCS001 | where {$_.status -eq "mounted"}               
Name                         Status     CopyQueueLength    ReplayQueueLength    ContentIndexState
USDB023\NYCS001     Mounted    0    0    Healthy
Mounted   0    0    Healthy
USDB019\NYCS001     Mounted    0    0    Healthy
001     Mounted    0    0    Healthy
USDB015\NYCS001     Mounted    0    0    Healthy
Set the lag servers auto activation to blocked via this cmdlet:      
Set-Mailboxserver -Identity NYCS003 -DatabaseCopyAutoActivationPolicy Blocked               
Set-Mailboxserver -Identity NYCS006 -DatabaseCopyAutoActivationPolicy Blocked   
Remove all database copies on both lag servers using the Exchange console (EMC), but you could also use a powershell command:       
Add-MailboxDatabaseCopy -Identity USDB001 -MailboxServer NYCS003 -ActivationPreference 5 -ReplayLagTime 5.00:00:00               
Add-MailboxDatabaseCopy -Identity USDB001 -MailboxServer NYCS006 -ActivationPreference 6 -ReplayLagTime 5.00:00:00               
Check replication and you can see that it is no longer complaining about cluster network.
Test-ReplicationHealth -Identity nycs001               
Server         Check                      Result     Error               
------          -----                      ------     -----               
NYCS001    ClusterService             Passed               
NYCS001    ReplayService              Passed               
NYCS001    ActiveManager              Passed