Skip to content
Menu
Jumlins TechBlog
  • Home
  • About
Jumlins TechBlog

[Powershell Script] Convert ImmutableID

Posted on 2018-09-122019-07-03 by Niklas Jumlin

I found a need to convert, or actually decode the ImmutableID (An Azure AD/Office 365 attribute) back and forth to the corresponding Hexadecimal, GUID- and DN value in order to match the value to an on-premise Active Directory object.

The thing about ImmutableID is that its encoded as a Base64 string that looks something like this 2bRnBQ6D80uTz6T14srMPw==.

The corresponding attribute in AD which is used as SourceAnchor is either the objectGUID, mS-DS-ConsistenceyGuid or msDS-SourceAnchor (requires Windows Server 2016 schema update).

The values for each of these attributes does match the value of the ImmutableID, but it does not appear like that at first sight.

Take a look at these examples:

The objectGUID is shown as a GUID-value, however, you can get the Hex or Decimal value by going into the editor of the attribute:

The mS-DS-ConsistencyGuid is shown as Hexadecimal:

You can also get the Decimal value of the mS-DS-ConsistencyGuid if you’d like, but its quite cumbersome going about this way to retrieve it.

The msDS-SourceAnchor attribute however does match the encoding and format of the ImmutableID. But as of AAD Connect May 2017 release, version 1.1.524, the default sourceAnchor used by the setup wizard is mS-DS-ConsistencyGuid.

 

miisclient.exe (Synchronization Service Manager)

If you’re familiar with the miisclient.exe (Synchronization Service Manager), you would probably have noticed that when looking at the statistics and trying to identify which users were added, removed or updated you will usually be presented a list of so-called Distinguished Names that are hard to distinguish (pun intended), these Distinguished Name-values are not the same as those of an Active Directory object either, these values can however be decoded to the ImmutableID value.

The way I usually go about identifying my user in this list is by first finding the ImmutableID for the user I’m working with, then decode its value to all the various formats with said script and then while looking into the miisclient I’ll know which DN value to look for.

Here’s the script that does all the conversions back and forth to all kinds of formats that I could think of.

 


<#

Copyright © 2018 Niklas Jumlin.  All rights reserved.   

THIS CODE AND ANY ASSOCIATED INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR

IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR

PURPOSE. THE ENTIRE RISK OF USE, INABILITY TO USE, OR RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.

------------------------------------------------------------------------------   

 NAME:   
 Translate_ImmutableID.ps1

 Author: Niklas Jumlin
 Web: https://blog.jumlin.com
   
 VERSION:   
 1.4 (2018-09-12) - Now converts decimal value of ms-DS-ConsistencyGuid or ObjectGUID to HEX, ImmutableID, DN and GUID-format.

 This script is indeed somewhat quick-n-dirty and can be improved upon a lot. But the basic requirements satisfied my own needs.

 Parts of this script is built upon blocks from these scripts:
 https://identitydude.com/2015/08/01/dn-value-in-aad-sync-aad-connect-the-new-format/
 https://gallery.technet.microsoft.com/office/Covert-DirSyncMS-Online-5f3563b1

------------------------------------------------------------------------------   

#>

#Requires -Version 3

[CmdletBinding()]

param (
	[Parameter(Mandatory = $true,
	HelpMessage="`
Input a ImmutableID-string, Azure CS DN value, GUID-ObjectGuid/ms-DS-ConsistencyGuid, Hex-ObjectGuid/ms-DS-ConsistencyGuid or Decimal-ObjectGuid/ms-DS-ConsistencyGuid`
`
ImmutableID: 2bRnBQ6D80uTz6T14srMPw==`
Decimal: 217 180 103 5 14 131 243 75 147 207 164 245 226 202 204 63`
HEX: D9 B4 67 05 0E 83 F3 4B 93 CF A4 F5 E2 CA CC 3F`
DN: CN={3262526e42513644383075547a3654313473724d50773d3d}`
GUID: 0567b4d9-830e-4bf3-93cf-a4f5e2cacc3f`
`
")]
	[string]$Value
)

# identification helper functions

function isGUID ($data) { 
	try { 	$guid = [GUID]$data 
		return 1 } 
	catch { return 0 } 
}

function isBase64 ($data) { 
	try { 	$decodedII = [system.convert]::frombase64string($data) 
        	return 1 } 
	catch { return 0 } 
}

function isHEX ($data) { 
	try { 	$decodedHEX = "$data" -split ' ' | foreach-object { if ($_) {[System.Convert]::ToByte($_,16)}}
		return 1 } 
	catch { return 0 } 
}

function isDN ($data) { 
	If ($data.ToLower().StartsWith("cn=")) {
		return 1 }
	else {	return 0 }
}

# conversion functions

function ConvertIItoDecimal ($data) {
	if (isBase64 $data) {
		$dec=([system.convert]::FromBase64String("$data") | ForEach-Object ToString) -join ' '
		return $dec
	}
}

function ConvertIIToHex ($data) {
	if (isBase64 $data) {
		$hex=([system.convert]::FromBase64String("$data") | ForEach-Object ToString X2) -join ' '
		return $hex
	}	
}

function ConvertIIToGuid ($data) {
	if (isBase64 $data) {
		$guid=[system.convert]::FromBase64String("$data")
		return [guid]$guid
	}
}

function ConvertHexToII ($data) {
	if (isHex $data) {
		$bytearray="$data" -split ' ' | foreach-object { if ($_) {[System.Convert]::ToByte($_,16)}}
		$ImmID=[system.convert]::ToBase64String($bytearray)
		return $ImmID
	}
}

function ConvertIIToDN ($data) {
	if (isBase64 $data) {
		$enc = [system.text.encoding]::utf8
		$result = $enc.getbytes($data)
		$dn=$result | foreach { ([convert]::ToString($_,16)) }
		$dn=$dn -join ''
		return $dn
	}
}

function ConvertDNtoII ($data) {
	if (isDN $data) {
		$hexstring = $data.replace("CN={","")
		$hexstring = $hexstring.replace("}","")
		$array = @{}
		$array = $hexstring -split "(..)" | ? {$_}
		$ImmID=$array | FOREACH { [CHAR][BYTE]([CONVERT]::ToInt16($_,16))}
		$ImmID=$ImmID -join ''
		return $ImmID
	}
}

function ConvertGUIDToII ($data) {
	if (isGUID $data) {
		$guid = [GUID]$data
    		$bytearray = $guid.tobytearray()
    		$ImmID=[system.convert]::ToBase64String($bytearray)
		return $ImmID
	}
}

# from byte string (converted to byte array)
If ( ($value -replace ' ','') -match "^[\d\.]+$") {
	$bytearray=("$value" -split ' ' | foreach-object {[System.Convert]::ToByte($_)})
	$HEXID=($bytearray| ForEach-Object ToString X2) -join ' '

	$identified="1"
	Write-host ""

	$ImmID=ConvertHexToII $HEXID
	$dn=ConvertIIToDN $ImmID
	$GUIDImmutableID = ConvertIIToGuid $ImmID

	Write-Host "HEX: $HEXID" -foregroundColor Green
	Write-Host "ImmutableID: $ImmID" -foregroundColor Green
	Write-Host "DN: CN={$dn}" -foregroundColor Green
	Write-Host "GUID: $GUIDImmutableID " -foregroundColor Green
}

# from hex
If ($value -match " ") {
	If ( ($value -replace ' ','') -match "^[\d\.]+$") {
		Return
	}
	$identified="1"
	Write-host ""

	$ImmID=ConvertHexToII $value
	$dec=ConvertIItoDecimal $ImmID
	$dn=ConvertIIToDN $ImmID
	$GUIDImmutableID = ConvertIIToGuid $ImmID

	Write-Host "Decimal: $dec" -foregroundColor Green
	Write-Host "ImmutableID: $ImmID" -foregroundColor Green
	Write-Host "DN: CN={$dn}" -foregroundColor Green
	Write-Host "GUID: $GUIDImmutableID " -foregroundColor Green
}

# from immutableid
If ($value.EndsWith("==")) {
	$identified="1"
	Write-host ""

	$dn=ConvertIIToDn $Value	
	$HEXID=ConvertIIToHex $Value
	$GUIDImmutableID = ConvertIIToGuid $Value
	$dec=ConvertIItoDecimal $value

	Write-Host "Decimal: $dec" -foregroundColor Green
	Write-Host "HEX: $HEXID" -foregroundColor Green
	Write-Host "DN: CN={$dn}" -foregroundColor Green
	Write-Host "GUID: $GUIDImmutableID " -foregroundColor Green
}

# from  dn
If ($value.ToLower().StartsWith("cn=")) {
	$identified="1"
	Write-host ""

	$ImmID=ConvertDNToII $Value
	$HEXID=ConvertIIToHex $ImmID
	$GUIDImmutableID = ConvertIIToGuid $ImmID
	$dec=ConvertIItoDecimal $ImmID

	Write-Host "Decimal: $dec" -foregroundColor Green
	Write-Host "ImmutableID: $ImmID" -foregroundColor Green
	Write-Host "HEX: $HEXID" -foregroundColor Green
	Write-Host "GUID: $GUIDImmutableID " -foregroundColor Green
}

# from guid
if ( isGuid $Value) {
	$identified="1"
	Write-host ""

	$ImmID=ConvertGUIDToII $Value
	$dn=ConvertIIToDN $ImmID
	$HEXID=ConvertIIToHex $ImmID
	$dec=ConvertIItoDecimal $ImmID

	Write-Host "Decimal: $dec" -foregroundColor Green
	Write-Host "ImmutableID: $ImmID" -foregroundColor Green
	Write-Host "HEX: $HEXID" -foregroundColor Green
	Write-Host "DN: CN={$dn}" -foregroundColor Green	
}

If (-not($identified)) {
	Write-host -fore red "You provided a value that was neither an ImmutableID (ended with ==), a DN (started with CN=), a GUID, a HEX-value nor a Decimal-value, please try again."
}

<# Examples

ImmutableID: 2bRnBQ6D80uTz6T14srMPw==
Decimal: 217 180 103 5 14 131 243 75 147 207 164 245 226 202 204 63
HEX: D9 B4 67 05 0E 83 F3 4B 93 CF A4 F5 E2 CA CC 3F
DN: CN={3262526e42513644383075547a3654313473724d50773d3d}
GUID: 0567b4d9-830e-4bf3-93cf-a4f5e2cacc3f

#>

Feel free to donate a beer (or coffee) if you found this useful :)

Share on Facebook

6 thoughts on “[Powershell Script] Convert ImmutableID”

  1. Terrence says:
    2019-01-09 at 22:36

    Thanks this was a god send. Had mismatch guid between o365 and on prem due to orphaned mailbox.

  2. Mick says:
    2020-07-30 at 03:33

    What a great handy script. Good on you.

  3. Gin says:
    2020-08-10 at 17:39

    Nicely done.
    Thank you for sharing.

  4. Stephen Inglis says:
    2020-11-09 at 15:57

    My absolute hero :-)

  5. Sebastien says:
    2021-05-27 at 18:18

    What a fucking good tool ! Widely deserved a beer ! thanks

  6. CK says:
    2022-10-16 at 14:11

    I’ve yet to try this out, as i’m learning on the fly, but I heard of this tool from watching a great video on Fixing ADConnect Sync issue, from SecureCRC. He certainly spoke highly and uses this often, so I look fwd. I just picked up a new client and they have a dup user. No clue what was used first for Imm_ID, and rather not Un/Re installed. I just need to find out the Imm_ID and sounds like your tool will convert for me. Just can’t understand why ADSynch would option the the single IMM_ID that requires conversion. You;d think with a simple tool like this, that they’d sink the UPN, keep like simple for the rest of the world, or ANY attribute that doens;t need converting, right!? Thanks for this!

Leave a Reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • Office 365 Groups/Teams powershell reporting script 2019-03-25
  • [Powershell Script] Convert ImmutableID 2018-09-12
  • Script to Schedule Mem and or vCPU up/downgrade 2015-05-13
  • Backing up VMs in Hyper-V 2013-01-09
  • Windows Server 2012 as a Workstation 2012-09-13

Archives

Categories

  • Exchange 2003
  • Exchange 2010
  • HTML/CSS
  • Imagick
  • JavaScript
  • Linux
  • Misc
  • Office 365 / Azure
  • PHP
  • PowerCLI
  • PowerShell
  • Projects
  • Scripts
  • Server
  • System Administration
  • VMware
  • Winbatch
  • Windows
  • Windows Server 2012

Recent Posts

  • Office 365 Groups/Teams powershell reporting script 2019-03-25
  • [Powershell Script] Convert ImmutableID 2018-09-12
  • Script to Schedule Mem and or vCPU up/downgrade 2015-05-13
  • Backing up VMs in Hyper-V 2013-01-09
  • Windows Server 2012 as a Workstation 2012-09-13
©2023 Jumlins TechBlog | Powered by WordPress & Superb Themes