#Requires -RunAsAdministrator $ErrorActionPreference = 'Stop' $Base = 'https://l2.penwin.cloud' $Token = if ($env:NETPROBE_TOKEN) { $env:NETPROBE_TOKEN } else { '' } $Site = if ($env:NETPROBE_SITE) { $env:NETPROBE_SITE } else { if ($args.Count -ge 1) { $args[0] } else { $null } } $Dur = if ($env:NETPROBE_DURATION) { $env:NETPROBE_DURATION } else { '5m' } $Iface = $env:NETPROBE_IFACE $PcapMsiURL = if ($env:PCAP_MSI_URL) { $env:PCAP_MSI_URL } else { 'https://www.win10pcap.org/download/Win10Pcap-v10.2-5002.msi' } $InstallDir = Join-Path $env:LOCALAPPDATA 'netprobe' New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null $Bin = Join-Path $InstallDir 'netprobe.exe' Write-Host "[*] downloading netprobe.exe to $Bin" [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Invoke-WebRequest -UseBasicParsing -Uri "$Base/install/netprobe-windows-amd64.exe" -OutFile $Bin $wpcap = Join-Path $env:WINDIR 'System32\wpcap.dll' $needPcap = -not (Test-Path $wpcap) if ($needPcap) { Write-Host "[*] Win10Pcap no detectado — descargando $PcapMsiURL" $PcapMsi = Join-Path $env:TEMP 'win10pcap.msi' try { Invoke-WebRequest -UseBasicParsing -Uri $PcapMsiURL -OutFile $PcapMsi } catch { Write-Warning "No pude descargar Win10Pcap ($_)" Write-Host "Instálalo manualmente: https://www.win10pcap.org/" exit 1 } Write-Host "[*] instalando Win10Pcap (silencioso)..." $p = Start-Process -FilePath 'msiexec.exe' -ArgumentList @('/i', $PcapMsi, 'ALLUSERS=1', '/qn', '/norestart') -Wait -PassThru Remove-Item $PcapMsi -Force -ErrorAction SilentlyContinue if ($p.ExitCode -ne 0 -and $p.ExitCode -ne 3010) { Write-Warning "Win10Pcap installer salió con código $($p.ExitCode)" exit $p.ExitCode } if (-not (Test-Path $wpcap)) { Write-Warning "Win10Pcap instalado pero wpcap.dll no encontrado" exit 1 } Write-Host "[*] Win10Pcap instalado OK" } $UserPath = [Environment]::GetEnvironmentVariable('Path','User') if ($UserPath -notlike "*$InstallDir*") { [Environment]::SetEnvironmentVariable('Path', "$UserPath;$InstallDir", 'User') $env:Path = "$env:Path;$InstallDir" Write-Host "[*] $InstallDir añadido al PATH del usuario" } & $Bin --version if (-not $Site) { Write-Host "" Write-Host "Instalación completa. Para lanzar un discover:" Write-Host " netprobe interfaces" Write-Host " netprobe discover --iface --duration 5m --site --output C:\temp\np" Write-Host " netprobe upload --input C:\temp\np --server $Base --site " exit 0 } if (-not $Iface) { # Try native PS first: default route → adapter GUID → NPF device try { $route = Get-NetRoute -DestinationPrefix '0.0.0.0/0' -ErrorAction Stop | Sort-Object RouteMetric | Select-Object -First 1 $adapter = Get-NetAdapter -InterfaceIndex $route.InterfaceIndex -ErrorAction Stop $Iface = '\Device\NPF_' + $adapter.InterfaceGuid.ToString('B').ToUpper() } catch {} } if (-not $Iface) { # Fallback: ask netprobe for non-loopback interface with an address try { $allIfaces = (& $Bin interfaces --json 2>$null) -join '' | ConvertFrom-Json $Iface = ($allIfaces | Where-Object { $_.name -notlike '*Loopback*' -and $_.addresses } | Select-Object -First 1).name if (-not $Iface) { $Iface = ($allIfaces | Where-Object { $_.name -notlike '*Loopback*' } | Select-Object -First 1).name } } catch {} } if (-not $Iface) { Write-Error "no pude autodetectar iface; usa NETPROBE_IFACE="; exit 2 } $Out = if ($env:NETPROBE_OUT) { $env:NETPROBE_OUT } else { Join-Path $env:TEMP ("netprobe-" + (Get-Date -UFormat '%Y%m%dT%H%M%SZ')) } New-Item -ItemType Directory -Force -Path $Out | Out-Null Write-Host "[*] iface=$Iface site=$Site duration=$Dur out=$Out" & $Bin discover --iface "$Iface" --duration $Dur --site "$Site" --output "$Out" $uargs = @('upload','--input',"$Out",'--server',"$Base",'--site',"$Site") if ($Token) { $uargs += @('--token',"$Token") } & $Bin @uargs Write-Host "[*] listo — subido a $Base"