Hex and decimal output in PowerShell

In UNIX/Linux/whatever there is this little utility called ‘od’ which makes it trivial to dump the output of a file in multiple formats.

Yesterday, I was working on a project and needed something similar. I could’ve downloaded Cygwin and installed it, or UnixUtils from Sourceforge, but no – I decided to write a PowerShell routine to give me what I needed.

If you’ve never had the need to see hexadecimal, alphanumeric, and decimal information on a file all at once, well, move along now!

Otherwise, below is my solution for your benefit. A couple of interesting points are my use of System.Char methods to determine whether a character is printable (viewable) and my use of the format operator (-f) which uses System.Format.

Many attributes in Active Directory (including many Exchange and DNS related attributes) have a raw form that devolves into a System.Byte[] array (or an array of System.Byte[] arrays). You can get an arbitrary file as a byte array by using the Get-Content cmdlet with the “-Encoding Byte” parameter.

Here is example output (with a line of header information that isn’t from this routine):

dNSRecord contains 62 rows of type System.Byte[] from DC=_gc._tcp.E14-Site._sites,DC=essential.local,CN=MicrosoftDNS,CN=System,DC=essential,DC=local
Array contains 62 entries
26 00 21 00 05 f0 00 00 d7  &.!..ð...   38   0  33   0   5 240   0   0 215
07 00 00 00 00 02 58 00 00  ......X..    7   0   0   0   0   2  88   0   0
00 00 ac 9a 36 00 00 00 00  ....6....    0   0 172 154  54   0   0   0   0
64 0c c4 1e 03 0c 77 69 6e  d.Ä...win  100  12 196  30   3  12 119 105 110
32 30 30 38 2d 64 63 2d 33  2008-dc-3   50  48  48  56  45 100  99  45  51
09 65 73 73 65 6e 74 69 61  .essentia    9 101 115 115 101 110 116 105  97
6c 05 6c 6f 63 61 6c 00     l.local.   108   5 108 111  99  97 108   0    

And without further ado:

function dumpByteArray([System.Byte[]]$array, [int]$width = 9)
{
	$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"
	}
}

Until next time…

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


Follow me on twitter: @EssentialExch

Hex and decimal output in PowerShell

In UNIX/Linux/whatever there is this little utility called ‘od’ which makes it trivial to dump the output of a file in multiple formats.

Yesterday, I was working on a project and needed something similar. I could’ve downloaded Cygwin and installed it, or UnixUtils from Sourceforge, but no – I decided to write a PowerShell routine to give me what I needed.

If you’ve never had the need to see hexadecimal, alphanumeric, and decimal information on a file all at once, well, move along now!

Otherwise, below is my solution for your benefit. A couple of interesting points are my use of System.Char methods to determine whether a character is printable (viewable) and my use of the format operator (-f) which uses System.Format.

Many attributes in Active Directory (including many Exchange and DNS related attributes) have a raw form that devolves into a System.Byte[] array (or an array of System.Byte[] arrays). You can get an arbitrary file as a byte array by using the Get-Content cmdlet with the “-Encoding Byte” parameter.

Here is example output (with a line of header information that isn’t from this routine):

dNSRecord contains 62 rows of type System.Byte[] from DC=_gc._tcp.E14-Site._sites,DC=essential.local,CN=MicrosoftDNS,CN=System,DC=essential,DC=local
Array contains 62 entries
26 00 21 00 05 f0 00 00 d7  &.!..ð...   38   0  33   0   5 240   0   0 215
07 00 00 00 00 02 58 00 00  ......X..    7   0   0   0   0   2  88   0   0
00 00 ac 9a 36 00 00 00 00  ....6....    0   0 172 154  54   0   0   0   0
64 0c c4 1e 03 0c 77 69 6e  d.Ä...win  100  12 196  30   3  12 119 105 110
32 30 30 38 2d 64 63 2d 33  2008-dc-3   50  48  48  56  45 100  99  45  51
09 65 73 73 65 6e 74 69 61  .essentia    9 101 115 115 101 110 116 105  97
6c 05 6c 6f 63 61 6c 00     l.local.   108   5 108 111  99  97 108   0    

And without further ado:

function dumpByteArray([System.Byte[]]$array, [int]$width = 9)
{
	$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"
	}
}

Until next time…

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


Follow me on twitter: @EssentialExch

Removing the Last Exchange 2003 Server…

Microsoft has lots of guidance about removing the last Exchange 2003 server from an administrative group (see KB 822931) and I definitely recommend you give that a read. They also have a technet article about removing the last Exchange 2003 server from your organization (after you’ve upgraded to Exchange 2007, of course). You should give that a read too.

But if you do these things lots of times (and if you are a consultant, you probably do – or if you play in your Exchange lab a lot, you probably do too); you just need a quick list of reminders. Here is the list I take onsite with me, when I’m removing an Exchange 2003 server:

Verify that all mailbox moves are complete (either within the console or “get-mailbox -server “).

Verify that all public folder moves are complete (“get-publicfolderstatistics -server “). Note: if they aren’t this can be tough. Check the scripts in $ExScripts like MoveAllReplicas and RemoveReplicaFromPFRecursive.

If you do NOT have an Edge server, verify that the Default receive connector allows Anonymous connections.

If you DO have an Edge server, verify that Edge synchronization has occurred and is operational (“test-edgesynchronization”).

Move all Offline Address Book generation servers to servers that will continue to exist

Move the “Default Public Store” on all Exchange 2003 Mailbox Stores to point to a Exchange 2007 PF

Delete the Public Folder databases from the Exchange 2003 server (note: this is not a required step, but if you can’t do this, then de-install of Exchange will fail – so this is a good place to go ahead and figure that out).

Delete both sides of Interop RGCs (and verify that they are the only RGCs still present: “get-routinggroupconnector”)

Delete SMTP connectors from ESM on the Exchange 2003 server (you can do this from the EMC on Exchange 2007 later, but you’ll get a version warning)

Evaluate Recipient Policies and delete all unused RPs from ESM on the Exchange 2003 server

Verify status of all recipient policies (ensure that Mailbox Manager boxes are unchecked)

Note: you may want to record Mailbox Manager settings to recreate MRM policies on Exchange 2007 to replace the MM policies

Relocate the PF heirarchy (in Exchange 2003 ESM, right-click the Exchange 2007 Administrative Group, select Next -> PF Container, drag PF object from the Exchange 2003 Administrative Group to the Exchange 2007 Administrative Group)

Delete the Domain Recipient Update Service(s) from ESM on Exchange 2003

Point the Enterprise Recipient Update Server to an Exchange 2007 mailbox server (or delete the RUS from Active Directory using adsiedit or LDP)

Uninstall Exchange

…..

Now, this is one of those postings where I have to say “this works for me”. I bet it’ll work for you too – but I can’t guarantee it!

Until next time…

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


Follow me on twitter: @EssentialExch

Backing Up Exchange 2007 on Windows 2008

It has been suggested to me that my series on backing up Exchange Server 2007 on Windows Server 2008 was so complicated that the content was truly inaccessible for the novice admin. For that, I apologize. At heart, I am a techie kind of guy and I spend a lot of time trying to make complicated things easy – in my blog articles, my magazines articles, and in the presentations I make at various conferences.

So, to make up for that, without any technical discussion whatsoever, I present my GUI solution (still PowerShell based) for backing up Exchange Server 2007 on Windows Server 2008. With the exception of the forms-based handling, all of the technical infrastructure has been discussed here and in article preceding that article.

The GUI solution requires .NET 2.0, but that’s already installed on any Exchange Server 2007 computer.

To use the backup script:

  1. Download the zip file to a directory for PowerShell scripts on the Exchange Server you want to back up
  2. Extract the two files contained in the zip file into that directory
  3. Create (or identify) a directory where you want backups to go
  4. Identify the first free drive letter on the server
  5. Modify the MBS-GUI-Exchange-backup.ps1 script parameter block to insert those two parameters
  6. Execute the script (from PowerShell, move to the directory where you extracted the scripts and type in ./MBS-GUI-Exchange-backup.ps1)

That’s it.That’s all it takes.

Down the script MBS-GUI-Exchange2007-Backup.zip.

Just one tiny technical comment: if you are on Exchange 2003, it would be relatively easy to modify this script to use BEtest to execute VSS backups for Exchange 2003.

Until next time…

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


Follow me on twitter: @EssentialExch

Backing Up Exchange 2007 on Windows 2008

It has been suggested to me that my series on backing up Exchange Server 2007 on Windows Server 2008 was so complicated that the content was truly inaccessible for the novice admin. For that, I apologize. At heart, I am a techie kind of guy and I spend a lot of time trying to make complicated things easy – in my blog articles, my magazines articles, and in the presentations I make at various conferences.

So, to make up for that, without any technical discussion whatsoever, I present my GUI solution (still PowerShell based) for backing up Exchange Server 2007 on Windows Server 2008. With the exception of the forms-based handling, all of the technical infrastructure has been discussed here and in article preceding that article.

The GUI solution requires .NET 2.0, but that’s already installed on any Exchange Server 2007 computer.

To use the backup script:

  1. Download the zip file to a directory for PowerShell scripts on the Exchange Server you want to back up
  2. Extract the two files contained in the zip file into that directory
  3. Create (or identify) a directory where you want backups to go
  4. Identify the first free drive letter on the server
  5. Modify the MBS-GUI-Exchange-backup.ps1 script parameter block to insert those two parameters
  6. Execute the script (from PowerShell, move to the directory where you extracted the scripts and type in ./MBS-GUI-Exchange-backup.ps1)

That’s it.That’s all it takes.

Down the script MBS-GUI-Exchange2007-Backup.zip.

Just one tiny technical comment: if you are on Exchange 2003, it would be relatively easy to modify this script to use BEtest to execute VSS backups for Exchange 2003.

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

More Multi-valued Parameters in PowerShell (SourceTransportServers in Set-SendConnector)

In my first article on Multi-valued Parameters in PowerShell, I discussed a certain class of array parameters that Exchange 2007 uses many times – the [System.Object[]] (i.e., array of arbitrary elements) class for RemoteIpRanges.

Unfortunately, that isn’t the only multi-valued type used by PowerShell for Exchange Server 2007. There are actually quite a few of them.

Another type that comes up fairly often is SourceTransportServers. This is used by the Set-SendConnector cmdlet among others. It is a collection of a specific type of objects that Exchange 2007 refers to as ADobjectIDs.

An ADobjectID is actually quite similar to a System.DirectoryServices.DirectoryEntry – however, in comparison, this type has very few populated properties. The fact that the property list for ADobjectID is quite small indicates the reason why Exchange uses this type instead of System.DirectoryServices.DirectoryEntry – the population of a few types is much more efficient than the population of all the types present for a DirectoryEntry.

Populating and updating SourceTransportServers is a common idea, especially when you are using provisioning scripts to completely deploy new servers. Here is an example of PowerShell code that you can use to do this:

$newhub = Get-ExchangeServer "newhubserver"
$adobject = New-Object Microsoft.Exchange.Data.Directory.ADobjectID $newhub.distinguishedName

$a = Get-SendConnector "Internet Email"
$a.SourceTransportServers.Add($adobject)

$a | Set-SendConnector

Until next time…

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


Follow me on twitter: @EssentialExch

First Article in Red Gate’s Simple-Talk

Red Gate is a company based out of Cambridge in the UK. I ran into some of their team at TechEd last year. They are a great bunch of folks.

I’ve been doing tech. review for them on a number of articles since then, and I just had my first article published with them.

If you have a minute, take a look-see: Determining MS Exchange Disk Performance. It covers what’s important to look at in measuring Exchange disk performance and some tools to use.

My next article with them will be Outlook/Exchange related, and then I hope to do an article on calculating the anticipated performance of a RAID subsystem. Neat techie stuff. 🙂

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

First Article in Red Gate’s Simple-Talk

Red Gate is a company based out of Cambridge in the UK. I ran into some of their team at TechEd last year. They are a great bunch of folks.

I’ve been doing tech. review for them on a number of articles since then, and I just had my first article published with them.

If you have a minute, take a look-see: Determining MS Exchange Disk Performance. It covers what’s important to look at in measuring Exchange disk performance and some tools to use.

My next article with them will be Outlook/Exchange related, and then I hope to do an article on calculating the anticipated performance of a RAID subsystem. Neat techie stuff. 🙂

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