Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
niark
Frequent Visitor

AD useraccountcontrol integer conversion

Hi all,

I used to use a simple PS code to translate an AD useraccountcontrol attribute value into a human readable format :

 

Function Translate-UAC {

Param ([int]$UAC)

$PropertyFlags = @(
	"SCRIPT", "ACCOUNTDISABLE", "RESERVED", "HOMEDIR_REQUIRED", "LOCKOUT", "PASSWD_NOTREQD", "PASSWD_CANT_CHANGE", "ENCRYPTED_TEXT_PWD_ALLOWED", "TEMP_DUPLICATE_ACCOUNT", "NORMAL_ACCOUNT", "RESERVED", "INTERDOMAIN_TRUST_ACCOUNT", "WORKSTATION_TRUST_ACCOUNT", "SERVER_TRUST_ACCOUNT", "RESERVED", "RESERVED", "DONT_EXPIRE_PASSWORD", "MNS_LOGON_ACCOUNT", "SMARTCARD_REQUIRED", "TRUSTED_FOR_DELEGATION", "NOT_DELEGATED", "USE_DES_KEY_ONLY", "DONT_REQ_PREAUTH", "PASSWORD_EXPIRED", "TRUSTED_TO_AUTH_FOR_DELEGATION", "RESERVED", "PARTIAL_SECRETS_ACCOUNT" "RESERVED" "RESERVED" "RESERVED" "RESERVED" "RESERVED"
)
#One property per line (commented because I use the second one)
#1..($PropertyFlags.Length) | Where-Object {$UAC -bAnd [math]::Pow(2,$_)} | ForEach-Object {$PropertyFlags[$_]} 

#One line for all properties (suits my script better)
$Attributes = ""
1..($PropertyFlags.Length) | ? {$UAC -bAnd [math]::Pow(2,$_)} | % {
If ($Attributes.Length -EQ 0) {$Attributes = $PropertyFlags[$_]}
Else {$Attributes = $Attributes + " | " + $PropertyFlags[$_]}
} Return $Attributes } Translate-UAC -UAC 66080

this function returns : PASSWD_NOTREQD | NORMAL_ACCOUNT | DONT_EXPIRE_PASSWORD

 

 

what I did in PBI, is to create a new table with all values (PASSWD_NOTREQD...)  and an index column starting by 1.

pbi.JPG

the question is, from a useraccountcontrol value in another table (AD_Table) how can I filter the value from TABLE1 if the calculation of the bitwise is 'true' and from that take the 'human readable value' and concatenate them into one cell...

 

here manual result :

userAccountControl  Column1

66082ACCOUNTDISABLE | PASSWD_NOTREQD | NORMAL_ACCOUNT | DONT_EXPIRE_PASSWORD
514ACCOUNTDISABLE | NORMAL_ACCOUNT
66048NORMAL_ACCOUNT | DONT_EXPIRE_PASSWORD
512NORMAL_ACCOUNT
66080PASSWD_NOTREQD | NORMAL_ACCOUNT | DONT_EXPIRE_PASSWORD

 

Thanks for your help !

1 ACCEPTED SOLUTION
niark
Frequent Visitor

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
	Result

the reference table is like this :

flaghexadecimaldecimal

SCRIPT0x00011
ACCOUNTDISABLE0x00022
RESERVED0x00044
HOMEDIR_REQUIRED0x00088
LOCKOUT0x001016
PASSWD_NOTREQD0x002032
PASSWD_CANT_CHANGE0x004064
ENCRYPTED_TEXT_PWD_ALLOWED0x0080128
TEMP_DUPLICATE_ACCOUNT0x0100256
NORMAL_ACCOUNT0x0200512
RESERVED0x04001024
INTERDOMAIN_TRUST_ACCOUNT0x08002048
WORKSTATION_TRUST_ACCOUNT0x10004096
SERVER_TRUST_ACCOUNT0x20008192
RESERVED0x400016384
RESERVED0x800032768
DONT_EXPIRE_PASSWORD0x1000065536
MNS_LOGON_ACCOUNT0x20000131072
SMARTCARD_REQUIRED0x40000262144
TRUSTED_FOR_DELEGATION0x80000524288
NOT_DELEGATED0x1000001048576
USE_DES_KEY_ONLY0x2000002097152
DONT_REQ_PREAUTH0x4000004194304
PASSWORD_EXPIRED0x8000008388608
TRUSTED_TO_AUTH_FOR_DELEGATION0x100000016777216
RESERVED0x200000033554432
PARTIAL_SECRETS_ACCOUNT0x400000067108864
RESERVED0x8000000134217728
RESERVED0x10000000268435456
RESERVED0x20000000536870912
RESERVED0x400000001073741824
RESERVED0x800000002147483648

 

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 🙂

View solution in original post

14 REPLIES 14

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.