¿Existen herramientas para tomar resultados basados en texto y canalizarlos a un objeto dinámico que pueda consultarse como columnas?
Específicamente, estoy invocando...
query session /server:MYSERVER
.. que está dando salida ..
SESSIONNAME USERNAME ID STATE TYPE DEVICE
services 0 Disc
console Jon 1 Active
Esta es mi primera tarea en una función de DevOps, actuar sobre este resultado en función de las condiciones de las columnas, pero después de varios intentos de canalizar hacia foreach, etc., me di cuenta de que son solo varias líneas de cadenas.
Lo que esperaba era algo como...
query session /server:MYSERVER | foreach `
{ `
if ($_.Username -eq "Jon") `
{`
custom-action $_.ID `
} `
}
(Tenga en cuenta que no necesariamente necesito evaluar el nombre de usuario, o no solo el nombre de usuario; solo lo hago en este ejemplo).
Obviamente esto no funcionará porque esto...
query session /server:192.168.1.103 | foreach { echo $_.GetType() }
.. genera esto ..
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
True True String System.Object
True True String System.Object
La única solución que encontré es extraer manualmente las columnas usando String.Substring(). Esperaba que hubiera herramientas de PowerShell que automatizaran esto.
[[Esto es un ejemplo,]] pero algunas columnas están en blanco y las columnas de ancho fijo no tienen el mismo ancho entre sí, por lo que analizar esto sería mucho más manual que los ejemplos allí. Esperaba que las actualizaciones de la versión de Powershell tuvieran mejores herramientas, ¿quizás?
Usando Windows Server 2012 R2 (que tiene PowerShell 4).
Respuesta1
No hay nada incorporado.
Sin embargo, no debería ser demasiado difícil crear una ayuda (en un módulo para una fácil reutilización, por supuesto) que tome una definición de cada columna (por ejemplo, nombre, posición inicial, longitud, tipo,...; o tal vez criterios alternativos para separe las columnas si las longitudes no se pueden predeterminar) y crea un objeto personalizado.
Respuesta2
Muchas de estas utilidades anteriores a PowerShell consultan varias API de Windows subyacentes, como WMI. Antes de profundizar en el análisis de texto, intentaría encontrar de dónde obtiene la información la utilidad y comenzar desde allí. Para su caso particular, no me sorprendería si realmente estuviera consultando la clase WMI Win32_LogonSession, que puede enumerar fácilmente usando PowerShell y recuperar objetos formateados correctamente. Es posible que este enfoque no funcione en todas las situaciones, pero al menos sería un buen punto de partida.
$users = get-wmiobject -query "Select * from Win32_LogonSession"
Con un poco de búsqueda en Google, parece una función prometedora para lo que necesitas: función get-loggedonuser
Respuesta3
Este es un comentario para la respuesta de Richard.
Esto es lo que se me ocurrió. Uno buscaría{} en todas las líneas (excepto la primera línea, que es $head) y pasaría a esta función.
Function ParseFixedWidthCols($head,$line) {
$colnamematches = $head | select-string "(\s*\w+\b\s*)" -allmatches | foreach { $_.matches }
$cols = @()
for ($ci=0; $ci -lt $colnamematches.Count; $ci++) {
$col = $colnamematches[$ci].Value
$cols += $col
}
$col = $cols[0]
$ret = New-Object PSObject
$cc = 0
for ($ci=0; $ci -lt $cols.Count; $ci++) {
$value = $line.Substring($cc, $cols[$ci].Length)
$ret | Add-Member -MemberType NoteProperty -name $cols[$ci].Trim() -value $value.Trim()
$cc += $cols[$ci].Length
}
return ret;
}