- PowerShell envía telemetría anónima al iniciar y durante la sesión, controlable mediante la variable de entorno POWERSHELL_TELEMETRY_OPTOUT.
- Las variables de entorno específicas de PowerShell y del sistema permiten ajustar privacidad, rutas de módulos, caché y políticas de ejecución heredables por procesos hijo.
- La telemetría personalizada hacia Azure Application Insights puede probarse y diagnosticarse con scripts de PowerShell o curl, verificando red, TLS y autenticación con Microsoft Entra ID.
- Usar correctamente estos mecanismos facilita añadir telemetría fiable a scripts en PowerShell manteniendo el control sobre seguridad y datos compartidos.

Si trabajas a diario con PowerShell y empiezas a oír hablar de telemetría en scripts y sesiones, es normal que te entren dudas: qué datos se mandan, a dónde van, cómo desactivarlos o incluso cómo aprovechar tú mismo esa telemetría para depurar o monitorizar tus propios scripts. Todo esto cobra todavía más importancia cuando manejas entornos corporativos o información sensible.
En las siguientes líneas verás, con bastante detalle y con un lenguaje lo más llano posible, cómo funciona la telemetría ligada a PowerShell, qué papel juegan las variables de entorno, cómo puedes optar por no participar, de qué forma enviar telemetría manualmente (por ejemplo a Application Insights) con PowerShell o curl, y qué problemas típicos de red, TLS o autenticación pueden hacer que falten datos en tus paneles.
Qué telemetría envía PowerShell de forma nativa
PowerShell, en sus versiones modernas, incluye un mecanismo propio para enviar datos de uso básicos a Microsoft a través de Application Insights. No hablamos del código que tú escribas, sino del propio motor de PowerShell cuando se ejecuta el binario pwsh.
Esta telemetría sirve a Microsoft para entender mejor cómo se usa PowerShell (versiones, plataformas, módulos, etc.) y priorizar nuevas funcionalidades o corrección de errores. Antes de enviarse, la información se anonimiza y se agrega para que no se identifique directamente al usuario.
Hay dos momentos clave donde se recopilan datos: al inicio de la sesión y periódicamente durante la ejecución. Es importante tener claro este comportamiento si quieres controlar al máximo qué se comparte desde tus entornos.
Además, el motor sólo envía esta telemetría cuando ejecutas el pwsh estándar; si PowerShell está incrustado como motor en otra aplicación host, esa telemetría de inicio no se genera.
Datos que se mandan al iniciar pwsh
Cuando se arranca una sesión con pwsh, el motor recopila un conjunto pequeño pero muy concreto de información de entorno que se envía una sola vez por arranque. Entre otros, se registran detalles del sistema operativo y de la instalación de PowerShell.
En ese arranque se incluyen datos como el fabricante del sistema operativo, el nombre y la versión de la plataforma, así como la versión concreta de PowerShell que estás ejecutando en ese momento, lo que ayuda a entender el mix de sistemas en los que se usa.
Otra pieza clave que se manda es el valor de la variable de entorno POWERSHELL_DISTRIBUTION_CHANNEL, que indica el canal por el que se instaló PowerShell (por ejemplo, paquete oficial, repositorio, etc.). Este valor lo establecen los instaladores y la recomendación es que los usuarios no lo toquen para no distorsionar las métricas.
También se incluye la versión del SDK de Application Insights utilizada por el propio PowerShell, el área geográfica aproximada del host basada en la IP, los parámetros pasados a pwsh sin sus valores (es decir, nombres de parámetros pero no contenidos) y la política de ejecución efectiva de la sesión que arranca.
Finalmente, el motor genera dos identificadores anónimos: un GUID aleatorio por usuario y otro GUID por sesión. No son datos personales directos, sino identificadores técnicos para agrupar sesiones y comportamientos sin exponer la identidad real.
Telemetría que se envía durante la sesión
Una vez que la sesión ya está en marcha, PowerShell va enviando de forma periódica información agregada de uso para entender qué características se usan y cómo. Esto se aplica tanto a la consola interactiva como a otros hosts que ejecuten el motor.
Entre estos datos se encuentran, por ejemplo, el número de veces que se llama a la API PowerShell.Create(), el listado de módulos de Microsoft importados junto con sus versiones o el recuento de módulos que llevan la etiqueta CrescendoBuilt, que ayuda a identificar el uso de ciertas herramientas.
También se informan los nombres de las características experimentales activadas y desactivadas, algo muy útil para saber qué experimentos tiene la comunidad realmente en producción; además, se envía el valor de la preferencia $PSNativeCommandUseErrorActionPreference (true, false o no establecido) y el número de sesiones remotas abiertas.
Otra parte interesante es el catálogo de subsystem registrados. PowerShell indica los nombres usados para subsistemas de autocompletado (Completion) o generales (general), pero si el nombre no está en esa lista, se envía como anonymous para preservar la privacidad.
Para terminar, se incluyen contadores sobre sugerencias generadas por CommandNotFound y estadísticas del uso de PowerShellUnsafeAssemblyLoad (incluyendo si la carga se completó con éxito o no), aspectos clave para mejorar diagnósticos y seguridad.
Cómo desactivar la telemetría nativa de PowerShell
Si en tu organización tienes políticas de privacidad estrictas, puedes indicar que no quieres que se envíe esta telemetría. Para ello PowerShell expone la variable de entorno POWERSHELL_TELEMETRY_OPTOUT, que debes establecer antes de iniciar cualquier sesión.
El valor reconocido para desactivar la telemetría puede ser true, yes o 1. Cualquiera de estas variantes indica al motor que no debe mandar datos de uso a Microsoft desde ese proceso ni desde procesos hijo que hereden el entorno.
Es importante entender que esta configuración se basa en variables de entorno, por lo que si quieres que sea persistente deberás definirla en el ámbito adecuado (usuario, máquina o scripts de inicio) antes de lanzar PowerShell, no después.
Si tienes dudas sobre cómo gestionar estas variables, la propia documentación sobre about_Environment_Variables y la guía de variables de entorno de PowerShell te ayudan a elegir el enfoque correcto según el sistema operativo.
Además, recuerda que los paquetes instaladores que distribuyen PowerShell configuran automáticamente POWERSHELL_DISTRIBUTION_CHANNEL para poder distinguir el canal de instalación. Esa variable también se incluye en la telemetría, por lo que no conviene manipularla de forma manual.
Variables de entorno clave que afectan a PowerShell
PowerShell trata las variables de entorno como un tipo de datos especial, siempre en forma de cadenas de texto heredables por procesos hijos. Esto las hace ideales para controlar opciones globales como privacidad, actualización o rutas de módulos.
El propio motor define una serie de variables específicas, entre las que destacan POWERSHELL_TELEMETRY_OPTOUT, POWERSHELL_DISTRIBUTION_CHANNEL, POWERSHELL_UPDATECHECK, PSExecutionPolicyPreference, PSModulePath, PSModuleAnalysisCachePath y PSDisableModuleAnalysisCacheCleanup.
En Windows, estas variables pueden vivir en el ámbito de máquina (sistema), de usuario o de proceso. El proceso actual combina automáticamente las definiciones de máquina y usuario, y lo que cambies en una sesión sólo afecta a ese proceso a menos que lo hagas persistente por otros medios.
Para modificar valores a nivel de máquina o usuario desde PowerShell deberás recurrir a la clase .NET System.Environment, que expone métodos para leer y escribir variables en esos ámbitos, siempre que tengas permisos suficientes para hacerlo.
Ten en cuenta que, al ser cadenas, las variables de entorno pueden concatenarse, vaciarse o eliminarse con bastante facilidad, lo que es muy útil para scripts de configuración compleja o automatización de despliegues.
Formas de acceder y modificar variables de entorno en PowerShell
PowerShell ofrece varias formas para consultar y modificar variables de entorno. Dependiendo de lo que estés haciendo (script rápido, módulo complejo, tarea de administración) te interesará usar una u otra.
La forma más directa es la sintaxis de variable con el prefijo $Env:, que te permite leer el valor de una variable o asignarle un nuevo valor como si fuera cualquier otra variable de PowerShell, por ejemplo $Env:windir o $Env:Foo = "Algo".
Además, se puede usar el proveedor de entorno (Env:) con los cmdlets estándar de elementos (Get-Item, New-Item, Set-Item, Remove-Item, etc.), lo que da un enfoque muy coherente con el tratamiento de unidades de sistema de archivos.
En escenarios donde quieras operar a nivel de máquina o usuario, o integrar con código .NET, tienes los métodos [Environment]::GetEnvironmentVariable() y [Environment]::SetEnvironmentVariable(). Estos métodos permiten elegir explícitamente el ámbito (Process, User o Machine) en sistemas Windows.
Desde PowerShell 7.5 hay, además, un comportamiento específico: puedes establecer una variable en cadena vacía o en $null para vaciarla o eliminarla de la sesión, tanto usando la sintaxis $Env: como mediante Set-Item o los métodos de System.Environment.
Variables de entorno de PowerShell relacionadas con telemetría y comportamiento
Varias características internas de PowerShell dependen de variables de entorno que actúan como banderas de preferencia heredables. Esto te permite ajustar el comportamiento del shell o de la telemetría sin tener que cambiar código en cada script.
La más evidente es POWERSHELL_TELEMETRY_OPTOUT, que como ya hemos visto sirve para desactivar la telemetría nativa del motor cuando se establece a true, yes o 1. Para que surta efecto debe existir antes de iniciar el proceso de PowerShell.
Otra muy importante es POWERSHELL_DISTRIBUTION_CHANNEL, que desde PowerShell 7.2 la rellenan automáticamente los instaladores para indicar cómo se instaló el producto. Se incluye en la telemetría, por lo que no se recomienda modificarla a mano.
La variable POWERSHELL_UPDATECHECK controla cómo y cuándo se muestran notificaciones de actualización. Acepta valores como Off para desactivar la función, Default para el comportamiento estándar o LTS para recibir avisos sólo de versiones de soporte extendido.
Por otro lado, PSExecutionPolicyPreference refleja la política de ejecución activa en la sesión actual cuando se ha configurado mediante el parámetro -ExecutionPolicy, el cmdlet Set-ExecutionPolicy con ámbito Process, o editando directamente la variable. Este ajuste afecta especialmente a scripts descargados o sin firmar en Windows.
Y, por supuesto, la ruta de búsqueda de módulos se controla con PSModulePath, que almacena una lista separada por punto y coma en Windows o por dos puntos en plataformas *nix, con ubicaciones tanto de sistema como de usuario e incluso rutas añadidas por instaladores externos.
Caché y análisis de módulos: ajustes finos
PowerShell mantiene una caché de análisis de módulos para acelerar las búsquedas de comandos y evitar tener que inspeccionar constantemente todos los módulos disponibles en cada arranque o búsqueda.
La variable de entorno PSModuleAnalysisCachePath define dónde se almacena ese archivo de caché. Por defecto apunta a rutas bajo $Env:LOCALAPPDATA en Windows o ~/.cache/powershell en sistemas no Windows, con un nombre de archivo diferenciado por instalación.
Si quieres cambiar esa ubicación, debes establecer esta variable antes de iniciar PowerShell, apuntando a una ruta completa (incluyendo el nombre del archivo) donde el proceso tenga permisos de escritura. Los cambios sólo se hacen efectivos para procesos que arranquen después del cambio.
Si tu objetivo es desactivar por completo la caché de módulos, puedes dirigir la ruta a un destino no escribible, como NUL en Windows o /dev/null en Linux. PowerShell intentará escribir la caché allí, no lo conseguirá, pero tampoco generará errores visibles en la sesión.
Complementando esto está la variable PSDisableModuleAnalysisCacheCleanup. Si la estableces a 1, desactiva las limpiezas automáticas que eliminan entradas de módulos que ya no existen, algo útil en escenarios específicos donde no interesa tocar esa caché.
Otras variables de entorno útiles para scripts y telemetría
Más allá de las específicas de PowerShell, hay un conjunto de variables de entorno del sistema que influyen directamente en cómo se ejecutan los scripts y cómo se comporta el terminal, especialmente en entornos multiplataforma.
La variable PATH determina por qué directorios buscar ejecutables, algo vital si vas a lanzar binarios externos desde tus scripts de PowerShell. En Windows los directorios se separan con ;, mientras que en Linux o macOS se usa :.
En Windows también existe PATHEXT, que lista las extensiones que se consideran ejecutables directamente. Si quieres que un lenguaje de scripting se ejecute en la misma consola (por ejemplo, archivos .py), deberás incluir la extensión aquí y registrarla en el sistema con herramientas como assoc y ftype desde CMD.
En plataformas no Windows, PowerShell se adapta a la convención XDG utilizando las variables XDG_CONFIG_HOME, XDG_DATA_HOME y XDG_CACHE_HOME para rutas de configuración, datos y caché, lo que facilita integrarse con el resto del sistema.
Para las características de salida a color y control del terminal, PowerShell 7.2 y posteriores respetan TERM y NO_COLOR. Según el valor de TERM se deshabilitan o ajustan secuencias ANSI, y si existe NO_COLOR, el estilo de salida se fuerza a texto plano sin color.
Logs y las salidas de tus scripts influyen en cómo se ven los logs y las salidas de tus scripts, algo que afecta tanto a la experiencia en consola como a la legibilidad de la telemetría capturada cuando rediriges salida a archivos.
Ejemplo práctico: Sophia Script y ajustes de privacidad y telemetría
Uno de los ejemplos más conocidos en la comunidad para tunear Windows 10 con PowerShell es Windows 10 Sophia Script, un conjunto de funciones orientadas a automatizar tareas de configuración, privacidad y desinstalación de componentes innecesarios.
Entre sus opciones, Sophia Script incluye la capacidad de ajustar la privacidad y la telemetría del sistema, desactivar tareas programadas de diagnóstico, desinstalar OneDrive, cambiar la ruta de %TEMP% o reubicar carpetas de usuario como Escritorio, Documentos, Descargas, Música, Imágenes o Vídeos mediante menús interactivos.
También ofrece funciones para desinstalar aplicaciones UWP para todas las cuentas respetando una lista de exclusiones configurable a través de formularios WPF, así como desactivar características de Windows o eliminar capacidades del sistema con asistentes visuales.
Otra parte interesante es que puede crear tareas en el Programador de tareas para limpieza periódica, ajustar el menú Inicio (anclando o desanclando elementos), manipular opciones de seguridad de Microsoft Defender como acceso controlado a carpetas o exclusiones, y refrescar iconos, variables de entorno y barra de tareas sin reiniciar el Explorador.
En definitiva, este tipo de script demuestra cómo, combinando PowerShell con configuraciones de telemetría, variables de entorno y automatización, se puede modelar por completo el comportamiento de un sistema Windows para adaptarlo a las políticas de una organización o a las preferencias personales.
Enviar telemetría desde PowerShell a Application Insights
Más allá de la telemetría nativa de PowerShell, muchas aplicaciones envían sus propios datos de monitorización a Azure Monitor Application Insights. A veces, sin embargo, abres Azure Portal y los gráficos aparecen vacíos o faltan registros clave.
Las causas típicas suelen ser errores de configuración del SDK o del agente de Application Insights, bloqueos de red hacia el punto de ingesta, limitación o descarte de telemetría en la canalización, incidencias puntuales de Log Analytics o problemas al consultar la API api.applicationinsights.io.
Un enfoque muy práctico para aislar el origen del problema consiste en enviar manualmente un único registro de telemetría de prueba desde PowerShell o desde curl. Si ese registro llega correctamente a la tabla de registros del recurso de Application Insights, sabes que gran parte de la canalización está funcionando.
Cuando pruebas desde la misma máquina o desde el mismo entorno donde corre tu aplicación (por ejemplo la VM o el App Service), además verificas que DNS, firewall, TLS y permisos no estén bloqueando el camino hasta la ingesta.
En escenarios donde el punto de ingesta está protegido con Microsoft Entra ID (antes Azure AD), debes asegurarte de que la aplicación o el script se autentican correctamente con el identificador de Entra; en caso contrario, la telemetría se rechazará aunque el resto de la instrumentación parezca correcta.
Script de PowerShell para probar telemetría de disponibilidad
Para comprobar que todo el circuito desde tu máquina hasta Application Insights funciona, puedes usar un script de PowerShell que envía un resultado de prueba de disponibilidad. Este tipo de telemetría es ideal porque no se somete a los mecanismos de muestreo de ingesta.
La idea es sencilla: proporcionas una cadena de conexión o una clave de instrumentación, el script la descompone para extraer el punto de ingesta y el InstrumentationKey, genera un JSON con un AvailabilityData de ejemplo y lo envía con Invoke-WebRequest al endpoint REST correspondiente.
Si sólo pasas la clave de instrumentación, el script construye una cadena de conexión con el endpoint global https://dc.services.visualstudio.com/. Si pasas la cadena de conexión completa, se usará el punto de ingesta regional definido en ella, y si pasas ambos, prevalece el definido en la cadena de conexión.
Durante la ejecución se establece un sello temporal en formato UTC ISO 8601, se rellena el cuerpo JSON con los datos de la prueba (duración, ubicación, mensaje, propiedades adicionales) y se lanza la petición POST. La respuesta HTTP 200 con itemsReceived igual a itemsAccepted indica que el punto de ingesta ha recibido y aceptado el registro.
Después, basta con entrar en la pestaña de Registros del recurso de Application Insights en Azure Portal, lanzar una consulta sobre el tipo correspondiente y comprobar que aparece ese registro de muestra. Si está, sabes que lo más probable es que el problema esté en el SDK o agente que usa tu aplicación real.
Probar telemetría con curl en Linux o Windows
Si el entorno desde el que quieres probar es Linux o macOS, o prefieres usar herramientas estándar en lugar de PowerShell, puedes hacer la misma prueba con curl enviando una petición POST con contenido JSON hacia el endpoint de Application Insights.
En estos casos creas un cuerpo JSON similar, con baseType igual a AvailabilityData, identificador de ejecución, nombre de la prueba, duración, indicador de éxito, ubicación, mensaje y propiedades opcionales. Recuerda ajustar siempre el campo time a una marca reciente, ya que la ingesta de Application Insights rechaza datos de más de 48 horas de antigüedad.
Para Linux o macOS, el comando suele incluir cabecera Content-Type: application/json, el método POST, el JSON en línea y la URL del punto de ingesta (por ejemplo https://dc.applicationinsights.azure.com/v2.1/track). En Windows, la sintaxis cambia ligeramente porque hay que escapar comillas en el JSON al pasarlo como argumento.
Una vez hecho esto, de nuevo revisas la respuesta HTTP y, si es correcta, vas a los registros de Application Insights para validar que tu telemetría de prueba ya está almacenada y consultable igual que ocurría con el script de PowerShell.
Este enfoque te permite descartar de un plumazo problemas de configuración de SDK, centrándote en red, DNS, TLS, autenticación del endpoint o políticas de muestreo según los síntomas que veas en la respuesta.
Script de PowerShell para probar telemetría de solicitudes
Además de las pruebas de disponibilidad, a menudo te interesa comprobar la telemetría de solicitudes HTTP, especialmente cuando tus dashboards se basan en las métricas de peticiones entrantes de una API o de una aplicación web.
Para ello puedes usar otro script de PowerShell muy parecido al de disponibilidad, pero esta vez generando un JSON con baseType igual a RequestData. Se suelen incluir campos como el identificador de la solicitud, el nombre de la operación (por ejemplo GET /ruta/prueba/), la hora de inicio, la duración, la URL, el código de respuesta y el método HTTP.
El script sigue la misma mecánica: descompone la cadena de conexión o la clave de instrumentación, construye la URL de ingesta (v2/track), calcula la hora actual en UTC, monta el JSON y ejecuta Invoke-WebRequest con método POST. Si obtienes código 200 y el contenido esperado en la respuesta, la parte de ingesta está funcionando.
Aquí entra un matiz importante: las solicitudes sí pueden verse afectadas por mecanismos de muestreo de ingesta en el lado servidor. Si has configurado muestreo para reducir el volumen de datos, es posible que no veas todas las peticiones de prueba salvo que lo desactives temporalmente o ajustes los porcentajes.
Una vez que tu registro de prueba aparece en Application Insights, el siguiente paso es centrarte en cómo está instrumentado tu código (SDK, filtros, muestreo, exclusiones, etc.) para averiguar por qué las peticiones reales no se registran con la misma facilidad que las pruebas manuales.
Problemas habituales de SSL/TLS al enviar telemetría
No es raro que, al lanzar estos scripts de prueba, te encuentres con errores relacionados con SSL o TLS durante el handshake, sobre todo en entornos restringidos o cuando hay proxies corporativos inspeccionando el tráfico.
En muchos servicios de Azure, incluido Application Insights, se exige como mínimo TLS 1.2 y determinados conjuntos de cifrado para aceptar conexiones. Si el sistema o la aplicación siguen usando TLS 1.0 o 1.1 por defecto, la conexión puede fallar incluso antes de que el servidor procese el JSON.
PowerShell permite forzar los protocolos admitidos estableciendo [System.Net.ServicePointManager]::SecurityProtocol antes de ejecutar Invoke-WebRequest. Puedes probar SSL3, TLS, TLS 1.1, TLS 1.2 o TLS 1.3 para ver qué funciona en tu entorno, aunque en producción es recomendable ajustarse a lo que marcan las guías de seguridad.
Si además tienes proxies o firewalls que realizan inspección SSL, puede que la validación de certificados falle. Existe la opción de deshabilitar la comprobación del certificado creando una política personalizada que siempre devuelva true, pero es algo que sólo deberías usar de forma diagnóstica y nunca como solución permanente.
Cuando necesitas cambiar las versiones por defecto de TLS usadas por aplicaciones .NET en Windows, lo adecuado es seguir las recomendaciones oficiales de configuración de TLS en el Registro y en el propio framework, en lugar de introducir hacks dispersos en los scripts.
Errores de autenticación con Microsoft Entra ID en Application Insights
Si tu recurso de Application Insights está configurado para aceptar sólo autenticación mediante Microsoft Entra ID (antes Azure AD), la telemetría enviada con clave de instrumentación sin credenciales válidas será rechazada con errores HTTP claros.
Un código HTTP 400 con mensaje indicando que la autenticación clásica no se admite suele significar que el recurso está marcado como only Entra ID, pero el SDK o el script están llamando a la API antigua. En ese caso hay que revisar la configuración del SDK y la cadena de conexión utilizada.
Un error HTTP 401 «Se requiere autorización» apunta a que el SDK sí está intentando usar Entra ID pero no puede adquirir un token válido; puede ser porque la identidad administrada no está habilitada, porque faltan credenciales o por problemas con Azure Identity en el cliente.
El código HTTP 403 «No autorizado» indica que se ha obtenido un token, pero la identidad utilizada no tiene permisos suficientes sobre el recurso de Application Insights o la suscripción. En este caso hay que revisar el control de acceso y asegurarse de que la identidad tiene, como mínimo, rol de Publicador de Métricas de Supervisión.
Dependiendo del lenguaje (Node.js, Python, etc.), conviene activar los registros internos del SDK o los logs de Azure Identity para ver exactamente qué etapa de la autenticación está fallando y con qué mensaje.
Telemetría, scripts y buenas prácticas en entornos reales
Todo lo anterior se traduce en que, cuando quieres añadir telemetría a scripts en PowerShell, tienes dos planos que manejar: por un lado la telemetría automática del propio motor y, por otro, la telemetría explícita que envías tú a sistemas como Application Insights u otros destinos.
En el plano nativo, es clave saber cómo funciona POWERSHELL_TELEMETRY_OPTOUT, qué datos se recogen al iniciar y durante la sesión, y cómo se usan variables como POWERSHELL_DISTRIBUTION_CHANNEL o POWERSHELL_UPDATECHECK para controlar comportamiento global.
En el plano de tus scripts, puedes aprovechar las variables de entorno, el proveedor Env:, los métodos de System.Environment y herramientas como Sophia Script para ajustar privacidad, rutas, caché y políticas de ejecución, al tiempo que instrumentas tus procesos para enviar métricas y logs a servicios externos.
Combinando pruebas manuales de telemetría con PowerShell y curl, supervisando protocolos TLS y ajustando bien la autenticación con Microsoft Entra ID, es posible tener un pipeline de telemetría robusto y fiable incluso en entornos corporativos muy controlados.
Cuando entiendes cómo se orquesta toda esta capa de telemetría, desde las variables de entorno hasta la ingesta en la nube, resulta mucho más sencillo decidir qué palancas tocar si un día tus gráficos en Azure o tus logs dejan misteriosamente de actualizarse.
Redactor apasionado del mundo de los bytes y la tecnología en general. Me encanta compartir mis conocimientos a través de la escritura, y eso es lo que haré en este blog, mostrarte todo lo más interesante sobre gadgets, software, hardware, tendencias tecnológicas, y más. Mi objetivo es ayudarte a navegar por el mundo digital de forma sencilla y entretenida.