PowerShell - Get-GuidFromHex
Lot of time I need to deal with conversion between different data structures. One most often I deal with is conversion from hex data to guid representation of it. I wrote simple function that handles that kind of conversion.
Since lot of guid representation stored in hex format uses little endian ordering, function has special switch -LittleEndian which will convert hex to guid using little endian byte ordering.
function Get-GuidFromHex
{
param
(
[string]
$HexString,
[switch]
$LittleEndian
)
#region Perform hex string validation
# if string provided is in raw hex format, remove heading '0x'
if ($HexString.StartsWith('0x'))
{
$HexString = $HexString.Substring(2);
}
# guid expects 32 bits, if provided string is not 32 bits length,
# we shouldn't bother with trying to convert it.
if ($HexString.Length -ne 32)
{
throw "Hex string is not valid length. Current length is '$($HexString.Length)', expected length is 32 characters.";
}
# validate if all characters from provided string is expected
# hex character.
[regex]$hexAllowedCharacters = '[0-9a-fA-F]';
foreach ($hexChar in $HexString.ToCharArray())
{
if (-not ($hexAllowedCharacters.Match($hexChar).Success))
{
throw "Unexpected character encountered '$hexChar'. Provided hex string is not in valid format";
}
}
#endregion
# if we are not using little endian ordering, just convert hex
# to expected data type for guid
if ( -not $LittleEndian.IsPresent)
{
$a = [uint32]('0x' + $HexString.Substring(0, 8));
$b = [uint16]('0x' + $HexString.Substring(8, 4));
$c = [uint16]('0x' + $HexString.Substring(12, 4));
}
# in case we selected little endian ordering, let's swap bits and reorder
# them to match little endian structure
else
{
$aArray = ($HexString.Substring(0, 8) -replace '.{2}(?=.)','$0,').Split(',');
$a = [uint32](
[string]::Format('0x{3}{2}{1}{0}',
$aArray[0],
$aArray[1],
$aArray[2],
$aArray[3]
)
);
$bArray = ($HexString.Substring(8,4) -replace '.{2}(?=.)','$0,').Split(',');
$b = [uint16](
[string]::Format('0x{1}{0}',
$bArray[0],
$bArray[1]
)
);
$cArray = ($HexString.Substring(12,4) -replace '.{2}(?=.)','$0,').Split(',');
$c = [uint16](
[string]::Format('0x{1}{0}',
$cArray[0],
$cArray[1]
)
);
}
# instantiate guid - https://msdn.microsoft.com/en-us/library/system.guid%28v=vs.110%29.aspx
return New-Object System.Guid($a, $b, $c,
[byte]::Parse($HexString.Substring(16,2), 'HexNumber'),
[byte]::Parse($HexString.Substring(18,2), 'HexNumber'),
[byte]::Parse($HexString.Substring(20,2), 'HexNumber'),
[byte]::Parse($HexString.Substring(22,2), 'HexNumber'),
[byte]::Parse($HexString.Substring(24,2), 'HexNumber'),
[byte]::Parse($HexString.Substring(26,2), 'HexNumber'),
[byte]::Parse($HexString.Substring(28,2), 'HexNumber'),
[byte]::Parse($HexString.Substring(30,2), 'HexNumber')
)
}
I usually store all functions in my PowerShell profile which automatically loads them in memory every time I start PowerShell session and can use them straight away.
Here is simple scenario. If you use DirSync or AAD Connect to sync your on-premise identities to cloud, every object will use ImmutableId property to store mapping relation between cloud and on-premise user. By default, on-premise objectGuid property becomes cloud ImmutableId stored as Base64 string:
Get-MsolUser -UserPrincipalName user@domain.com | Select-Object ImmutableId
ImmutableId
-----------
etyLZDkvKUKZzTogkajbig==
Now we need to convert Base64 string to hex:
([Convert]::FromBase64String("etyLZDkvKUKZzTogkajbig==") | ForEach-Object { "{0:x}" -f $_ }) -join ""
7adc8b64392f294299cd3a2091a8db8a
And finally we can use Get-GuidFromHex to get actual guid ( hex has little endian ordering ):
Get-GuidFromHex -HexString "7adc8b64392f294299cd3a2091a8db8a" -LittleEndian
Guid
----
648bdc7a-2f39-4229-99cd-3a2091a8db8a
Comments
- Anonymous
May 18, 2016
excellent thanks