Posts Tagged Exchange 2003

Script to suppress Link State Updates

If you are in process of upgrading from Exchange 2003 to Exchange 2010, you must have read “Upgrade from Exchange 2003 Transport” article on Technet which spells out the details of a requirement – “minor link state updates must be suppressed to make sure that message looping doesn’t occur when a route is recalculated”.

I will not go into details of the requirement, however, if you read the details in the “Suppress Link State Updates” article, you know that the task can be daunting, especially if you have multiple Exchange 2003 servers, possibly in geographically dispersed locations.

Well, sweat no more. I have written a script that will help you get it done easily. Here’s the script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#############################################################################
# Suppress-Linkstate.ps1
# Using static text file or Get-ExchangeServer, this script will configure
# selected Exchange 2003 servers to suppress Link State to aid in upgrade to
# Exchange Server 2010 environment.
#
# Use this script in accordance to the following Technet article
# http://technet.microsoft.com/en-us/library/aa996728.aspx
#
# Created by
# Bhargav Shukla
# http://www.bhargavs.com
#
# DISCLAIMER
# ==========
# THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE
# RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
#############################################################################
 
function Suppress-Linkstate
{
# Create empty results file or overwrite existing file
"Server Name,SuppressStateChanges,ServiceStopState,ServiceStartState" | Out-File .\results.csv -Encoding ASCII
 
	foreach ($Server in $Servers)
	{
		# Do Nothing if $_ is null
		if ($Server -ne $null)
		{
		# Set server to connect to
		#$Server = "$_"
 
		# Read SuppressStateChanges from servers
 
			# Set Registry Key variables
			$REG_KEY = "System\\CurrentControlSet\\Services\\RESvc\\Parameters"
			$VALUE = "SuppressStateChanges"
 
			# Open remote registry
			$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Server)
 
			# Open the targeted remote registry key/subkey as read/write
			$regKey = $reg.OpenSubKey($REG_KEY,$true)
 
			# Set SuppressStateChanges to 1 if key exists
			if ($regKey -ne $null)
			{
			$regKey.Setvalue('SuppressStateChanges', '1', 'Dword')
 
			# Write changes to registry without closing it
			$regKey.Flush()
 
			# Read and Store SuppressStateChanges value in variable
			$SuppressStateChanges = $regkey.getvalue($VALUE)
 
			# Close the Reg Key
			$regKey.Close()
			}
 
		# Restart SMTP service, the Microsoft Exchange Routing Engine service, and the Microsoft Exchange MTA Stacks service
		#### You must specify a timeout (in seconds) or the script could potentially never end
		$TimeOut = 30
 
		#### This will stop a single service on all servers in sequence
		$ServiceFilters = "(name = 'smtpsvc')","(name = 'resvc')","(name = 'msexchangemta')"
 
 
			$Locator = new-object -com "WbemScripting.SWbemLocator"
			$WMI = $Locator.ConnectServer($Server, "root\cimv2")
		# Stop Service and check for timeout or sucessful stop
			$ServiceFilters | %{
				$ThisFilter = $_
				(Get-WmiObject -Class Win32_Service -ComputerName $Server -filter "$ThisFilter AND state='running'") | %{
					$Service = $_
					$Refresher = new-object -comobject "WbemScripting.SWbemRefresher"
					$FreshObject = $Refresher.Add($WMI,$Service.__RELPATH)
					$Refresher.Refresh()
					$Then = Get-Date
					:Checking Do {
						$Service.StopService() | out-null
						$Refresher.Refresh()
						if (($FreshObject.Object.properties_ | ?{$_.name -eq "state"}).value -eq "Stopped") {
							$ServiceStopState = "Service $($Service.Name) stopped";
 
							# Store result string in a variable
							$result = "$Server,$SuppressStateChanges,$ServiceStopState,$ServiceStartState"
 
							# Write results to file
							$result | Out-File .\results.csv -Encoding ASCII -Append
 
							$ServiceStopState = $null
 
							break :Checking;
						} Else {
							If (((Get-Date) - $Then).seconds -ge $TimeOut){
								$ServiceStopState = "Service $($Service.Name) stop TIMEOUT";
 
								# Store result string in a variable
								$result = "$Server,$SuppressStateChanges,$ServiceStopState,$ServiceStartState"
 
								# Write results to file
								$result | Out-File .\results.csv -Encoding ASCII -Append
 
								$ServiceStopState = $null
 
								break :Checking;
							}
						}
					} While ($True)
				}
			}
 
		# Start Service and check for timeout or sucessful start
			$ServiceFilters | %{
				$ThisFilter = $_
				(Get-WmiObject -Class Win32_Service -ComputerName $Server -filter "$ThisFilter AND state='Stopped'") | %{
					$Service = $_
					$Refresher = new-object -comobject "WbemScripting.SWbemRefresher"
					$FreshObject = $Refresher.Add($WMI,$Service.__RELPATH)
					$Refresher.Refresh()
					$Then = Get-Date
					:Checking Do {
						$Service.StartService() | out-null
						$Refresher.Refresh()
						if (($FreshObject.Object.properties_ | ?{$_.name -eq "state"}).value -eq "running") {
							$ServiceStartState = "Service $($Service.Name) started";
 
							# Store result string in a variable
							$result = "$Server,$SuppressStateChanges,$ServiceStopState,$ServiceStartState"
 
							# Write results to file
							$result | Out-File .\results.csv -Encoding ASCII -Append
 
							$ServiceStartState = $null
 
							break :Checking;
						} Else {
							If (((Get-Date) - $Then).seconds -ge $TimeOut){
								$ServiceStartState = "Service $($Service.Name) start TIMEOUT";
 
								# Store result string in a variable
								$result = "$Server,$SuppressStateChanges,$ServiceStopState,$ServiceStartState"
 
								# Write results to file
								$result | Out-File .\results.csv -Encoding ASCII -Append
 
								$ServiceStartState = $null
 
								break :Checking;
							}
						}
					} While ($True)
				}
			}
		}
	}
}
 
 
#Add Exchange 2010 snapin if not loaded
# Uncomment following four (4) lines if using dynamic list mentioned below
If ((Get-PSSnapin | where {$_.Name -match "E2010"}) -eq $null)
{
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
}
 
# Uncomment next line if you want to dynamically get Exchange 2003 servers using Exchange 2010 Management Shell
$Servers = (get-exchangeserver | Where-Object {$_.AdminDisplayVersion -like '*6.5*'} | ForEach-Object {$_.Name})
# Comment line above and Uncomment next line if you want to provide list of servers in a text file (one server per line)
# You can't have both of the abovementioned lines uncommented. Please use one of your choice.
# $Servers = Get-Content .\servers.txt
 
$Servers | Suppress-Linkstate

Few important pointers:

  • The script can use one of the two methods, please comment and uncomment necessary lines as documented in script

     – Dynamically retrieve list of Exchange 2003 servers in your environment using Get-ExchangeServer cmdlet from an Exchange 2010 server

     – Use list of Exchange 2003 servers provided in servers.txt file (one server per line)

  • If you choose to use dynamic method, you  must have Exchange server 2010 admin tools installed on the machine where the script is run from
  • The output will be store in results.csv file
  • Timeout value in line 62 works fine in my lab tests, it may not work for you. Please adjust the value as necessary

You can download the script from here: Suppress-Linkstate.ps1

I am sure there are ways to optimize and improve this script. I would love to know how I can make the script better and more useful. Please feel free to drop me a line using contact form. I will be happy to hear your feedback and improve script. You can also use comments option on this post to leave your feedback.

Share

Tags: , , ,

Webcast Series – Upgrade Exchange 2003 to Exchange 2010 – Part 1

Update: I will not be posting future updates or next parts of the series as lot of work is being done by my friend Robert Gillies in his series of articles on Exchange Team Blog feature “Robert’s Rules of exchange”. Sorry for any inconvenience and I hope you will find Robert’s series of articles helpful.

Ever since Exchange 2010 is RTM, I have been advocating to upgrade directly to Exchange 2010 if it makes sense for your environment. As I discussed with administrators who manage Exchange 2003 environments, I received a very positive response from many who expressed their strong interest in skipping Exchange 2007 and upgrade to Exchange 2010.

Since I have had a lab that was designed for this purpose only, I decided to create a webcast series that will walk through the process of upgrading from Exchange 2003 environment to Exchange 2010 environment.

I am publishing Part 1 of multi part series here. I will be publishing more parts as time permits but no less than once a month. You can download the webcast here. The webcast works best when viewed in 1024×768 or higher resolution.

I also request that you provide your  questions, comments and feedback to feedback@bhargavs.com. It will greatly help me improve future webcasts.

I hope this webcast series will help you learn Exchange 2010 upgrade process and you can apply the learning in real-world. Thanks and enjoy!

Share

Tags: , , ,

New Podcast from RunAs Radio

Recently, I had privilege of talking to Richard and Greg from RunAs radio. We discussed the features of the newly released Exchange 2010 and why businesses still running Exchange 2003 should jump right to the latest version and skip 2007 entirely.

I am sure the listeners will benefit from it. You can download the podcast from http://bit.ly/5fSqbp. Comments welcome.

Share

Tags: , , , ,

Exchange 2003 support and Windows Server 2008 R2 Domain Controllers

When I originally wrote this post, Windows Server 2008 R2 Domain Controllers were not supported for Exchange 2003, however, in recent months the guidance from product team has changed and new support guidance now includes Windows Server 2008 R2 Domain Controllers as supported configuration.

Please refer to this article on Technet for more information.

MS Exchange Team recently published an article on Exchange 2007 Supportability Matrix. As I read more into it and look at the accompanying article on Technet, it is noteworthy that we talk about Exchange 2003 support as well.

I got questions from multiple customers I work with on this. As I realize many organizations are still in process of deploying Exchange 2007. Many have Exchange 2003 SP2 in production and majority of users are on Exchange 2003 mailbox servers.

This poses an interesting challenge. If an organization wants to move forward with Windows Server 2008 R2 (specifically – R2) Domain Controllers, they hit a huge roadblock. The supportability Matrix provides specific guidance around that and that means Exchange 2003 is not supported against Windows 2008 R2 Domain Controllers.

When I looked at Microsoft Support Lifecycle site for Exchange 2003, I noticed that Mainstream support for Exchange 2003 ended 4/14/2009. Given SP2 support note says support for SP2 will end at release of new Service Pack or end of Support Lifecycle of Exchange 2003 which is sometime in 2014, it still is important to note that when Mainstream support ends, only security fixes are provided for the product without any cost to customer.

It isn’t surprising that Exchange Product team may have decided to focus their efforts in developing features that customers asked for in current and future versions and not for the products that are in Extended Support phase of Lifecycle. I have no visibility in the effort of development and testing of any fix/service pack, features that goes into Exchange Server products but if I have to assume, I am sure it is huge for every possible combination they may have to test.

So to summarize, I know it is going to be painful to plan around the supportability of Exchange 2003 and Windows Server 2008 R2 Domain Controllers. The best approach I can recommend is follow the published guidance and plan around migration to Exchange 2007 before you can upgrade all your domain Controllers to Windows Server 2008 R2 and raise Domain / Forest functional level.

Last but not least, do read the site disclaimer, the views presented here are of my own and not of my employer.

Share

Tags: , ,

Check Exchange 2003 vitals with PowerShell – Part II

In continuation to my previous post “Check Exchange 2003 vitals with PowerShell”, I also have a code block that you can replace if you want to query all exchange servers in your environment dynamically with script instead of using text file as in the code I posted earlier.

In the code I posted earlier, the following lines read the file servers.txt.

1
2
3
# Read file and store server names in variable
 
$Servers = (Get-Content .\servers.txt)

Replace it with the following, which queries Active Directory for objectclass msExchExchangeServer and returns all servers found.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Get Exchange Servers from Active Directory
 
function GetExchangeServers()
{
	# Set variables to connect to Active Directory, searching Configuration Naming Context
	$root= New-Object System.DirectoryServices.DirectoryEntry("LDAP://RootDSE")
	$configpartition = [adsi]("LDAP://CN=Microsoft Exchange,CN=Services," + $root.configurationNamingContext)
 
	# Set variables for search criteria
	$search = New-Object System.DirectoryServices.DirectorySearcher($configpartition)
	$search.filter = '(objectclass=msExchExchangeServer)'
 
	# Perform Serach, this will return all Exchange Server objects
	$ExchServer = $search.FindAll()
 
	# Output Name property of each server object stored in ExchServer array
	$ExchServer | foreach {$_.properties.name}
 
	# Comment the line above and uncomment the line below if you want to search specific Exchange servers by name
	# The example filter below will only output servers that have MBX in their name (i.e. MBX01, SRVMBX45 etc.)
	#$ExchServer | foreach {$_.properties.legacyexchangedn -match "MBX"}
}

You will also have to replace the lines:

1
2
# Get vitals for each server stored in $Servers array
$Servers | %{getVitals}

with the following:

1
2
# Get vitals for each server stored in $Servers array
GetExchangeServers | %{getVitals}


Comments welcome.

Share

Tags: ,

Check Exchange 2003 vitals with PowerShell

I have written recently about Free System PTEs and /PAE usage in Exchange 2003 mailbox servers.

I set out to write a PowerShell script that will run against given list of servers and report back certain vitals including boot.ini settings, SystemPages registry setting and current performance data for Free Sytem PTEs and Pool Non-Paged Bytes.

 

The output csv can be used as a checkpoint for server health and can be used for reporting matrix. The script can easily be modified to add more performance counters and registry checks as necessary.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# Read file and store server names in variable
 
$Servers = (Get-Content .\servers.txt)
 
# Write header in output file
 
# Store header in variable
$headerLine =
@"
 
Server Name,Boot String,3GB,PAE,UserVA,Basevideo,SystemPages,Free System PTEs, Pool Non-Paged Bytes
"@
 
# Write header to file
$headerLine | Out-File .\results.csv -Encoding ASCII -Append
 
function getVitals()
 
{
	# Set server to connect to
	$Server = "$_"
 
# Read SystemPages from servers
 
	# Set Registry Key variables
	$REG_KEY = "System\\CurrentControlSet\\Control\\Session Manager\\Memory Management"
	$VALUE = "SystemPages"
 
	# Open remote registry
	$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Server)
 
	# Open the targeted remote registry key/subkey
	$regKey= $reg.OpenSubKey($REG_KEY)
 
	# Read and Store SystemPages value in variable
	$SystemPages = $regkey.getvalue($VALUE)
 
	# Close the Reg Key
	$regKey.Close()
 
# Read Boot.ini from Servers
 
	# Store Boot.ini contents in variable
	$iniContent = Get-Content "\\$Server\c$\boot.ini"
 
	# Store Boot string and values in variables
	$bootString = $iniContent[4] -replace ","," "
	$userva = ($bootString -split " " | foreach {if ($_ -match "userva") {$_}} | foreach {$_ -replace "/userva=",""})
 
	if ($iniContent[4] -match "3gb") {$3gb="Present"} else {$3gb="Missing"}
	if ($iniContent[4] -match "PAE") {$pae="Present"} else {$pae="Missing"}
	if ($iniContent[4] -match "basevideo") {$basevideo="Present"} else {$userva="Missing"}
 
# Read System Pages and NPP values from Performance Counters
 
	# Read performance counters
	$freeSPTEs = (Get-WmiObject Win32_PerfFormattedData_PerfOS_Memory -ComputerName $Server).FreeSystemPageTableEntries
	$poolNPBytes = (Get-WmiObject Win32_PerfFormattedData_PerfOS_Memory -ComputerName $Server).PoolNonPagedBytes
 
# Write data to file
 
	# Store result string in a variable
	$result = "$Server,$bootString,$3gb,$pae,$userva,$basevideo,$SystemPages,$freeSPTEs,$poolNPBytes"
 
	# Write results to file
	$result | Out-File .\results.csv -Encoding ASCII -Append
 
}
 
 
# Get vitals for each server stored in $Servers array
$Servers | %{getVitals}
Share

Tags: ,

Why should I use /PAE on my Exchange 2003 servers?

Many times I come across the configurations where the servers physically have 4GB memory installed but OS does not see it all. OS usually reports between 512 to 768 MB less!

Running Exchange 2003 on such server with recommended memory tuning parameters as documented in my previous post, makes it even worse because doing this starves the system of available memory. Available MB is the counter to watch on such systems along with Free System PTEs.

So, what causes this to happen? Is it not ok to use the memory tuning in such configurations?

The answer is, why is the system not reporting correct memory and what can you do to address that.

Typically only system above 4GB requires the use of /PAE switch in order for OS to see correct amount of memory by loading PAE kernel. Why would it work in a system with only 4GB RAM installed? The answer lies in PCI-Express based chipsets and how they use MMIO. Microsoft Exchange Team has published a detailed article explaining this.

If you are used to the original guidance of not using /PAE switch on your Exchange 2003 servers, it is time to reconsider.

As organizations refresh their old hardware and are not ready yet to deploy Exchange 2007, they tend to follow their documented build process and overlook the impact of new hardware components on the memory. When they notice it, it is usually because they have a problem with the server and they dig deeper.

So go look at your Exchange 2003 servers and see if they are reporting less memory than actually installed. Maybe it’s time to use /PAE in boot.ini!

Share

Tags:

Free System Page Table Entries in Exchange 2003

When troubleshooting performance of Exchange 2003, most overlooked performance counter is Free System PTEs. Very simply put PTE is basically an I/O partition table.

Why is PTE important?

If a system is running out of PTEs, it can cause system hangs, sporadic lockups, general unresponsiveness. All is bad for a server running enterprise messaging.

Why is it more apparent in Exchange 2003 servers? It is due to the fact that the underlying 32-bit architecture memory limitations and resource requirements of Exchange 2003. There is published guidance on memory tuning and affects of various configurations on System PTEs. The Microsoft KB articles are 325044, 815372 and 311901.

Simply put, most Exchange 2003 servers have 4GB memory installed and /3GB switch configured in boot.ini. This significantly reduces system PTEs. The balance is shifting to provide more resources for Exchange to run smoothly at a cost. If not tuned properly, this can backfire and put your server at a risk ok being unhealthy and prone to crashes.

What can you do to fix this?

Follow the best practices documented in the Microsoft KB articles above. I have listed some obvious steps below:

Remove unused drivers. Drives reserve System PTEs. If not used, removing them can free up PTEs for system usage. The amount of PTEs depends on driver.

Remove display drivers and install System VGA driver shipped with Windows version you are running. This can be as significant as 15000 PTEs from my testing and real world results. Also, use /basevideo in boot.ini (with system VGA driver) which can free up additional ~1000 PTEs. Using /basevideo with OEM video driver can actually use more PTEs.

Tune /userva values. In most cases /userva=3030 should be sufficient. You can tune it in steps and try /userva=2970 and /userva=2900. Understand that this is a balancing act. I suggest don’t change it from 3030 if not needed.

Make sure SystemPages registry entry is set to 0 if you are running Windows Server 2003 SP1 or later.

Use /PAE switch in boot.ini if you are running Windows Server 2003 SP1 or later. (Why use /PAE switch is a subject for a different post)

Always test your configuration in lab before deploying it to production.

If any of the above steps are not clear, refer to KB article 815372.

What is healthy for Free System PTEs counter?

If System PTEs are lower than 5000, the server is in critical condition and you should address the situation immediately.

If System PTEs are above 5000 and below 10,000, there is some memory tuning necessary.

If System PTEs are in 10,000-15,000 range, it is healthy (this is subjective statement, other factors must be considered, we are talking about memory and System PTEs specifically and there may be issues with disk, processor which are not being considered in this post).

If System PTEs are above 20,000 you may be treading Exchange performance for System Performance. Verify that the configuration items mentioned above are correctly set.

Further reading:

System Pages set too High

Memory Management | SystemPages

Clint Huffman | prescriptive guidance on how to troubleshoot PTEs

Jeff Stokes | PTE Depletion, Handle Leaks

wikipedia | Page Table

 

Quote of the day:
Reading is to the mind what exercise is to the body. – Sir Richard Steele

Share

Tags:

Error c10308a2 when remotely adding e-mail address to users

We encountered an error today at my client site. When an administrator tried to add an e-mail address to mail-enabled user from their workstation using Active Directory Users and Computers, the encountered an error c10308a2.

error c10308a2

The error is documented in KB article 905809.

My client was confused after looking at the article and needed some help interpreting the information and find out what he needed to do to fix the issue.

We first assigned the permissions to Service Control Manager as mentioned in Method 1. This is essential of the Network Trace shows the errors when call to Service Control Manager fails.

After this, the error persisted. Which indicates that user does not have permissions to access msExchangeSA service. The figure below shows the error as captured by Network Monitor.

permissions

At this point, you need to follow Method 2 mentioned in KB article. You can either create a new GPO or edit an existing GPO that applies to your Exchange servers. Once user or group the user is member of is assigned read permissions to System Attendant service, and GPO is effectively applied to the exchange servers, administrative user should be able to successfully edit or add e-mail addresses to mail-enabled users.

If you are interested in learning what happens behind the scenes when you add an e-mail address to a user account, Ben Winzenz has wrote an article about it at The Microsoft Exchange Team Blog.

One more thing. If Network trace shows LDAP payload as encrypted, it may not help you understand what is going on within LDAP queries.

Encrypted LDAP packets

Ben shines again here and has written an article about how to disable LDAP encryption and signing on an Exchange server.

Quote of the day:
I know that you believe that you understood what you think I said, but I am not sure you realize that what you heard is not what I meant. – Robert McCloskey

Share

Tags: