Posts RSS Comments RSS 253 Posts and 407 Comments till now

blog: WS2008 R2 Active Directory Webcast – Tomorrow, Friday 4/24

Tomorrow Laura Hunter and Brian Desmond will be doing a webcast discussing and premoting the new Active Directory features in Windows Server 2008 R2 as well as answering AD questions. They have a 90 minute slot and they expect to spend ~45-60 minutes on R2 and the remainder taking questions on the presentation and AD in general.

The webcast is hosted by O?Reilly and is free to attend. If you can?t make it, a recording will be available.

Here are the details:

Registration Link - HERE

Date: Friday, April 24, 2009

Time: 10am PT, San Francisco
6pm - London | 1pm - New York | Sat, Apr 25th at 3am - Sydney | Sat, Apr 25th at 2am - Tokyo | Sat, Apr 25th at 1am - Beijing | 10:30pm - Mumbai

Presented by: Brian Desmond, Laura E. Hunter

Duration: Approximately 90 minutes.

Cost: Free

WS2008 R2 Active Directory Webcast – Tomorrow, Friday 4/24

Tomorrow Laura Hunter and Brian Desmond will be doing a webcast discussing and premoting the new Active Directory features in Windows Server 2008 R2 as well as answering AD questions. They have a 90 minute slot and they expect to spend ~45-60 minutes on R2 and the remainder taking questions on the presentation and AD in general.

The webcast is hosted by O’Reilly and is free to attend. If you can’t make it, a recording will be available.

Here are the details:

Registration Link – HERE

Date: Friday, April 24, 2009

Time: 10am PT, San Francisco
6pm – London | 1pm – New York | Sat, Apr 25th at 3am – Sydney | Sat, Apr 25th at 2am – Tokyo | Sat, Apr 25th at 1am – Beijing | 10:30pm – Mumbai

Presented by: Brian Desmond, Laura E. Hunter

Duration: Approximately 90 minutes.

Cost: Free

blog: WS2008 R2 Active Directory Webcast – Tomorrow, Friday 4/24

Tomorrow Laura Hunter and Brian Desmond will be doing a webcast discussing and premoting the new Active Directory features in Windows Server 2008 R2 as well as answering AD questions. They have a 90 minute slot and they expect to spend ~45-60 minutes on R2 and the remainder taking questions on the presentation and AD in general.

The webcast is hosted by O’Reilly and is free to attend. If you can’t make it, a recording will be available.

Here are the details:

Registration Link - HERE

Date: Friday, April 24, 2009

Time: 10am PT, San Francisco 6pm - London | 1pm - New York | Sat, Apr 25th at 3am - Sydney | Sat, Apr 25th at 2am - Tokyo | Sat, Apr 25th at 1am - Beijing | 10:30pm - Mumbai

Presented by: Brian Desmond, Laura E. Hunter

Duration: Approximately 90 minutes.

Cost: Free

Hanging out in PA!

Mrs. Laura Hunter invited me to a Code Camp in Philly. If you live anywhere close? stop by. It is free and there are some heavy hitters that are going to be there (I mean Eric Fleischman and Gil Kirkpatrick.) It is on a weekend so no work excuses :P

 

More Detail here

Developer & IT Pro Event in Philadelphia- Saturday April 18th

Hanging out in PA!

Mrs. Laura Hunter invited me to a Code Camp in Philly. If you live anywhere close… stop by. It is free and there are some heavy hitters that are going to be there (I mean Eric Fleischman and Gil Kirkpatrick.) It is on a weekend so no work excuses :P

 

More Detail here

Developer & IT Pro Event in Philadelphia- Saturday April 18th

Getting the UpToDateness Vector (UTDV) in Powershell

A year or so ago I needed to get the UTDV Table (defined in detail HERE by Laura Hunter of ShutUpLaura.) At the time, the only way I knew how to get this information was to get the replUpToDateVector attribute from the NC on the target DC. I could have used Repadmin shown below, but that wouldn’t have been any fun. I did however end up with the massive script at the bottom of this post. It required decoding the UTDV table and resolving the Invocation ID to a name or “DeletedDSA.”

Fast forward to the present.

During the course of a long conversation on an ActiveDir thread (“Domain Controller Version”,) joe (aka joeware) and I got into side conversation about getting the UTDV table (ironically due to a statement/question in the thread by the same Laura, mentioned earlier.)

This led me to a wonderful little .NET method (GetReplicationCursors) on DirectoryServices.ActiveDirectory.DomainController class. This was so much easier I wanted to kick myself for not finding it sooner.

In any case, it was a great learning experience so I wanted to share it you. Enjoy my pain and victory.

Using Repadmin

repadmin /showutdvec [dc]  "[ DN for Naming Context ]"

The easy way.
Using System.DirectoryServices.ActiveDirectory.DomainController

Write-Host
$domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$NC = "DC={0}" -f ($domain.Name -replace "\.",",DC=")
foreach($dc in $domain.DomainControllers)
{
    Write-Host "$($DC.Name)"
    Write-Host "================"
    $UDTV =  $dc.GetReplicationCursors($NC)
    $GUID = @{n=‘DSA’;e={if($_.SourceServer){$_.SourceServer}else{$_.SourceInvocationId}}}
    $UDTV | Select-Object $GUID,
                          UpToDatenessUsn,
                          LastSuccessfulSyncTime | Sort DSA -desc | Format-Table -auto
    Write-Host
}

The Hard way.
I initially did all the work myself using this function. This gets the Up To Dateness vector and decodes it. It also translates the Invocation ID (if possible.)

param([string]$server)

Begin{
    function Get-InvocationIDFromBytes{
        Param([byte[]]$GuidArray)
        $GUIDSection1 = @(1..4)
        $GUIDSection2 = @(1..2)
        $GUIDSection3 = @(1..2)
        $GUIDSection4 = @(1..2)
        $GUIDSection5 = @(1..6)
   
        $start = 0
       
        $InvocationIDString = ""
       
        foreach($byte in $GuidArray)
        {
            $InvocationIDString = $InvocationIDString + "\" + ([string]::Format("{0:X2}",$byte))
        }
       
        [system.Array]::Copy($GuidArray,$start,$GUIDSection1,0,4)
        [system.Array]::Copy($GuidArray,($start+4),$GUIDSection2,0,2)
        [system.Array]::Copy($GuidArray,($start+6),$GUIDSection3,0,2)
        [system.Array]::Copy($GuidArray,($start+8),$GUIDSection4,0,2)
        [system.Array]::Copy($GuidArray,($start+10),$GUIDSection5,0,6)
        [system.Array]::Reverse($GUIDSection1)
        [system.Array]::Reverse($GUIDSection2)
        [system.Array]::Reverse($GUIDSection3)
       
        [string]$GuidString1 = $GUIDSection1 | %{[string]::Format("{0:X2}",$_)}
        [string]$GuidString2 = $GUIDSection2 | %{[string]::Format("{0:X2}",$_)}
        [string]$GuidString3 = $GUIDSection3 | %{[string]::Format("{0:X2}",$_)}
        [string]$GuidString4 = $GUIDSection4 | %{[string]::Format("{0:X2}",$_)}
        [string]$GuidString5 = $GUIDSection5 | %{[string]::Format("{0:X2}",$_)}
       
        $GuidString1 = $GuidString1.replace(" ","")
        $GuidString2 = $GuidString2.replace(" ","")
        $GuidString3 = $GuidString3.replace(" ","")
        $GuidString4 = $GuidString4.replace(" ","")
        $GuidString5 = $GuidString5.replace(" ","")
       
        $InvocationGUID = "{0}-{1}-{2}-{3}-{4}" -f $GuidString1,$GuidString2,$GuidString3,$GuidString4,$GuidString5
       
        $name = Get-NameFromInvocationID $InvocationIDString
        if(!$DCInvocationID.$InvocationGUID)
        {
            if($name)
            {
                $DCInvocationID.add($InvocationGUID,($InvocationIDString,$name))
            }
            else
            {
                $DCInvocationID.add($InvocationGUID,$InvocationIDString)
            }
        }
        return $InvocationGUID
    }
    function Get-USNFromBytes{
        Param([byte[]]$USNArray)
        [system.Array]::Reverse($USNArray)
        [string]$USN = $USNArray | %{[string]::Format("{0:X2}",$_)}
        $usn = $usn.replace(" ","")
        $usn = [int]"0x$usn"
        $usn.PadRight(12)
    }
    function Get-DateFromBytes{
        Param([byte[]]$dateArray)
        [system.Array]::Reverse($dateArray)
        $temp = @(1..5)
        [system.Array]::Copy($dateArray,3,$temp,0,5)
        [string]$date = $temp | %{[string]::Format("{0:X2}",$_)}
        $date = $date.replace(" ","")
        $date = [int64]"0x$date"
        $date = $date + "0000000"
        [system.DateTime]::FromFileTime($date)
    }
    function Get-NameFromInvocationID{
        Param($InvocationID)
        [string]$config = ([adsi]"LDAP://RootDSE").ConfigurationNamingContext
        $de = new-Object System.DirectoryServices.DirectoryEntry("LDAP://$Config")
        $filter = "(&(invocationID=$InvocationID)(objectcategory=ntdsdsa))"
        $ds = new-Object System.DirectoryServices.DirectorySearcher($de,$filter)
        $hresult = $ds.findone()
        if($hresult.Path)
        {
            $ResultDE = $hresult.GetDirectoryEntry()
            $name = ($ResultDE.psbase.parent).DNSHostName
        }
        $name
    }
    function Decode-UpToDateVectorTable{
        Param([byte[]]$table)
       
        $guid = @(1..16)
        $USN = @(1..8)
        $Date = @(1..8)
        $UTDTable = @()
        $name = $null
       
        for($i=16;$i -lt $table.count;$i+=32)
        {
            [system.Array]::Copy($table,$i,$Guid,0,16)
            [system.Array]::Copy($table,$i+16,$USN,0,8)
            [system.Array]::Copy($table,$i+16+8,$Date,0,8)
           
            $GUIDString = Get-InvocationIDFromBytes $GUID
            $USNString  = Get-USNFromBytes $usn
            $dateString = Get-DateFromBytes $Date
            $UTDEntry = "" | Select-Object Name,USN,Date
            [system.Array]$dcname = $DCInvocationID.$GUIDString
            if($dcname[1])
            {
                $UTDEntry.Name = $dcname[1]
                $UTDEntry.USN =  $USNString
                $UTDEntry.Date = $DateString
                $UTDTable += $UTDEntry
            }
            else
            {
                $UTDEntry.Name = $GUIDString
                $UTDEntry.USN =  $USNString
                $UTDEntry.Date = $DateString
                $UTDTable += $UTDEntry
            }
        }  
        $UTDTable
    }
    $DCInvocationID = @{}
    $utdTables = @()
    $process = @()
}
Process{
    if($_)
    {
        $process += $_
    }
}
End{
    if($server){$process += $server}
    foreach($srv in $process)
    {
        $table = ([adsi]"LDAP://$srv").replUpToDateVector[0]
        if($process.count -gt 1)
        {
            $utdTableEntry = "" | Select-Object Name,UpToDatenessVector
            $utdTableEntry.Name = $srv
            $utdTableEntry.UpToDatenessVector = Decode-UpToDateVectorTable $table | Sort-Object Name -des
            $utdTables += $utdTableEntry
        }
        else
        {
            Decode-UpToDateVectorTable $table | Sort-Object Name -des
        }
    }
    if($utdTables){return $utdTables}
}

Back From the MVP Summit

Well… Just got back from a week in Redmond. It was awesome!

First I want to thank MS for putting this all together. It was a testament to their commitment to the community and desire to see their products succeed.

While this was my first MVP summit, I did hear several others comment on how this was the best one yet.

I was VERY lucky to have a seasoned MVP vet (Dean Wells) show me the ropes and introduce me to some of the (IMO) smartest technical people on the planet. These guys/gals are not only incredibly smart… but they were an absolute blast to hang out with.

I doubt they subscribe to my blog but I wanted to do a shout out and link their blogs/Sites

Dean Wells: Absolute Great Trainer/Consultant http://www.msetechnology.com
joe Richards (joeware): http://blog.joeware.net/
Joe Kaplan : http://www.joekaplan.net/
Brian Desmond: http://briandesmond.com/blog/default.aspx
Laura Hunter: http://www.shutuplaura.com/
Mr Hunter (Mark Arnold) : http://markarnold.blogspot.com/
Gil Kirkpatrick (NetPro): http://www.gilsblog.com/
Ulf B. Simon-Weidner’s: http://msmvps.com/blogs/UlfBSimonWeidner/Default.aspx
Tony Murray (founder activedir.org): www.ActiveDir.org Blog: http://www.open-a-socket.com/
Little Jimmy: http://www.jimmytheswede.blogspot.com/
Darren Mar-Elia (SDMSoftware): http://www.sdmsoftware.com/blog/
Princess Jorge!: http://blogs.dirteam.com/blogs/jorge/
Brett Shirley: http://blogs.msdn.com/brettsh/
Eric Fleischman: http://blogs.technet.com/efleis/default.aspx (currently VERY slow to post)

I can not tell you (literally I am under NDA :) ) How much I learned this past week.

What I can say is that for Powershell… the future is VERY BRIGHT!

The time with the Powershell Dev team was great. Again… can’t say much, but they have great plans.

I spent about 5hrs with the Active Directory team discussing their plans. If the AD Team can pull off what they have planned… OMG it is awesome. AD administration will never be the same.

The next version of SCVMM looks great.