cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Syndicate_Admin
Administrator
Administrator

Función de decodificación de máscara de bits useraccountcontrol de Active Directory

Todos

Estoy trabajando a través de la publicación de conversión de enteros useraccountcontrol de AD:

https://community.powerbi.com/t5/Desktop/AD-useraccountcontrol-integer-conversion/td-p/437105

Existe esta función (lenguaje Power BI M) en este mensaje y aparece a continuación:

// 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

Esto no funciona si la entrada está en blanco o no es numérica.

Para algunas de las filas de usuario, mi AD devuelve en blanco en el Control de cuentas de usuario.

Preguntas

  1. ¿Alguien sabe cómo salir de la función si la entrada está en blanco?

He buscado en Internet pero no encuentro cómo salir de una función.

  1. ¿Debo comprobar la entrada como en blanco a través de la cadena vacía "" o Null?

Cuando miro la tabla para este campo usando filtro, dice que está en blanco.

  1. También debo comprobar si la entrada no es numérica. ¿Cómo lo hago?

Gracias por cualquier ayuda

1 ACCEPTED SOLUTION
Syndicate_Admin
Administrator
Administrator

¿@phillip_from_oz

En la función personalizada, se espera que la entrada sea de tipo numérico. Si no desea mantener valores no numéricos en la columna userAccountControl, puede cambiar esta columna al tipo Número decimal. Los valores en blanco se convertirán en nulos y los valores no numéricos se convertirán en Error. Reemplace Errores por null. 22012701.jpg

A continuación, cuando agregue la columna de función personalizada, compruebe si el valor de entrada es null. Cuando no sea null, invoque la función personalizada.

= Table.AddColumn(#"Replaced Errors", "UAC", each if [userAccountControl] = null then null else fnConvertUAC([userAccountControl], UACRef, "decimal", "|"))

Si desea mantener valores no numéricos en la columna userAccountControl, debe mantener esta columna de tipo Texto. A continuación, extraiga el número decimal para invocar la función personalizada cuando agregue la columna.

= Table.AddColumn(#"Changed Type", "UAC", each let __number = Number.From([userAccountControl]) in if (try Value.Is(__number, type number) otherwise false) then fnConvertUAC(__number, UACRef, "decimal", "|") else null)

¡Espero que ayude!

Saludos
Equipo de soporte de la comunidad _ Jing
Si esta publicación ayuda, por favor acéptala como Solución para ayudar a otros miembros a encontrarla.

View solution in original post

4 REPLIES 4
Syndicate_Admin
Administrator
Administrator

¿@phillip_from_oz

En la función personalizada, se espera que la entrada sea de tipo numérico. Si no desea mantener valores no numéricos en la columna userAccountControl, puede cambiar esta columna al tipo Número decimal. Los valores en blanco se convertirán en nulos y los valores no numéricos se convertirán en Error. Reemplace Errores por null. 22012701.jpg

A continuación, cuando agregue la columna de función personalizada, compruebe si el valor de entrada es null. Cuando no sea null, invoque la función personalizada.

= Table.AddColumn(#"Replaced Errors", "UAC", each if [userAccountControl] = null then null else fnConvertUAC([userAccountControl], UACRef, "decimal", "|"))

Si desea mantener valores no numéricos en la columna userAccountControl, debe mantener esta columna de tipo Texto. A continuación, extraiga el número decimal para invocar la función personalizada cuando agregue la columna.

= Table.AddColumn(#"Changed Type", "UAC", each let __number = Number.From([userAccountControl]) in if (try Value.Is(__number, type number) otherwise false) then fnConvertUAC(__number, UACRef, "decimal", "|") else null)

¡Espero que ayude!

Saludos
Equipo de soporte de la comunidad _ Jing
Si esta publicación ayuda, por favor acéptala como Solución para ayudar a otros miembros a encontrarla.

Gracias por la respuesta.
user.userAccountControl ya es numérico cuando configuro la conexión desde mi Active Directory

Así es
Obtener consulta >blank

Elija la tabla de usuarios

Vaya a la sección Pasos aplicados a la derecha

Elija la última instrucción.
Haga clic con el botón derecho

Add Step to User Table.jpg

Elija "Insertar paso después"

Agregar este código

Table.AddColumn(#"Expanded user", "UAC_flag", each if [user.userAccountControl] = null then null else fnConvertUAC([user.userAccountControl], flaghexadecimaldecimal, "Dec", "|"))

Elija Cerrar y aplicar

UAC_Flag sigue vacía incluso cuando user.userAccountControl no está

¿Por qué? ¿Cómo soluciono esto?
UAC_Flag.jpg

user_account_control.jpg

Hola
He descubierto por qué la columna está en blanco en el sentido de que hay un error en el fnConvertUAC.
Ejecuté el código como se da contra el número 512 (fuction invoke) y devolvió un espacio en blanco.

Así que recodifiqué toda la función para que ahora no haya búsqueda de tablas. Todas las operaciones de bits se realizan mediante código explícito. También funciona mucho más rápido.

(n as number) as text =>
let
  result2 = Number.BitwiseAnd(n,1),
  val2=if result2 > 0 then "SCRIPT" else "",
  result3 = Number.BitwiseAnd(n,2),
  val3=if result3 > 0 then "ACCOUNTDISABLE" else "",
  result5 = Number.BitwiseAnd(n,8),
  val5=if result5 > 0 then "HOMEDIR_REQUIRED" else "",
  result6 = Number.BitwiseAnd(n,16),
  val6=if result6 > 0 then "LOCKOUT" else "",
  result7 = Number.BitwiseAnd(n,32),
  val7=if result7 > 0 then "PASSWD_NOTREQD" else "",
  result8 = Number.BitwiseAnd(n,64),
  val8=if result8 > 0 then "PASSWD_CANT_CHANGE" else "",
  result9 = Number.BitwiseAnd(n,128),
  val9=if result9 > 0 then "ENCRYPTED_TEXT_PWD_ALLOWED" else "",
  result10 = Number.BitwiseAnd(n,256),
  val10=if result10 > 0 then "TEMP_DUPLICATE_ACCOUNT" else "",
  result11 = Number.BitwiseAnd(n,512),
  val11=if result11 > 0 then "NORMAL_ACCOUNT" else "",
  result13 = Number.BitwiseAnd(n,2048),
  val13=if result13 > 0 then "INTERDOMAIN_TRUST_ACCOUNT" else "",
  result14 = Number.BitwiseAnd(n,4096),
  val14=if result14 > 0 then "WORKSTATION_TRUST_ACCOUNT" else "",
  result15 = Number.BitwiseAnd(n,8192),
  val15=if result15 > 0 then "SERVER_TRUST_ACCOUNT" else "",
  result18 = Number.BitwiseAnd(n,65536),
  val18=if result18 > 0 then "DONT_EXPIRE_PASSWORD" else "",
  result19 = Number.BitwiseAnd(n,131072),
  val19=if result19 > 0 then "MNS_LOGON_ACCOUNT" else "",
  result20 = Number.BitwiseAnd(n,262144),
  val20=if result20 > 0 then "SMARTCARD_REQUIRED" else "",
  result21 = Number.BitwiseAnd(n,524288),
  val21=if result21 > 0 then "TRUSTED_FOR_DELEGATION" else "",
  result22 = Number.BitwiseAnd(n,1048576),
  val22=if result22 > 0 then "NOT_DELEGATED" else "",
  result23 = Number.BitwiseAnd(n,2097152),
  val23=if result23 > 0 then "USE_DES_KEY_ONLY" else "",
  result24 = Number.BitwiseAnd(n,4194304),
  val24=if result24 > 0 then "DONT_REQ_PREAUTH" else "",
  result25 = Number.BitwiseAnd(n,8388608),
  val25=if result25 > 0 then "PASSWORD_EXPIRED" else "",
  result26 = Number.BitwiseAnd(n,16777216),
  val26=if result26 > 0 then "TRUSTED_TO_AUTH_FOR_DELEGATION" else "",
  result28 = Number.BitwiseAnd(n,67108864),
  val28=if result28 > 0 then "PARTIAL_SECRETS_ACCOUNT" else "",
  mylist={val2,val3,val5,val6,val7,val8,val9,val10,val11,val13,val14,val15,val18,val19,val20,val21,val22,val23,val24,val25,val26,val28},
  mylist_filtered = List.Select(mylist, each _ <> ""),
  myflag=Text.Combine(mylist_filtered,"|")
in
    myflag

El código se generó a partir de un programa de PowerShell, así que codifiqué solo una máscara y el resto fue generado por PowerShell.
¡Todo bien ahora!

@phillip_from_oz

¡Wow, es genial! ¡Puede marcar una respuesta apropiada como Solución para que otras personas la encuentren rápidamente!

Saludos

Jing

Helpful resources

Announcements
Microsoft Build 768x460.png

Microsoft Build is May 24-26. Have you registered yet?

Come together to explore latest innovations in code and application development—and gain insights from experts from around the world.

charticulator_carousel_with_text (1).png

Charticulator Design Challenge

Put your data visualization and design skills to the test! This exciting challenge is happening now through May 31st!

Power BI Dev Camp Session 22 768x460.jpg

Check it out!

Mark your calendars and join us on Thursday, May 26 at 11a PDT for a great session with Ted Pattison!

Top Kudoed Authors