TEC’2009 Berlin (The Experts Conference)

TEC’2009 is coming up soon… I’ll be there and I hope you will be too. TEC is a place to get acquainted with some of the top folks in Active DIrectory, ILM/FIM, and Exchange.

Here is what Gil Kirkpatrick, the founder of the conference had to say:

 

I just wanted to remind all the list denizens that I will again be hosting The Experts Conference Europe this September 14-16 in Berlin, Germany.
TEC is comprised to two conferences this year. TEC/Identity and Access features speakers from Microsoft (Alex Weinert, Markus Vilcinskas, and Tomasz Onyszko for ILM/FIM 2010, Dean Wells, Nathan Muggli, and Brett Shirley for DS, and Matt Steele for Geneva), as well as notable MVPs Guido Grillenmeier, Jorge de Almeida-Pinto, and Brian Desmond.
TEC/Exchange includes Ross Smith IV, Greg Taylor, and Brett Shirley from Microsoft, as well as Exchange MVPs Ilse van Criekinge and Michael B. Smith.
You can see the entire TEC agenda at http://www.tec2009.com, and if you have any questions, contact me at gil.kirkpatrick@quest.com.
It would be great to see some of the activedir crowd at TEC this year. If you need to come up with a justification, well, listening to brettsh explain the innards of ESE is worth the price of admission right there.
-gil
I hope to see you there!

 


Follow me on twitter: @EssentialExch

TEC’2009 Berlin (The Experts Conference)

TEC’2009 is coming up soon… I’ll be there and I hope you will be too. TEC is a place to get acquainted with some of the top folks in Active DIrectory, ILM/FIM, and Exchange.

Here is what Gil Kirkpatrick, the founder of the conference had to say:

I just wanted to remind all the list denizens that I will again be hosting The Experts Conference Europe this September 14-16 in Berlin, Germany.
TEC is comprised to two conferences this year. TEC/Identity and Access features speakers from Microsoft (Alex Weinert, Markus Vilcinskas, and Tomasz Onyszko for ILM/FIM 2010, Dean Wells, Nathan Muggli, and Brett Shirley for DS, and Matt Steele for Geneva), as well as notable MVPs Guido Grillenmeier, Jorge de Almeida-Pinto, and Brian Desmond.
TEC/Exchange includes Ross Smith IV, Greg Taylor, and Brett Shirley from Microsoft, as well as Exchange MVPs Ilse van Criekinge and Michael B. Smith.
You can see the entire TEC agenda at http://www.tec2009.com, and if you have any questions, contact me atgil.kirkpatrick@quest.com.
It would be great to see some of the activedir crowd at TEC this year. If you need to come up with a justification, well, listening to brettsh explain the innards of ESE is worth the price of admission right there.
-gil
I hope to see you there!


Follow me on twitter: @EssentialExch

Getting the Contents of an Active Directory Integrated DNS Zone

Microsoft has long offered (where “long” means “since Windows Server 2003”) the “dnscmd.exe” program to control the actions of a DNS server. And, if you installed the adminpack (RSAT-Tools-DNS on Vista/Server 2008 and above) you could perform this control on a remote workstation/server as well.

However, the output of dnscmd leaves….something…. to be desired, especially when you want to format and manipulate that output.

Using a prior blog post of mine (Hex and Decimal Output In PowerShell), I more-or-less reverse-engineered the format of how Active Directory Integrated zones (DNS domains) are stored in Active Directory. For all of my personal testing, the program below was successful at displaying the output and decoding it properly. However, that doesn’t mean I decode everything!!! Just those things I could test.

A key desire of mine was to be able to get the contents of an ADI zone into a CSV (comma-separated-value) format; so of course that option is present. I also wanted proper timeout values for aging/scavenging, so of course that happens by default (which dnscmd can’t do at all).

If the script below doesn’t work for you, I’d be interested in hearing about it, and why it doesn’t work. Of course, I make no promises, but I’ll probably fix those issues. ๐Ÿ™‚

Without further ado…

##
## dns-dump.ps1
##
## Michael B. Smith
## michael at smithcons dot com
## http://TheEssentialExchange.com/blogs/michael
## May/June, 2009
##
## Use as you wish, no warranties expressed, implied or explicit.
## Works for me, but it may not for you.
## If you use this, I would appreciate an attribution.
##

Param(
	[string]$zone,
	[string]$dc,
	[switch]$csv,
	[switch]$help
)

function dumpByteArray([System.Byte[]]$array, [int]$width = 9)
{
	## this is only used if we run into a record format
	## we don't understand.

	$hex = ""
	$chr = ""
	$int = ""

	$i = $array.Count
	"Array contains {0} elements" -f $i
	$index = 0
	$count = 0
	while ($i-- -gt 0)
	{
		$val = $array[$index++]

		$hex += ("{0} " -f $val.ToString("x2"))

		if ([char]::IsLetterOrDigit($val) -or 
		    [char]::IsPunctuation($val)   -or 
		   ([char]$val -eq " "))
		{
			$chr += [char]$val
		}
		else
		{
			$chr += "."
		}

		$int += "{0,4:N0}" -f $val

		$count++
		if ($count -ge $width)
		{
			"$hex $chr $int"
			$hex = ""
			$chr = ""
			$int = ""
			$count = 0
		}		
	}

	if ($count -gt 0)
	{
		if ($count -lt $width)
		{
			$hex += (" " * (3 * ($width - $count)))
			$chr += (" " * (1 * ($width - $count)))
			$int += (" " * (4 * ($width - $count)))
		}

		"$hex $chr $int"
	}
}

function dword([System.Byte[]]$arr, [int]$startIndex)
{
	## convert four consecutive bytes in $arr into a
	## 32-bit integer value... if I had bit-manipulation
	## primitives in PowerShell, I'd use them instead
	## of the multiply operator.

	$res = $arr[$startIndex]
	$res = ($res * 256) + $arr[$startIndex + 1]
	$res = ($res * 256) + $arr[$startIndex + 2]
	$res = ($res * 256) + $arr[$startIndex + 3]

	return $res
}

function analyzeArray([System.Byte[]]$arr, [System.Object]$var)
{
	$nameArray = $var.distinguishedname.ToString().Split(",")
	$name = $nameArray[0].SubString(3)

	## AGE is stored backwards. The most-significant-byte comes
	## last, instead of first, unlike all the other 32-bit values.
	$age = $arr[23]
	$age = ($age * 256) + $arr[22]
	$age = ($age * 256) + $arr[21]
	$age = ($age * 256) + $arr[20]
	if ($age -ne 0)
	{
		## hours since January 1, 1601 (start of Windows epoch)
		## there is a long-and-dreary way to do this manually,
		## but get-date makes it trivial to do the conversion.
		$timestamp = (get-date -year 1601 -month 1 -day 1 -hour 0 -minute 0 -second 0).AddHours($age)
	}

	$ttl = dword $arr 12

	if ($arr[0] -eq 4 -and $arr[1] -eq 0)
	{
		# "A" record
		$ip = "{0}.{1}.{2}.{3}" -f $arr[24], $arr[25], $arr[26], $arr[27]

		if ($csv)
		{
			$formatstring = "{0},{1},{2},{3},{4}"
		}
		else
		{
			$formatstring = "{0,-30}`t{1,-24}`t{2}`t{3}`t{4}"
		}

		if ($age -eq 0)
		{
			$formatstring -f $name, "[static]", $ttl, "A", $ip
		}
		else
		{
			$formatstring -f $name, ("[" + $timestamp.ToString() + "]"), $ttl, "A", $ip
		}
	}
	elseif ((($arr[0] -eq 80) -or ($arr[0] -eq 82)) -and $arr[1] -eq 0)
	{
		# "SOA" record
		# "Start-Of-Authority"

		$nslen = $arr[44]
		$segments = $arr[45]
		$index = 46
		$nsname = ""
		while ($segments-- -gt 0)
		{
			$segmentlength = $arr[$index++]
			while ($segmentlength-- -gt 0)
			{
				$nsname += [char]$arr[$index++]
			}
			if ($segments -gt 0) { $nsname += "." }
		}
		$priserver = $nsname
		# "Primary server: $nsname"

		$index += 1
		$nslen = $arr[$index++]
		$segments = $arr[$index++]

		$nsname = ""
		while ($segments-- -gt 0)
		{
			$segmentlength = $arr[$index++]
			while ($segmentlength-- -gt 0)
			{
				$nsname += [char]$arr[$index++]
			}
			if ($segments -gt 0) { $nsname += "." }
		}
		# "Responsible party: $nsname"
		$resparty = $nsname

		#"TTL: $ttl"
		# "Age: $age"

####		$unk1 = dword $arr 16
####		"Unknown1: $unk1"

		$serial = dword $arr 24
		# "Serial: $serial"

		$refresh = dword $arr 28
		# "Refresh: $refresh"

		$retry = dword $arr 32
		# "Retry: $retry"

		$expires = dword $arr 36
		# "Expires: $expires"

		$minttl = dword $arr 40
		# "Minimum TTL: $minttl"

		if ($age -eq 0)
		{
			$agestr = "[static]"
		}
		else
		{
			$agestr = "[" + $timestamp.ToString() + "]"
		}

		if ($csv)
		{
			$formatstring = "{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10}"

			$formatstring -f $name, $agestr, $ttl, `
				"SOA", $priserver, $resparty, `
				$serial, $refresh, $retry, `
				$expires, $minttl
		}
		else
		{
			$formatstring = "{0,-30}`t{1,-24}`t{2}`t{3}"

			$formatstring -f $name, $agestr, $ttl, "SOA"
			(" " * 32) + "Primary server: $priserver"
			(" " * 32) + "Responsible party: $resparty"
			(" " * 32) + "Serial: $serial"
			(" " * 32) + "TTL: $ttl"
			(" " * 32) + "Refresh: $refresh"
			(" " * 32) + "Retry: $retry"
			(" " * 32) + "Expires: $expires"
			(" " * 32) + "Minimum TTL (default): $minttl"
		}

		#### dumpByteArray $arr
	}
	elseif ((($arr[0] -eq 32) -or ($arr[0] -eq 30)) -and $arr[1] -eq 0)
	{
		# "NS" record
		$nslen = $arr[24]
		$segments = $arr[25]
		$index = 26
		$nsname = ""
		while ($segments-- -gt 0)
		{
			$segmentlength = $arr[$index++]
			while ($segmentlength-- -gt 0)
			{
				$nsname += [char]$arr[$index++]
			}
			if ($segments -gt 0) { $nsname += "." }
		}

		if ($csv)
		{
			$formatstring = "{0},{1},{2},{3},{4}"
		}
		else
		{
			$formatstring = "{0,-30}`t{1,-24}`t{2}`t{3}`t{4}"
		}

		if ($age -eq 0)
		{
			$formatstring -f $name, "[static]", $ttl, "NS", $nsname
		}
		else
		{
			$formatstring -f $name, ("[" + $timestamp.ToString() + "]"), $ttl, "NS", $nsname
		}
	}
	elseif ((($arr[0] -eq 36) -or ($arr[0] -eq 38)) -and $arr[1] -eq 0)
	{
		# "SRV" record

		$port = $arr[28]
		$port = ($port * 256) + $arr[29]

		$weight = $arr[26]
		$weight = ($weight * 256) + $arr[27]

		$pri = $arr[24]
		$pri = ($pri * 256) + $arr[25]

		$nslen = $arr[30]
		$segments = $arr[31]
		$index = 32
		$nsname = ""
		while ($segments-- -gt 0)
		{
			$segmentlength = $arr[$index++]
			while ($segmentlength-- -gt 0)
			{
				$nsname += [char]$arr[$index++]
			}
			if ($segments -gt 0) { $nsname += "." }
		}

		if ($csv)
		{
			$formatstring = "{0},{1},{2},{3},{4},{5}"
		}
		else
		{
			$formatstring = "{0,-30}`t{1,-24}`t{2}`t{3} {4} {5}"
		}

		if ($age -eq 0)
		{
			$formatstring -f `
				$name, "[static]", `
				$ttl, "SRV", `
				("[" + $pri.ToString() + "][" + $weight.ToString() + "][" + $port.ToString() + "]"), `
				$nsname
		}
		else
		{
			$formatstring -f `
				$name, ("[" + $timestamp.ToString() + "]"), `
				$ttl, "SRV", `
				("[" + $pri.ToString() + "][" + $weight.ToString() + "][" + $port.ToString() + "]"), `
				$nsname
		}

	}
	else
	{
		$name
		$var.distinguishedname.ToString()
		dumpByteArray $arr
	}

}

function processAttribute([string]$attrName, [System.Object]$var)
{
	$array = $var.$attrName.Value
####	"{0} contains {1} rows of type {2} from {3}" -f $attrName, $array.Count, $array.GetType(), $var.distinguishedName.ToString()

	if ($array -is [System.Byte[]])
	{
####		dumpByteArray $array
####		" "
		analyzeArray $array $var
####		" "
	}
	else
	{
		for ($i = 0; $i -lt $array.Count; $i++)
		{
####			dumpByteArray $array[$i]
####			" "
			analyzeArray $array[$i] $var
####			" "
		}
	}
}

function usage
{
"
.\dns-dump -zone  [-dc ] [-csv] |
	   -help

dns-dump will dump, from Active Directory, a particular named zone. 
The zone named must be Active Directory integrated.

Zone contents can vary depending on domain controller (in regards
to replication and the serial number of the SOA record). By using
the -dc parameter, you can specify the desired DC to use. Otherwise,
dns-dump uses the default DC.

Usually, output is formatted for display on a workstation. If you
want CSV (comma-separated-value) output, specify the -csv parameter.
Use out-file in the pipeline to save the output to a file.

Finally, to produce this helpful output, you can specify the -help
parameter.

This command is basically equivalent to (but better than) the:

	dnscmd /zoneprint 
or
	dnscmd /enumrecords  '@'

commands.

Example 1:

	.\dns-dump -zone essential.local -dc win2008-dc-3

Example 2:

	.\dns-dump -help

Example 3:

	.\dns-dump -zone essential.local -csv |
            out-file essential.txt -encoding ascii

	Note: the '-encoding ascii' is important if you want to
	work with the file within the old cmd.exe shell. Otherwise,
	you can usually leave that off.
"
}

	##
	## Main
	##

	if ($help)
	{
		usage
		return
	}

	if ($args.Length -gt 0)
	{
		write-error "Invalid parameter specified"
		usage
		return
	}

	if (!$zone)
	{
		throw "must specify zone name"
		return
	}

	$root = [ADSI]"LDAP://RootDSE"
	$defaultNC = $root.defaultNamingContext

	$dn = "LDAP://"
	if ($dc) { $dn += $dc + "/" }
	$dn += "DC=" + $zone + ",CN=MicrosoftDNS,CN=System," + $defaultNC

	$obj = [ADSI]$dn
	if ($obj.name)
	{
		if ($csv)
		{
			"Name,Timestamp,TTL,RecordType,Param1,Param2"
		}

		#### dNSProperty has a different format than dNSRecord
		#### processAttribute "dNSProperty" $obj

		foreach ($record in $obj.psbase.Children)
		{
			####	if ($record.dNSProperty) { processAttribute "dNSProperty" $record }
			if ($record.dnsRecord)   { processAttribute "dNSRecord"   $record }
		}
	}
	else
	{
		write-error "Can't open $dn"
	}

	$obj = $null

Until next time…

If there are things you would like to see written about, please let me know!


Follow me on twitter: @EssentialExch

Handling the userPrincipalName in PowerShell

I dealt with the importance of the userPrincipalName in one of my very early blog postings, dated May 26, 2004: The User Principal Name and You.

While my company has changed, the basic information contained within that post has not changed at all.

I would add one fact: the current Active Directory forest domain is an implied userPrincipalName domain and is not reflected in the list of userPrincipalName domains (also called uPNSuffixes) that are presented in such tools as Active Directory Domains and Trusts. The Active Directory Users and Computer tool is aware of this, and will present it as an option when configuring new user objects.

This PowerShell code handles the addition, reporting, and elimination of UPN suffixes:

#
# userPrincipalName processing routines
#
# Michael B. Smith
# michael@smithcons.com
# April 6, 2009
#
[int] $ADS_PROPERTY_CLEAR	= 1
[int] $ADS_PROPERTY_UPDATE	= 2
[int] $ADS_PROPERTY_APPEND	= 3
[int] $ADS_PROPERTY_DELETE	= 4

function get-ConfigurationPartition
{
	$rootdse  = [ADSI]"LDAP://RootDSE"
	$configNC = $rootdse.ConfigurationNamingContext
	$rootdse  = $null

	$partition = [ADSI]("LDAP://CN=Partitions," + $configNC)

	return $partition
}

function get-UPN
{
	$config = get-ConfigurationPartition
	$suffix = $config.uPNSuffixes
	$config = $null

	return $suffix
}

function test-UPN([string]$upn)
{
	$suffixes = get-UPN

	if (!$suffixes)
	{
		return $false
	}

	if (($suffixes -is [System.String]) -and ($suffixes -eq $upn))
	{
		return $true
	}

	foreach ($suffix in $suffixes)
	{
		if ($suffix -eq $upn)
		{
			return $true
		}
	}

	return $false
}

function new-UPN([string]$upn)
{
	if (test-UPN $upn)
	{
		write-error "$upn already exists"
	}
	else
	{
		$config = get-ConfigurationPartition
		$config.PutEx($ADS_PROPERTY_APPEND, "uPNSuffixes", @($upn))
		$config.SetInfo()
		$config = $null
	}
}

function remove-UPN([string]$upn)
{
	if (test-UPN $upn)
	{
		$config = get-ConfigurationPartition
		$config.PutEx($ADS_PROPERTY_DELETE, "uPNSuffixes", @($upn))
		$config.SetInfo()
		$config = $null
	}
	else
	{
		write-error "$upn doesn't exist"
	}
}

Until next time…

If there are things you would like to see written about, please let me know!


Follow me on twitter: @EssentialExch

TEC’09 In Review

Last week I attended and spoke at “The Experts Conference” (www.tec2009.com) in Las Vegas. I spoke on using VSS with Exchange, and on designing highly available solutions and infrastructure.

This was the eighth year for this conference. In earlier years it was known as DEC (Directory Experts Conference), but over the last several years, as the organizers added more tracks, that has become less and less accurate. So they expanded the name. This year was the first year for an Exchange track.

Note: In prior years, this conference was hosted by NetPro. Last year, Quest acquired NetPro, so this conference is now hosted by Quest.

Can I hear a “wow”?! It was great. You should’ve been there.

TEC is famous for being in-depth. Instead of the 100-200 level presentations you get at most conferences, at TEC you get 300-400 level presentations. In-depth, technical, and very interesting…

Among Exchange MVPs, I and Ilse van Criekinge were speakers, with Lee Mackey also in attendance. But the real stars of the Exchange track were David Espinoza, Brett Shirley and Evan Dodds.

David is the man responsible at Microsoft for getting new releases of Exchange shipped. His title is “Senior Program Manager, Exchange Ship Team”. Among other things, he runs the Exchange TAP. David gave a talk on the software development process for Exchange at Microsoft and answered many questions. He indicated that his talk had never been given outside of Microsoft before and I can believe it – it was very in-depth and instructive as to how “things get done” at Microsoft.

Brett Shirley calls himself “Borg #2 of 6”. He is one of the six programmers of the ESE database engine. The second in seniority, which is where the #2 comes from. ๐Ÿ™‚ Brett gave two deep-dive presentations. One was about the development of ESE over the last several years and the second about how ESE works. They were both pretty stellar.

Evan Dodds is “PowerShell Guy” for Exchange at Microsoft. He spoke on a panel.

Now, regardless of the presentations, the major cool factor was being able to hang with these guys and talk with them and discuss items. Hearing the inside story. Finally being able to understand why “this” happened instead of “that”. That is – the truth before it got scrubbed by marketing!

And I did go to two Active Directory presentations. The Microsoft attendance on that side of the fence was just as stellar, with Nathan Muggli, Stuart Kwan, and Mark Wahl from Microsoft present. There were also many well-known Directory Services MVPs. Somewhat surprisingly, Dmitri Gavrilov, who is now on the Exchange Team, presented sessions on the Directory Services track instead of the Exchange Track.

I recommend that you put this very technical conference on your short list in years to come – if you are a technical guy or gal. Much more of a techie conference than a management conference, you get some very guru-like folks here.

Until next time…

As always, if there are items you would like me to talk about, please drop me a line and let me know!


Follow me on twitter: @EssentialExch

TEC’09 In Review

Last week I attended and spoke at “The Experts Conference” (www.tec2009.com) in Las Vegas. I spoke on using VSS with Exchange, and on designing highly available solutions and infrastructure.

This was the eighth year for this conference. In earlier years it was known as DEC (Directory Experts Conference), but over the last several years, as the organizers added more tracks, that has become less and less accurate. So they expanded the name. This year was the first year for an Exchange track.

Note: In prior years, this conference was hosted by NetPro. Last year, Quest acquired NetPro, so this conference is now hosted by Quest.

Can I hear a “wow”?! It was great. You should’ve been there.

TEC is famous for being in-depth. Instead of the 100-200 level presentations you get at most conferences, at TEC you get 300-400 level presentations. In-depth, technical, and very interesting…

Among Exchange MVPs, I and Ilse van Criekinge were speakers, with Lee Mackey also in attendance. But the real stars of the Exchange track were David Espinoza, Brett Shirley and Evan Dodds.

David is the man responsible at Microsoft for getting new releases of Exchange shipped. His title is “Senior Program Manager, Exchange Ship Team”. Among other things, he runs the Exchange TAP. David gave a talk on the software development process for Exchange at Microsoft and answered many questions. He indicated that his talk had never been given outside of Microsoft before and I can believe it – it was very in-depth and instructive as to how “things get done” at Microsoft.

Brett Shirley calls himself “Borg #2 of 6”. He is one of the six programmers of the ESE database engine. The second in seniority, which is where the #2 comes from. ๐Ÿ™‚ Brett gave two deep-dive presentations. One was about the development of ESE over the last several years and the second about how ESE works. They were both pretty stellar.

Evan Dodds is “PowerShell Guy” for Exchange at Microsoft. He spoke on a panel.

Now, regardless of the presentations, the major cool factor was being able to hang with these guys and talk with them and discuss items. Hearing the inside story. Finally being able to understand why “this” happened instead of “that”. That is – the truth before it got scrubbed by marketing!

And I did go to two Active Directory presentations. The Microsoft attendance on that side of the fence was just as stellar, with Nathan Muggli, Stuart Kwan, and Mark Wahl from Microsoft present. There were also many well-known Directory Services MVPs. Somewhat surprisingly, Dmitri Gavrilov, who is now on the Exchange Team, presented sessions on the Directory Services track instead of the Exchange Track.

I recommend that you put this very technical conference on your short list in years to come – if you are a technical guy or gal. Much more of a techie conference than a management conference, you get some very guru-like folks here.

Until next time…

As always, if there are items you would like me to talk about, please drop me a line and let me know!


Follow me on twitter: @EssentialExch

Monitoring Exchange Server 2007 with System Center Operations Manager 2007

Just a few days ago, my new book (of the subject title!) started shipping from Amazon. If it hasn’t already, it should start appearing in your local bookstores this week.

If you want to order from Amazon, you can get it here.

Eight months in the making, this book was a labor of love. Including information on installing and configuring OpsMgr 2007, it also includes much information about operating a reliable Exchange environment. Even if you don’t have OpsMgr in your organization, you can learn from this book the key areas of Exchange that need monitoring and how to do so.

A strong PowerShell component is provided in several chapters to assist you in the generation of synthetic transactions for testing your Exchange environment.

While the book is written toward a key audience of Exchange Server 2007 administrators, much material is also provided for the Exchange Server 2003 administrator. The book uses a virtualized environment to describe a test roll-out of an OpsMgr 2007 and Exchange 2003/2007 mixed environment.

Since Exchange Server depends on the health of Windows Server, Active Directory, DNS, and IIS; tracking the health and well-being of these key services is also covered.

Go buy it. You’ll like it. ๐Ÿ™‚

The chapter titles are:

  1. An Evolution of Server Management
  2. Monitoring Exchange Server 2007
  3. Installing and Configuring OpsMgr 2007
  4. Deplying OpsMgr 2007
  5. The First Management Pack: WIndows Server
  6. The Active Directory Management Pack
  7. The Domain Name System (DNS) Management Pack
  8. The Internet Information Services Management Pack
  9. SQL Server: An Ancillary Management Pack
  10. Exchange Server 2003
  11. Exchange Server 2007
  12. Exchange Server 2007 Redundancy
  13. Exchange Server Operations
  14. Tracking Mail Flow

Until next time…

As always, if there are items you would like me to talk about, please drop me a line and let me know!


Follow me on twitter: @EssentialExch

Monitoring Exchange Server 2007 with System Center Operations Manager 2007

Just a few days ago, my new book (of the subject title!) started shipping from Amazon. If it hasn’t already, it should start appearing in your local bookstores this week.

If you want to order from Amazon, you can get it here.

Eight months in the making, this book was a labor of love. Including information on installing and configuring OpsMgr 2007, it also includes much information about operating a reliable Exchange environment. Even if you don’t have OpsMgr in your organization, you can learn from this book the key areas of Exchange that need monitoring and how to do so.

A strong PowerShell component is provided in several chapters to assist you in the generation of synthetic transactions for testing your Exchange environment.

While the book is written toward a key audience of Exchange Server 2007 administrators, much material is also provided for the Exchange Server 2003 administrator. The book uses a virtualized environment to describe a test roll-out of an OpsMgr 2007 and Exchange 2003/2007 mixed environment.

Since Exchange Server depends on the health of Windows Server, Active Directory, DNS, and IIS; tracking the health and well-being of these key services is also covered.

Go buy it. You’ll like it. ๐Ÿ™‚

The chapter titles are:

  1. An Evolution of Server Management
  2. Monitoring Exchange Server 2007
  3. Installing and Configuring OpsMgr 2007
  4. Deplying OpsMgr 2007
  5. The First Management Pack: WIndows Server
  6. The Active Directory Management Pack
  7. The Domain Name System (DNS) Management Pack
  8. The Internet Information Services Management Pack
  9. SQL Server: An Ancillary Management Pack
  10. Exchange Server 2003
  11. Exchange Server 2007
  12. Exchange Server 2007 Redundancy
  13. Exchange Server Operations
  14. Tracking Mail Flow

Until next time…

As always, if there are items you would like me to talk about, please drop me a line and let me know!


Follow me on twitter: @EssentialExch

Single-Label Domains (SLDs) and the Next Version of Exchange

I’ve written several times about the inadvisability of having an Active Directory domain name that has a single-label. My most recent article was Wrapping Up SLDs and Exchange Server 2007 in April of 2008.

At that time, Ed Beck of Microsoft wanted to assure me that if customers found bugs, they should report them and Microsoft would investigate the issues and address the issues based on the standard engineering review decision process within Microsoft. That is, Microsoft was’t closing the door on fixing problems with SLDs in Exchange 2007.

Now, the next version of Exchange, which is code-named E14, is in development. Yesterday, Ed emailed me and told me that Microsoft released a forward-looking statement indicating that they are investigating the SLD policy for E14 (Ed authored the article on the MS Exchange Team Blog: Next version of Exchange and Single Label Domain (SLD) policy under review).

I guess if I were you – and using an SLD – now would be the time to make yourself known! Feedback is accepted on the Exchange Team Blog site for quite a while after a posting. Let them know your opinion!

Until next time…

As always, if there are items you would like me to talk about, please drop me a line and let me know!


Follow me on twitter: @EssentialExch

userAccountControl manipulation

The userAccountControl attribute, which resides on each user and computer object in an Active Directory forest, is responsible for, well, controlling lots of things about those accounts. For example it controls whether an account is locked out, or whether an account is disabled, or whether the password for the account expires.

The feature named User Account Control, introduced in Windows Vista, has nothing to do with the userAccountControl attribute. The naming collision is unfortunate.

The userAccountControl attribute is a bit-field attribute. This means that while many things are controlled by a single attribute value, each unique value can have an impact on an account. For information about all the possible values that the attribute can take, see KB 305144, How to use the UserAccountControl flags to manipulate user account properties.

In a forum I spend time with, a poster wanted to disable the “password never expires” flag on all the user accounts contained within an OU. Of course, you can do this manually, but that is subject to error and is very tedious. So, I provided them a PowerShell script to accomplish their objective. See below, and be aware that you can use the same techniques shown in this script to modify any bit-wise value.

You’ll note the use of “-band” and “-bxor” in the PowerShell script. These stand for “bit-wise AND” and similarly “bit-wise XOR”, respectively. The bit-wise operators ensure that each bit of a value is calculated against each corresponding bit in the paired value.

	$ou = "LDAP://cn=Users,dc=essential,dc=local"

	$ADS_UF_DONT_EXPIRE_PASSWD = 0x010000

	$objDomain = New-Object System.DirectoryServices.DirectoryEntry( $ou )
	$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
	$objSearcher.SearchRoot = $objDomain
	$objSearcher.Filter = "(&(objectCategory=person)(objectClass=user))"
	$results = $objSearcher.FindAll()

	foreach( $result in $results )
	{
		$user = [adsi] $result.Path
		$value = $user.userAccountControl.Item( 0 )

		( $user.Name.item( 0 ) + ' ' + $value.ToString() )

		if( ( $value -band $ADS_UF_DONT_EXPIRE_PASSWD ) -ne 0 )
		{
			$value = $value -bxor $ADS_UF_DONT_EXPIRE_PASSWD
			$user.userAccountControl = $value
			$user.SetInfo()
			( "`t" + $user.name + ' updated to $value' )
		}
	}

Until next time…

As always, if there are items you would like me to talk about, please drop me a line and let me know!


Follow me on twitter: @EssentialExch