May 2009 - Posts

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!

Posted by michael | 1 comment(s)
Filed under: ,

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 <servername>").

Verify that all public folder moves are complete ("get-publicfolderstatistics -server <servername>"). 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!

Posted by michael | with no comments