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 :)
niark Thanks for following through with the solution. I'm having trouble implementing the last step of your solution within PowerBI. I have the data and columsn in powerBI, but how are you invoking the PS script you developed? Any guidance would be appreciated.
- niark7 years agoFrequent Visitor
Hi Anonymous ,
the code has to be used as a function.
please follow these steps :
go to "edit queries"
create a new blank query
open the advanced editor
paste the code as is
name the query as you want (ei:fnConvertUAC)
in the "applied step" pane add a new step (right click) and paste the content of the formula : #"Invoked Custom Function1" = Table.AddColumn(<Previous Step>, <Name of the column to create>, each fnConvertUAC([userAccountControl], UACRef, "decimal", "|"))
where
[userAccountControl] = the column where the data are
UACRef = the table having the references (headers are "flag" "hexadecimal" "decimal") in my previous post
"decimal" = the column to use to compare (as userAccountControl is an [int] the decimal column should be used)
"|" = the separator you want
Hope it's clearer.
and sorry for the delay, the email sent by the forum was under my spams...
Regards
- bagurudeen7 years agoNew Member
Hi,
I am getting the below error when I invoke the function.
Function:
= Table.AddColumn(user, "UAC", each fnConvertUAC([userAccountControl], UAC_Flags, "decimal", "|"))
Error:
Expression.Error: The column 'decimal' of the table wasn't found.
Details:
decimal- niark7 years agoFrequent VisitorHi bagurudeen,
« decimal » is the name of the column containing the values. Power query is a case sentive language be careful with such mistakes.
Regards