DelVol: cambia fácilmente letra de unidades en Windows

Lo pensé mucho para publicar este artículo, pues no me parece que la herramienta que voy a describir llegue a ser de utilidad para mucha gente; sin embargo, decidí hacerlo por algunas razones: primero, haré mención de su uso en un artículo que escribiré para Implementa Windows. Segundo, es una buena oportunidad para documentar su funcionamiento, y tercero, quizá a otras personas les pueda solucionar el mismo problema que yo tuve.

El problema

Parte de mi rol en el trabajo es realizar ingeniería de imágenes en las empresas, tratando siempre de automatizar todo lo que más pueda en el proceso de instalación de Windows. Como es de esperarse, todas las empresas son muy diferentes, así que siempre me encuentro con nuevos requerimientos, unos más sencillos que otros.

En este caso, necesitaba una forma de automatizar el proceso para quitarle la letra de unidad a una partición; más específicamente, necesitaba liberar la letra D y cambiarla por cualquier otra letra en tiempo de implementación desde MDT.

Las opciones

La primera opción, como suele ser normal, es ver una forma soportada para hacer el cambio de unidad con alguna herramienta integrada de Windows, así que opté por Diskpart. Lo único que debemos saber es el número de volumen que tiene asignada la partición con la letra a cambiar y la nueva letra que vamos a asignarle.

En mi caso, para cambiar de la D a la Z, suponiendo que el volumen es el 0, tendría que utilizar los siguientes comandos:

> Diskpart
> List Volume
> Select Volume 0
> Assign Letter=Z

image

Lo malo con Diskpart es que siempre debía saber el número de volumen y la nueva letra de unidad; si me equivocaba en alguno de los dos o la letra de unidad estaba tomada, no tenía como manejarlo.

La segunda opción era, por supuesto, PowerShell. Soy un entusiasta, pero aún muy malo para construir scripts profesionales, así que traté de encontrar la mejor opción para hacer el cambio de forma automatizada. El script que manejé durante algunas pruebas era así:

$drive = Get-WmiObject -Class win32_volume -Filter “DriveLetter = ‘D:'”

Set-WmiInstance
-input $drive -Arguments @{DriveLetter=”Q:”}

A diferencia de Diskpart, PowerShell utilizaba el módulo de WMI para consultar el volumen que estaba montado con la letra D y luego le asignaba la letra Q.

Aunque me liberé del primer problema, saber el volumen, aún estaba condicionado por la disponibilidad de la letra que le iba a asignar; no obstante, es probable que haya podido encontrar la forma de buscar con PowerShell qué unidades estaban tomadas, pero eso le habría dado más duración al script, además de subir la probabilidad de error. Por otro lado, la ejecución de scripts de PowerShell desde MDT me parece algo lenta y propensa a fallar, pues hay dependencias de que se habilite correctamente la ejecución y de versiones de PowerShell para soportar los módulos.

Podía dejar cualquiera de las dos, pero, como última opción, opté por tratar de entender un poco más cómo funciona la asignación de particiones con la API de Windows y construir mi propia herramienta: DelVol.

Un poco de teoría

Normalmente nosotros reconocemos los volúmenes que tenemos activos en el equipo por su etiqueta (Datos, Windows, Backup, OSDisk, etc.) o por la letra que les fueron asignados, sea por Windows o por nosotros (D:\, E:\, J:\, etc.); pero Windows no puede utilizar la misma estrategia porque, por ejemplo, un volumen puede tener asignado una letra y una etiqueta, solo la letra, solo la etiqueta o ninguna de las dos. Otro ejemplo claro es que la letra puede variar cada que se desconecta y reconecta, puesto que Windows asigna por disponibilidad.

El sistema operativo, entonces, reconoce cada volumen con algo llamado Volume GUID Path, que está compuesto por un prefijo, «\\?\», la palabra «Volume» y un identificador único asignado por Windows. Por ejemplo, el volume GUID path  de la unidad Z:\ en mi equipo quedaría así:

\\?\Volume{45c09333-0000-0000-0000-100000000000}\

Si están interesados en saber el volume GUID path de sus particiones, Windows tiene una herramienta integrada llamada MountVol:

image

Windows Sysinternals también ofrece una herramienta un poco mejor llamada DiskExt que muestra, además del GUID, otros detalles relevantes como la unidad y disco al que pertenece:

image

Yo también hice un pequeño ejecutable que utiliza las funciones GetVolumeInformation y GetVolumeNameForVolumeMountPoint para obtener el volume GUID path, letra de unidad, tipo de sistema de archivos y serial asignado por Windows. El uso es muy sencillo, si yo quiero saber el detalle para la letra Z, solo debo indicársela como argumento agregando los dos puntos y el backslash, así:

VolInfo.exe Z:\

image

Pueden descargar los archivos fuente desde el repositorio de GitHub. El ejecutable está en la carpeta de Exefile: https://github.com/SergioCalderonR/VolInfo 

La solución: DelVol

DelVol es una sencilla herramienta de línea de comandos que me permite especificar la letra de unidad a la que le quiero cambiar la letra y ella se encargará de buscar internamente cuál es la siguiente letra disponible para asignársela, liberando la anterior para nuevo uso. La herramienta utiliza varias funciones de la API de Windows, de esta forma elimino la necesidad de versiones de framework y proporciono compatibilidad desde Windows 7 en adelante.

Gracias a que la herramienta se encarga de buscar la siguiente letra disponible, también elimino la preocupación de que la letra esté ocupada, tal cual me sucedía con Diskpart y PowerShell.

¿Cómo funciona?

Solo es necesario indicarle como argumento la letra de unidad y la herramienta hará el resto. Por ejemplo, si deseo liberar la letra Z, el comando sería:

DelVol.exe Z:\

image

Es necesario indicar la letra de unidad con los dos puntos y el backslash, de lo contrario la herramienta devolverá un error, esto es porque las funciones requieren este formato para funcionar, aunque espero hacer esto más fácil en el futuro.

En caso de equivocación o de lanzar solo el ejecutable sin argumentos, la aplicación mostrará una pequeña ayuda con ejemplo:

image

Como pueden ver, la ventaja de interactuar directamente con la API de Windows es el rendimiento al ejecutar, además de tener un poco más de control sobre lo que estoy haciendo.

¿Dónde descargar?

La solución está disponible también en mi repositorio de Github, por si alguien está interesado en conocer el código y, por qué no, aportar:

https://github.com/SergioCalderonR/DelVol 

Si solo desean el ejecutable, pueden obtenerlo al descargar la solución, en la carpeta Exefile.

SNAGHTML87a094[5]

image

Espero sea de utilidad.

Saludos,

<

p align=”justify”>—Checho

Establecer la ubicación predeterminada de la carpeta OneDrive a través de directivas de grupo

Hace unos días, como parte de mi trabajo, estaba apoyando un compañero en un proyecto de ingeniería de imágenes en Windows 10 y nos encontramos con que uno de los requerimientos que tenía el cliente sobre la imagen era cambiar la ubicación predeterminada de la carpeta OneDrive a otra partición de forma predeterminada, así el usuario que iniciara sesión solo tendría que indicar la cuenta y no hacer el cambio manualmente.

Predeterminadamente no se puede hacer el cambio hasta después de configurada la cuenta, además de que aplica por usuario; así que nos dimos en la tarea de buscar y encontramos un artículo técnico de la base de conocimientos de Office donde describía una serie de directivas de grupo asociadas a unos archivos ADMX disponibles para descargar:
https://support.office.com/en-us/article/Use-Group-Policy-to-control-OneDrive-sync-client-settings-0ecb2cf5-8882-42b3-a6e9-be6bda30899c

Lamentablemente me encontré con que para para algunas personalizaciones como la que yo buscaba, establecer la ubicación predeterminada de la carpeta OneDrive, había que hacer personalizaciones manuales sobre los archivos, pero la plantilla que uno descarga no tiene ni siquiera el XML con todos los valores base que requiere para funcionar y la ayuda está pésimamente documentada.

Con el ánimo de dejar algo de documentación para futuras ocasiones en que lo necesite y para el que le pueda servir, escribiré a continuación cómo deben de quedar configurados los archivos para que la directiva se pueda aplicar correctamente.

Requerimientos

1. Debemos saber cuál es el Tenant ID de nuestro Azure AD. Si necesitan saber cómo encontrar el Tenant ID, pueden ver este artículo

2. Aunque podemos hacer las modificaciones con el Bloc de notas, yo les recomiendo utilizar un editor como Notepad++ para los siguientes pasos. Pueden descargarlo desde aquí:
https://notepad-plus-plus.org/

Descarga de archivos

Aunque hay dos partes desde la web oficial que se pueden descargar, la mejor es la que está en la misma KB que compartí arriba: download the OneDrive Deployment Package

Configuración del ADMX y ADML

Una vez descarguemos el paquete de implementación, debemos descomprimir el contenido para poder empezar a modificar los dos archivos importantes, OneDrive.admx y OneDrive.adml:

image

Procedemos a hacer clic derecho sobre el archivo OneDrive.admx y lo editamos con Notepad++

image

Lo primero que debemos hacer es ubicarnos en las directivas DefaultRootDir y DisableCustomRoot para remplazar nuestro tenant ID por la cadena que veremos en el XML, así: {INSERT YOUR TENANT’S GUID HERE}

image

image

Naturalmente todos tendremos un identificador diferente.

Es importante aclarar que debemos tener cuidado de no incluir comillas adicionales ni corchetes, por ejemplo:

image

La directiva que nos va a permitir modificar la ubicación predeterminada de la carpeta de OneDrive es la que está con el nombre de DefaultRootDir, así que debemos hacerle algunas correcciones sobre lo que trae predeterminadamente la plantilla para que funcione.

Después de la etiqueta de supportedOn y antes de elements, vamos a agregar esto:

<enabledValue>
     <string>D:\ODUsers\%UserName%</string>
</enabledValue>
<disabledValue>
     <string></string>
</disabledValue>

Lo anterior es para que la plantilla aplique el cambio en el registro y aparezca como Enabled en la consola de directivas de grupo.

Noten que en la etiqueta de string yo agregué una ruta predeterminada; esto es de vital importancia para que pueda funcionar. La ruta puede ser cualquiera, pero debemos asegurarnos de que sea la misma tanto en este archivo .admx como en el .adml más adelante.

Todo quedaría así:


<policy name=”DefaultRootDir” class=”User” displayName=”$(string.DefaultRootDir)” explainText=”$(string.DefaultRootDir_help)” presentation=”$(presentation.DefaultRootDir_Pres)” key=”SOFTWARE\Microsoft\OneDrive\Tenants\81e570c6-569e-4b33-8ef5-8574e89d545b” valueName=”DefaultRootDir”>
       <parentCategory ref=”OneDriveNGSC” />
       <supportedOn ref=”windows:SUPPORTED_Windows7″ />
     <enabledValue>
        <string>D:\ODUsers\%UserName%</string>
     </enabledValue>
     <disabledValue>
         <string></string>
     </disabledValue>
       <elements>
         <text id=”OneDriveSyncFolder” valueName=”DefaultRootDir” required= “true” expandable=”true” />
       </elements>
     </policy>


image

Guardamos los cambios desde nuestro editor y cerramos el OneDrive.admx.

Hacemos clic derecho sobre el archivo OneDrive.adml y procedemos a editarlo también.

image

Al principio del archivo, debajo de  <stringTable>, vamos a agregar lo siguiente:

<!– OneDrive Sync Folder –>
<string id=”OneDriveSyncFolder”>OneDrive Sync Folder</string>

Nos quedaría así:


<resources>
     <stringTable>
    
       <!– OneDrive Sync Folder –>
       <string id=”OneDriveSyncFolder”>OneDrive Sync Folder</string>


image

Después de esta modificación, bajamos del todo en el archivo hasta la etiqueta llamada <presentationTable>; allí ubicamos la etiqueta de <defaultValue> y cambiamos su contenido por la ruta que deseamos mostrar predeterminadamente al abrir la plantilla en el Administrador de directivas de grupo. En mi caso, pondré la ubicación a:

D:\ODUsers\%UserName%


<presentationTable>
    <presentation id=”AutomaticUploadBandwidthPercentage_Pres”>
    <text>Select the maximum amount of bandwidth to take up when uploading files.</text>
         <text>Valid values are from 10 – 90.</text>
         <decimalTextBox refId=”BandwidthSpinBox” defaultValue=”70″ spinStep=”1″>Bandwidth:</decimalTextBox>
       </presentation>
       <presentation id=”DefaultRootDir_Pres”>
        <textBox refId=”OneDriveSyncFolder”>
         <label>OneDrive Sync Folder</label>
        <defaultValue>D:\ODUsers\%UserName%</defaultValue>
       </textBox>
      </presentation>
   </presentationTable>


image

Guardamos el archivo desde el editor y cerramos.

Importar los archivos al repositorio central del Directorio activo

En este punto voy a asumir que ya tienen creado un repositorio central en el controlador de dominio; si no es así, los invito a seguir este artículo para crearlo:

https://support.microsoft.com/en-us/help/3087759/how-to-create-and-manage-the-central-store-for-group-policy-administra

Para registrar los archivos correctamente, seguimos estos pasos:

1. Cerramos cualquier instancia del Administrador de directivas de grupo que tengamos abierta

2. Copiamos el archivo OneDrive.admx a la carpeta raíz de PolicyDefinitios del repositorio central:

image

3. Copiamos el archivo OneDrive.adml en la subcarpeta en-US de PolicyDefinitios:

image

Crear la directiva de grupo

Por último, procedemos a abrir el Administrador de directivas de grupo, creamos o editamos la plantilla desde donde queremos configurar la carpeta de OneDrive y navegamos hasta:

User Configuration\Policies\Administrative Templates\OneDrive

Doble clic sobre la plantilla Set the default location for the OneDrive folder

image

En la ventana de la plantilla, seleccionamos Enabled y, si es necesario, modificamos la ruta en la que OneDrive hará la sincronización, debajo de OneDrive Sync Folder:

image

Como nosotros modificamos la ruta en el archivo OneDrive.admx y OneDrive.adml, será la que aparezca predeterminadamente. Si necesitamos que sea otra, basta con cambiarla y ya.

Hacemos clic en el botón OK para habilitar la directiva. Debemos asegurarnos de que en la ventana del Administrador de directivas se quede viendo como Enabled:

image

Probar la directiva de grupo

Iniciamos en un equipo que tenga Windows 7 o Windows 10 y el último cliente de OneDrive instalado con un usuario de dominio que le aplique la directiva, ejecutamos OneDrive y procedemos a realizar la configuración:

1. Iniciar sesión con la cuenta:

image

2. Ingreso de contraseña:

image

3. Confirmación de la carpeta predeterminada:

image

Noten que, predeterminadamente, la carpeta de OneDrive está apuntando a la misma ubicación que definimos en la directiva de grupo.

4. Sincronización de archivos:

image

5. Confirmación:

image

6. Por último, confirmamos que la carpeta se haya creado físicamente en la ruta que indicamos en la directiva de grupo:

image

Espero les sea de utilidad.

Saludos,

<

p align=”justify”>Checho

Establecer un fondo personalizado para la Pantalla de bloqueo en Windows 10, versión 1703, con un paquete de aprovisionamiento

Una de las características que introdujo Windows 8 a nivel de interfaz gráfica fue la pantalla de bloqueo, que permitía tener una imagen personalizada mostrándose justo antes del inicio de sesión en Windows. Desde ese entonces y hasta la la compilación 1511 de Windows 10 las organizaciones podían establecer una imagen corporativa en todas las ediciones de Windows a través de directivas de grupo; sin embargo, desde Windows 10, versión 1607, solo es posible en ediciones Education y Enterprise, así que todas las empresas que tenían Windows 10 Pro perdieron esta opción, por lo menos de forma soportada.

Con la reciente liberación de Windows 10 Creators Update (versión 1703), Microsoft habilitó un nuevo CSP, más concretamente Personalization CSP, que permite configurar tanto el fondo de pantalla de escritorio como el de la Pantalla de bloqueo utilizando directivas MDM en las ediciones empresariales de Windows 10. Gracias a que los paquetes de aprovisionamiento se basan principalmente en directivas MDM, las empresas con Windows 10 Pro no necesitan tener Windows Intune para empezar a aprovechar estas nuevas características.

A continuación, mostraré cómo podemos utilizar la última versión del Windows Imaging and Configuration Designer (Windows ICD) para construir un paquete de aprovisionamiento que despliegue un fondo de pantalla de bloqueo personalizado y evite que el usuario lo pueda cambiar.

Requerimientos

1. Instalar todas las herramientas de implementación desde la última versión del ADK, la cual pueden descargar desde el sitio oficial:
https://developer.microsoft.com/en-us/windows/hardware/windows-assessment-deployment-kit

image

2. Un equipo cliente que tenga instalado Windows 10 Pro, versión 1703; es decir, Creators Update

Nota: este proceso funciona perfectamente en las ediciones Enterprise y Education también, pero ahí es más fácil por directivas de grupo.

Creación del paquete de aprovisionamiento

Lo primero que vamos a hacer es crear y configurar el paquete de aprovisionamiento con las directivas MDM que deseamos aplicar.

1. Desde nuestro equipo técnico en donde instalamos el ADK ejecutamos el Windows Imaging and Configuration Designer

2. En la página de inicio, hacemos clic en Advanced provisioning para crear un paquete completamente personalizado

image

3. En la ventana de New project, indicamos un nombre para el paquete debajo de Name y hacemos clic en el botón Next

image

  1. En la página de Choose which settings to view and configure, seleccionamos All Windows desktop editions y clic en Next

image

5. En la página de Import a provisioning package (optional), dejamos en blanco y clic en el botón de Finish

image

Windows Configuration Designer abrirá nuestro paquete de aprovisionamiento con todas las configuraciones disponibles debajo de Runtime settings:

image

Personalización del paquete

Aunque un solo paquete de aprovisionamiento puede contener múltiples configuraciones, nos enfocaremos solo en establecer nuestro fondo para la Pantalla de bloqueo.

1. Expandimos Runtime settings, luego el nodo de Personalization y clic en DeployLockScreenImage

2. En el panel central, hacemos clic en el botón de Browse y buscamos la imagen que deseamos establecer con extensión .jpeg o .jpg (se pueden más formatos, pero no viene al caso)

image

3. Después de escoger la imagen, hacemos clic en LockScreenImageUrl y en el campo de texto del centro escribimos el nombre de la imagen que seleccionamos en el paso 2. Para mi caso, por ejemplo, sería balls.jpg

image

4. Expandimos el nodo de SharedPC, luego PolicyCustomization, clic en SetEduPolicies y cambiamos el valor en el panel central de FALSE a TRUE

image

Nota: el paso 4 solo es necesario si vamos a configurar el fondo para la Pantalla de bloqueo en Windows 10 Pro, versión 1703.

Compilación del paquete

Finalmente, seguimos estos pasos para compilar nuestro paquete de aprovisionamiento:

1. Hacemos clic en el botón de Export, ubicado en la parte superior izquierda, y luego en Provisioning Package

image

2. En la primera ventana de Build, cambiamos el owner de OEM a IT Admin y clic en Next

image

Nota: el owner determina la prioridad en que Windows realizará configuraciones en el equipo, en caso de que hayan dos paquetes tratando de establecer las mismas directivas con distintas configuraciones.

3. En la página de Select security details for the provisioning package, hacemos clic en Next

image

4. En la página de Select where to save the provisioning package, dejamos el directorio predeterminado y hacemos clic en Next

image

5. En la página de Build the provisioning package, hacemos clic en el botón de Build para crear nuestro paquete de aprovisionamiento

image

6. En la página de All done, hacemos clic en el enlace que nos da el Output location para acceder al paquete de aprovisionamiento y clic en el botón de Finish

image

¡Todo listo! Lo único que nos queda es copiar nuestro CusttomLockScreen.ppkg o como lo hayan nombrado al equipo en donde aplicaremos la directiva para probar.

Prueba del paquete en Windows 10 Pro, versión 1703

Así luce la Pantalla de bloqueo en un escenario no administrado:

image

Como ven, la selección predeterminada es la de Windows spotlight, aunque el usuario lo puede cambiar por una imagen fija.

Lo que haremos será copiar el paquete de aprovisionamiento creado anteriormente y hacer doble clic para lanzarlo.

Normalmente el paquete nos da una leve descripción de tareas generales que hará y las opciones de aceptar o cancelar:

image

Lo único que tenemos que hacer es darle a Yes, add it y Windows se encargará de toda la configuración.

Una vez se cierre la ventana del paquete de aprovisionamiento, abrimos nuevamente la aplicación de Configuraciones, Personalización, Pantalla de bloqueo para ver cómo luce ahora:

image

Windows indica que algunas de las opciones están siendo administradas por la organización, por ende deshabilita toda personalización que pueda hacer el usuario.

Para comprobar que todo quedó aplicado, basta con bloquear el equipo y ver que nuestro fondo corporativo fue aplicado en la Pantalla de bloqueo.

image

Espero sea de utilidad.

—Checho

SetWall: cambia el fondo de pantalla aplicado por directivas de grupo

El mes pasado escribí un artículo sobre cómo cambiar el fondo de pantalla establecido a través de directivas de grupo, además de mostrar algunos detalles técnicos sobre las operaciones en registro que se llevan a cabo en el proceso. Como mencioné en ese momento, realizo este cambio manualmente cada que mi equipo actualiza las directivas de grupo, así que decidí construir una pequeña aplicación que realizará este procedimiento cada que lo necesitara y la compartiré por aquí.

SetWall

SetWall es una aplicación de consola que utiliza varias funciones de la API de Windows para modificar el fondo de pantalla y notificarle al sistema operativo para que lo pueda visualizar. No hice modificaciones de seguridad, así que el cambio de fondo durará lo que demoren las directivas de grupo para volverse a forzar en el equipo, pero igual siempre puede volverse a ejecutar la aplicación.

¿Cómo funciona?

Para ejecutar SetWall, basta con abrir un símbolo del sistema con privilegios elevados y lanzar como parámetro la ruta del JPG o PNG:

SetWall.exe [RutaImagen]

Donde [RutaImage] debe contener la extensión del archivo, por ejemplo:

SetWall.exe C:\Imagen.jpg

La aplicación verificará que el archivo exista en la ruta utilizando la función GetFileAttributes y si no hay problemas, procederá a aplicar el fondo de forma local para luego abrir la subclave en donde se almacena la directiva y escribir el nuevo contenido con la ruta de la imagen. Finalmente, llama a la función SystemParametersInfo para notificarle al sistema operativo del cambio y que se pueda ver inmediatamente.

Así es como se ve mi equipo con el fondo corporativo:

image

Para cambiar el fondo por una imagen ubicada en D:\WALL, basta con ejecutar SetWall con el nombre de archivo completo:

SetWall.exe “D:\WALL\img10.jpg”

La aplicación debe notificar el cambio en local y dominio:

SNAGHTML6087a79

En caso de intentar establecer algún TXT u otro tipo de archivo diferente a JPG y PNG, la aplicación nos dará un error:

SNAGHTML6099afc

El resultado final será el fondo de pantalla que queríamos, en vez del corporativo:

image

Descarga

Para los que estén interesados, la aplicación se puede descargar desde aquí:

https://1fichier.com/?mvw7d6fqgp

Si en algún momento logro que el cambio sea permanente, actualizaré la aplicación en el mismo servidor.

Saludos,

—Checho

Monitorear la creación de archivos en Windows utilizando Sysmon

Hace unos días recibí, por fin, mi copia del libro Troubleshooting with the Windows Sysinternals tools de Mark Russinovich y Aaron Margosis, copia que estaba esperando desde principios de año, pero que había tenido retrasos de publicación. Mi pensado es pasar por todas las herramientas lo más detallado posible; sin embargo, después del capítulo introductorio, me concentré en la aplicación más nueva de todas, System Monitor (Sysmon), pues quiero aprovechar este espacio para describir un escenario en el que puede ser de mucha ayuda y aprender por ahí derecho.

Sysmon es una herramienta escrita por Mark Russinovich y Thomas Garnier, basada en los mismos mecanismos que Process Monitor, pero enfocada completamente a rastrear actividad maliciosa en los equipos de la red. Sysmon, a diferencia de casi todas las herramientas de Sysinternals, debe ser instalada para empezar a monitorear, solo se concentra en una serie de eventos y puede utilizarse un archivo XML de configuración para realizar filtros específicos sobre estos eventos. Por otra parte, toda la actividad que Sysmon rastrea queda escrita en el Visor de eventos de Windows para un posterior análisis.

Aunque podría escribir un artículo de uso general de la herramienta, quiero enfocar esta entrada explícitamente a uno de los eventos: creación de archivos. Describiré cómo podemos instalar y configurar Sysmon para que podamos ver en el Visor de eventos todos los archivos que se crean, además de datos importantes como el proceso implicado en la creación, hora exacta, etc.

 

Instalación y configuración de Sysmon

Lo primero que debemos hacer es descargar, instalar y configurar Sysmon en el sistema operativo. A continuación, pasaré a describir cómo realizar todos estos procedimientos.

  1. Descargamos el paquete de Sysmon desde la web de Sysinternals: https://technet.microsoft.com/en-us/sysinternals/sysmon
  2. Creamos una carpeta llamada Sysmon en la unidad de Windows y guardamos el instalador, descomprimido, ahí:

    image

  3. Ejecutamos el símbolo del sistema con privilegios elevados y navegamos hasta la carpeta C:\Sysmon
  4. Creamos y configuramos el archivo de configuración de Sysmon:

Creación del archivo de configuración

El archivo de configuración consiste en un XML que contiene un elemento root, Sysmon,  y varios elementos hijos, con sus respectivos filtros para estos eventos que Sysmon leerá y aplicará. Es necesario indicarle explícitamente qué excluirá y qué incluirá porque si no, Sysmon empezará a escribir en el visor de evento todos los eventos.

Antes de construir el XML, debemos consultar la versión del schema ejecutando el siguiente comando:

sysmon –? config

Veremos, entre bastante información, un formato XML en la consola con la versión del schema.

image

Para el momento de escribir este artículo, la versión es 3.20, pero podría variar cuando lo ejecuten, así que más vale verificar antes de crear el archivo de configuración.

El secreto del archivo de configuración consiste en saber indicarle los filtros para todo lo que deseamos. Para este caso, es necesario deshabilitar todos los eventos adicionales y solo dejar el de FileCreate, correspondiente a la creación de archivos. Así quedaría el archivo:


<Sysmon schemaversion=”3.20″>
<!–Captures only FileCreate events–>
    <EventFiltering>
    <!–Let’s disable all events but FileCreate–>
        <FileCreate onmatch=”exclude”/>
        <ProcessCreate onmatch=”include”/>
        <FileCreateTime onmatch=”include”/>
        <NetworkConnect onmatch=”include”/>
        <ProcessTerminate onmatch=”include”/>
        <DriverLoad onmatch=”include”/>
        <ImageLoad onmatch=”include”/>
        <CreateRemoteThread onmatch=”include”/>
        <RawAccessRead onmatch=”include”/>
        <ProcessAccess onmatch=”include”/>
        <RegistryEvent onmatch=”include”/>               
        <FileCreateStreamHash onmatch=”include”/>   
    </EventFiltering>
</Sysmon>


Noten que el único evento que tiene el atributo onmatch como exclude es el de FileCreate; esto indica que Sysmon va a monitorear toda la actividad que tengan los eventos de creación de archivos. Todos los demás eventos, al estar con el atributo de include y sin ninguna regla de condición, quedarán deshabilitados.

Nota:

Aquí hay que tener cuidado, pues como veremos más adelante, al empezar a jugar con las reglas de condición los atributos varían.

Debemos guardar este archivo con cualquier nombre y extensión .XML. Preferiblemente, almacenarlo en la misma ruta que el ejecutable de Sysmon para que sea fácil referenciarlo. En mi caso le puse el nombre de Config.xml.

image

 

Para proceder, finalmente, con la instalación, ejecutamos desde el símbolo del sistema:

Sysmon.exe –accepteula -i C:\Sysmon\Config.xml

Debemos tener un resultado similar al siguiente:

image

Para verificar cuáles reglas quedaron aplicadas para los filtros, ejecutamos Sysmon –c

image

Revisión del los logs creados por Sysmon

De aquí en adelante basta con abrir el Visor de eventos y navegar hasta Applications and Services logs\Microsoft\Windows\Sysmon\Operational para poder ver todos los eventos que se están generando con respecto a la creación de archivos en nuestro sistema:

image

El evento 11 corresponderá siempre a la creación de archivos, aunque en la categoría lo describe también. Cada fila de información (Information) nos entregará los detalles precisos sobre el evento:

image

Cada evento tiene unos nombres de etiquetas que entregan diferente información. Por ejemplo, en la creación de archivo podemos ver el proceso que lo hizo con la etiqueta de Image; el archivo creado con la etiqueta de TargetFilename y la hora exacta con la etiqueta de CreationUtcTime.

Como está la configuración, vamos a ver todos los eventos de creación de archivos, independiente de que en unos confiemos y en otros no. Esta información es perfecta para auditoría o análisis forense, pero llegará un punto en el que deseemos concentrarnos en uno o más archivos específicamente y ahí Sysmon también nos puede ayudar.

Ahora, supongamos que entre todos los eventos encontramos uno que parece ser malicioso:

image 

Opciones avanzadas

Para poder concentrarnos específicamente en la creación del archivo MalwareFile.txt creado en la unidad de Windows, podemos indicarle fácilmente a Sysmon que solo monitoree las ocurrencias de ese nombre, sin importar en dónde lo escriba.

Nosotros podemos crear unas reglas de condiciones incluyentes o excluyentes con los elementos hijos, es decir, los nombres de etiqueta que aparecen en el evento, para poder suplir diferentes necesidades. Cuando el atributo del elemento es include, todo lo que esté dentro de la etiqueta FileCreate es lo que se escribirá en el Visor de eventos, dependiendo de la condición con la etiqueta.

En el siguiente ejemplo, estoy utilizando la etiqueta TargetFilename para decirle que me muestre siempre los resultados que contengan el nombre de MalwareFile.txt; para conseguir este filtro, utilizo la condición “contains” dentro del nombre de etiqueta, así:

image

De esta forma, no importa en qué unidad se cree el archivo, voy a poder verlo en el Visor de eventos.

La modificación en la configuración de Sysmon no requiere reinicio y se aplica inmeditamente; basta con ejecutar desde el símbolo del sistema con privilegios elevados:

Sysmon –c C:\Sysmon\Config

image

Si utilizamos nuevamente Sysmon –c, veremos que el filtro está aplicado:

image

 

Ahora supongamos que deseamos tener registro de todos los archivos creados que contengan la palabra «Malware» y se copien en la partición del sistema operativo. La regla de condición, teniendo en cuenta las etiquetas de Image y de TargetFilename quedarían expresadas en el XML así:

<FileCreate onmatch=”include”>
            <TargetFilename condition=”image”>C:\</TargetFilename>
            <TargetFilename condition=”contains”>Malware</TargetFilename>
</FileCreate>

Aquí estoy utilizando la etiqueta TargetFilename, que contiene el nombre completo, incluyendo la ruta, para establecer dos reglas de condición:

1. La imagen debe ser el la unidad del sistema operativo, C
2. El archivo debe contener el nombre de «Malware» para que lo escriba en el Visor de eventos

Siempre se debe correr el comando de Sysmon –c con el XML de configuración para que los filtros queden aplicados; es decir:

Sysmon –c C:\Sysmon\Config.xml

De esta forma podríamos ver toda ocurrencia de la palabra «Malware» en los archivos creados en la unidad de Windows:

image

Como pueden ver en el ejemplo, el archivo contiene la palabra clave en la mitad.

Entre mejor implementemos los filtros en Sysmon, más fructífero será nuestro análisis. Es una herramienta sorprendente.

Limitaciones

Si el código de la aplicación tiene como disposición CREATE_ALWAYS, es decir, que el archivo se escriba si no estaba o se sobreescriba si ya estaba, Sysmon solo registrará en el Visor de eventos la primera vez que se escribió, no cuando se haya sobreescrito. Dicho esto, una aplicación podría sobreescribir datos maliciosos sobre un archivo ya creado y no quedaría nada en el Visor de eventos.

Pude contactar a Mark Russinovich sobre esto y él me dijo que estaban considerando agregar la sobreescritura también para una futura actualización.

Espero escribir más adelante sobre el monitoreo de operaciones en registro también.

Saludos,

—Checho

Cambiar el fondo de pantalla establecido por directivas de grupo en Windows 10

En mi empresa, como en todas las organizaciones, hay una directiva de grupo que establece un fondo de pantalla corporativo en todas las estaciones Windows. Si bien es algo normal y los encargados de TI suelen cambiarlo con cierta frecuencia, se vuelve muy aburridor estar viendo el mismo fondo de pantalla todos los días; por este motivo, decidí explorar un poco cómo reconoce Windows la directiva para cambiarlo por uno que sea de mi gusto y compartirlo por aquí.

Nota: es necesario contar con privilegios administrativos para poder realizar los procedimientos que voy a describir aquí.

Explorando la directiva del fondo de pantalla

Para poder seguir lo que pasa al activar una directiva de grupo, es necesario forzar la configuración con la herramienta de gpupdate, con el parámetro de /force, y seguirla con Process Monitor mientras hace el procedimiento.

image

Ya que Process Monitor genera bastante bulla con el log, debemos configurar filtro para que nos muestre lo que esté haciendo el proceso de svchost.exe, encargado de replicar las directivas de grupo, que las operaciones sean de escritura en el registro y que no muestre nada de sistema de archivos, procesos o redes.

image

Después de esto, abrí el cuadro de búsqueda (CTRL + F) y procedí a buscar todas las ocurrencias que tuviese la palabra «Wallpaper».

image

El primer resultado, aunque no es exactamente el que buscaba, encontré algunos detalles interesantes:

image

El Path hacía referencia a la subclave de registro que almacena la información correspondiente a las GPO aplicadas tanto en máquina como en usuario. En este caso, al SID correspondiente a mi usuario, S-1-5-21-3916089143-2390449709-3607105231-11656.

Noten que, según me indicaba Process Monitor, Windows estaba escribiendo un valor (RegSetValue) con el nombre de DisplayName y su contenido era GPO Wallpaper, nombre de la GPO que se encargaba de configurar el fondo de pantalla corporativo en mi equipo.

Haciendo clic derecho desde Process Monitor e indicando Jumpt To…, encontré todos los detalles referentes a la directiva de grupo en el registro: nombre, ubicación física, ruta completa de la OU, identificador único de la GPO, entre otras.

image

Toda esta información estaba alojada en la subclave HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\DataStore\SID, mas no era la única GPO, pues en la raíz de DataStore están alojados las GPO tanto para usuario como para máquina. Las que corresponden a la máquina están en la subclave de Machine, y las de usuario, en su respectiva subclave que tiene como nombre el SID.
 

image

Esta información puede llegar a ser muy útil si estamos haciendo diagnóstico de problemas con directivas de grupo que no estén aplicando en los clientes; sin embargo, no me decía desde dónde estaba llamando al fondo de pantalla ni la ubicación de este. Lo que hice fue seguir buscando en Process Monitor con la misma palabra, Wallpaper, y esto fue lo que encontré:

SNAGHTML22c85cd8

Windows creó un valor de registro llamado Wallpaper en la ruta HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\; cabe agregar que normalmente las directivas de grupo, correspondientes a usuario, se agregan en la subclave de Policies.

Abrí el Registro de Windows para explorar de una forma más visual y hallé lo que estaba buscando, la ruta exacta de la directiva de fondo de pantalla.

image

El primer valor, Wallpaper, hace referencia a la ruta física, normalmente de red, en donde está ubicada la imagen a establecer como fondo de pantalla; el segundo valor, WallpaperStyle, le dice a Windows cómo debe posicionar la imagen en el escritorio: centrado, ajustado, etc.

Una vez obtenida la información, el siguiente paso, naturalmente, era proceder a hacer la personalización.

Cambiar el fondo de pantalla por uno personalizado

Para realizar el cambio de fondo corporativo a uno personal, realizamos los siguientes pasos:

1. Asegurarnos de estar en la subclave de registro: HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System

2. Doble clic sobre el valor Wallpaper para abrir la ventana de edición

3. Le indicamos una ruta completa, local o de red, en donde esté alojado nuestro fondo de pantalla, en el cuadro de texto:

image

4. Clic en el botón de Aceptar (OK)

5. Reiniciamos el sistema o reiniciamos el proceso de Explorer.exe para que el fondo se aplique y lo veamos en nuestra pantalla

¿Se puede impedir el cambio efectuado por la directiva?

En teoría sí, pero después de intentarlo muchas veces, me encontré con la sorpresa que no. Básicamente, para evitar el cambio habría que quitarle todo tipo de privilegios de escritura al usuario SYSTEM sobre la subclave de System o incluso de Policies; sin embargo, todos los administradores, incluyendo SYSTEM, por supuesto, tienen el privilegio de tomar propiedad (SeTakeOwnershipPrivilege), lo que les permite volver a restablecer todos los permisos de las subclaves.

Trataré de adentrarme más en esto cuando aprenda un poco de Internals.

Saludos,

—Checho

Inyectar actualización acumulativa en Windows 10 utilizando DISM

En mi empresa actual tenemos un canal de internet (a parte de malo) tan registringo que ingresar a Windows Update para descargar actualizaciones de sistema operativo no es una opción viable. Por fortuna, Microsoft está liberando actualizaciones aucumulativas que contienen todos los parches a la fecha, así que basta con descargar solo un paquete y proceder a implementarlo en nuestro equipo, dependiendo de la arquitectura.

El proceso de instalación es solo hacer doble clic sobre el .MSU apropiado y seguir el pequeño asistente de instalación:

image

Aunque es muy sencillo, se vuelve mucho más productivo aprender a automatizarlo para que el proceso sea rápido en cada equipo donde queramos actualizar. En este artículo mostraré cómo podemos lograr eso con la versión de DISM embebida en Windows.

En este artículo utilizaré la versión 1607 de Windows 10 y el último parche acumulativo, KB3197356, que pueden descargar desde aquí:
https://support.microsoft.com/en-us/kb/3197356

Extraer el CAB e inyectar actualización

Para poder inyectar en una imagen con conexión una actualización, el paquete debe tener de tipo .cab; sin embargo, las actualizaciones descargadas de los servidores de Microsoft siempre están como .msu, así que debemos hacer la extracción del .cab antes de proceder a instalar.

Para exraer el .cab e inyectar la actualización realizamos los siguientes pasos:

1. Descargamos la actualización acomulativa a una ruta local; para este caso, yo la guardé en la carpeta C:\CU

image

2. Hacemos clic derecho sobre el menú de inicio y luego en Símbolo del sistema (administrador)

image

3. Desde el símbolo del sistema navegamos hasta la ruta en donde está la KB, por ejemplo: cd C:\CU

image

4. Extraemos todos los .cab que contiene el .MSU con la herramienta de Expand, así:

Expand -F:*.cab KB3197356.msu C:\CU

*Nota: el nombre KB3197356.msu es el nombre que le puse al paquete, así que eso variará en cada caso.

image

El resultado será dos archivos, el WSUSSCAN y la KB en cuestión.

image

5. Eliminamos el paquete de WSUSSCAN

6. Para inyectar la KB, que es la que realmente necesitamos, ejecutamos el siguiente comando desde el mismo símbolo del sistema:

Dism /Online /Add-Package /PackagePath:C:\CU

image

*Notas:

Este proceso puede tardar varios minutos en un mismo porcentaje.

– Los nombres de los directorios pueden variar en cada equipo.

7. Reiniciamos el equipo para que Windows aplique la actualización

image

Después del reinicio, Windows estará completamente actualizado y podremos seguir trabajando.

Espero sea de utilidad.

Saludos,

—Checho

Interpretar las principales operaciones de registro con Process Monitor: RegCreateKey

En el primer artículo de esta seríe describí las funciones RegOpenKeyEx y RegCloseKey, así como la forma de interpretarlas, básicamente, desde la herramienta de Process Monitor. En esta nueva entrega me concentraré exclusivamente a la función RegCreateKeyEx, puesto que es un poco más completa de comprender cuando estamos haciendo diagnóstico.

RegCreateKeyEx

La operación principal de esta función, perteneciente a la API de Windows, consiste en crear una subclave de registro; en caso de que la subclave ya exista, la función la abre para utilizarla posteriormente. Ahora, tomando de ejemplo la subclave HKEY_CURRENT_USER\WinSide, la siguiente gráfica explica la definición que acabo de dar:

SNAGHTML256a06ea

 

HKEY_CURRENT_USER o su abreviación, HKCU, como lo dije en el primer artículo de esta serie, es una clave raíz; aunque WinSide es la verdadera subclave, se le puede llamar también subclave a todo el conjunto, es decir, HKEY_CURRENT_USER\WinSide.

Teniendo en cuenta la misma subclave de ejemplo, HKCU\WinSide, analicemos un poco el código que podríamos escribir en C/C++ con la API. Estas son las variables que requiere la función:

//RegCreateKeyEx
    HKEY hKey = HKEY_CURRENT_USER;
   LPCWSTR subKey = L”WinSide”;
    DWORD reserved = 0;
    LPWSTR classType = NULL;
    DWORD options = REG_OPTION_NON_VOLATILE;
    REGSAM samDesired = KEY_WRITE;
    LPSECURITY_ATTRIBUTES securityAttributes = NULL;
    HKEY createdKey;
    DWORD disposition;

La variable hKey contiene la clave raíz que pudo ser abierta por alguna función como RegOpenKeyEx o, como en este caso, una de las claves raíces que tiene el registro de Windows; la variable de subKey es un apuntador al nombre de la subclave que deseamos abrir o crear, en este caso WinSide; reserved es una variable reservada por el sistema y siempre debe ser cero; classType es el tipo de clase definida para la clave, pero puede ser NULL; la variable options me permite indicar diferentes comportamientos que puede tener la subclave, en el caso de REG_OPTION_NON_VOLATILE, le indica a Windows que la información almacenada se conserva después del reinicio; samDesired indica los derechos de acceso para la subclave, es decir, qué quiero hacer; la variable de securityAttributes almacena los atributos de seguridad, pero al darle NULL la subclave obtiene los predeterminados; createdKey va a tener el handle de la subclave abierta o creada; y disposition me indicará si la sublcave existía y se abrio o no existía y se creó.

Para poder ilustrar lo que Process Monitor captura, invocaré a la función RegCreateKeyEx para que abra o cree la subclave:

/* Función para crear o abrir la subclave
    HKEY_CURRENT_USER\WinSide */

    LONG createKey = RegCreateKeyEx(hKey, subKey, reserved,
                            classType, options, samDesired,
                securityAttributes, &createdKey, &disposition);

La variable createKey recibirá el código de error devuelto por el manejador de errores de Windows; yo puedo utilizar una función adicional para traducir eso a texto, pero obtaré por lo más sencillo que es validar si es satisfactorio o si es necesario mostrar el código de error, así:

if (createKey != ERROR_SUCCESS)
    {
        wprintf(L”Error opening the key. Code: %li\n”, createKey);
    }
    else
    {
        wprintf(L”Subkey was opened or created!\n”);
    }

 

Por supuesto, yo podría darle un poco más de estilo y aprovechar el valor retornado por disposition: es REG_CREATED_NEW_KEY si Windows creó la clave desde cero o REG_OPENED_EXISTING_KEY si la clave ya existía y solo se abrió. Nada más útil que llamar al condicional switch.

switch (disposition)
        {
        case REG_CREATED_NEW_KEY:
            wprintf(L”Key did not existed and was created\n”);
            break;

        case REG_OPENED_EXISTING_KEY:
            wprintf(L”Key existed and was just opened\n”);
            break;

        default:
            wprintf(L”Unkown value\n”);
            break;
        }

El código de toda la validación se vería así:

if (createKey != ERROR_SUCCESS)
    {
        wprintf(L”Error opening the key. Code: %li\n”, createKey);
    }
else
    {
       
        switch (disposition)
        {
          case REG_CREATED_NEW_KEY: //Key was created
            wprintf(L”Key did not existed and was created\n”);
            break;

          case REG_OPENED_EXISTING_KEY: //Key was opened
            wprintf(L”Key existed and was just opened\n”);
            break;

          default:
            wprintf(L”Unkown value\n”);
            break;
        }

        //Do not forget to close the handle!
        RegCloseKey(createdKey);
    }

De esta forma la consola mostrará el mensaje adecuado según se haya creado o abierto la subclave.

Aquí pueden ver la documentación oficial de RegCreateKeyEx:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724844(v=vs.85).aspx 

Process Monitor en acción

Empecemos por ver cómo nos muestra Process Monitor las operaciones que se hagan sobre la subclave HKCU\WinSide, para eso basta con filtrar por ruta y proceso de la aplicación, así:

image

Al ejecutar la aplicación, sin que esté la subclave creada, la validación se va por el REG_CREATED_NEW_KEY y me muestra el mensaje correspondiente:

image

¿Qué pasa en Process Monitor? Esto es lo que me muestra después de mostrado el mensaje:

image

La primera operación que hay listada es RegCreateKey, que corresponde a la que en código tengo como RegCreateKeyEx, está trabajando sobre el Path de HKCU\WinSide, handle que abrió o creó, según sea la disposición. El resultado, como también pueden ver fue SUCCESS, lo que indica que la operación se completó sin problemas y, finalmente, la columna de Detail me da datos importantes como el Desired Access (derechos de acceso solicitados) y Disposition (que me indica si la clave se creó o se abrió).

Después de estas operaciones, vemos que RegCloseKey se encarga de hacer la operación sobre la misma subclave, HKCU\WinSide, para cerrar el handle, es decir, terminar lo que se está haciendo sobre la subclave.

Noten que aunque yo conozco el código, los datos extraídos son todos desde Process Monitor, así que no necesitaría el código para saber qué pretende hacer la aplicación efectuando esa operación. Como datos adicionales, puedo entrar a las propiedades de la operación haciendo doble clic, pestaña de Process y ver detalles más completos:

image


Integrity
me indica el nivel de integridad en el que se está ejecutando el proceso, que en este caso es Medium, como cada proceso de usuario estándar; Architecture me indica, como su nombre en inglés lo dice, la arquitectura de la aplicación, que en este caso es 32-bit, por lo que en algún punto está actuando también la capa de emulación de WOW64.

Si vamos a la pestaña de Stack, podremos ver detalles de toda la transición entre User Mode y Kernel Mode, información bastante completa para alguien que entienda de Windows Internals. Una de las cosas que se puede identificar, por ejemplo, es que puedo ver que a la función exacta que se llama es RegCreateKeyExW (el W al final indica que se compiló como Unicode).

image


Nota:
para ver claramente esto, es necesario que Process Monitor tenga configurado los símbolos.

Aunque desde la vista general de Process Monitor puedo ver los detalles, también está disponible la pestaña de Event en donde tengo todo el resumen:

image

Es importante anotar que así en el código de la aplicación el valor de disposition sea NULL, Process Monitor podrá mostrarlo y así sabremos, a ciencia cierta, si la clave se abrió o se creó. Por ejempo, si yo ejecuto otra vez la misma aplicación de muestra, pero esta vez sin indicarle el disposition, puedo el resultado será el mismo:

image

Debido a que la subclave ya existía, puedo concluir, gracias al detalle de Process Monitor (Disposition: REG_OPENED_EXISTING_KEY), que Windows abrió la clave sin necesidad de crearla otra vez.

Una característica particular que tiene las llamadas a la API es que puedo crear más de una subclave de una vez. Por ejemplo, si en el código que mostré en este artículo quisiera abrir o crear la subclave HKCU\WinSide\Learning\Internals, bastaría con indicarle a la variable subKey todo el árbol, así:

LPCWSTR subKey = L”WinSide\\Learning\\Internals”;


Nota:
el doble signo de ‘\’ es para indicarle que deseamos poner una barra inversa y no una secuencia de escape.

Después de esto, solo es necesario ejecutarlo y esperar el resultado. El mensaje que nos devolverá será para toda la subclave y no para cada una individualmente.

En Process Monitor, sin embargo, podremos ver todo el proceso:

image

Lo primero que intenta hacer la aplicación es abrir la subclave HKCU\WinSide\Learning\Internals; como la clave no existe, empieza a hacer todo el procedimiento de abrir o crear desde la primera subclave, WinSide, hasta la última subclave, Internals. Noten que cada subclave se va cerrando después de pasar el handle a la otra. Cuando termina toda la operación hasta Internals, todos los handles se cierran y el resultado es nuestra subclave creada:

image

Desde Process Monitor, entonces, podemos identificar cuál es la subclave final desde antes de que la aplicación la cree y hacer un seguimiento detallado de cada subclave.

Espero que esto les pueda servir tanto como a mi me está sirviendo para aprender. Intentaré mejorar cada vez más las entradas, conforme vaya aprendiendo yo; además, es posible que toque otras funciones, sea de registro o de sistema de archivos.

 

P.D.: cualquier comentario o corrección es bienvenido.

 

Saludos,

—Checho

Personalizar la barra de tareas de Windows 10 con directivas de grupo

El pasado mes de mayo escribí un artículo sobre una característica bastante llamativa en Windows 10, versión 1511, que, expandiendo lo que ya se podía en Windows 8.1 Update, permitía crear un diseño parcial del menú de inicio para todos los usuarios, utilizando Directivas de grupo.

Windows 10, versión 1607, agregó otra funcionalidad más a estas características para anclar una serie de accesos predeterminados en la barra a través de Directivas de grupo y así ayudar a los administradores de infraestructura a estandarizar fácilmente las personalizaciones de usuario. En este artículo explicaré cómo podemos realizar estas personalizaciones.

Requerimientos

1. Controladores de dominio con los ADMX actualizados a Windows 10, versión 1607

2. Equipo con Windows 10, versión 1607, que sirva de referencia

3. Equipos con Windows 10 Enterprise o Education, versión 1607, en donde se implemente la directiva de grupo

Nota: esta característica no está disponible en ediciones Home y Pro.

Paso 1: configurar la barra de tareas

Estos pasos se deben realizar en el equipo de referencia, que puede estar o no unido al dominio de la empresa. Lo más importante es que si vamos a referenciar aplicaciones no integradas en Windows, estas deben instalarse también en los equipos en donde se va a desplegar la directiva.

Lo primero que hay que hacer, después de instalar las aplicaciones, si es que se requiere agregar un acceso directo, es anclar todos los accesos directos que vamos a predeterminar en los demás equipos. Basta con buscar la aplicación en el menú de inicio, hacer clic derecho y luego clic izquierdo en Anclar a la barra de tareas.

image

Para este artículo, yo anclé el Internet Explorer, Notepad++, Conexión a acceso remoto y el Símbolo del sistema.

image

Paso 2: crear y guardar el XML

El siguiente paso es crear o personalizar el XML. Microsoft provee una muestra en su documentación, así solo debemos dedicarnos a encontrar el Desktop Application Link Path adecuado para cada aplicación anclada; se utilizan dos rutas:

  • %APPDATA%\Microsoft\Windows\Start Menu\Programs
  • %ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs

Nota: las aplicaciones de interfaz moderna también se pueden anclar y relacionar en el XML que se crea, pero no las mostraré en el ejemplo, puesto que casi no se ve en la vida real; de hecho, las empresas tienden a bloquear estas aplicaciones.

Los accesos directos pueden estar en una u otra, por lo que toca buscarlo manualmente carpeta por carpeta. Por ejemplo, el acceso al Notepad++ está en:

%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Notepad++\Notepad++.lnk

image

El Internet Explorer, por poner otro ejemplo, está en la ruta:

%APPDATA%\Microsoft\Windows\Start Menu\Programs\Accessories\Internet Explorer.lnk

image

Ambas rutan deben estar dentro de la etiqueta <taskbar:DesktopApp DesktopApplicationLinkPath=/> del XML, así:


<?xml version=”1.0″ encoding=”utf-8″?>
<LayoutModificationTemplate
    xmlns=”
http://schemas.microsoft.com/Start/2014/LayoutModification”
    xmlns:defaultlayout=”http://schemas.microsoft.com/Start/2014/FullDefaultLayout”
    xmlns:start=”http://schemas.microsoft.com/Start/2014/StartLayout”
    xmlns:taskbar=”http://schemas.microsoft.com/Start/2014/TaskbarLayout”
    Version=”1″>
  <CustomTaskbarLayoutCollection>
    <defaultlayout:TaskbarLayout>
      <taskbar:TaskbarPinList>
        <taskbar:DesktopApp DesktopApplicationLinkPath=”%APPDATA%\Microsoft\Windows\Start Menu\Programs\Accessories\Internet Explorer.lnk”/>
        <taskbar:DesktopApp DesktopApplicationLinkPath=”%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Notepad++\Notepad++.lnk”/>
        <taskbar:DesktopApp DesktopApplicationLinkPath=”%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Accessories\Remote Desktop Connection.lnk”/>
        <taskbar:DesktopApp DesktopApplicationLinkPath=”%APPDATA%\Microsoft\Windows\Start Menu\Programs\System Tools\Command Prompt.lnk”/>
       
      </taskbar:TaskbarPinList>
    </defaultlayout:TaskbarLayout>
</CustomTaskbarLayoutCollection>
</LayoutModificationTemplate>


image

Nota: la base de este XML está tomada de la documentación de Microsoft.

Después de agregar las entradas correspondientes a cada acceso directo anclado, debemos guardar el XML con cualquier nombre descriptivo y ubicaro en una ruta de red, en la que pueda acceder el controlador de dominio que creará la directiva. Para este caso, yo la ubiqué en \\DC\Resources y lo llamé TaskBarLayout1.xml.

image

Paso 3: crear y desplegar la directiva

En el controlador de dominio, después de actualizar los ADMX, creamos o editamos la GPO destinada para personalizar la barra de tareas en los equipos con Windows 10, versión 1607, y realizamos lo siguiente:

1. User Configuration > Policies > Administrative Templates > Start Menu and Taskbar

2. Doble clic en la plantilla de Start Layout

image

3. Habilitamos la directiva y escribimos debajo de Start Layout File la ruta del XML

image

4. Clic en Apply y OK para terminar

Paso 4: probar la directiva de grupo

Si todo sale bien, cuando unamos un nuevo equipo al dominio o simplemente  reiniciemos para forzar directivas de grupo, la barra de tareas debe aparecer con todos los nuevos accesos a la derecha.

Así está la barra de tareas sin aplicar la directiva:

image

Así se ve después de aplicada:

image

Parece increíble que una característica así se haya tardado tanto en llegar, ¿no creen?

Espero sea de utilidad.

Saludos,

—Checho

Explorando el «Registry Redirector» en Windows

Antes de empezar

Si no estoy mal, este es el primer artículo en el que escribiré sobre una característica interna del sistema operativo; así que pido disculpas de antemano por cualquier equivocación que tenga y por si el código que aquí expondré no es el más profesional. Dicho esto, ¡empecemos!

Windows de 32 bit en Windows de 64 bit (WOW64)

Debido a que el trabajo de «Registry Redirector» hace parte de WOW64 , es necesario dar una introducción, mas no voy a profundizar porque de esto no se trata el artículo y, a decir verdad, no tengo aún el conocimiento para exponerlo.

«Windows 32 –bit On Windows 64-bit (WOW64)» es una capa de emulación que permite ejecutar aplicaciones basadas en 32 bits en un sistema operativo de 64 bits sin que la aplicación lo llegue a percibir. WOW64 tiene una colección de DLLs en modo usuario (existe modo usuario y modo kernel) que interceptan llamadas desde y hacia un proceso de 32 bits y hace la respectiva traducción para que todo funcione en el ambiente de 64 bits.

Registry Redirector

Lo primero que hay que decir es que este es que el mecanismo que voy a pasar a describir no es nuevo, pues existe desde Windows Vista, pero aún tiene influencia en problemas relacionados a la compatibilidad de aplicaciones.

El trabajo del «Registry Redirector» es aislar las aplicaciones de 32 y de 64 bits de ciertas partes del registro con diferentes nodos  para almacenar la información. Básicamente, intercepta la llamada que hace la aplicación, sea de 32 o de 64 bits, a su respectiva ubicación lógica y la dirige a una ubicación física. Este proceso es completamente transparente para la aplicación (y para nosotros), así que las aplicaciones de 32 bits, por ejemplo, pueden seguir accediendo a sus datos como si estuvieran en un sistema base de 32 bits. Esto es para que puedan correr y convivir sin problemas.

Las subclaves que son dirigidas se guardan en la subclave de Wow6432Node; por ejemplo, todo lo que una aplicación de 32 bits intente escribir en HKEY_LOCAL_MACHINE\Software es dirigido a la subclave HKEY_LOCAL_MACHINE\Wow6432Node.

Nota: de aquí en adelante utilizaré las siglas de HKLM y HKCU para poder referirme a las claves de HKEY_LOCAL_MACHINE y HKEY_CURRENT_USER, respectivamente.

¿Cómo lo vemos en acción?

Para poder ver y entender este mecanismo, decidí escribir, con mi pobre conocimiento en C, una aplicación propuesta por la documentación oficial de Microsoft y mostrarla en este artículo, con la ayuda adicional de Process Monitor.

La aplicación

La aplicación que escribí se llama DemoApp.exe y lo que hace es tratar de abrir la subclave WinSide, ubicada en la subclave HKEY_LOCAL_MACHINE\Software. Si la subclave existe, consulta el contenido del valor predeterminado, Default, y lo muestra en consola; si no, la aplicación crea la subclave de WinSide , escribe el contenido del valor predeterminado y procede a mostrarlo en consola. 

Nota: en cada subclave que se crea siempre existe el valor de Default, que puede o no tener un contenido.

A continuación, muestro una imagen en donde trato de ilustrar las operaciones que hace la aplicación.

SNAGHTML1cd7165

La imagen anterior, aunque resume el comportamiento general de la aplicación, es fiel a la gráfica cuando el ejectuable es de la misma arquitectura que el sistema operativo instalado; sin embargo, cuando la aplicación es de 32 bit y se ejecuta en un sistema de 64, el Registry Redirector actuará sobre la subclave de HKLM\WinSide y la ubicación física cambiará, así:

SNAGHTML36a031

Esta dirección al nodo físico, como ya lo dije, es completamente transparente para la aplicación, así que el desarrollador no tiene que preocuparse realmente por este mecanismo.

El código (para los interesados)

Importante: insisto en que soy un programador novato de C, así que seguramente encontrarán errores o mejoras prácticas en mi código. ¡Cualquier aporte es bienvenido!

Lo primero que hice fue crear una serie de macros para remplazar el mensaje según esté compilada la aplicación; es decir, si ejecuto la versión compilada a 64 bits, el mensaje será «64-bit app on WINx64», de lo contrario, «32-bit app on WINx64».

#ifdef _M_AMD64

#define MSG L”64-bit app on WINx64.\n”

#else

#define MSG L”32-bit app on WINx64.\n”

#endif

Luego creé una función llamada showValue que utiliza la función RegGetValue de la API de Windows para consultar el contenido del valor Default y luego mostrarlo. La función personalizada quedó así:

/*This function receives some variables to show a registry value’s –
content, but only REG_SZ is working by now.*/
void showValue(HKEY openKeyResult, LPCWSTR regValueName, DWORD flags)
{
    //Buffer that receives the value’s data.
    WCHAR valuesData[255];
    PVOID pValuesData = valuesData; //A.K.A. pvData
    DWORD sizeOfBuffer = sizeof(valuesData); //A.K.A. pcbData
    DWORD typeOfData;

    LONG getValue = RegGetValue(openKeyResult, NULL, regValueName,
                                flags, &typeOfData, pValuesData,  &sizeOfBuffer);

    if (getValue != ERROR_SUCCESS)
    {
        wprintf(L”Error getting the value. Code: %li\n”, getValue);
    }
    else
    {
        switch (typeOfData)
        {
        case REG_SZ:
            wprintf(L”Value’s data: %s\n”, (PWCHAR)pValuesData);
            break;

        default:
            wprintf(L”No other types are allowed.\n”);
            break;
        }
    }

}

Nota: RegGetValue está documentada en la página oficial de MSDN:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724868(v=vs.85).aspx

La función recibe una variable openKeyResult, que es el handle a la subclave abiera previamente con RegOpenkeyEx (en wmain la utilizo); regValueName, que es el nombre del valor a consultar y flags, que me indica el tipo de datos que voy a utilizar.

Finalmente está el código de la función principal wmain. Aquí lo que hice fue declarar las variables necesarias para usar la función RegCreateKeyEx que abre o crea la subclave, luego las que requiere RegSetValueEx para escribir el contenido del valor Default y las de RegGetValue para consultar e imprimir el contenido del valor Default.

La siguiente porción de código se puede resumir así en esta secuencia:

¿Existe la subclave HKEY_LOCAL_MACHINE\Software\WinSide?

  • : consultar e imprimir el contenido del valor Default.
  • No: crear la subclave WinSide, escribir el contenido del valor Default e imprimirlo.

Así se ve todo esto usando C y la API de Windows:

int wmain()
{

    void showValue(HKEY openKeyResult, LPCWSTR regValueName, DWORD flags);
   

    //RegCreateKeyEx
    HKEY hKey = HKEY_LOCAL_MACHINE;
    LPCWSTR subKey = L”Software\\WinSide”;
    DWORD reserved = 0;
    LPWSTR classTypeOfKey = NULL;
    DWORD options = REG_OPTION_NON_VOLATILE;
    REGSAM samDesired = KEY_READ | KEY_WRITE;
    LPSECURITY_ATTRIBUTES securityAttributes = NULL;
    //Handle to the opened or created key.
    HKEY openKeyResult;
    DWORD disposition;

    //RegSetValueEx
    LPCWSTR valueName = NULL; //To set the default value’s content.
    DWORD typeOfData = REG_SZ;
    const BYTE *pData = (const BYTE*)MSG;
    DWORD size = sizeof(MSG);

    //RegGetValue
    LPCWSTR valueNameDefault = NULL; //To get the default value’s data.

    //Restrict the data type of value queried.
    DWORD flags = RRF_RT_ANY;
       

    LONG createKey = RegCreateKeyEx(hKey, subKey, reserved, classTypeOfKey,
                                    options, samDesired, securityAttributes,
                                    &openKeyResult, &disposition);

    if (createKey != ERROR_SUCCESS)
    {
        wprintf(L”Error opening or creating the key. Code: %li\n”, createKey);

    }
    else
    {
        LONG setValue;
       
        switch (disposition)
        {
        case REG_CREATED_NEW_KEY:

            //Let’s create the value!
            setValue = RegSetValueEx(openKeyResult, valueName, reserved,
                typeOfData, pData, size);

            if (setValue != ERROR_SUCCESS)
            {
                wprintf(L”Registry value could not be set.\n”);
            }
            else
            {
                wprintf(L”Registry value set.\n”);
            }

            //Let’s query it!
            showValue(openKeyResult, valueNameDefault, flags);
            break;

        case REG_OPENED_EXISTING_KEY:

            //Let’s query the value!
            showValue(openKeyResult, valueNameDefault, flags);
            break;

        }

        //Closing the key.
        RegCloseKey(openKeyResult);

       
    }

    return 0;

}

Lo más interesante de todo esto es que en las variables hKey y subKey estoy apuntando HKLM como clave y Software\WinSide como subclave, así que en teoría siempre debería escribir ahí; sin embargo, el Registry Redirector se encargará de dirigir la escritura a la ubicación física de acuerdo a la arquitectura del proceso, es decir, HKLM\Software\WinSide para x64 y WKLM\Software\Wow6432Node\WinSide para x86.

El resultado

Afortunadamente, Visual Studio me permite cambiar la arquitectura en la que la aplicación compila sin mucho esfuerzo, así que puedo mostrar el resultado fácilmente.

image

Ejecución de la aplicación a 32 bits en Windows de 64 bits

Cuando lanzo DemoApp.exe compilada a 32 bits, recibo este mensaje:

image

Como lo mencioné en la gráfica de la aplicación y en el código, estoy consultando el contenido del valor Default y mostrándolo. Si analizamos la traza con Process Monitor, veremos lo que ocurrió:

SNAGHTMLb91b44

Primero se muestra la operación de RegCreateKey, la cual intenta abrir la clave y si no existe, la crea; luego RegSetValue para crear el contenido del valor Default y finalmente RegQueryValue, operación que remplaza al RegGetValue en el código que expuse anteriormente para obtener el contenido del valor Default y poder imprimirlo después. Noten que todas las operaciones se hacen sobre la ruta HKLM\Software\WOW6432Node\WinSide, puesto que el proceso es de 32 bits.

Al ingresar a las propiedades de la entrada RegCreateKey, pestaña de Stack, puedo ver todas las ocurrencias de las DLLs, encargadas de interceptar las llamadas y realizar la traducción:

image

La aplicación cree que escribe en la ubicación física nativa, pero en cada operación que haga siempre será dirigida a WOW6432Node\WinSide.

Nota: existe una excepción en donde una aplicación puede leer y escribir en la subclave nativa, así el mecanismo del Registry Redirector esté funcionando; solo es necesario ingresar en la máscara de acceso, samDesired, el derecho de acceso KEY_WOW64_64KEY para usarla luego con RegCreateKeyEx, así:

REGSAM samDesired = KEY_READ | KEY_WRITE | KEY_WOW64_64KEY;

Si al ejecutar la aplicación los descriptores de seguridad (los que me dicen si puedo) no me lo deniega, la aplicación escribirá en HKLM\Software, sin hacer dirección a Wow6432Node.

Nota: no tengo idea de cómo se puede establecer esto en desarrollos con .Net, pero me imagino que existe la forma.

Ejecución de la aplicación a 64 bits en Windows de 64 bits

Esto es lo que pasa cuando lanzo la aplicación, compilada a 64 bits, en Windows de la misma arquitectura:

image

Observen que el mensaje ahora es «64-bit app on WINx64», pero es la misma aplicación.

Así se ve en Process Monitor:

image

Al estar la aplicación a 64 bits, no es necesario que actúe la capa de emulación de WOW64, por ende, el mecanismo del Registry Redirector tampoco se activa y la aplicación escribe en la ubicación nativa: HKLM\Software\WinSide.

Lo mismo a nivel de Stack, la comunicación es directa:

image

Eso es todo lo que tengo para escribir sobre el Registry Redirector. Agradezco mucho cualquier corrección, pues me ayudarán a aprender.

Espero escribir próximamente sobre Registry Reflection para ampliar un poco más WOW64.

Saludos,

—Checho