
Herramienta de inventario de clientes y detección de desviaciones basada en Azure que recopila datos de configuración de Windows (antivirus, parches, Bitlocker) en LogAnalytics para paneles impulsados por KQL y alertas de Sentinel.

¿Tienes el control? - ¿o algunos de tus procesos de infraestructura básicos como parcheo, antivirus, habilitación de BitLocker se están desviando? ¿O te gustaría hacer un inventario avanzado, donde puedas consultar el estado de la garantía contra la garantía de Lenovo o Dell? Entonces sigue leyendo.
Echa un vistazo a ClientInspector, que puede ayudarte a obtener una gran visibilidad de tu entorno cliente completo.
ClientInspector es gratuito para la comunidad, construido para ser una demostración genial de cómo puedes recuperar datos de tus clientes usando Azure Log Ingestion Pipeline, Azure Data Collection Rules, Azure LogAnalytics; visualizarlos con Azure Monitor y Azure Dashboards - y obtener "alertas de desviación" usando Microsoft Sentinel.
ClientInspector (v2) sube los datos recopilados a registros personalizados en el espacio de trabajo de Azure LogAnalytics - usando Log ingestion API, Azure Data Collection Rules (DCR) y Azure Data Collection Endpoints (DCE).




Es importante para mí declarar que no intento construir una herramienta de gestión separada que compita con el stack de seguridad y gestión de Microsoft.
Nada supera al stack de gestión y seguridad de Microsoft Azure/M365. Son soluciones estrella.
Pero realmente me apasionan las capacidades de registro y el poder de traer datos de vuelta desde clientes, servidores, la nube y sistemas de terceros - y obtener información valiosa a partir de los datos.
Tengo una solución similar para servidores - ServerInspector. Desafortunadamente, no es pública.
Buena caza 😄
¿Qué datos se recopilan?
Paneles de estado deseado - ¿Cómo obtener información de mi entorno a partir de los datos?
¿Cómo consulto los datos? - Kusto (KQL) es la respuesta
Arquitectura, Esquema y Redes
Implementación
Dependencias
Ejecución de ClientInspector.ps1 - 3 modos
Salida de muestra de ClientInspector
Seguridad
Diseño del conjunto de datos de ClientInspector
Modo detallado y más ayuda
Costo - ¿Cuánto cuesta almacenar estos datos?
Hallazgos de errores, por favor infórmenme
Contacto
Video 3m 19s - Ejecutar ClientInspector mediante línea de comandos (modo normal)
Video 1m 40s - Creación automática de 2 tablas y DCR (modo detallado)
Video 1m 37s - Creación automática de 2 tablas y DCR (modo normal)
Video 1m 34s - Ver esquema de DCR y tabla)
Video 2m 19s - Manipulación de datos
Video 1m 58s - Consultas Kusto contra datos
Video 3m 01s - Dashboards
Video 0m 48s - Ejemplo de uso de datos - consulta contra la base de garantías de Lenovo
Video 7m 25s - Implementación mediante ClientInspector DeploymentKit
ClientInspector se puede usar para recopilar mucha información útil de tus clientes Windows - y enviar los datos a Tablas personalizadas de Azure LogAnalytics.
El script recopila la siguiente información (configuraciones, información, configuración, estado):
Siéntete libre de agregar más recopilaciones de datos interesantes para adaptarse a tus necesidades. Si deseas participar en la comunidad, envíame un correo electrónico con tus recopilaciones, si crees que pueden beneficiar a toda la comunidad.
Puedes usar cualquier dato fuente que pueda recuperarse en PowerShell (wmi, cim, datos externos, api rest, formato xml, formato json, formato csv, etc.)
Es muy importante entender que los datos típicamente necesitan ser manipulados antes de enviarlos, para asegurar que sean válidos y que cualquier dato irrelevante haya sido eliminado.
ClientInspector utiliza las 24 funciones del módulo de PowerShell, AzLogDcIngestPS, para manejar la manipulación de datos fuente, eliminar "ruido" en los datos, renombrar columnas prohibidas en tablas/DCR - y soportar necesidades de transparencia con información adicional como UserLoggedOn, CollectionTime, Computer:
Write-Output "" Write-Output "Collecting Bios information ... Please Wait !"
$DataVariable = Get-CimInstance -ClassName Win32_BIOS
#-------------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------------
$DataVariable = Convert-CimArrayToObjectFixStructure -data $DataVariable -Verbose:$Verbose
$DataVariable = Add-CollectionTimeToAllEntriesInArray -Data $DataVariable -Verbose:$Verbose
$DataVariable = Add-ColumnDataToAllEntriesInArray -Data $DataVariable -Column1Name Computer -Column1Data $Env:ComputerName -Column2Name UserLoggedOn -Column2Data $UserLoggedOn -Verbose:$Verbose
$DataVariable = Filter-ObjectExcludeProperty -Data $DataVariable -ExcludeProperty __*,SystemProperties,Scope,Qualifiers,Properties,ClassPath,Class,Derivation,Dynasty,Genus,Namespace,Path,Property_Count,RelPath,Server,Superclass -Verbose:$Verbose
Consulte más detalles sobre las funciones disponibles en AzLogDcrIngestPS - y cómo usarlas aquí
Como parte del despliegue inicial usando ClientInSpectorV2-DeploymentKit, tendrá acceso a muchos Azure Dashboards y Azure Workbooks.
La idea de los paneles es que muestran dónde su infraestructura se está desviando del 'estado deseado'. Piense en ellos como KPIs, donde la infraestructura no está bajo control.
En lugar de tener una tarea de parcheo y gestión de antivirus, puede considerar tener KPIs que muestren dónde las computadoras no están parcheadas - o donde la protección en tiempo real del antivirus no se está ejecutando - o máquinas que han mostrado pantalla azul durante las últimas 24 horas.
Este es el mismo concepto que Microsoft Secure Score.















Enlace para ver la lista completa de los Azure Workbooks proporcionados
Todos los Azure Dashboards de ejemplo se crean a partir de partes ancladas de Azure Workbooks, por lo que si desea profundizar, puede hacer clic en un enlace y obtendrá acceso a la información detallada.

Enlace para ver los Azure Dashboards proporcionados
Si desea agregar más paneles o libros de trabajo, generalmente comenzará investigando los datos recopilados en las tablas de registros personalizados usando consultas KQL. Cuando haya encontrado la consulta deseada, puede crear nuevas vistas en los libros de trabajo y anclar sus favoritos a sus paneles.
Si no conoce el lenguaje Kusto, le recomiendo que comience a experimentar con él, ya que es un lenguaje realmente potente.
Video 1m 58s - Consultas Kusto sobre datos
Video 3m 01s - Paneles
Escriba su primera consulta con el lenguaje de consulta Kusto
Analice los resultados de consultas usando KQL
A continuación se muestran 4 ejemplos de consultas para comenzar, basados en los datos de ClientInspector.
Si desea realizar búsqueda avanzada, puede usar consultas tradicionales Kusto (KQL) en las tablas
#----------------------------------------------------------------------------------------------------------------------
#----------------------------------------------------------------------------------------------------------------------
$LogAnalyticsWorkspaceId = "e74ca75a-c0e6-4933-a4f7-e5ae943fe4ac"
#----------------------------------------------------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------------------------- $Query = @' InvClientComputerInfoBiosV2_CL | summarize TimeGenerated = arg_max(TimeGenerated,) by Computer | join (InvClientComputerInfoSystemV2_CL | summarize TimeGenerated = arg_max(TimeGenerated,) by Computer) on $left.Computer == $right.Computer | join (InvClientComputerOSInfoV2_CL | summarize TimeGenerated = arg_max(TimeGenerated,*) by Computer) on $left.Computer == $right.Computer | project Computer, UserLoggedOn, SerialNumber, Manufacturer, PCSystemType, SystemFamily, Model, Windows=Caption2, WindowsVersion=Version1, TimeGenerated '@
write-output "Collecting computer information from LogAnalytics" $Query = Invoke-AzOperationalInsightsQuery -WorkspaceId $LogAnalyticsWorkspaceId -Query $Query $ComputerInfoArray = $Query.Results $ComputerInfoArray
</details>
## Ejemplo de consulta 4: Integración de datos con otras fuentes (verificación de garantía contra la base de datos de garantía de Lenovo)
Cuando tenemos los datos en Azure LogAnalytics, podemos empezar a integrarlos con otras fuentes, como los datos de garantía de Dell o Lenovo mediante una consulta REST API.
[Video 0m 48s - Ejemplo de uso de datos - consulta contra la base de datos de garantía de Lenovo](https://youtu.be/3ZDyTwiLU0w)
Aquí hay un ejemplo de salida, creada automáticamente por un script de PowerShell que extrae una lista de equipos y números de serie, y luego realiza una consulta a la base de datos de garantía de Lenovo para obtener información sobre cuándo se compró el equipo y su estado de garantía.
[Ejemplo de salida de garantía (Excel), basado en datos recopilados por ClientInspector](https://github.com/KnudsenMorten/ClientInspectorV2/raw/main/img/WarrantyInfo.xlsx)
<br>
# Arquitectura, Esquema y Redes
ClientInspector (v2) está subiendo los datos recopilados a **registros personalizados** en el **área de trabajo de Azure LogAnalytics** utilizando la **API de ingesta de registros**, **Reglas de recopilación de datos de Azure (DCR)** y **Puntos de conexión de recopilación de datos de Azure (DCE)**.

## Esquema
Tanto la DCR como la tabla de LogAnalytics tienen un esquema que debe coincidir con el esquema del objeto de origen. Esto se maneja utilizando funciones del módulo AzLogDcrIngestPS.
[Video 1m 40s - Creación automática de 2 tablas y DCR (modo verbose)](https://youtu.be/rIUNs3yT-eI)
[Video 1m 37s - Creación automática de 2 tablas y DCR (modo normal)](https://youtu.be/khQMDcON6r8)
[Video 1m 34s - Ver esquema de DCR y tabla)](https://youtu.be/NDSNhvpa4Gs)
AzLogDcrIngestPS admite 2 modos para administrar el esquema: **Combinar** y **Sobrescribir**
### SchemaMode = Merge (Combinar, predeterminado)
Si establece SchemaMode = Merge, las nuevas propiedades del objeto de origen se agregarán (combinarán) al esquema actual de Log Analytics. La DCR importará el esquema de la tabla de Log Analytics para asegurarse de que sean idénticos.
El modo predeterminado es Merge, si no define la variable SchemaMode en las funciones:
CheckCreateUpdate-TableDr-Structure
CreateUpdate-AzLogAnalyticsCustomLogTableDcr
CreateUpdate-AzDataCollectionRuleLogIngestCustomLog
### SchemaMode = Overwrite (Sobrescribir)
Si establece SchemaMode = Overwrite, el esquema en la DCR y la tabla se sobrescribirá (actualizará) según el esquema del objeto de origen.
## Redes
Tiene 3 opciones de conectividad a Azure para la carga de datos:
|Método de carga|Detalles de conectividad|Cumplimiento del SO|
|:--------------|:-----------------------|:------------------|
|Acceso público|El punto de conexión REST envía al DCE a través de la IP pública del DCE|El punto de conexión admite TLS 1.2|
|Acceso privado|El punto de conexión REST envía al DCE a través del enlace privado del DCE|El punto de conexión admite TLS 1.2|
|Log-hub|El punto de conexión REST envía datos a través de [log-hub](https://github.com/KnudsenMorten/AzLogDcrIngestPSLogHub) - un concepto que he creado.|El punto de conexión no admite TLS 1.2.<br>Azure no aceptará la conectividad desde estos dispositivos directamente|
### Puntos de conexión conectados a Internet - Cumplimiento a nivel de SO

Debe permitir los siguientes puntos de conexión en su cortafuegos:
|Punto de conexión|Propósito|Puerto|Dirección|Evasor de inspección HTTPS|
|:---------------|:--------|:----|:--------|:-------------------------|
|global.handler.control.monitor.azure.com|Servicio de control de acceso|Puerto 443|Saliente|Sí|
|URI de ingesta de logs del DCE<br><br>ejemplo<br>https://dce-log-platform-management-client-demo-p-iur0.westeurope-1.ingest.monitor.azure.com|Ingesta de datos de registro|Puerto 443|Saliente|Sí|
<br>
### Sin acceso a Internet o incumplimiento a nivel de SO, p. ej., que ejecuta TLS 1.0/1.1
[Consulte el concepto de log-hub usando este enlace](https://github.com/KnudsenMorten/AzLogDcrIngestPSLogHub)

<br>
# Implementación
Espero que experimente que es bastante fácil poner todo en funcionamiento. Los 3 pasos se describen a continuación.
Antes de comenzar, le recomiendo que lea con más detalle sobre los componentes en la introducción a continuación.
<details>
<summary>Introducción de los componentes de Azure utilizados como parte de ClientInspector</summary>
<br>
Se necesitan los siguientes componentes:
| Recurso de Azure | Propósito | Más información |
| :------------- | :----- | :----- |
| Cualquier punto de conexión REST | Esta es la fuente que envía datos | |
| API de ingesta de registros | Esta es la nueva API que reemplaza la antigua API del recopilador de datos HTTP | https://learn.microsoft.com/es-es/azure/azure-monitor/logs/logs-ingestion-api-overview |
| Punto de conexión de recopilación de datos (DCE) | Este es el punto de entrada de comunicación desde el punto de conexión. Los datos se envían a un **URI de ingesta del punto de conexión de recopilación de datos de Azure**. Un único DCE puede admitir múltiples DCR, por lo que puede especificar una DCR diferente para diferentes fuentes y tablas de destino. | https://learn.microsoft.com/es-es/azure/azure-monitor/essentials/data-collection-endpoint-overview?tabs=portal |
| Reglas de recopilación de datos (DCR) | Las reglas de recopilación de datos definen los datos recopilados (esquema) y especifican cómo y dónde deben enviarse o almacenarse esos datos. La DCR debe comprender la estructura de los datos de entrada y la estructura de la tabla de destino. Si no coinciden, puede usar una transformación para convertir los datos de origen para que coincidan con la tabla de destino. También puede usar la transformación para filtrar datos de origen y realizar otros cálculos o conversiones. | https://learn.microsoft.com/es-es/azure/azure-monitor/essentials/data-collection-rule-overview |
| Área de trabajo de Azure LogAnalytics | Los datos se envían a registros personalizados en Azure LogAnalytics | https://learn.microsoft.com/es-es/azure/azure-monitor/logs/log-analytics-overview |
| Workbooks de Azure | Como parte de la implementación, se implementarán workbooks de muestra | https://learn.microsoft.com/es-es/azure/azure-monitor/visualize/workbooks-overview |
| Paneles de Azure | Como parte de la implementación, se implementarán workbooks de muestra | https://learn.microsoft.com/es-es/azure/azure-monitor/visualize/tutorial-logs-dashboards |
| Kusto (KQL) | Los datos se pueden analizar usando consultas Kusto (KQL) | https://learn.microsoft.com/es-es/azure/azure-monitor/logs/get-started-queries |
</details>
Los pasos para configurar ClientInspector en su entorno son:
1. [Configurar el entorno usando ClientInSpectorV2-DeploymentKit](https://github.com/KnudsenMorten/ClientInspectorV2-DeploymentKit)
2. Ejecutar ClientInspector por primera vez (configuración inicial) - ver más abajo
<details>
<summary>Cómo configurar la configuración inicial de las tablas de Azure LogAnalytics y las Reglas de recopilación de datos (primera vez)</summary>
<br>
Recomiendo tener un equipo de referencia que se utilice para la administración de tablas/DCR. De esta manera, es un proceso controlado si se deben realizar cambios, por ejemplo, si el esquema del objeto de origen cambia.
<br>
<br>
Configuración:
1. Cuando ejecute el DeploymentKit, preparará automáticamente el archivo ClientInspector para usted, por lo que solo necesita insertar las variables.```js
$TenantId = "xxxx"
$LogIngestAppId = "xxxx"
$LogIngestAppSecret = "xxxx"
$DceName = "xxxx"
$LogAnalyticsWorkspaceResourceId = "xxxx"
$AzDcrPrefixClient = "xxx"
$AzDcrSetLogIngestApiAppPermissionsDcrLevel = $false
$AzDcrLogIngestServicePrincipalObjectId = "xxx"
$AzDcrDceTableCreateFromReferenceMachine = @()
$AzDcrDceTableCreateFromAnyMachine = $true
Descargue el script de detección ClientInspector_Detection.ps1 (haga clic derecho y elija 'guardar enlace como')
Abra el archivo con su editor favorito. Ajuste la frecuencia con la que desea que se ejecute el inventario```js ##################################
##################################
$RunEveryHours = 8
$LastRun_RegPath = "HKLM:\SOFTWARE\ClientInspector"
$LastRun_RegKey = "ClientInSpector_System"
3. Ahora necesitamos crear el trabajo de corrección. Vaya al portal de Microsoft Intune -> Informes -> Análisis de puntos finales -> Correcciones proactivas y cree un paquete de script como se muestra a continuación.
NOTA: Para el script de corrección, use el archivo **ClientInspector.ps1**.


### Limitación de Intune
NOTA: Intune tiene una limitación de 200 Kb de tamaño para un script de corrección.**

En caso de alcanzar este límite, propongo dividir el script en 2 scripts.


Recuerde incluir la sección de encabezado, incluida la sección UserLoggedOn, como encabezado del segundo archivo. UserLoggedOn se usa para mostrar qué usuario ha iniciado sesión.
He preparado una [configuración de script de ejemplo](https://github.com/KnudsenMorten/ClientInspectorV2/tree/main/Sample%20intune%20setup%20if%20file%20size%20is%20more%20than%20200%20Kb), donde puede ver cómo separarlos. Nota: el código NO está actualizado en estos scripts, así que asegúrese de tomar las secciones del archivo ClientInspector maestro.
Básicamente la estructura es:
El Archivo 1 contiene el encabezado + UserLoggedOn (sección 1) + secciones 2-9 + escribe la marca de verificación en HKLM\Software\ClientInspector\ClientInspector_System_1
El Archivo 2 contiene el encabezado + UserLoggedOn (sección 1) + secciones 10-18 + escribe la marca de verificación en HKLM\Software\ClientInspector\ClientInspector_System_2



</details>
<details>
<summary>¿Cómo implementar usando ConfigMgr (o cualquier otra herramienta que ejecute un archivo CMD)?</summary>
<br>
Ejecutará el script de inventario mediante un paquete tradicional + implementación.
1. [Descargue el archivo CMD ClientInspector.cmd](https://github.com/KnudsenMorten/ClientInspectorV2/raw/main/ConfigMgr/ClientInspector.cmd) (clic derecho y elija 'guardar enlace como')
2. Cree una estructura de origen en su directorio de origen del paquete de ConfigMgr, por ejemplo, llamada ClientInspector.
3. Copie los 2 archivos necesarios **ClientInspector.cmd** y **ClientInspector.ps1** en el directorio.
4. Cree un paquete y apunte el paquete a ejecutar **ClientInspector.cmd**
5. Cree una implementación.
</details>
<br>
# Dependencias
## Módulo de Powershell AzLogDcringestPS - creado por mí (Morten Knudsen)
ClientInspector requiere el módulo de Powershell **AzLogDcrIngestPS**
Las características principales del módulo de Powershell **AzLogDcrIngestPS** incluyen:
* crear/actualizar los DCR y tablas automáticamente, basándose en el esquema del objeto de origen
* validar el esquema para problemas de convención de nombres. Si se encuentra alguno, mitigará los problemas
* actualizar el esquema de DCR y tablas, si la estructura del objeto de origen cambia
* corrección automática si algo sale mal con un DCR o tabla
* puede eliminar datos del objeto de origen, si hay columnas de datos que no desea enviar
* puede convertir objetos de origen basados en objetos CIM o PS en PSCustomObjects/array
* puede agregar información relevante a cada registro, como UserLoggedOn, Computer, CollectionTime
Puede encontrar información más detallada sobre el módulo utilizando los enlaces siguientes:
[AzLogDcrIngestPS (Github)](https://github.com/KnudsenMorten/AzLogDcrIngestPS)
[AzLogDcrIngestPS (Galería de Powershell)](https://www.powershellgallery.com/packages/AzLogDcrIngestPS)
[AzLogDcrIngestPSLogHub (Github)](https://github.com/KnudsenMorten/AzLogDcrIngestPSLogHub)
<br>
## Módulos de Powershell de terceros
Prefiero obtener información de actualizaciones de Windows utilizando un módulo de Powershell conocido, PSWindowsUpdate.
|NombreMódulo|Propósito|Más información|Crédito|
|:---------|:------|:--------|:-----|
|NuGet|Proveedor de paquetes común utilizado para implementar muchos módulos de Powershell, incluido AzLogDcrIngestPS<br><br>El proveedor de paquetes se instalará automáticamente en el equipo cuando se ejecute el script|[Enlace](https://www.nuget.org/packages)|
|PSWindowsUpdate|Recopilación de información de actualizaciones de Windows (actualizaciones pendientes, actualizaciones instaladas, etc.)<br><br>El módulo se instalará automáticamente en el equipo cuando se ejecute el script|[Enlace](https://www.powershellgallery.com/packages/PSWindowsUpdate)|Michal Gajda
<br>
# Ejecutar ClientInspector.ps1 - 3 modos
ClientInspector admite 3 formas de instalar/actualizar/importar el módulo de Powershell necesario: **Descargar**, **PsGallery**, **LocalPath**
Por defecto, descargará la última versión de PsGallery en el ámbito CurrentUser.
[Video 3m 19s - Ejecutar ClientInspector usando la línea de comandos (modo normal)](https://youtu.be/4kA4BE0zJ9g)
## .\ClientInspector.ps1 -funcion:LocalPath
ClientInspector buscará el archivo **AzLogDcrIngest.psm1** en el directorio desde donde se ejecutará el script.
Si AzLogDcrIngest.psm1 falta, el script terminará; de lo contrario, realizará un import-module.
Ejemplo```
.\ClientInspector.ps1 -verbose:$false -function:localpath
ClientInspector | Inventory of Operational & Security-related information
Developed by Morten Knudsen, Microsoft MVP - for free community use
Using AzLogDcrIngestPS module from local path D:\scripts\ClientInspectorV2
$DataVariable = ValidateFix-AzLogAnalyticsTableSchemaColumnNames -Data $DataVariable -Verbose:$Verbose
$DataVariable = Build-DataArrayToAlignWithSchema -Data $DataVariable -Verbose:$Verbose
Puedes verificar el objeto fuente ejecutando este comando.````
# Get insight about the schema structure of an object BEFORE changes. Command is only needed to verify columns in schema
Get-ObjectSchemaAsArray -Data $DataVariable -Verbose:$Verbose







Iniciar Powershell como administrador local
Iniciar el script usando este comando```js C:\ClientInspector\ClientInspector.ps1 -verbose:$true
4. ClientInspector se ejecutará durante 10-20 min y creará las tablas y reglas de recolección de datos necesarias, basadas en la estructura real de su entorno. Revise los resultados en la pantalla y busque errores (en rojo)
5. Cuando todo se vea bien, vuelva a ejecutar el script y se ejecutará mucho más rápido. Verifique que los datos estén llegando usando consultas Kusto en las diferentes tablas. NOTA: Puede tomar aproximadamente 10-15 min para la primera carga de datos, ya que la canalización debe crearse en el backend
6. Como último cambio, necesitamos cambiar 2 parámetros en los parámetros para indicarle a ClientInspector que solo realice cambios de esquema cuando se ejecute desde la máquina de referencia.```js
$AzLogDcrTableCreateFromReferenceMachine = @("<<MyReferenceMachineComputerName>>") # sample @("ComputerName")
$AzLogDcrTableCreateFromAnyMachine = $false # important so changes can only happen on reference machine
ClientInspector descargará la última versión desde mi repositorio de Github y la almacenará en la ruta local cada vez que se ejecute (aprox. 300 kb)
Ejemplo``` .\ClientInspector.ps1 -verbose:$false -function:download
ClientInspector | Inventory of Operational & Security-related information Developed by Morten Knudsen, Microsoft MVP - for free community use
Downloading latest version of module AzLogDcrIngestPS from https://github.com/KnudsenMorten/CientInspectorV2 into local path D:\scripts\ClientInspectorV2
## .\ClientInspector.ps1 -function:PsGallery -scope [AllUsers|CurrentUser]
Este parámetro requiere otro parámetro: -scope [AllUsers | CurrentUser]
ClientInspector comprobará si el módulo está instalado en el ámbito elegido. Si no está instalado, descargará automáticamente la última versión desde Powershell Gallery e importará el módulo. Si el cliente está ejecutando la última versión, continuará.
Ejemplo```
.\ClientInspector.ps1 -verbose:$false -function:PSGallery -scope:CurrentUser
ClientInspector | Inventory of Operational & Security-related information
Developed by Morten Knudsen, Microsoft MVP - for free community use
Powershell module was not found !
Installing in scope currentuser .... Please Wait !
| Comando | Descripción |
|---|---|
sudo -l | Lista los comandos sudo disponibles. |
sudo -u user command | Ejecuta un comando como otro usuario. |
su user | Cambia a otro usuario. |
Las técnicas de escalada de privilegios implican obtener acceso de mayor nivel a un sistema. Los métodos comunes incluyen explotar configuraciones incorrectas, servicios vulnerables y exploits del kernel.
sudo -l
sudo -u root /bin/bash
.\ClientInspector.ps1 -verbose:$false -function:PsGallery -scope:currentuser
ClientInspector | Inventory of Operational & Security-related information Developed by Morten Knudsen, Microsoft MVP - for free community use
Checking latest version at PsGallery for AzLogDcrIngestPS module OK - Running latest version
</details>
<br>
## Ejemplo de salida de ClientInspector
[Video 3m 19s - Ejecutando ClientInspector mediante línea de comandos (modo normal)](https://youtu.be/4kA4BE0zJ9g)
<br>
# Seguridad
## Firma de código
Tanto el **archivo ClientInspector.ps1** como el **módulo AzLogDcrIngestPS (AzLogDcrIngest.psm1)** están firmados con mi certificado de firma de código (2LINKIT - mi empresa). De esta manera puede ejecutarlos si requiere que los scripts estén firmados. Por supuesto, también puede optar por firmarlos con su propio certificado de firma de código interno.

Por favor, [descargue el certificado de clave pública](https://github.com/KnudsenMorten/ClientInspectorV2/raw/main/Trusted_Publisher_Certificate/2LINKIT-TrustedPublisher.cer) y colóquelo en su contenedor de 'trusted publisher' para confiar en el publicador (2LINKIT - mi empresa). Puede implementar esto usando Intune o Directiva de grupo.



### La implementación de Intune no requiere que el publicador de confianza esté en su lugar
Por defecto, Intune realiza un BYPASS al ejecutar scripts de corrección.
## Estructura
La seguridad de **ClientInspector** se divide en 4 capas: **data-in**, **data-upload** (enviar al backend) y **data-view** (paneles) - y **schema-management**
| Fase | Implementación de seguridad | Delegaciones / Permisos |
|:-----|:---------------------------|:------------------------|
|Data-in (recopilación)|Esta fase está controlada por el método que elija para realizar la recopilación real (Intune, ConfigMg u otro tercero)|El script debe ejecutarse como administrador local (contexto de sistema) para poder recopilar datos centrales del hardware y Windows|
|Data-upload|La autenticación para la API de ingesta de registros se realiza en el DCE, que utiliza la autenticación estándar de Azure Resource Manager.<br><br>Una estrategia común es usar un ID de aplicación y una clave de aplicación, que también es el método utilizado en ClientInspector.<br><br>Azure AppId y Secret se almacenan en el encabezado de ClientInspector por simplicidad.<br><br>También es posible usar Azure Keyvault para almacenar el AppId y Secret.|[Detalles cubiertos en ClientInspectV2-DeploymentKit](https://github.com/KnudsenMorten/ClientInspectorV2-DeploymentKit#security-1)|
|Data-view|Permisos RCAC de Azure|Otorgue acceso a sus Azure LogAnalytics, Azure Workbooks y Azure Dashboards|
|Schema-management|Método 1: RBAC de Azure (recomendado)<br><br>Método 2: Aplicación de Azure con secreto o certificado|[Detalles cubiertos en ClientInSpectorV2-DeploymentKit](https://github.com/KnudsenMorten/ClientInspectorV2-DeploymentKit#azure-rbac-security-adjustment-separation-of-permissions-between-log-ingestion-and-tabledcr-management)|
<br>
# Diseño del conjunto de datos de ClientInspector
Cada uno de los conjuntos de datos (bios, applications, bitlocker, etc.) se construyen con la misma estructura de 4 fases:
## Fase 1/4 - Variables (nombres - dónde enviar los datos)```
#-------------------------------------------------------------------------------------------
# Variables
#-------------------------------------------------------------------------------------------
$TableName = 'InvClientComputerInfoSystemV2' # must not contain _CL
$DcrName = "dcr-" + $AzDcrPrefixClient + "-" + $TableName + "_CL"
#-------------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------------
Write-Output "" Write-Output "Collecting Computer system information ... Please Wait !"
$DataVariable = Get-CimInstance -ClassName Win32_ComputerSystem
## Fase 3/4 - Manipulación de Datos (asegurar que los datos estén en el formato correcto y que se elimine cualquier "ruido" y se agregue información relevante)```
#-------------------------------------------------------------------------------------------
# Preparing data structure
#-------------------------------------------------------------------------------------------
# convert CIM array to PSCustomObject and remove CIM class information
$DataVariable = Convert-CimArrayToObjectFixStructure -data $DataVariable -Verbose:$Verbose
# add CollectionTime to existing array
$DataVariable = Add-CollectionTimeToAllEntriesInArray -Data $DataVariable -Verbose:$Verbose
# add Computer & UserLoggedOn info to existing array
$DataVariable = Add-ColumnDataToAllEntriesInArray -Data $DataVariable -Column1Name Computer -Column1Data $Env:ComputerName -Column2Name UserLoggedOn -Column2Data $UserLoggedOn
# Validating/fixing schema data structure of source data
$DataVariable = ValidateFix-AzLogAnalyticsTableSchemaColumnNames -Data $DataVariable -Verbose:$Verbose
# Aligning data structure with schema (requirement for DCR)
$DataVariable = Build-DataArrayToAlignWithSchema -Data $DataVariable -Verbose:$Verbose
#-------------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------------
CheckCreateUpdate-TableDcr-Structure -AzLogWorkspaceResourceId $LogAnalyticsWorkspaceResourceId -SchemaMode Merge -AzAppId $LogIngestAppId -AzAppSecret $LogIngestAppSecret -TenantId $TenantId -Verbose:$Verbose
-DceName $DceName -DcrName $DcrName -TableName $TableName -Data $DataVariable -LogIngestServicePricipleObjectId $AzDcrLogIngestServicePrincipalObjectId
-AzDcrSetLogIngestApiAppPermissionsDcrLevel $AzDcrSetLogIngestApiAppPermissionsDcrLevel -AzLogDcrTableCreateFromAnyMachine $AzLogDcrTableCreateFromAnyMachine
-AzLogDcrTableCreateFromReferenceMachine $AzLogDcrTableCreateFromReferenceMachine
#-----------------------------------------------------------------------------------------------
#-----------------------------------------------------------------------------------------------
Post-AzLogAnalyticsLogIngestCustomLogDcrDce-Output -DceName $DceName -DcrName $DcrName -Data $DataVariable -TableName $TableName ` -AzAppId $LogIngestAppId -AzAppSecret $LogIngestAppSecret -TenantId $TenantId -Verbose:$Verbose
<br>
**CONSEJO: error 513 - la entidad es demasiado grande**
Por defecto, ClientInspector envía los datos en lotes según un tamaño medio calculado por registro. En caso de que su conjunto de registros sea de tamaño diferente, podría recibir un error 513.
La causa es que está alcanzando el límite de 1 MB por cada carga (limitación de Azure Pipeline). Microsoft desea recibir muchos fragmentos más pequeños de datos, ya que se trata de un entorno compartido. He visto este problema al recuperar la lista de todas las aplicaciones instaladas. Al parecer, las aplicaciones almacenan información de tamaños muy dispares.
Puede mitigar este problema añadiendo el parámetro **-BatchAmount <número de registros a enviar por lote>** al comando Post. Si quiere estar seguro, establézcalo en 1.```
Post-AzLogAnalyticsLogIngestCustomLogDcrDce-Output -DceName $DceName `
-DcrName $DcrName `
-Data $DataVariable `
-TableName $TableName `
-AzAppId $LogIngestAppId `
-AzAppSecret $LogIngestAppSecret `
-TenantId $TenantId `
-BatchAmount 1 `
-Verbose:$Verbose `
#-----------------------------------------------------------------------------------------------
#-----------------------------------------------------------------------------------------------
$Schema = Get-ObjectSchemaAsArray -Data $Data
$StructureCheck = Get-AzLogAnalyticsTableAzDataCollectionRuleStatus -AzLogWorkspaceResourceId $AzLogWorkspaceResourceId -TableName $TableName
-DcrName $DcrName -SchemaSourceObject $Schema
-SchemaMode $SchemaMode
-AzAppId $AzAppId -AzAppSecret $AzAppSecret
-TenantId $TenantId `
-Verbose:$Verbose
#-----------------------------------------------------------------------------------------------
#-----------------------------------------------------------------------------------------------
$Schema = Get-ObjectSchemaAsHash -Data $Data -ReturnType Table
-Verbose:$Verbose
CreateUpdate-AzLogAnalyticsCustomLogTableDcr -AzLogWorkspaceResourceId $AzLogWorkspaceResourceId -SchemaSourceObject $Schema
-SchemaMode $SchemaMode
-TableName $TableName -AzAppId $AzAppId
-AzAppSecret $AzAppSecret -TenantId $TenantId
-Verbose:$Verbose
$Schema = Get-ObjectSchemaAsHash -Data $Data -ReturnType DCR
CreateUpdate-AzDataCollectionRuleLogIngestCustomLog -AzLogWorkspaceResourceId $AzLogWorkspaceResourceId -SchemaSourceObject $Schema
-SchemaMode $SchemaMode
-DceName $DceName -DcrName $DcrName
-TableName $TableName -LogIngestServicePricipleObjectId $LogIngestServicePricipleObjectId
-AzDcrSetLogIngestApiAppPermissionsDcrLevel $AzDcrSetLogIngestApiAppPermissionsDcrLevel -AzAppId $AzAppId
-AzAppSecret $AzAppSecret -TenantId $TenantId
-Verbose:$Verbose
$AzDcrDceDetails = Get-AzDcrDceDetails -DcrName $DcrName -DceName $DceName
-AzAppId $AzAppId -AzAppSecret $AzAppSecret
-TenantId $TenantId `
-Verbose:$Verbose
Post-AzLogAnalyticsLogIngestCustomLogDcrDce -DceUri $AzDcrDceDetails[2] -DcrImmutableId $AzDcrDceDetails[6]
-TableName $TableName -DcrStream $AzDcrDceDetails[7]
-Data $Data -BatchAmount $BatchAmount
-AzAppId $AzAppId -AzAppSecret $AzAppSecret
-TenantId $TenantId `
-Verbose:$Verbose
<br>
# Verbose-mode & More help
If you want to get more detailed information about that is happening, you can enable verbose mode (-verbose:$true)```
.\ClientInspector.ps1 -verbose:$true -function:localpath
Si prefieres probar usando Powershell ISE, también puedes habilitar el modo verbose usando la variable $Verbose``` $Verbose = $false # can be $true or $false
Si deseas obtener ayuda sobre la sintaxis y ejemplos del módulo AzLogDcrLogIngestPS, puedes escribir
get-module```
PS get-command -module AzLogDcrIngestPS
CommandType Name Version Source
----------- ---- ------- ------
Function Add-CollectionTimeToAllEntriesInArray 1.1.17 AzLogDcrIngestPS
Function Add-ColumnDataToAllEntriesInArray 1.1.17 AzLogDcrIngestPS
Function Build-DataArrayToAlignWithSchema 1.1.17 AzLogDcrIngestPS
Function CheckCreateUpdate-TableDcr-Structure 1.1.17 AzLogDcrIngestPS
Function Convert-CimArrayToObjectFixStructure 1.1.17 AzLogDcrIngestPS
Function Convert-PSArrayToObjectFixStructure 1.1.17 AzLogDcrIngestPS
Function CreateUpdate-AzDataCollectionRuleLogIngestCusto... 1.1.17 AzLogDcrIngestPS
Function CreateUpdate-AzLogAnalyticsCustomLogTableDcr 1.1.17 AzLogDcrIngestPS
Function Delete-AzDataCollectionRules 1.1.17 AzLogDcrIngestPS
Function Delete-AzLogAnalyticsCustomLogTables 1.1.17 AzLogDcrIngestPS
Function Filter-ObjectExcludeProperty 1.1.17 AzLogDcrIngestPS
Function Get-AzAccessTokenManagement 1.1.17 AzLogDcrIngestPS
Function Get-AzDceListAll 1.1.17 AzLogDcrIngestPS
Function Get-AzDcrDceDetails 1.1.17 AzLogDcrIngestPS
Function Get-AzDataCollectionRuleTransformKql 1.1.17 AzLogDcrIngestPS
Function Get-AzDcrListAll 1.1.17 AzLogDcrIngestPS
Function Get-AzLogAnalyticsTableAzDataCollectionRuleStatus 1.1.17 AzLogDcrIngestPS
Function Get-ObjectSchemaAsArray 1.1.17 AzLogDcrIngestPS
Function Get-ObjectSchemaAsHash 1.1.17 AzLogDcrIngestPS
Function Post-AzLogAnalyticsLogIngestCustomLogDcrDce 1.1.17 AzLogDcrIngestPS
Function Post-AzLogAnalyticsLogIngestCustomLogDcrDce-Output 1.1.17 AzLogDcrIngestPS
Function Update-AzDataCollectionRuleDceEndpoint 1.1.17 AzLogDcrIngestPS
Function Update-AzDataCollectionRuleResetTransformKqlDef... 1.1.17 AzLogDcrIngestPS
Function Update-AzDataCollectionRuleTransformKql 1.1.17 AzLogDcrIngestPS
Function ValidateFix-AzLogAnalyticsTableSchemaColumnNames 1.1.17 AzLogDcrIngestPS
Obtener ayuda con un cmdlet específico - get-help Add-CollectionTimeToAllEntriesInArray -full``` get-help Add-CollectionTimeToAllEntriesInArray -full
NAME Add-CollectionTimeToAllEntriesInArray
SYNOPSIS Add property CollectionTime (based on current time) to all entries on the object
SYNTAX Add-CollectionTimeToAllEntriesInArray [-Data] []
DESCRIPTION Gives capability to do proper searching in queries to find latest set of records with same collection time Time Generated cannot be used when you are sending data in batches, as TimeGenerated will change An example where this is important is a complete list of applications for a computer. We want all applications to show up when queriying for the latest data
PARAMETERS -Data Object to modify
Required? true
Position? 1
Default value
Accept pipeline input? false
Accept wildcard characters? false
<CommonParameters>
This cmdlet supports the common parameters: Verbose, Debug,
ErrorAction, ErrorVariable, WarningAction, WarningVariable,
OutBuffer, PipelineVariable, and OutVariable. For more information, see
about_CommonParameters (https:/go.microsoft.com/fwlink/?LinkID=113216).
INPUTS None. You cannot pipe objects
OUTPUTS Updated object with CollectionTime
-------------------------- EXAMPLE 1 --------------------------
PS C:\>#-------------------------------------------------------------------------------------------
# Variables
#-------------------------------------------------------------------------------------------
$Verbose = $true # $true or $false
#-------------------------------------------------------------------------------------------
# Collecting data (in)
#-------------------------------------------------------------------------------------------
$DNSName = (Get-CimInstance win32_computersystem).DNSHostName +"." + (Get-CimInstance win32_computersystem).Domain
$ComputerName = (Get-CimInstance win32_computersystem).DNSHostName
[datetime]$CollectionTime = ( Get-date ([datetime]::Now.ToUniversalTime()) -format "yyyy-MM-ddTHH:mm:ssK" )
$UserLoggedOnRaw = Get-Process -IncludeUserName -Name explorer | Select-Object UserName -Unique
$UserLoggedOn = $UserLoggedOnRaw.UserName
$DataVariable = Get-CimInstance -ClassName Win32_Processor | Select-Object -ExcludeProperty "CIM*"
#-------------------------------------------------------------------------------------------
# Preparing data structure
#-------------------------------------------------------------------------------------------
$DataVariable = Convert-CimArrayToObjectFixStructure -data $DataVariable -Verbose:$Verbose
$DataVariable
# add CollectionTime to existing array
$DataVariable = Add-CollectionTimeToAllEntriesInArray -Data $DataVariable -Verbose:$Verbose
$DataVariable
#-------------------------------------------------------------------------------------------
# Output
#-------------------------------------------------------------------------------------------
VERBOSE: Adding CollectionTime to all entries in array .... please wait !
Caption : Intel64 Family 6 Model 165 Stepping 5
Description : Intel64 Family 6 Model 165 Stepping 5
InstallDate :
Name : Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz
Status : OK
Availability : 3
ConfigManagerErrorCode :
ConfigManagerUserConfig :
CreationClassName : Win32_Processor
DeviceID : CPU0
ErrorCleared :
ErrorDescription :
LastErrorCode :
PNPDeviceID :
PowerManagementCapabilities :
PowerManagementSupported : False
StatusInfo : 3
SystemCreationClassName : Win32_ComputerSystem
SystemName : STRV-MOK-DT-02
AddressWidth : 64
CurrentClockSpeed : 2904
DataWidth : 64
Family : 198
LoadPercentage : 1
MaxClockSpeed : 2904
OtherFamilyDescription :
Role : CPU
Stepping :
UniqueId :
UpgradeMethod : 1
Architecture : 9
AssetTag : To Be Filled By O.E.M.
Characteristics : 252
CpuStatus : 1
CurrentVoltage : 8
ExtClock : 100
L2CacheSize : 2048
L2CacheSpeed :
L3CacheSize : 16384
L3CacheSpeed : 0
Level : 6
Manufacturer : GenuineIntel
NumberOfCores : 8
NumberOfEnabledCore : 8
NumberOfLogicalProcessors : 16
PartNumber : To Be Filled By O.E.M.
ProcessorId : BFEBFBFF000A0655
ProcessorType : 3
Revision :
SecondLevelAddressTranslationExtensions : False
SerialNumber : To Be Filled By O.E.M.
SocketDesignation : U3E1
ThreadCount : 16
Version :
VirtualizationFirmwareEnabled : False
VMMonitorModeExtensions : False
VoltageCaps :
PSComputerName :
CollectionTime : 12-03-2023 16:08:33
RELATED LINKS https://github.com/KnudsenMorten/AzLogDcrIngestPS
<br>
# Costo: ¿cuánto cuesta almacenar estos datos?
Los datos de **500** clientes que realizan inventario **diario** con ClientInspector le costarán aproximadamente **200 DKK al mes / 27 USD al mes**.
<br>
# Errores y hallazgos, por favor infórmeme
Hoy en día, ClientInspectorV1 se utiliza en miles de ordenadores (y ServerInspectorV1 en miles de servidores).
Dado que ClientInspectorV2 es una reestructuración completa de V1 que se está implementando ahora (por ejemplo, con una nueva convención de nombres), no puedo prometerle que no se encontrarán errores.
Pero **le prometo** que los solucionaré tan pronto como mi tiempo libre me lo permita. Por favor, envíeme un correo electrónico a [email protected] con sus hallazgos.
Considere hacer un fork del sitio de Github, o esté atento a las actualizaciones en los paneles/libros de trabajo o en el script de ClientInspector.
Además, ClientInspector está diseñado para cubrir diferentes diseños y plataformas, pero puede tener configuraciones únicas que no estén cubiertas por las colecciones o paneles.
Pero el enfoque abierto le permite ajustar tanto los paneles, los libros de trabajo como el script de ClientInspector para que funcione al 100% para usted. Considérelo una demostración para hacer más con las tecnologías de registro de Azure; no es un producto de pago con soporte 24x7. ¡Es gratuito para todos!
<br>
# Contacto
Si tiene comentarios sobre la solución, o simplemente quiere conectarse conmigo, contácteme a través de estos canales; me encantaría conectar:
[Github](https://github.com/KnudsenMorten)
[Twitter](https://twitter.com/knudsenmortendk)
[Blog](https://mortenknudsen.net/)
[LinkedIn](https://www.linkedin.com/in/mortenwaltorpknudsen/)
[Perfil de Microsoft MVP](https://mvp.microsoft.com/en-us/PublicProfile/5005156?fullName=Morten%20Knudsen)
[Sessionize](https://sessionize.com/mortenknudsen/)
[Correo electrónico](mailto:[email protected])
<br>
# Muchas gracias a los grandes profesionales de los equipos de producto de Microsoft: ¡son estrellas de rock! :smile:
Por último, quisiera dar un gran reconocimiento a algunas personas con las que he trabajado en la construcción del módulo de PowerShell AzLogDcrIngestPS y en mi trabajo diario con las capacidades de registro y visualización de Azure:
|Nombre|Rol|
|:---|:---|
|Ivan Varnitski|Gerente de programa - Azure Pipeline|
|Evgeny Ternovsky|Gerente de programa - Azure Pipeline|
|Nick Kiest|Gerente de programa - Azure Data Collection Rules|
|Oren Salzberg|Gerente de programa - Azure LogAnalytics|
|Guy Wild|Redactor técnico - Azure LogAnalytics|
|John Gardner|Gerente de programa - Azure Workbooks|
|Shikha Jain|Gerente de programa - Azure Workbooks|
|Shayoni Seth|Gerente de programa - Azure Monitor Agent|
|Jeff Wolford|Gerente de programa - Azure Monitor Agent|
|Xema Pathak|Gerente de programa - Azure VMInsight (integración con Azure Monitor Agent)|
