Forum Discussion
AD useraccountcontrol integer conversion
- 8 years ago
Here is the solution :
// input is the cell with the decimal value ei:512 // tableref is the table referencing the decimal values with the 'human readable' ones // columnref is the column name of tableref where decimal values are // delimiter is the character to split by ei:| // the result is a text ei:PASSWD_NOTREQD|NORMAL_ACCOUNT|DONT_EXPIRE_PASSWORD // the function can be updated to return a table/list to have it expanded for example (input as number, tableref as table, columnref as text,delimiter as text) as text => let //create a list with all potential values. should be 32 for this purpose values = {1..Table.RowCount(tableref)}, //function to have the power of a decimal value fnPower = (value as number) => Number.Power(2,value), //function to have the bitwise "and" value. this function compare the power value against the input ei: 8/512 fnBitwise = (value as number, v as number) => Number.BitwiseAnd(value,v), //all values are calculated (pow2) and the bitwise and is retrieved //an index column is then added to get the position of the values //the result is filtered to get records that are not 0 (0 means the bitwise comparison failed) TableResult = Table.SelectRows( Table.AddIndexColumn( Table.FromList( List.Transform( values, each fnBitwise(fnPower(_),input) ), Splitter.SplitByNothing(), null, null, ExtraValues.Error ), "Index", 1, 1 ), each ([Column1] <> 0) ), //the result is merged with the reference table on the referenced column. the inner join is used to filtered out not required values //then the rows are merged into one cell with the positioned delimiter Result = Text.Combine( Table.ExpandTableColumn( Table.RemoveColumns( Table.NestedJoin(TableResult,{"Column1"},tableref,{columnref},columnref,JoinKind.Inner), {"Column1", "Index"} ), columnref ,{"flag"} ,{"flag"} )[flag], delimiter ) in Resultthe reference table is like this :
flaghexadecimaldecimal
SCRIPT 0x0001 1 ACCOUNTDISABLE 0x0002 2 RESERVED 0x0004 4 HOMEDIR_REQUIRED 0x0008 8 LOCKOUT 0x0010 16 PASSWD_NOTREQD 0x0020 32 PASSWD_CANT_CHANGE 0x0040 64 ENCRYPTED_TEXT_PWD_ALLOWED 0x0080 128 TEMP_DUPLICATE_ACCOUNT 0x0100 256 NORMAL_ACCOUNT 0x0200 512 RESERVED 0x0400 1024 INTERDOMAIN_TRUST_ACCOUNT 0x0800 2048 WORKSTATION_TRUST_ACCOUNT 0x1000 4096 SERVER_TRUST_ACCOUNT 0x2000 8192 RESERVED 0x4000 16384 RESERVED 0x8000 32768 DONT_EXPIRE_PASSWORD 0x10000 65536 MNS_LOGON_ACCOUNT 0x20000 131072 SMARTCARD_REQUIRED 0x40000 262144 TRUSTED_FOR_DELEGATION 0x80000 524288 NOT_DELEGATED 0x100000 1048576 USE_DES_KEY_ONLY 0x200000 2097152 DONT_REQ_PREAUTH 0x400000 4194304 PASSWORD_EXPIRED 0x800000 8388608 TRUSTED_TO_AUTH_FOR_DELEGATION 0x1000000 16777216 RESERVED 0x2000000 33554432 PARTIAL_SECRETS_ACCOUNT 0x4000000 67108864 RESERVED 0x8000000 134217728 RESERVED 0x10000000 268435456 RESERVED 0x20000000 536870912 RESERVED 0x40000000 1073741824 RESERVED 0x80000000 2147483648 and to use it, add a custom function column :
#"Invoked Custom Function1" = Table.AddColumn(#"Removed Columns", "UAC", each fnConvertUAC([userAccountControl], UACRef, "decimal", "|"))
Hope it will help.
if someone comes with a better/quicker/less code way, don't hesitate to share :)
Here is the solution :
// input is the cell with the decimal value ei:512
// tableref is the table referencing the decimal values with the 'human readable' ones
// columnref is the column name of tableref where decimal values are
// delimiter is the character to split by ei:|
// the result is a text ei:PASSWD_NOTREQD|NORMAL_ACCOUNT|DONT_EXPIRE_PASSWORD
// the function can be updated to return a table/list to have it expanded for example
(input as number, tableref as table, columnref as text,delimiter as text) as text =>
let
//create a list with all potential values. should be 32 for this purpose
values = {1..Table.RowCount(tableref)},
//function to have the power of a decimal value
fnPower = (value as number) => Number.Power(2,value),
//function to have the bitwise "and" value. this function compare the power value against the input ei: 8/512
fnBitwise = (value as number, v as number) => Number.BitwiseAnd(value,v),
//all values are calculated (pow2) and the bitwise and is retrieved
//an index column is then added to get the position of the values
//the result is filtered to get records that are not 0 (0 means the bitwise comparison failed)
TableResult = Table.SelectRows(
Table.AddIndexColumn(
Table.FromList(
List.Transform(
values,
each fnBitwise(fnPower(_),input)
),
Splitter.SplitByNothing(),
null,
null,
ExtraValues.Error
),
"Index",
1,
1
),
each ([Column1] <> 0)
),
//the result is merged with the reference table on the referenced column. the inner join is used to filtered out not required values
//then the rows are merged into one cell with the positioned delimiter
Result = Text.Combine(
Table.ExpandTableColumn(
Table.RemoveColumns(
Table.NestedJoin(TableResult,{"Column1"},tableref,{columnref},columnref,JoinKind.Inner),
{"Column1", "Index"}
),
columnref
,{"flag"}
,{"flag"}
)[flag],
delimiter
)
in
Resultthe reference table is like this :
flaghexadecimaldecimal
| SCRIPT | 0x0001 | 1 |
| ACCOUNTDISABLE | 0x0002 | 2 |
| RESERVED | 0x0004 | 4 |
| HOMEDIR_REQUIRED | 0x0008 | 8 |
| LOCKOUT | 0x0010 | 16 |
| PASSWD_NOTREQD | 0x0020 | 32 |
| PASSWD_CANT_CHANGE | 0x0040 | 64 |
| ENCRYPTED_TEXT_PWD_ALLOWED | 0x0080 | 128 |
| TEMP_DUPLICATE_ACCOUNT | 0x0100 | 256 |
| NORMAL_ACCOUNT | 0x0200 | 512 |
| RESERVED | 0x0400 | 1024 |
| INTERDOMAIN_TRUST_ACCOUNT | 0x0800 | 2048 |
| WORKSTATION_TRUST_ACCOUNT | 0x1000 | 4096 |
| SERVER_TRUST_ACCOUNT | 0x2000 | 8192 |
| RESERVED | 0x4000 | 16384 |
| RESERVED | 0x8000 | 32768 |
| DONT_EXPIRE_PASSWORD | 0x10000 | 65536 |
| MNS_LOGON_ACCOUNT | 0x20000 | 131072 |
| SMARTCARD_REQUIRED | 0x40000 | 262144 |
| TRUSTED_FOR_DELEGATION | 0x80000 | 524288 |
| NOT_DELEGATED | 0x100000 | 1048576 |
| USE_DES_KEY_ONLY | 0x200000 | 2097152 |
| DONT_REQ_PREAUTH | 0x400000 | 4194304 |
| PASSWORD_EXPIRED | 0x800000 | 8388608 |
| TRUSTED_TO_AUTH_FOR_DELEGATION | 0x1000000 | 16777216 |
| RESERVED | 0x2000000 | 33554432 |
| PARTIAL_SECRETS_ACCOUNT | 0x4000000 | 67108864 |
| RESERVED | 0x8000000 | 134217728 |
| RESERVED | 0x10000000 | 268435456 |
| RESERVED | 0x20000000 | 536870912 |
| RESERVED | 0x40000000 | 1073741824 |
| RESERVED | 0x80000000 | 2147483648 |
and to use it, add a custom function column :
#"Invoked Custom Function1" = Table.AddColumn(#"Removed Columns", "UAC", each fnConvertUAC([userAccountControl], UACRef, "decimal", "|"))
Hope it will help.
if someone comes with a better/quicker/less code way, don't hesitate to share :)
Hi,
Just wanted to thank you for the solution you provided to the other person. After much headscratching I worked out how to use your solution. All I have to say is you must be really smart 🙂 I wonder if the Power BI people will integrate your idea in to Power BI AD interface so it can translate the Microsoft hex codes in to human readable format.
Ciao