monitor de puertos.ps1
Este script en PowerShell crea una aplicación gráfica que permite a los administradores de sistemas monitorear conexiones TCP/IP a un host y puerto específicos, registrando los resultados en un archivo de log. Además, proporciona una interfaz de usuario intuitiva para visualizar y filtrar resultados.
Funciones principales
Voy a describir las funciones principales que componene este script
Función CheckConnection:
function CheckConeccion { param($targetHost, $port, $logFile) while ($true) { $startTime = [DateTime]::Now try { $tcpClient = New-Object System.Net.Sockets.TcpClient $tcpClient.ReceiveTimeout = 320 $tcpClient.SendTimeout = 320 $tcpClient.Connect($targetHost, $port) if ($tcpClient.Connected) { $endTime = [DateTime]::Now $responseTime = ($endTime - $startTime).TotalMilliseconds $logMessage = "[$(Get-Date -Format "HH:mm:ss")] Conexión exitosa al puerto $port en $targetHost - Tiempo de respuesta: $responseTime ms" Add-Content -Path $logFile -Value $logMessage $tcpClient.Close() } } catch [System.Net.Sockets.SocketException] { $logMessage = "[$(Get-Date -Format "HH:mm:ss")] No se pudo establecer la conexión al puerto $port en $targetHost (error de socket)" Add-Content -Path $logFile -Value $logMessage } catch { $logMessage = "[$(Get-Date -Format "HH:mm:ss")] No se pudo establecer la conexión al puerto $port en $targetHost (error desconocido)" Add-Content -Path $logFile -Value $logMessage } finally { if ($null -ne $tcpClient) { $tcpClient.Close() $tcpClient = $null } } Start-Sleep -Seconds 2 if ($script:stopFlag) { break } } }
¡Copiado!
$timer.Add_Tick:
$timer.Add_Tick({ if ($null -ne $Global:script:logJob) { $output = Receive-Job $Global:script:logJob if ($output) { $SalidaResultados.SuspendLayout() $SalidaResultados.SelectionStart = $SalidaResultados.TextLength $SalidaResultados.SelectionLength = 0 foreach ($line in $output.Split("`n")) { $line = $line.Trim() if ($line -match "No se pudo establecer la conexión") { $SalidaResultados.SelectionColor = [System.Drawing.Color]::Red } elseif ($line -match "Conexión exitosa") { $SalidaResultados.SelectionColor = [System.Drawing.Color]::Green } else { $SalidaResultados.SelectionColor = $SalidaResultados.ForeColor } $SalidaResultados.AppendText($line + "`r`n") } $SalidaResultados.ScrollToCaret() $SalidaResultados.ResumeLayout() } } })
¡Copiado!
- Verifica si el job de log está activo:
- Comprueba si $Global:script:logJob no es nulo.
- Recibe la salida del job de log:
- Usa Receive-Job para obtener la salida del job de log.
- Si hay salida disponible:
- Suspende el diseño del control $SalidaResultados para mejorar el rendimiento mientras se actualiza el contenido.
- Establece el punto de inicio de la selección en la longitud actual del texto del control.
- Establece la longitud de la selección en 0 para asegurarse de que no haya texto seleccionado previamente.
- Procesa cada línea de la salida:
- Divide la salida en líneas usando Split("n")`.
- Para cada línea, elimina los espacios en blanco al principio y al final con Trim().
- Dependiendo del contenido de la línea, establece el color de selección:
- Si la línea contiene "No se pudo establecer la conexión", el color de selección se establece en rojo ([System.Drawing.Color]::Red).
- Si la línea contiene "Conexión exitosa", el color de selección se establece en verde ([System.Drawing.Color]::Green).
- Si no coincide con ninguna de las condiciones anteriores, el color de selección se establece en el color de texto predeterminado del control ($SalidaResultados.ForeColor).
- Añade la línea al control de salida usando AppendText() y añade un retorno de carro y nueva línea (\r\n).
- Desplaza el cursor al final del texto:
- Llama a ScrollToCaret() para asegurarse de que el control de salida se desplace automáticamente hasta la última línea añadida.
- Llama a ScrollToCaret() para asegurarse de que el control de salida se desplace automáticamente hasta la última línea añadida.
- Llama a ResumeLayout() para reanudar el diseño del control después de haber añadido todas las líneas.
Funcion ReadLogFile:
#actualiza la interfaz gráfica con nuevas líneas del log. function ReadLogFile { param($logFile) $lastPosition = 0 while ($true) { if (Test-Path $logFile) { $fileContent = Get-Content $logFile -Raw if ($fileContent.Length -gt $lastPosition) { $newContent = $fileContent.Substring($lastPosition) $lastPosition = $fileContent.Length Write-Output $newContent } } Start-Sleep -Milliseconds 500 if ($script:stopFlag) { break } } }
¡Copiado!
Funcion $startButton.Add_Click():
$startButton.Add_Click({ # Validar entradas if ([string]::IsNullOrWhiteSpace($TBObjetivo.Text) -or [string]::IsNullOrWhiteSpace($TBPuerto.Text)) { [System.Windows.Forms.MessageBox]::Show("Debe ingresar una IP y un puerto válidos.", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error) return } $script:stopFlag = $false $targetHost = $TBObjetivo.Text $port = [int]$TBPuerto.Text $logFile = $TBArchivo.Text if($targetHost -eq ""){} # Limpiar el archivo de log antes de comenzar Clear-Content -Path $logFile -ErrorAction SilentlyContinue $Global:script:job = Start-Job -ScriptBlock ${function:CheckConeccion} -ArgumentList $targetHost, $port, $logFile $Global:script:logJob = Start-Job -ScriptBlock ${function:ReadLogFile} -ArgumentList $logFile $startButton.Enabled = $false $BDetener.Enabled = $true # Limpiar la salida en la GUI $SalidaResultados.Clear() $script:allLines = @() })
¡Copiado!
- Verifica si los campos de texto $TBObjetivo (para la IP) y $TBPuerto (para el puerto) están vacíos o contienen solo espacios en blanco.
- Si alguno de los campos está vacío, muestra un mensaje de error y termina la ejecución de la función.
- Establece $script:stopFlag en false, lo que probablemente indica que un proceso no debe detenerse.
- Asigna los valores de los campos de texto a las variables $targetHost, $port y $logFile.
- Limpia el contenido del archivo de log especificado en $logFile antes de comenzar, ignorando cualquier error que pueda ocurrir si el archivo no existe.
- Inicia un job en segundo plano para ejecutar la función CheckConeccion con los argumentos $targetHost, $port y $logFile.
- Inicia otro job en segundo plano para ejecutar la función ReadLogFile con el argumento $logFile.
- Deshabilita el botón $startButton para evitar múltiples clics.
- Habilita el botón $BDetener para permitir detener el proceso.
- Limpia el contenido del control $SalidaResultados en la interfaz de usuario.
- Inicializa $script:allLines como un array vacío, probablemente para almacenar líneas de salida o log.
Funcion $BDetener.Add_Click():
$BDetener.Add_Click({ $script:stopFlag = $true if ($null -ne $Global:script:job) { Stop-Job $Global:script:job Remove-Job $Global:script:job $Global:script:job = $null } if ($null -ne $Global:script:logJob) { Stop-Job $Global:script:logJob Remove-Job $Global:script:logJob $Global:script:logJob = $null } $startButton.Enabled = $true $BDetener.Enabled = $false $BFiltrarRojo.Enabled = $true $BMostrarTodo.Enabled = $true })
¡Copiado!
- Cambia $script:stopFlag a true, lo que probablemente indica a otros procesos o scripts que deben detenerse.
- Verifica si $Global:script:job no es nulo.
- Si el job existe, lo detiene usando Stop-Job.
- Luego, elimina el job con Remove-Job.
- Finalmente, establece $Global:script:job a null para limpiar la referencia.
- Verifica si $Global:script:logJob no es nulo.
- Si el job existe, lo detiene usando Stop-Job.
- Luego, elimina el job con Remove-Job.
- Finalmente, establece $Global:script:logJob a null para limpiar la referencia.
- Habilita el botón $startButton para permitir iniciar el proceso nuevamente.
- Deshabilita el botón $BDetener para evitar múltiples clics mientras no hay jobs en ejecución.
Funcion $BDetener.Add_Click():
$BFiltrarRojo.Add_Click({ $SalidaResultados.Clear() $logContent = Get-Content $TBArchivo.Text foreach ($line in $logContent) { if ($line -match "No se pudo establecer la conexión") { $SalidaResultados.SelectionStart = $SalidaResultados.TextLength $SalidaResultados.SelectionLength = 0 $SalidaResultados.SelectionColor = [System.Drawing.Color]::Red $SalidaResultados.AppendText("$line`r`n") } } $SalidaResultados.ScrollToCaret() })
¡Copiado!
- Llama al método Clear() para vaciar cualquier texto existente en el control de salida.
- Utiliza un bucle foreach para recorrer cada línea en el array $script:allLines.
- Verifica si la línea contiene la cadena "No se pudo establecer la conexión" usando el operador -match.
- Habilita el botón $startButton para permitir iniciar el proceso nuevamente.
- Si la línea coincide con el filtro, ajusta las propiedades de selección del control $SalidaResultados:
- SelectionStart se establece en la longitud actual del texto, para añadir el nuevo texto al final.
- SelectionLength se establece en 0, para que no haya selección previa.
- SelectionColor se establece en rojo ([System.Drawing.Color]::Red).
- Añade la línea filtrada al control de salida usando AppendText() y añade un retorno de carro y nueva línea (\r\n).
- Llama a ScrollToCaret() para asegurarse de que el control de salida se desplace automáticamente hasta la última línea añadida.
Funcion $BMostrarTodo.Add_Click():
$BMostrarTodo.Add_Click({ $SalidaResultados.Clear() $logContent = Get-Content $TBArchivo.Text foreach ($line in $logContent) { $SalidaResultados.SelectionStart = $SalidaResultados.TextLength $SalidaResultados.SelectionLength = 0 if ($line -match "No se pudo establecer la conexión") { $SalidaResultados.SelectionColor = [System.Drawing.Color]::Red } elseif ($line -match "Conexión exitosa") { $SalidaResultados.SelectionColor = [System.Drawing.Color]::Green } else { $SalidaResultados.SelectionColor = $SalidaResultados.ForeColor } $SalidaResultados.AppendText("$line`r`n") } $SalidaResultados.ScrollToCaret() })
¡Copiado!
- Llama al método Clear() para vaciar cualquier texto existente en el control de salida.
- Utiliza un bucle foreach para recorrer cada línea en el array $script:allLines.
- Ajusta las propiedades de selección del control $SalidaResultados:
- SelectionStart se establece en la longitud actual del texto, para añadir el nuevo texto al final.
- SelectionLength se establece en 0, para que no haya selección previa.
- Dependiendo del contenido de la línea, establece el color de selección:
- Si la línea contiene "No se pudo establecer la conexión", el color de selección se establece en rojo ([System.Drawing.Color]::Red).
- Si la línea contiene "Conexión exitosa", el color de selección se establece en verde ([System.Drawing.Color]::Green).
- Para cualquier otra línea, el color de selección se establece en el color de texto predeterminado del control ($SalidaResultados.ForeColor).
- Añade la línea al control de salida usando AppendText() y añade un retorno de carro y nueva línea (\r\n).
- Llama a ScrollToCaret() para asegurarse de que el control de salida se desplace automáticamente hasta la última línea añadida.
Codigo completo:
<# AUTOR: Vladimir Campos REQUISITOS Windows con PowerShell: El script está escrito en PowerShell, por lo que necesitas un sistema operativo Windows con PowerShell instalado. Windows 10 y 11 ya vienen con PowerShell preinstalado. PowerShell 5.1 o superior: Aunque debería funcionar en versiones anteriores, se recomienda usar PowerShell 5.1 o PowerShell 7 para una mejor compatibilidad y rendimiento. #> #Creado por Vladimir Campos Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing $timer = New-Object System.Windows.Forms.Timer $timer.Interval = 1000 $ImagenBytes = [Convert]::FromBase64String('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') $pictureBox.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::StretchImage $LPNG = "iVBORw0KGgoAAAANSUhEUgAAAMgAAAAuCAYAAABtRVYBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAGq2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNy4xLWMwMDAgNzkuYTg3MzFiOSwgMjAyMS8wOS8wOS0wMDozNzozOCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6ODIxNzExM2UtNmZjNS0zNjQyLWIzMDctOGEzNDM3ZmY2NWRkIiB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6Mzk4YTY5ZDMtYzljYS0zYzRhLWE4YTctZjhmYmM2MmYxOWU0IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjEzNDk3YzZlLWVjNTgtMzM0YS1hZWY2LWFhMWFlODRjNGE0YiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjMuMCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDI0LTExLTIwVDEzOjU2OjExLTA2OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyNC0xMS0yMFQxNzo1MTo0My0wNjowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyNC0xMS0yMFQxNzo1MTo0My0wNjowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4MjE3MTEzZS02ZmM1LTM2NDItYjMwNy04YTM0MzdmZjY1ZGQiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6ODIxNzExM2UtNmZjNS0zNjQyLWIzMDctOGEzNDM3ZmY2NWRkIi8+IDx4bXBNTTpIaXN0b3J5PiA8cmRmOlNlcT4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjQ4OTAyZGY4LTNjNzQtNzc0MC05YjM1LTBjYjkyODRjYTgyMCIgc3RFdnQ6d2hlbj0iMjAyNC0xMS0yMFQxNzo0NzoyMi0wNjowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIzLjAgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoxMzQ5N2M2ZS1lYzU4LTMzNGEtYWVmNi1hYTFhZTg0YzRhNGIiIHN0RXZ0OndoZW49IjIwMjQtMTEtMjBUMTc6NTE6NDMtMDY6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMy4wIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz55i9rdAAAuNUlEQVR4nO2deXyU1fnovzOTmclkZ0IC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" $lenbytes = [Convert]::FromBase64String($LPNG) $lenmemoria = New-Object System.IO.MemoryStream $lenmemoria.Write($lenbytes, 0, $lenbytes.Length) $lenmemoria.Position = 0 $imagenl = [System.Drawing.Image]::FromStream($lenmemoria, $true) $ms = New-Object System.IO.MemoryStream(,$ImagenBytes) $image = [System.Drawing.Image]::FromStream($ms) $bitmap = New-Object System.Drawing.Bitmap($image) $iconHandle = $bitmap.GetHicon() $icon = [System.Drawing.Icon]::FromHandle($iconHandle) $image.Dispose() $bitmap.Dispose() #monitorea un puerto y registra resultados function CheckConeccion { param($targetHost, $port, $logFile) while ($true) { $startTime = [DateTime]::Now try { $tcpClient = New-Object System.Net.Sockets.TcpClient $tcpClient.ReceiveTimeout = 320 $tcpClient.SendTimeout = 320 $tcpClient.Connect($targetHost, $port) if ($tcpClient.Connected) { $endTime = [DateTime]::Now $responseTime = ($endTime - $startTime).TotalMilliseconds $logMessage = "[$(Get-Date -Format "HH:mm:ss")] Conexión exitosa al puerto $port en $targetHost - Tiempo de respuesta: $responseTime ms" Add-Content -Path $logFile -Value $logMessage $tcpClient.Close() } } catch [System.Net.Sockets.SocketException] { $logMessage = "[$(Get-Date -Format "HH:mm:ss")] No se pudo establecer la conexión al puerto $port en $targetHost (error de socket)" Add-Content -Path $logFile -Value $logMessage } catch { $logMessage = "[$(Get-Date -Format "HH:mm:ss")] No se pudo establecer la conexión al puerto $port en $targetHost (error desconocido)" Add-Content -Path $logFile -Value $logMessage } finally { if ($null -ne $tcpClient) { $tcpClient.Close() $tcpClient = $null } } Start-Sleep -Seconds 2 if ($script:stopFlag) { break } } } #actualiza la interfaz gráfica con nuevas líneas del log. function ReadLogFile { param($logFile) $lastPosition = 0 while ($true) { if (Test-Path $logFile) { $fileContent = Get-Content $logFile -Raw if ($fileContent.Length -gt $lastPosition) { $newContent = $fileContent.Substring($lastPosition) $lastPosition = $fileContent.Length Write-Output $newContent } } Start-Sleep -Milliseconds 500 if ($script:stopFlag) { break } } } $Formulario = New-Object System.Windows.Forms.Form $Formulario.Text = "Monitor de Conexión" $Formulario.Size = New-Object System.Drawing.Size(800,600) $Formulario.Icon=$icon $Formulario.StartPosition = "CenterScreen" $Formulario.FormBorderStyle = 'FixedDialog' $Formulario.ControlBox = $false $pictureBox = New-Object System.Windows.Forms.PictureBox $pictureBox.Size = New-Object System.Drawing.Size(200, 40) $pictureBox.Location = New-Object System.Drawing.Point(10, 10) $pictureBox.Image = $imagenl $Formulario.Controls.Add($pictureBox) $LObjetivo = New-Object System.Windows.Forms.Label $LObjetivo.Location = New-Object System.Drawing.Point(240,23) $LObjetivo.Size = New-Object System.Drawing.Size(20,20) $LObjetivo.Text = "IP:" $Formulario.Controls.Add($LObjetivo) $TBObjetivo = New-Object System.Windows.Forms.TextBox $TBObjetivo.Location = New-Object System.Drawing.Point(260,20) $TBObjetivo.Size = New-Object System.Drawing.Size(150,20) $Formulario.Controls.Add($TBObjetivo) $LPuerto = New-Object System.Windows.Forms.Label $LPuerto.Location = New-Object System.Drawing.Point(430,20) $LPuerto.Size = New-Object System.Drawing.Size(45,23) $LPuerto.Text = "Puerto:" $Formulario.Controls.Add($LPuerto) $TBPuerto = New-Object System.Windows.Forms.TextBox $TBPuerto.Location = New-Object System.Drawing.Point(480,20) $TBPuerto.Size = New-Object System.Drawing.Size(50,20) $Formulario.Controls.Add($TBPuerto) $LArchivo = New-Object System.Windows.Forms.Label $LArchivo.Location = New-Object System.Drawing.Point(175,53) $LArchivo.Size = New-Object System.Drawing.Size(85,20) $LArchivo.Text = "Archivo de Log:" $Formulario.Controls.Add($LArchivo) $TBArchivo = New-Object System.Windows.Forms.TextBox $TBArchivo.Location = New-Object System.Drawing.Point(260,50) $TBArchivo.Size = New-Object System.Drawing.Size(270,20) $TBArchivo.Text = "error.log" $Formulario.Controls.Add($TBArchivo) $startButton = New-Object System.Windows.Forms.Button $startButton.Location = New-Object System.Drawing.Point(565,20) $startButton.Size = New-Object System.Drawing.Size(75,23) $startButton.Text = "Iniciar" $Formulario.Controls.Add($startButton) $BDetener = New-Object System.Windows.Forms.Button $BDetener.Location = New-Object System.Drawing.Point(665,20) $BDetener.Size = New-Object System.Drawing.Size(75,23) $BDetener.Text = "Detener" $BDetener.Enabled = $false $Formulario.Controls.Add($BDetener) $SalidaResultados = New-Object System.Windows.Forms.RichTextBox $SalidaResultados.Location = New-Object System.Drawing.Point(10,80) $SalidaResultados.Size = New-Object System.Drawing.Size(760,440) $SalidaResultados.MultiLine = $true $SalidaResultados.ScrollBars = "Vertical" $Formulario.Controls.Add($SalidaResultados) $BFiltrarRojo = New-Object System.Windows.Forms.Button $BFiltrarRojo.Location = New-Object System.Drawing.Point(10, 530) $BFiltrarRojo.Size = New-Object System.Drawing.Size(120, 23) $BFiltrarRojo.Text = "Mostrar solo errores" $BFiltrarRojo.Enabled = $false $Formulario.Controls.Add($BFiltrarRojo) $BMostrarTodo = New-Object System.Windows.Forms.Button $BMostrarTodo.Location = New-Object System.Drawing.Point(140, 530) $BMostrarTodo.Size = New-Object System.Drawing.Size(120, 23) $BMostrarTodo.Text = "Mostrar todo" $BMostrarTodo.Enabled = $false $Formulario.Controls.Add($BMostrarTodo) $BSalir = New-Object System.Windows.Forms.Button $BSalir.Location = New-Object System.Drawing.Point(665, 50) $BSalir.Size = New-Object System.Drawing.Size(75, 23) $BSalir.Text = "Salir" $Formulario.Controls.Add($BSalir) $BSalir.Add_Click({ $Formulario.Close() }) $script:stopFlag = $false $Global:script:job = $null $Global:script:logJob = $null $script:allLines = @() $startButton.Add_Click({ # Validar entradas if ([string]::IsNullOrWhiteSpace($TBObjetivo.Text) -or [string]::IsNullOrWhiteSpace($TBPuerto.Text)) { [System.Windows.Forms.MessageBox]::Show("Debe ingresar una IP y un puerto válidos.", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error) return } $script:stopFlag = $false $targetHost = $TBObjetivo.Text $port = [int]$TBPuerto.Text $logFile = $TBArchivo.Text if($targetHost -eq ""){} # Limpiar el archivo de log antes de comenzar Clear-Content -Path $logFile -ErrorAction SilentlyContinue $Global:script:job = Start-Job -ScriptBlock ${function:CheckConeccion} -ArgumentList $targetHost, $port, $logFile $Global:script:logJob = Start-Job -ScriptBlock ${function:ReadLogFile} -ArgumentList $logFile $startButton.Enabled = $false $BDetener.Enabled = $true # Limpiar la salida en la GUI $SalidaResultados.Clear() $script:allLines = @() }) $BDetener.Add_Click({ $script:stopFlag = $true if ($null -ne $Global:script:job) { Stop-Job $Global:script:job Remove-Job $Global:script:job $Global:script:job = $null } if ($null -ne $Global:script:logJob) { Stop-Job $Global:script:logJob Remove-Job $Global:script:logJob $Global:script:logJob = $null } $startButton.Enabled = $true $BDetener.Enabled = $false $BFiltrarRojo.Enabled = $true $BMostrarTodo.Enabled = $true }) $BFiltrarRojo.Add_Click({ $SalidaResultados.Clear() $logContent = Get-Content $TBArchivo.Text foreach ($line in $logContent) { if ($line -match "No se pudo establecer la conexión") { $SalidaResultados.SelectionStart = $SalidaResultados.TextLength $SalidaResultados.SelectionLength = 0 $SalidaResultados.SelectionColor = [System.Drawing.Color]::Red $SalidaResultados.AppendText("$line`r`n") } } $SalidaResultados.ScrollToCaret() }) $BMostrarTodo.Add_Click({ $SalidaResultados.Clear() $logContent = Get-Content $TBArchivo.Text foreach ($line in $logContent) { $SalidaResultados.SelectionStart = $SalidaResultados.TextLength $SalidaResultados.SelectionLength = 0 if ($line -match "No se pudo establecer la conexión") { $SalidaResultados.SelectionColor = [System.Drawing.Color]::Red } elseif ($line -match "Conexión exitosa") { $SalidaResultados.SelectionColor = [System.Drawing.Color]::Green } else { $SalidaResultados.SelectionColor = $SalidaResultados.ForeColor } $SalidaResultados.AppendText("$line`r`n") } $SalidaResultados.ScrollToCaret() }) $timer.Add_Tick({ if ($null -ne $Global:script:logJob) { $output = Receive-Job $Global:script:logJob if ($output) { $SalidaResultados.SuspendLayout() $SalidaResultados.SelectionStart = $SalidaResultados.TextLength $SalidaResultados.SelectionLength = 0 foreach ($line in $output.Split("`n")) { $line = $line.Trim() if ($line -match "No se pudo establecer la conexión") { $SalidaResultados.SelectionColor = [System.Drawing.Color]::Red } elseif ($line -match "Conexión exitosa") { $SalidaResultados.SelectionColor = [System.Drawing.Color]::Green } else { $SalidaResultados.SelectionColor = $SalidaResultados.ForeColor } $SalidaResultados.AppendText($line + "`r`n") } $SalidaResultados.ScrollToCaret() $SalidaResultados.ResumeLayout() } } }) $timer.Start() $Formulario.ShowDialog( ) if ($null -ne $Global:script:job) { Stop-Job $Global:script:job Remove-Job $Global:script:job } if ($null -ne $Global:script:logJob) { Stop-Job $Global:script:logJob Remove-Job $Global:script:logJob }
¡Copiado!