Archive for category Exchange Server

All Exchange 2010 network communications in a diagram

Today, Michel de Rooij posted an update to his Exchange 2010 SP1 Network ports diagram. You can find it here.

This is a great resource if you ever need to refer to network flow between different roles and well as different clients to server communications. This is too good of information to pass on without sharing.

I am sure you will benefit from it if you have anything to do with Exchange server.

Huge thanks to Michel for creating this very helpful document.

Originally posted at http://blogs.technet.com/bshukla

Print Friendly
Share

Comparison of Outlook 2010 and OWA features

I see many asking for comparison between Outlook 2010 and OWA with Exchange Server 2010 mailbox. While I did not have time lately with my commitments and travel, I came across Steve’s recent post which compares the features. He also included Outlook 2011 comparison which is great!

Here’s the link to his blog entry: http://www.stevieg.org/2010/11/comparison-outlook-2010-owa-2010-outlook-2011-features/

Thanks Steve for creating the comparison that will benefit many!

Originally posted at http://blogs.technet.com/bshukla

Print Friendly
Share

Deep Zoom Role Posters for Exchange 2010

Many of you may already have seen the post on Microsoft Exchange Team Blog announcing the availability of Exchange 2010 Architecture poster. you may also have seen Transport Architecture Diagrams published a while ago.

If you have not, head over to those links and download those posters as they are great for learning and reference. For those who are mobile and don’t want to carry around printed poster, I have created Deep Zoom versions of the posters. If you have not experienced Deep Zoom, check it out at http://zoom.it/

The Deep Zoom posters for Exchange 2010 are located here:

http://zoom.it/Phu7 – Transport Role Architecture 
http://zoom.it/cuvV – Transport Extensibility
http://zoom.it/47Xd – Exchange 2010 Architecture

Enjoy!

Originally posted at http://blogs.technet.com/bshukla

Print Friendly
Share

Script to change Address Book Service throttling on Exchange 2010

If you are deploying BlackBerry in Exchange 2010 environment, one of the requirements is to change throttling limits on Address Book Service from default 50 to 100,000. While I reserve my judgment to what number is right, you will have to change it to some number above 50 for sure.

If you have many CAS servers where you have to change this, it quickly becomes painful because you have to change config file and restart services.

Well, sweat no more if you are in this situation. Use my script instead.

You can download the script here: Set-ThrottlingLimit.ps1

I will avoid posting entire code here but below are some examples of how you can run it:

The following example will query specified server for current value of MaxSessionsPerUser:

 

Set-ThrottlingLimit -Server Server1

 

The following example will set MaxSessionsPerUser to 5000 and restart services MSEXchangeRPC and MSExchangeAB without confirmation:

 

Set-ThrottlingLimit -Server Server1 -MaxSessionsPerUser "5000" -force $true

 

The following example will set MaxSessionsPerUser to 5000 and restart services MSEXchangeRPC and MSExchangeAB after confirmation from user:

 

Set-ThrottlingLimit -Server Server1 -MaxSessionsPerUser "5000"

 

Questions and Comments are always welcome.

Originally posted at http://blogs.technet.com/bshukla

Print Friendly
Share

Script to configure static ports on Exchange Server 2010

This post is depricated. Please use newer version of script and read more details here: http://www.bhargavs.com/index.php/2011/10/21/script-to-configure-static-ports-on-exchange-server-2010-2/

If you are planning to implement or are implementing Exchange Server 2010, you may have already noticed that with new changes introduced in this version we highly recommend that you load balance your CAS servers using hardware load balancer. The client connections are not mediated through RPC Client Access service on CAS and that’s why load balancing CAS is very important.

Now if you know how Outlook clients work with Exchange RPC/MAPI, you may as well be aware that it uses random high ports for connection to the Exchange servers. This may not work well when you try to configure your hardware load balancer device. There are many other reasons why you may decide that you would rather use a static port or two for services that need it. It also makes it easy to configure network devices to work with few ports than a whole upper range of high ports.

To that matter, TechNet article “Load Balancing Requirements of Exchange Protocols” has done a great job documenting how you can configure static ports on CAS and Mailbox servers. Henrik Walther has also provided some more details on TechNet wiki article “Configuring Static RPC Ports on an Exchange 2010 Client Access Server”.

Now only if you had the script to do it all for you so you can enjoy doing other things that may be more important or interesting to you… :)

Well, that’s why I have created this script… just for YOU!

So, how do I run the script?

There are few ways you can run it. One is to just call the script with your server name.

& 'c:\scripts\Set-StaticPorts.ps1' -Server Server1

This will change RPC and Address Book ports on the server you specify.

If you want to change many servers, store your servers in a variable and pipe it. Use whichever method works for you to create the array variable with servers you need. One example is to use text file containing one server per line:

$Servers = Get-Content c:\scripts\servers.txt
$Servers | Foreach {& 'c:\scripts\Set-StaticPorts.ps1' -Server $_}

The script can be run remotely as long as you have proper permissions on the server to change registry and exchange configuration files.

So far, in examples above, we did not specify which ports to use for each service. The script accommodates for this by having default values 7575 and 7576 for RPC Service and Address Book Service respectively. But what if you want to specify your own ports? Run:

& 'c:\scripts\Set-StaticPorts.ps1' -Server Server1 -rpcport "50000" -abport "50001"

This will allow you to define your own ports. Just ensure you are not using well known ports or ports in use by other services in your environment to avoid any conflict or confusion.

The script is noisy as you may notice when you run it. It is intentional. It will prompt for your confirmation when changing ports if they are already changed before. It will ask for confirmation before restarting services. Now you may say, I am running the script and I know what I am doing. Well, let the force be with you. –force parameter I mean!

& 'c:\scripts\Set-StaticPorts.ps1' -Server Server1 -rpcport "50000' -abport "50001" –force $true

And this will silcence prompting. It will still write output for each server to the host. You can redirect it to a file as well!

 

& 'c:\scripts\Set-StaticPorts.ps1' -Server Server1 -rpcport "50000" -abport "50001" –force $true | out-file c:\scripts\results.txt

So, where is this script? You can download it here: Set-StaticPorts.ps1

If you are still reading, here’s the actual script to refer:

# FUTURE, Update to run with -auto to find cas servers and run automatically
# FUTURE, Update to rung with -auto to find PF stores and run on PF host
#############################################################################
# Set-StaticPorts.ps1
# This script will configure static ports for RPC Client Access and
# Address Book Service on Exchange 2010 CAS servers.
#
# Usage syntax:
# Set-StaticPorts [-Server]  [-rpcport]  [-abport]  [-force]
#
# Usage Examples:
# Set-StaticPorts -Server Server1 -rpcport "50000" -abport "50001" -force $true
# Set-StaticPorts -Server Server1
#
# Use this script in accordance to the following Technet wiki article:
# http://social.technet.microsoft.com/wiki/contents/articles/configuring-static-rpc-ports-on-an-exchange-2010-client-access-server.aspx
#
# Created by
# Bhargav Shukla
# http://blogs.technet.com/bshukla
# 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.
#############################################################################

# Declare Parameters with defaults
param([string]$server,[string]$rpcport = '7575',[string]$abport = '7576',[bool]$force = $false)

# Filter to set tcp-port, for avoiding redundancy in the code that follows
function tcp-port
{
	if (($regkey.getvalue($VALUE)) -eq $null)
	{
		# Create / Set TCP/IP Port key and value
		$regKey.Setvalue('TCP/IP Port', "$rpcport", 'Dword')

		# Make changes effective immediately
		$regKey.Flush()

		# Read and store current value
		$global:TCPPort = $regkey.getvalue($VALUE)	

		# Close registry key
		$regKey.Close()

		Write-Host -ForegroundColor Green "TCP/IP Port for RPC Client Access is set to $TCPPort on server $server."
	}
	else
	{
		if (($regkey.getvalue($VALUE)) -ne $rpcport)
		{
			$rpccurrport = $regkey.getvalue($VALUE)
			If (($force) -or (Read-Host "Change the RPC Client Service port from $rpccurrport to $rpcport ? [Y/N]") -eq "Y")
			{
				# Create / Set TCP/IP Port key and value
				$regKey.Setvalue('TCP/IP Port', "$rpcport", 'Dword')

				# Make changes effective immediately
				$regKey.Flush()

				# Read and store current value
				$global:TCPPort = $regkey.getvalue($VALUE)	

				# Close registry key
				$regKey.Close()

				Write-Host -ForegroundColor Green "TCP/IP Port for RPC Client Access is set to $TCPPort on server $server."
			}
			else
			{
				Write-Host -ForegroundColor Green "No changes to RPC Client Service port are made on server $server."
			}
		}
		else
		{
			Write-Host -ForegroundColor Green "No changes to RPC Client Service port are necessary on server $server."
		}
	}
}

function get-installpath
{
	# Set Exchange base key and value to read
	$Reg_ExSetup = "SOFTWARE\\Microsoft\\ExchangeServer\\v14\\Setup"
	$VALUE = "MsiInstallPath"

	# Set regKey for MsiInstallPath
	$regKey= $reg.OpenSubKey($REG_ExSetup)

	# Get Install Path from Registry and replace : with $
	$installPath = ($regkey.getvalue($VALUE) | foreach {$_ -replace (":","`$")})

	# Set Address Book Service config file path
	$global:ABFile = "\\$Server\$installPath"+"Bin\microsoft.exchange.addressbook.service.exe.config"

	# Close registry key
	$regKey.Close()
}

function restart-services
{
	# Restart Microsoft Exchange RPC Client Access and Microsoft Exchange Address Book 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 = 'msexchangerpc')","(name = 'msexchangeab')"

	$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")
					{
						Write-Warning "Service $($Service.Name) is stopped on server $Server."
						break :Checking;
					} Else {
						If (((Get-Date) - $Then).seconds -ge $TimeOut)
						{
							Write-Warning "Service $($Service.Name) timed out while trying to stop on server $Server. Please restart service manually."
							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")
					{
						Write-Host "Service $($Service.Name) started successfully on server $Server"
						break :Checking;
					} Else {
						If (((Get-Date) - $Then).seconds -ge $TimeOut)
						{
							Write-Warning "Service $($Service.Name) timed out while trying to start on server $Server. Please restart service manually."
							break :Checking;
						}
					}
				} While ($True)
			}
		}
}

If ($server)
{
	# Set Registry Key variables
	$REG_BASE = "System\\CurrentControlSet\\Services\\MSExchangeRPC"
	$REG_KEY = "System\\CurrentControlSet\\Services\\MSExchangeRPC\\ParametersSystem"
	$VALUE = 'TCP/IP Port'

	# 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)

	# Create/Modify Key and Values as necessary
	if ($regKey)
	{
	tcp-port
	}
	else
	{
	$regBase = $reg.OpenSubKey($REG_BASE,$true)
	$regBase.CreateSubKey('ParametersSystem')
	$regBase.Close()
	# Open the targeted remote registry key/subkey as read/write
	$regKey = $reg.OpenSubKey($REG_KEY,$true)
	tcp-port
	}

	# Get location of Address Book Service configuration file
	get-installpath

	# Verify the file exists, exit if it doesn't
	if (Test-Path $ABFile -ErrorAction SilentlyContinue)
	{
		# Backup file before editing
		$currentDate = (get-date).tostring("MM_dd_yyyy-hh_mm_s")
		$ABbackup = $ABFile + ".$currentDate"
		$xml = [xml](get-content $ABFile)
		$xml.Save($ABbackup)

		# Edit RpcTcpPort if 0, ask user for approval if not 0
		$root = $xml.get_DocumentElement();
		ForEach ($item in $root.appSettings.add)
		{
		if (($item.key -eq "RpcTcpPort") -and ($item.value -eq "0"))
			{
				$item.value="$abport"
				Write-Host -ForegroundColor Green "TCP/IP Port for Address Book Service is set to $ABPort on server $server."
			}
			else
			{
			If (($item.key -eq "RpcTcpPort") -and ($item.value -ne "$abport"))
				{
				if (($force) -or (Read-Host "Change port from $($item.value) to $abport on server $server ? [Y/N]") -eq "Y")
					{
						$item.value="$abport"
						Write-Host -ForegroundColor Green "TCP/IP Port for Address Book Service is set to $ABPort on server $server."
					}
				else
					{
						Write-Host -ForegroundColor Green "No changes are made to TCP/IP Port for Address Book Service on server $server."
					}
				}
			}
		}
		$xml.Save($ABFile)
	}
	else
	{
	Write-Host -ForegroundColor Red -BackgroundColor Black "Address Book Service configuration file does not exist for server $server. Please verify file and update manually."
	}

	# Ask for and restart services if requested
	If (($force) -or (Read-Host "Restart services MSExchangeRPC and MSExchangeAB? [Y/N]") -eq "Y")
		{
			restart-services
		}
		else
		{
			Write-Warning "Please restart the Microsoft Exchange RPC Client Access (MSExchangeRPC) service for changes to take effect."
		}

	# Reminder for MAilbox Servers
	Write-Warning "Please do not forget to change ports on Mailbox servers for Public Folder Access."
}
else
{
Write-Host -ForegroundColor Red -BackgroundColor Black "Server Name is null. Please provide Server where static ports need to be set."
Write-Host -ForegroundColor Red -BackgroundColor Black "The syntax is 'Set-StaticPorts.ps1 `"servername`" `"1234`" `"1235`"'."
Write-Host -ForegroundColor Red -BackgroundColor Black "Please replace values of `"1234`" and `"1235`" with valid port numbers for RPC and Address Book Services respectively."
}

This is a cross post from http://blogs.technet.com/bshukla

Print Friendly
Share

How to install Update Rollups remotely on Exchange 2010 server

If you are like me, you are always looking for ways to not leave your chair, or for that matter, not switch windows.

When it comes to install Update Rollups on every Exchange 2010 server you have, the same applies. So I set out to find a way and I found one! Even though this requires some work upfront, it will make it easy ever after.

Pre-Requisites:

The cost of making it easier for future is the work you have to do now. Well, let’s get to it. In order to be able to connect to your Exchange servers remotely, you will need to configure winrm (if not configured already). All you need to do is run

winrm quickconfig

from elevated PowerShell session (run as administrator). The command adds an HTTP listener, configures the server to allow remote requests, and creates a Firewall exception rule. I am assuming that you are running Windows Server 2008 R2. I have not tested this on other server versions, however it should work if PowerShell v2 and WinRM is installed correctly.

Script:

So, how do I run the script?

Get-Content “\\server\share\servers.txt” | Foreach-Object {Invoke-Command –ComputerName $_ –FilePath “\\server\share\Install-UpdateRollups.ps1”}

The command will read list of servers from servers.txt (specify your path where it reads \\server\share\servers.txt) and call script to install Update Rollup specified in the script. Notice that I am user serialization by piping. This way I am running update only on one server at a time. The command could be change to look like this:

Invoke-Command –ComputerName (Get-Content “\\server\share\servers.txt”) –FilePath “\\server\share\Install-UpdateRollups.ps1”

however, I have not tested it on multiple computers and unsure of the success using this method.

After the installation of Update Rollup, the script will prompt user for reboot and if user approves, script will also reboot the server.

So, a million dollar question is, where is this script? You can download it here: Install-UpdateRollups.ps1

The code is pasted below for reference:

#############################################################################
# Install-UpdateRollups.ps1
# Remotely installs Update Rollups on Exchange 2007 or Exchange 2010 servers
#
# Pre-requisites
# --------------
# Requires winrm enabled on destination servers. Run winrm quickconfig to enable.
# Requires write access to $Log_Drive folder and $Install_Drive folder if "Logs"
#   folder doesn't exist in $Install_Drive.
#
# Created by
# Bhargav Shukla
# http://blogs.technet.com/bshukla
# 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.
#############################################################################

#Update variables to reflect correct locations and Update Rollup installer file name
$Install_Drive = "\\server\share"
$RU_File = "installer.msp"
$Log_Drive = "$Install_Drive\Logs"
$ServerName = $Env:COMPUTERNAME

# Check for RU install file
$CheckRUPath = "$Install_Drive\$RU_File"
Write-Host -ForegroundColor Green "Checking for $CheckRUPath"
if (-not (Test-Path $CheckRUPath))
{
	Write-Host -ForegroundColor Red "ERROR: Update Rollup File not found!"
	Write-Host -ForegroundColor Red "ERROR: Exiting."
	exit
}

# Check for Logs path, create folder if doesn't exist
$CheckLogPath = "$Log_Drive"
Write-Host -ForegroundColor Green "Checking for $CheckLogPath"
if (-not (Test-Path $CheckLogPath))
{
	Write-Host -ForegroundColor Yellow "ERROR: Log Folder not found!"
	Write-Host -ForegroundColor Yellow "INFO:  Creating Log Folder..."
	New-Item -Path $Install_Drive -Name Logs -itemtype directory -Force
}

# Disable "Check for publisher's certificate revocation"
Write-Host ""
Write-Host -ForegroundColor Green "Disabling publisher's certificate revocation check..."
set-ItemProperty -path "HKCU:\Software\Microsoft\Windows\CurrentVersion\WinTrust\Trust Providers\Software Publishing" -name State -value 146944

Write-Host -ForegroundColor Green "Installing Exchange Update Rollup..."
	$oProcess = [System.Diagnostics.Process]::Start("$Install_Drive\$RU_File", " /passive /lv $Log_Drive\$ServerName-InstallRollup.log /norestart")
	$oProcess.WaitForExit() 

# Enable "Check for publisher's certificate revocation"
Write-Host -ForegroundColor Green "Re-enabling Check for publisher's certificate revocation..."
Set-ItemProperty -path "HKCU:Software\Microsoft\Windows\CurrentVersion\WinTrust\Trust Providers\Software Publishing" -name State -value 146432

# Reboot if user responds [Y]es
if ((Read-Host "Reboot? [Y/N]") -eq "Y")
{
write-host -ForegroundColor Red "Rebooting Server $ServerName."
Restart-Computer
}
Update:

I failed to mention the effect of double-hops and delegation of authentication for the remote installation mentioned above to work. Here’s why it is a problem:

Your install files and list of servers are located on a server (let’s call it ServerA). You are running the invoke-command from a client computer (let’s call it ClientA) and you are going to install RU on Exchange servers (let’s call it EXA, EXB and EXC). When you run the command, get-content is run is local runspace of ClientA and works fine. The next step is to pipe the servernames to invoke-command. The install script mentioned above is then called from share on ServerA. However, this is now remote runspace on exchange servers EXA, EXB and EXC. The error you will notice is when the install script checks for existence of RU file. Even if the RU file exists in mentioned share and permissions are given to account you are using to run the commands from ClientA, you will see that script errors and exits unexpectedly. It thinks the RU file doesn’t exist when it actually does!

That is because, your credentials from ClientA are passed to EXA, however, to access the file on ServerA, your credentials needs to be passed on to it. This is delegation. And we have not configured any delegation yet! This will cause script block to fail since it can’t access the RU file without access.

How can you solve this? Here are the steps:

1. on ClientA run:

Enable-wsmancredssp -role client –delegatecomputer *

This will enable credssp delegation from ClientA to computers you define in –delegatecomputer. In our example, we allowed delegation to all computer by using * which is ok for lab. In production environment, you may want to restrict it to your domain name (i.e. *.domain.com) or list of servers (i.e. EXA.domain.com, EXB.domain.com, EXC.domain.com).

2. on all target servers, EXA, EXB and EXC in our example, run:

Enable-wsmancredssp -role server

This will allow target servers to use credentials specified by ClientA using CredSSP to access files on ServerA.

3. on ClientA, run the install command:

$cred = Get-Credential
Get-Content “\\server\share\servers.txt” | Foreach-Object {Invoke-Command –ComputerName $_ –FilePath “\\server\share\Install-UpdateRollups.ps1” –Authentication CredSSP –Credential $cred}

Notice the use of CredSSP and explicit specification of credentials. This is important and required for the remote install process to work.

One more gotcha. The process above does not work if your ClientA isn’t Windows 7, Vista or Windows Server 2008. This is because CredSSP isn’t available to Windows XP or Windows Server 2003. You can host your share on Windows Server 2003, however, you must run step 1 and 3 from a client that is capable of using CredSSP.

Here are some references for further reading:

Multi-Hop Support in WinRM

Using invoke-command to launch a script on a remote computer which connects to network resources

Enable-WSManCredSSP

 

This article is also posted to http://www.bhargavs.com

Print Friendly
Share

What does New-ExchangeCertificate –confirm do?

Depends who is asking.

Let’s assume a scenario where you are trying to create a new self-signed certificate on Exchange 2007 using a script. You run the command “New-Exchange Certificate – Services “IMAP, POP3, IIS, SMTP” –Confirm:$false”. The script stops at a prompt when it tries to confirm overwrite of existing SMTP certificate (because current self-signed certificate is assigned to that function). Since this is breaking your script, you decide to throw in –force to force override of the prompt.

Now you face another error: “Parameter set cannot be resolved using the specified named parameters.

This is because –Force serves different purpose in Exchange 2007. According to TechNet:

Use this parameter switch to overwrite an existing certificate request file that matches the same file path as specified in this cmdlet. By default, this cmdlet will not overwrite existing files.

Unfortunately, there is no way you can override the dreaded SMTP certificate prompt in Exchange 2007 (that I know of).

Now let’s turn our attention to Exchange 2010. Since New-ExchangeCertificate cmdlet does not directly write to a file, –force serves the purpose you expected in previous scenario. According to TechNet:

The Force switch specifies whether to override the confirmation prompt and set the new self-signed certificate as the default certificate for TLS for internal SMTP communication. By default, this cmdlet requires a confirmation before setting the new certificate as the default certificate for TLS encryption of internal SMTP communication.

So in case you were wondering, there you go.

Print Friendly
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!

Print Friendly
Share

Tags: , , ,

Automate Update Rollup installation during Exchange 2010 setup

If you are about to install Exchange 2010, one of the checks in your checklist should be Update Rollup 1 for Exchange 2010. This would come after you have installed Exchange 2010 on your server. But what if I tell you that you can slipstream RU1 with your Exchange setup?

All you have to do is populate a folder with RU installer and use /UpdatesDir switch with setup.com. The example would be setup.com /role:mailbox /UpdatesDir:”C:\ExchangeSources\RUs”. Once this command successfully completes, you will see that the exchange install is complete and your determined patches from the UpdatesDir are applied to the server in single step! Isn’t that a thing of beauty?

Exchange Server Update Rollups are cumulative so you don’t need to have RU1 installer if you build a new server with RU2 in future. All you need is RU2 installer file in UpdatesDir and exchange source to install from.

There are many other useful switches to automate Exchange 2010 setup. you can find the reference on Technet.

Print Friendly
Share

Tags: , ,

How do I check Update Rollup version on Exchange 20xx Server?

Instead of updating my previous post which covers only Exchange 2007, I decided to create a new post which covers both versions.

Now that Update Rollup for Exchange Server 2010 is available, I have updated my previous script to check for Update Rollup versions on both Exchange Server 2007 and Exchange Server 2010. No need to have two versions of script. Just download this one!

Here’s what has changed between versions:

  • Product GUID has changed to AE1D439464EB1B8488741FFA028E291C (Exchange 2010) from 461C2B4266EDEF444B864AD6D9E5B613 (Exchange 2007).
  • Exchange writes installation information to HKLM\SOFTWARE\Microsoft\ExchangeServer\v14\Setup instead of “HKLM\SOFTWARE\Microsoft\Exchange\Setup”

The script below will do the work for you so you don’t need to remember what I just said above. Isn’t that what script is for?

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
# Store header in variable
$headerLine =
@"
 
Server Name,Rollup Update Description,Installed Date,ExSetup File Version
"@
 
# Write header to file
$headerLine | Out-File .\results.csv -Encoding ASCII -Append
 
function getRU()
{
# Set server to connect to
	$Server = "$_".ToUpper()
 
 
# Check if server is running Exchange 2007 or Exchange 2010
 
	$ExchVer = (Get-ExchangeServer $Server | ForEach {$_.AdminDisplayVersion.Major})
 
# Set appropriate base path to read Registry
# Exit function if server is not running Exchange 2007 or Exchange 2010
	if ($ExchVer -eq "8" -or $ExchVer -eq "14")
		{
			switch ($ExchVer)
			{
			 "14"	{
			 			$REG_KEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\AE1D439464EB1B8488741FFA028E291C\\Patches"
						$Reg_ExSetup = "SOFTWARE\\Microsoft\\ExchangeServer\\v14\\Setup"
			 		}
			 "8"	{
			 			$REG_KEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\461C2B4266EDEF444B864AD6D9E5B613\\Patches"
						$Reg_ExSetup = "SOFTWARE\\Microsoft\\Exchange\\Setup"
			 		}
			}
		}
	else
		{return}
 
# Read Rollup Update information from servers
 
# Set Registry constants
	$VALUE1 = "DisplayName"
	$VALUE2 = "Installed"
	$VALUE3 = "MsiInstallPath"
 
# Open remote registry
	$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Server)
 
# Set regKey for MsiInstallPath
	$regKey= $reg.OpenSubKey($REG_ExSetup)
 
# Get Install Path from Registry and replace : with $
	$installPath = ($regkey.getvalue($VALUE3) | foreach {$_ -replace (":","`$")})
 
# Set ExSetup.exe path
	$binFile = "Bin\ExSetup.exe"
 
# Get ExSetup.exe file version
	$exSetupVer = ((Get-Command "\\$Server\$installPath$binFile").FileVersionInfo | ForEach {$_.FileVersion})
 
# Create an array of patch subkeys
	$regKey= $reg.OpenSubKey($REG_KEY).GetSubKeyNames() | ForEach {"$Reg_Key\\$_"}
 
# Walk through patch subkeys and store Rollup Update Description and Installed Date in array variables
	$dispName = [array] ($regkey | %{$reg.OpenSubKey($_).getvalue($VALUE1)})
	$instDate = [array] ($regkey | %{$reg.OpenSubKey($_).getvalue($VALUE2)})
 
# Loop Through array variables and output to a file
	$countmembers = 0
 
	if ($regkey -ne $null)
	{
		while ($countmembers -lt $dispName.Count)
		{
		$server+","+$dispName[$countmembers]+","+$instDate[$countmembers].substring(0,4)+"/"+$instDate[$countmembers].substring(4,2)+"/"+$instDate[$countmembers].substring(6,2)+","+$exsetupver | Out-File .\results.csv -Encoding ASCII -Append
		$countmembers++
		}
	}
	else
	{
		$server+",No Rollup Updates are installed,,"+$exsetupver | Out-File .\results.csv -Encoding ASCII -Append
	}
}
 
# Get Exchange 2007 servers and write Rollup Updates to results file
$Servers = (Get-ExchangeServer | Where-Object {($_.AdminDisplayVersion -match "8" -OR $_.AdminDisplayVersion -match "14") -AND $_.ServerRole -ne "ProvisionedServer" -and $_.ServerRole -ne "Edge"} | ForEach {$_.Name})
$Servers | ForEach {getRU}

Download – Get-ExchangeUpdateRollups.ps1

Print Friendly
Share

Tags: