├── MonitorNetAdapter.ps1 └── README.md /MonitorNetAdapter.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .DESCRIPTION 3 | A script to monitor a network adapters connection status in realtime and 4 | log any disconnects and reconnects. 5 | 6 | 7 | .NOTES 8 | Name: MonitorNetAdapter 9 | Author: Steven Whitney 10 | Version: 1.2 11 | DateCreated: 2023-Mar-07 12 | 13 | .LINK 14 | https://github.com/knightlygains/NetAdapterMonitor-Powershell 15 | #> 16 | 17 | # Disconnected=0, 18 | # Connecting=1, 19 | # Connected=2, 20 | # Disconnecting=3, 21 | # Hardware_Not_present=4, 22 | # Hardware_disabled=5, 23 | # Hardware_malfunction=6, 24 | # Media_disconnected=7, 25 | # Authenticating=8, 26 | # Authentication_succeeded=9, 27 | # Authentication_failed=10, 28 | # Invalid_address=11, 29 | # Credentials_required=12 30 | Write-Host " _____ _ _____ _ _ _____ _ _ 31 | | | |___| |_| _ |_| |___ ___| |_ ___ ___ | |___ ___|_| |_ ___ ___ 32 | | | | | -_| _| | . | .'| . | _| -_| _| | | | | . | | | _| . | _| 33 | |_|___|___|_| |__|__|___|__,| _|_| |___|_| |_|_|_|___|_|_|_|_| |___|_| 34 | |_| 35 | " 36 | Write-Host "This script is used to monitor a network adapter's connection every second, and then log the date and time the second it is found to be disconnected." 37 | Write-Host "" 38 | 39 | $script:time = Get-Date -Format HH:mm:ss 40 | 41 | Function getAdapters { 42 | #Variable that allows us to loop through and get all adapters with 'Wi' in the name. 43 | $adapters = Get-CimInstance -Class Win32_NetworkAdapter | Select-Object Name, deviceID, NetConnectionStatus 44 | 45 | #Loop through adapters and create/update variables for each one. 46 | foreach ($adapter in $adapters) { 47 | Set-Variable -Name "$($adapter.deviceID) : Adapter:$($adapter.Name)" -Value $adapter.NetConnectionStatus -Scope script #create variable 48 | } 49 | } 50 | 51 | #Function to calculate time left from total seconds provided 52 | Function getTimeLeft ($n) { 53 | $day = ($n / (24 * 3600)) 54 | 55 | $n = $n % (24 * 3600) 56 | $hour = $n / 3600 57 | 58 | $n %= 3600 59 | $minutes = $n / 60 60 | 61 | $n %= 60 62 | $seconds = $n 63 | 64 | $daysLeft = [Math]::Floor($day) 65 | $hoursleft = [Math]::Floor($hour) 66 | $minutesLeft = [Math]::Floor($minutes) 67 | 68 | if ($daysLeft -ge 1) { 69 | return "Remaining: Day:$daysLeft Hr:$hoursLeft Min:$minutesLeft Sec:$seconds." 70 | } 71 | if ($hoursLeft -ge 1) { 72 | return "Remaining: Hr:$hoursLeft Min:$minutesLeft Sec:$seconds." 73 | } 74 | if ($minutesLeft -ge 1) { 75 | return "Remaining: Min:$minutesLeft Sec:$seconds." 76 | } 77 | 78 | return "Remaining: Sec:$seconds." 79 | } 80 | 81 | $script:monitorCount = 1 #Variable to track step in animation 82 | $script:incline = $true #Variable to track direction animation should go in 83 | #Function to update animation 84 | Function monitorAnimation { 85 | 86 | if ($monitorCount -eq 1) { 87 | Write-Host "|" -ForegroundColor Yellow -NoNewline; 88 | Write-Host "- |" -NoNewline 89 | $script:incline = $true 90 | if ($incline) { 91 | $script:monitorCount += 1 92 | } 93 | else { 94 | $script:monitorCount -= 1 95 | } 96 | return 97 | } 98 | if ($monitorCount -eq 2) { 99 | Write-Host "| - |" -NoNewline 100 | if ($incline) { 101 | $script:monitorCount += 1 102 | } 103 | else { 104 | $script:monitorCount -= 1 105 | } 106 | return 107 | } 108 | if ($monitorCount -eq 3) { 109 | Write-Host "| - |" -NoNewline 110 | if ($incline) { 111 | $script:monitorCount += 1 112 | } 113 | else { 114 | $script:monitorCount -= 1 115 | } 116 | return 117 | } 118 | if ($monitorCount -eq 4) { 119 | Write-Host "| -" -NoNewline 120 | Write-Host "|" -ForegroundColor Green -NoNewline 121 | $script:incline = $false 122 | $script:monitorCount -= 1 123 | return 124 | } 125 | } 126 | 127 | #Get wifi adapters and create/update variables made from them. 128 | getAdapters 129 | 130 | #Variable that will allow us to loop through the variables we made in the function getAdapters 131 | $adapterVariables = Get-Variable -Name "*Adapter*" 132 | 133 | #List available network adapter variables for selection 134 | foreach ($adap in $adapterVariables) { 135 | if ($($adap.value) -eq 2) { 136 | Write-Host "$($adap.Name) is connected!" -ForegroundColor Green 137 | } 138 | else { 139 | Write-Host "$($adap.Name) is disconnected..." -ForegroundColor Red 140 | } 141 | } 142 | 143 | Write-Host "" 144 | 145 | #Get user input for monitoring 146 | $answer = Read-Host "Select an adapter to monitor. (Enter the number seen before 'Adapter')" 147 | Write-Host "" 148 | $answer2 = Read-Host "How long will we monitor? (Answer in minutes)" 149 | Write-Host "" 150 | 151 | try { 152 | # Answered in minutes, so multiply by 60 seconds 153 | $script:monitor_length_seconds = [int]$answer2 * 60 154 | $script:total_seconds = $monitor_length_seconds 155 | } 156 | catch { 157 | Write-Host "Invalid input for time to wait.`n" 158 | break 159 | } 160 | 161 | #Check input and begin monitoring if necessary 162 | if (-not(Get-Variable -Name "$answer :*")) { 163 | Write-Host "Invalid adpater selection." 164 | Write-Host "" 165 | break 166 | } 167 | else { 168 | $adapter = Get-Variable -Name "$answer :*" #Get variable that corresponds with our answer 169 | if (-not($adapter.Value -eq 2)) { 170 | Write-Host "Device is disconnected. No monitoring necessary." 171 | Write-Host "" 172 | break 173 | } 174 | else { 175 | Write-Host "Monitoring $($adapter.Name)." 176 | Write-Host "Monitoring will begin in 5 seconds and check every second for connection status." 177 | Write-Host "" 178 | Start-Sleep 5 179 | } 180 | } 181 | 182 | $script:reconnectTime = $null 183 | $script:disconnectTime = $null 184 | #Function to update results txt file with disconnect info. 185 | Function logConnection ($connectionStart) { 186 | 187 | if (-not($null -eq (Get-Variable -Name "$answer :*"))) { 188 | $script:resultsDir = "C:\AdapterMonitorResults" 189 | $script:resultsTxtPath = "$resultsDir\AdapterMonitorResults.txt" 190 | 191 | #If directory already exists 192 | if (Test-Path $resultsDir) { 193 | if (-not(Test-Path $resultsTxtPath -PathType leaf)) { 194 | New-item -Path $resultsDir -Name "AdapterMonitorResults.txt" -ItemType "file" | Out-Null 195 | } 196 | } 197 | else { 198 | #Make the directory and the txt file 199 | mkdir $resultsDir | Out-Null 200 | New-item -Path $resultsDir -Name "AdapterMonitorResults.txt" -ItemType "file" | Out-Null 201 | } 202 | 203 | $adapter = Get-Variable -Name "$answer :*" 204 | 205 | if ($connectionStart) { 206 | Add-Content -Path $resultsTxtPath -Value "Monitoring started on $($adapter.Name) at $(Get-Date)." 207 | } 208 | 209 | if ($disconnectCounter -ge 1 -AND $connected) { 210 | $script:reconnectTime = Get-Date 211 | $timeWhileDisconnected = New-TimeSpan -Start $disconnectTime -End $reconnectTime 212 | $timeWhileDisconnected = $timeWhileDisconnected.ToString("dd' days 'hh' hours 'mm' minutes and 'ss' seconds'") 213 | Write-Host "Reconnected at $time." -ForegroundColor Green 214 | Add-Content -Path $resultsTxtPath -Value "`n$($adapter.Name) reconnected at $(Get-Date)." 215 | Add-Content -Path $resultsTxtPath -Value "Disconnected for $timeWhileDisconnected" 216 | } 217 | 218 | if ($disconnectCounter -eq 1) { 219 | $script:disconnectTime = Get-Date 220 | Write-Host "Disconnected at $time." -ForegroundColor Red 221 | Add-Content -Path $resultsTxtPath -Value "`n$($adapter.Name) disconnected at $(Get-Date)." 222 | } 223 | } 224 | } 225 | 226 | $script:disconnectCounter = 0 227 | $script:startMonitor = $false 228 | $script:connected = $false 229 | #Function to update adapter NetConenctionStatus values and show status in terminal 230 | Function monitorAdapter { 231 | $timeLeft = getTimeLeft($monitor_length_seconds) 232 | getAdapters #update wifi adapter variables for next loop through 233 | 234 | $adapterValue = Get-Variable -Name "$answer :*" -ValueOnly 235 | 236 | #If connected, reset disconnect counter and update animation and adapter variables 237 | if ($adapterValue -eq 2) { 238 | $script:connected = $true 239 | Write-Host "Connected" -ForegroundColor Green -NoNewline 240 | Write-Host " Ctrl+C to QUIT" 241 | monitorAnimation 242 | Write-Host "$timeLeft`n" 243 | logConnection 244 | $script:disconnectCounter = 0 245 | } 246 | 247 | #If disconnected, update disconnect counter, log connection info if necessary, and update adapter variables 248 | if (-not($adapterValue -eq 2)) { 249 | $script:connected = $false 250 | $script:disconnectCounter += 1 251 | Write-Host "Disconnected." -ForegroundColor Red -NoNewline 252 | Write-Host " Ctrl+C to QUIT" 253 | Write-Host "|" -ForegroundColor Red -NoNewline; Write-Host "-XX-" -ForegroundColor Yellow -NoNewline; Write-Host "|" -ForegroundColor Red -NoNewline; 254 | Write-Host "$timeLeft" 255 | Write-Host "" 256 | logConnection 257 | } 258 | } 259 | 260 | #If a variable coresponds with answer (it's not null), run the while loop 261 | if (-not($null -eq (Get-Variable -Name "$answer :*"))) { 262 | 263 | #We've started monitoring, so log monitor start 264 | logConnection($connectionStart = $true) 265 | $script:startMonitor = $true 266 | 267 | $stopwatch = [system.diagnostics.stopwatch]::StartNew() 268 | 269 | while ($script:startMonitor) { 270 | 271 | if (($stopwatch.ElapsedMilliseconds / 1000) -lt $script:total_seconds) { 272 | 273 | $monitor_length_seconds = $script:total_seconds - ([math]::Floor($stopwatch.ElapsedMilliseconds / 1000)) 274 | monitorAdapter 275 | Start-Sleep -Seconds 1 276 | } 277 | else { 278 | $script:startMonitor = $false 279 | break 280 | } 281 | } 282 | } 283 | 284 | Write-Host "Results have been saved to a txt file at $script:resultsTxtPath.`n" 285 | 286 | Start-Process explorer $script:resultsDir -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NetAdapterMonitor-Powershell 2 | Powershell script to monitor a network adapter every second until it disconnects. 3 | Run this script on a local machine to monitor a network adapter's connection status every second. 4 | You can run this script on a remote machine as well with: Invoke-Command -ComputerName $Computer -FilePath $scriptPath. 5 | Windows Remote Management will need to be enabled on the remote machine to run the script remotely. 6 | Results are logged to a txt file in the current user's documents directory. 7 | 8 | This script could be useful for when a user claims their wireless keeps disconnecting but you don't have time to sit and watch it for 5-10+ minutes. 9 | --------------------------------------------------------------------------------