AD useraccountcontrol conversión de enteros

Un usuario Pregunto ✅

niark

Hola a todos,

Solía ​​usar un código PS simple para traducir un valor de atributo de control de cuenta de usuario de AD a un formato legible por humanos:

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

esta función devuelve: PASSWD_NOTREQD | NORMAL_ACCOUNT | DONT_EXPIRE_PASSWORD

lo que hice en PBI, es crear una nueva tabla con todos los valores (PASSWD_NOTREQD …) y una columna de índice que comienza por 1.

pbi.JPG

la pregunta es, a partir de un valor de control de cuenta de usuario en otra tabla (AD_Table), ¿cómo puedo filtrar el valor de TABLE1 si el cálculo del bit a bit es ‘verdadero’ y de ahí tomar el ‘valor legible por humanos’ y concatenarlos en una celda … .

aquí resultado manual:

userAccountControl Column1

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

Gracias por tu ayuda !

niark

En respuesta a niark

Esta es la solucion:

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

la tabla de referencia es así:

bandera hexadecimaldecimal

TEXTO 0x0001 1
CONTABLE 0x0002 2
RESERVADO 0x0004 4
HOMEDIR_REQUIRED 0x0008 8
BLOQUEO 0x0010 dieciséis
PASSWD_NOTREQD 0x0020 32
PASSWD_CANT_CHANGE 0x0040 64
ENCRYPTED_TEXT_PWD_ALLOWED 0x0080 128
TEMP_DUPLICATE_ACCOUNT 0x0100 256
NORMAL_ACCOUNT 0x0200 512
RESERVADO 0x0400 1024
INTERDOMAIN_TRUST_ACCOUNT 0x0800 2048
WORKSTATION_TRUST_ACCOUNT 0x1000 4096
SERVER_TRUST_ACCOUNT 0x2000 8192
RESERVADO 0x4000 16384
RESERVADO 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
LA CONTRASEÑA EXPIRÓ 0x800000 8388608
TRUSTED_TO_AUTH_FOR_DELEGATION 0x1000000 16777216
RESERVADO 0x2000000 33554432
PARTIAL_SECRETS_ACCOUNT 0x4000000 67108864
RESERVADO 0x8000000 134217728
RESERVADO 0x10000000 268435456
RESERVADO 0x20000000 536870912
RESERVADO 0x40000000 1073741824
RESERVADO 0x80000000 2147483648

y para usarlo, agregue una columna de función personalizada:

# «Función personalizada invocada1» = Table.AddColumn (# «Columnas eliminadas», «UAC», cada fnConvertUAC ([userAccountControl], UACRef, «decimal», «|»))

Espero que te ayude.

si alguien viene con una forma mejor / más rápida / menos codificada, no dude en compartir 🙂

KenSkinner

¡Vaya, eso funciona totalmente! Nunca antes había intentado trabajar con una función personalizada, pero definitivamente has abierto una puerta genial. ¡Gracias!

Hola @niark,

Proporcione más detalles sobre los datos de origen en Power BI y la tabla de resultados que desea lograr.

Cómo obtener una respuesta rápida a su pregunta

Saludos,

Yuliana Gu

niark

En respuesta a v-yulgu-msft

Hola,

las fuentes :

tableName = Usuario

contenido =

nombre para mostrar control de cuentas del usuario
Usuario1 66082
Usuario2 514
Usuario3 66048
Usuario4 512
Usuario5 66080

tableName = UAC_Flags

contenido =

Bandera Maleficio dic
TEXTO 0x0001 1
CONTABLE 0x0002 2
RESERVADO 0x0004 4
HOMEDIR_REQUIRED 0x0008 8
BLOQUEO 0x0010 dieciséis
PASSWD_NOTREQD 0x0020 32
PASSWD_CANT_CHANGE 0x0040 64
ENCRYPTED_TEXT_PWD_ALLOWED 0x0080 128
TEMP_DUPLICATE_ACCOUNT 0x0100 256
NORMAL_ACCOUNT 0x0200 512
RESERVADO
INTERDOMAIN_TRUST_ACCOUNT 0x0800 2048
WORKSTATION_TRUST_ACCOUNT 0x1000 4096
SERVER_TRUST_ACCOUNT 0x2000 8192
RESERVADO
RESERVADO
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
LA CONTRASEÑA EXPIRÓ 0x800000 8388608
TRUSTED_TO_AUTH_FOR_DELEGATION 0x1000000 16777216
RESERVADO
PARTIAL_SECRETS_ACCOUNT 0x04000000 67108864
RESERVADO
RESERVADO
RESERVADO
RESERVADO
RESERVADO

Resultado Esperado :

nombre para mostrar control de cuentas del usuario Banderas
Usuario1 66082 ACCOUNTDISABLE | PASSWD_NOTREQD | NORMAL_ACCOUNT | DONT_EXPIRE_PASSWORD
Usuario2 514 ACCOUNTDISABLE | NORMAL_ACCOUNT
Usuario3 66048 NORMAL_ACCOUNT | DONT_EXPIRE_PASSWORD
Usuario4 512 NORMAL_ACCOUNT
Usuario5 66080 PASSWD_NOTREQD | NORMAL_ACCOUNT | DONT_EXPIRE_PASSWORD

PBInewbie21

En respuesta a niark

@niark – Gracias por la solución. Tengo tiempo para entender el código M pero seguí todos la mayoría de los pasos. Todavía no estoy seguro de cómo llegaste a la tabla UAC_Flags? ¿El código que proporcionó lo genera o lo obtuvo de otro lugar?

niark

En respuesta a niark

Esta es la solucion:

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

la tabla de referencia es así :

bandera hexadecimaldecimal

TEXTO 0x0001 1
CONTABLE 0x0002 2
RESERVADO 0x0004 4
HOMEDIR_REQUIRED 0x0008 8
BLOQUEO 0x0010 dieciséis
PASSWD_NOTREQD 0x0020 32
PASSWD_CANT_CHANGE 0x0040 64
ENCRYPTED_TEXT_PWD_ALLOWED 0x0080 128
TEMP_DUPLICATE_ACCOUNT 0x0100 256
NORMAL_ACCOUNT 0x0200 512
RESERVADO 0x0400 1024
INTERDOMAIN_TRUST_ACCOUNT 0x0800 2048
WORKSTATION_TRUST_ACCOUNT 0x1000 4096
SERVER_TRUST_ACCOUNT 0x2000 8192
RESERVADO 0x4000 16384
RESERVADO 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
LA CONTRASEÑA EXPIRÓ 0x800000 8388608
TRUSTED_TO_AUTH_FOR_DELEGATION 0x1000000 16777216
RESERVADO 0x2000000 33554432
PARTIAL_SECRETS_ACCOUNT 0x4000000 67108864
RESERVADO 0x8000000 134217728
RESERVADO 0x10000000 268435456
RESERVADO 0x20000000 536870912
RESERVADO 0x40000000 1073741824
RESERVADO 0x80000000 2147483648

y para usarlo, agregue una columna de función personalizada:

# «Función personalizada invocada1» = Table.AddColumn (# «Columnas eliminadas», «UAC», cada fnConvertUAC ([userAccountControl], UACRef, «decimal», «|»))

Espero que te ayude.

si alguien viene con una forma mejor / más rápida / menos codificada, no dude en compartir 🙂

En respuesta a niark

Realmente me gusta esto, pero estoy luchando con esto. Después de crear la nueva consulta en blanco y pegar el código de arriba. No me da la opción de hacer clic derecho en los pasos aplicados. Quiere que yo ingrese los parámetros. ¿Tienes capturas de pantalla o algo que pueda ayudarme con esto? Yo realmente lo apreciaría.

mmatijas

En respuesta a niark

Hola,

Solo quería agradecerle por la solución que le brindó a la otra persona. Después de mucho rascarme la cabeza, descubrí cómo usar tu solución. Todo lo que tengo que decir es que debes ser muy inteligente 🙂 Me pregunto si la gente de Power BI integrará su idea en la interfaz de Power BI AD para que pueda traducir los códigos hexadecimales de Microsoft a un formato legible por humanos.

Ciao

Anónimo

En respuesta a niark

@niark Gracias por seguir adelante con la solución. Tengo problemas para implementar el último paso de su solución dentro de PowerBI. Tengo los datos y las columnas en powerBI, pero ¿cómo invocas el script PS que desarrollaste? Se agradecería cualquier orientación.

niark

En respuesta a Anónimo

Hola @Anónimo,

el código debe usarse como una función.

por favor siga estos pasos:

ir a «editar consultas»

crear una nueva consulta en blanco

abre el editor avanzado

pegar el código como está

nombre la consulta como desee (ei:fnConvertUAC)

en el panel «paso aplicado» agregue un nuevo paso (clic derecho) y pegue el contenido de la fórmula: # «Función personalizada invocada1» = Table.AddColumn ( , , cada fnConvertUAC ([userAccountControl], UACRef, «decimal», «|»))

dónde

[userAccountControl] = la columna donde están los datos

UACRef = la tabla que tiene las referencias (los encabezados son «bandera» «hexadecimal» «decimal») en mi publicación anterior

«decimal» = la columna que se utilizará para comparar (ya que userAccountControl es un [int] se debe usar la columna decimal)

«|» = el separador que quieres

Espero que esté más claro.

y perdón por la demora, el correo electrónico enviado por el foro estaba bajo mis spam …

Saludos

Bagurudeen

En respuesta a niark

Hola,

Recibo el siguiente error cuando invoco la función.

Función:

= Table.AddColumn (usuario, «UAC», cada fnConvertUAC ([userAccountControl], UAC_Flags, «decimal», «|»))

Error:

Expression.Error: No se encontró la columna ‘decimal’ de la tabla.
Detalles:
decimal

niark

En respuesta a Bagurudeen

Hola bagurudeen,

«Decimal» es el nombre de la columna que contiene los valores. Power query es un lenguaje sensible a casos, tenga cuidado con este tipo de errores.

Saludos

Bagurudeen

En respuesta a niark

Muchas gracias por tu rápida respuesta.

Ahora, cuando ejecuto la función, está creando una columna vacía.

Tabla de usuarios:

displayNameuserAccountControl

Usuario1 66082
Usuario2 514
Usuario3 66048
Usuario4 512
Usuario5

66080

Pasos aplicados

= Table.FromRows (Json.Document (Binary.Decompress (Binary.FromText («i45WCi1OLTJU0lEyMzOwMFKK1YGIGAFFTA1N4HxjiAoTC7iICVgFQocp1AwDpdhYAA. [Serialized.Text = true]) en la tabla de tipos [displayName = _t, userAccountControl = _t])

= Table.TransformColumnTypes (Fuente, {{«userAccountControl», Int64.Type}})

Tabla UAC_Flags:

BanderaHexDec

TEXTO 0x0001 1
CONTABLE 0x0002 2
RESERVADO 0x0004 4
HOMEDIR_REQUIRED 0x0008 8
BLOQUEO 0x0010 dieciséis
PASSWD_NOTREQD 0x0020 32
PASSWD_CANT_CHANGE 0x0040 64
ENCRYPTED_TEXT_PWD_ALLOWED 0x0080 128
TEMP_DUPLICATE_ACCOUNT 0x0100 256
NORMAL_ACCOUNT 0x0200 512
RESERVADO nulo
INTERDOMAIN_TRUST_ACCOUNT 0x0800 2048
WORKSTATION_TRUST_ACCOUNT 0x1000 4096
SERVER_TRUST_ACCOUNT 0x2000 8192
RESERVADO nulo
RESERVADO nulo
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
LA CONTRASEÑA EXPIRÓ 0x800000 8388608
TRUSTED_TO_AUTH_FOR_DELEGATION 0x1000000 16777216
RESERVADO nulo
PARTIAL_SECRETS_ACCOUNT 0x04000000 67108864
RESERVADO nulo
RESERVADO nulo
RESERVADO nulo
RESERVADO nulo
RESERVADO nulo

Pasos aplicados:

= Table.FromRows (Json.Document (Binary.Decompress (Binary.FromText ( «rZPBjuMgDIZfpcp5DkBIQo8MeFrUBDLgTKeqRrzGPv4SSNqm073tIRLCP / bn3871WgXlzYjVW0X + EEJoOtDq5 + 1aSaXcZFGbIN97WOMsHViOewjgv0CvEZ4OPEeObgBtfPTwORl / V4h0EFnRO3Vy01qUkrlomyOjDOGso3WYXq8v2Syo2aNASYtRHaU9rGh8FrWFAKzylxFBR4RvjGN6IPvenW8sIpdkhQZhGKOext4oiRCXxouSklnJmkJnnR9kvyp2RcKypKG / bNnlb740FsFrN0hjI / op4FMKUaoQXoDOzp8CSjTuSZ7VCWlWc7IvULmef5WXFaWg + y3bbgP3 + la7ZDB8j2mAMXvuvN7d6mevm6YuBIMNsXeHRPurfPa5pqQrBGGQHpX0erscfFGyllFeRpjbSQP8cD5q6OGQ7SiJxSJvGGdCLJPBVbbkzJi5fLK16QrpFCDJQjzBJTrbXx5AywT2HW3Y3YBEGUcPcsLjHTS7T / e8Jvy + ksmexS79AJntr4Voidh0hS7OOZ + 6e + Auv0TXdWz5MV7u1ZjcNGkhAygPGLary2 + J2o6SxMD / nei / X / 78BQ == «, BinaryEncoding.Base64), Compression.Deflate)), let _t = ((escriba texto) meta [Serialized.Text = true]) en la tabla de tipos [Flag = _t, Hex = _t, Dec = _t])

= Table.TransformColumnTypes (Fuente, {{«Flag», escriba texto}, {«Hex», escriba texto}, {«Dec», Int64.Type}})

= Table.TransformColumnTypes (# «Tipo cambiado», {{«Dec», número de tipo}})

Tu codigo:

= (ingrese como número, tableref como tabla, columnref como texto, delimitador como texto) como texto =>
dejar
// crea una lista con todos los valores potenciales. debe ser 32 para este propósito
valores = {1..Table.RowCount (tableref)},
// función para tener la potencia de un valor decimal
fnPower = (valor como número) => Number.Power (2, valor),
// función para tener el valor bit a bit «y». esta función compara el valor de potencia con la entrada ei: 8/512
fnBitwise = (valor como número, v como número) => Number.BitwiseAnd (valor, v),
// todos los valores se calculan (pow2) y el bit a bit y se recupera
// luego se agrega una columna de índice para obtener la posición de los valores
// el resultado se filtra para obtener registros que no son 0 (0 significa que la comparación bit a bit falló)
TableResult = Table.SelectRows (
Table.AddIndexColumn (
Table.FromList (
List.Transform (
valores,
cada fnBitwise (fnPower (_), entrada)
),
Divisor.SplitByNothing (),
nulo,
nulo,
ExtraValues.Error
),
«Índice»,
1,
1
),
cada ([Column1] <> 0)
),
// el resultado se fusiona con la tabla de referencia en la columna referenciada. la unión interna se usa para filtrar valores no requeridos
// luego las filas se fusionan en una celda con el delimitador posicionado
Resultado = Text.Combine (
Table.ExpandTableColumn (
Table.RemoveColumns (
Table.NestedJoin (TableResult, {«Column1»}, tableref, {columnref}, columnref, JoinKind.Inner),
{«Columna1», «Índice»}
),
columnref
,{«bandera»}
,{«bandera»}
)[flag],
delimitador
)
en
Resultado

Función invocada:

= Table.AddColumn (usuario, «UAC», cada fnConvertUAC ([userAccountControl], UAC_Flags, «Dec», «|»))

Resultado:

displayNameuserAccountControlUAC

Usuario1 66082
Usuario2 514
Usuario3 66048
Usuario4 512
Usuario5 66080

No sé lo que estoy haciendo mal, agradezco su ayuda. Gracias de nuevo.

CyberPro

En respuesta a Bagurudeen

Si aún tiene problemas, haga un pequeño ajuste en la tabla de referencia. Haga que los nombres de las columnas (es decir, bandera, hexadecimal, dec) sean todos en minúsculas | flag hex dec – ¡esto solucionará el error!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *