PowerShell Constrained Language Mode

I am trying to convert an Azure ObjectID to SID with this code (PowerShell Helpers to convert Azure AD Object IDs and SIDs – Modern IT – Cloud – Workplace)

$ObjectId = “73d664e4-0886-4a73-b745-c694da45ddb4”
$bytes = [Guid]::Parse($ObjectId).ToByteArray()
$array = New-Object ‘UInt32’ 4
[Buffer]::BlockCopy($bytes, 0, $array, 0, 16)
$sid = “S-1-12-1-$array”.Replace(’ ', ‘-’)

And this is working if $ExecutionContext.SessionState.LanguageMode = “FullLanguage”
But not if $ExecutionContext.SessionState.LanguageMode = “ConstrainedLanguage”
How can I get this to work in ConstrainedLanguage mode?

Welcome to the forum. :wave:t4:

When you post code, sample data, console output or error messages please format it as code using the preformatted text button ( </> ). Simply place your cursor on an empty line, click the button and paste your code.

Thanks in advance

How to format code in PowerShell.org <---- Click :point_up_2:t4: :wink:

If you like to format it manually … it’s 3 backticks - not periods. :wink:

As you can read in the help …

in constrained language mode you can only use native PowerShell cmdlets and commands.

So you cannot use this:

since it is .Net. :wink:

So the answer to your question will pretty likely be - you can’t. Sorry. :man_shrugging:t4:

The code is failing on this line:

[Buffer]::BlockCopy($bytes, 0, $array, 0, 16)

As [Buffer] is not an allowed type in constrained language mode you cannot call the BlockCopy() method. However, all that’s doing is converting the bytes in your byte array to [UInt32]. You can replicate that functionality using the bitwise operators:

$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"
$ObjectId = "73d664e4-0886-4a73-b745-c694da45ddb4"
$bytes = [Guid]::Parse($ObjectId).ToByteArray()
$array = New-Object 'UInt32[]' 4
$array[0] = ([uint32]$bytes[3] -shl 24) + ([uint32]$bytes[2] -shl 16) + ([uint32]$bytes[1] -shl 8) + [uint32]$bytes[0]
$array[1] = ([uint32]$bytes[7] -shl 24) + ([uint32]$bytes[6] -shl 16) + ([uint32]$bytes[5] -shl 8) + [uint32]$bytes[4]
$array[2] = ([uint32]$bytes[11] -shl 24) + ([uint32]$bytes[10] -shl 16) + ([uint32]$bytes[9] -shl 8) + [uint32]$bytes[8]
$array[3] = ([uint32]$bytes[15] -shl 24) + ([uint32]$bytes[14] -shl 16) + ([uint32]$bytes[13] -shl 8) + [uint32]$bytes[12]
$sid = "S-1-12-1-$array".Replace(' ', '-')

Thanks matt-bloomfield
Can see it working, but not sure I totally understand why, witch means I can’t get the reverse to work :frowning:

$sid = "S-1-12-1-1943430372-1249052806-2496021943-3034400218"
$text = $sid.Replace('S-1-12-1-', '')
$array = [UInt32[]]$text.Split('-')

$bytes = New-Object 'Byte[]' 16
[Buffer]::BlockCopy($array, 0, $bytes, 0, 16)
[Guid]$guid = $bytes

How would you do this with bitwise operators?

I am sure this could be written more succinctly with a loop, but it’s nearly dinner time :plate_with_cutlery:

$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"
$sid = "S-1-12-1-1943430372-1249052806-2496021943-3034400218"
$text = $sid.Replace('S-1-12-1-', '')
$array = [UInt32[]]$text.Split('-')

$bytes = New-Object 'Byte[]' 16
$bytes[0]  = $array[0] -band 0xff
$bytes[1]  = $array[0] -shr 8 -band 0xff
$bytes[2]  = $array[0] -shr 16-band 0xff
$bytes[3]  = $array[0] -shr 24 -band 0xff
$bytes[4]  = $array[1] -band 0xff
$bytes[5]  = $array[1] -shr 8 -band 0xff
$bytes[6]  = $array[1] -shr 16-band 0xff
$bytes[7]  = $array[1] -shr 24 -band 0xff
$bytes[8]  = $array[2] -band 0xff
$bytes[9]  = $array[2] -shr 8-band 0xff
$bytes[10] = $array[2] -shr 16-band 0xff
$bytes[11] = $array[2] -shr 24 -band 0xff
$bytes[12] = $array[3] -band 0xff
$bytes[13] = $array[3] -shr 8-band 0xff
$bytes[14] = $array[3] -shr 16-band 0xff
$bytes[15] = $array[3] -shr 24 -band 0xff
[Guid]$guid = $bytes
1 Like

But it works :wink: