Created
February 9, 2026 12:15
-
-
Save NotNahid/4db4bcd3c7ee8b7ed4c9f936f2aba3cf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Add-Type -AssemblyName System.Windows.Forms | |
| Add-Type -AssemblyName System.Drawing | |
| # ============================================ | |
| # MAIN FORM | |
| # ============================================ | |
| $form = New-Object System.Windows.Forms.Form | |
| $form.Text = "Network Speed Monitor" | |
| $form.Size = New-Object System.Drawing.Size(450, 380) | |
| $form.StartPosition = "CenterScreen" | |
| $form.FormBorderStyle = "FixedSingle" | |
| $form.MaximizeBox = $false | |
| $form.BackColor = [System.Drawing.Color]::FromArgb(30, 30, 30) | |
| # ============================================ | |
| # MINI OVERLAY FORM (shows on taskbar area when minimized) | |
| # ============================================ | |
| $miniForm = New-Object System.Windows.Forms.Form | |
| $miniForm.FormBorderStyle = "None" | |
| $miniForm.Size = New-Object System.Drawing.Size(220, 50) | |
| $miniForm.TopMost = $true | |
| $miniForm.ShowInTaskbar = $false | |
| $miniForm.BackColor = [System.Drawing.Color]::FromArgb(20, 20, 20) | |
| $miniForm.Opacity = 0.92 | |
| $miniForm.Visible = $false | |
| $miniForm.StartPosition = "Manual" | |
| # Round corners for mini form | |
| Add-Type @" | |
| using System; | |
| using System.Runtime.InteropServices; | |
| public class RoundCorner { | |
| [DllImport("Gdi32.dll")] | |
| public static extern IntPtr CreateRoundRectRgn(int left, int top, int right, int bottom, int w, int h); | |
| [DllImport("user32.dll")] | |
| public static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw); | |
| } | |
| "@ | |
| $miniForm.Add_Load({ | |
| $rgn = [RoundCorner]::CreateRoundRectRgn(0, 0, $miniForm.Width, $miniForm.Height, 15, 15) | |
| [RoundCorner]::SetWindowRgn($miniForm.Handle, $rgn, $true) | |
| }) | |
| # Position mini form at bottom-right above taskbar | |
| $screen = [System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea | |
| $miniForm.Location = New-Object System.Drawing.Point( | |
| ($screen.Right - $miniForm.Width - 10), | |
| ($screen.Bottom - $miniForm.Height - 5) | |
| ) | |
| # Mini form download label | |
| $miniDlLabel = New-Object System.Windows.Forms.Label | |
| $miniDlLabel.Text = "⬇ 0.00 KB/s" | |
| $miniDlLabel.Font = New-Object System.Drawing.Font("Consolas", 10, [System.Drawing.FontStyle]::Bold) | |
| $miniDlLabel.ForeColor = [System.Drawing.Color]::FromArgb(0, 255, 130) | |
| $miniDlLabel.Location = New-Object System.Drawing.Point(10, 4) | |
| $miniDlLabel.AutoSize = $true | |
| $miniForm.Controls.Add($miniDlLabel) | |
| # Mini form upload label | |
| $miniUlLabel = New-Object System.Windows.Forms.Label | |
| $miniUlLabel.Text = "⬆ 0.00 KB/s" | |
| $miniUlLabel.Font = New-Object System.Drawing.Font("Consolas", 10, [System.Drawing.FontStyle]::Bold) | |
| $miniUlLabel.ForeColor = [System.Drawing.Color]::FromArgb(100, 180, 255) | |
| $miniUlLabel.Location = New-Object System.Drawing.Point(10, 26) | |
| $miniUlLabel.AutoSize = $true | |
| $miniForm.Controls.Add($miniUlLabel) | |
| # Close button on mini form | |
| $miniCloseBtn = New-Object System.Windows.Forms.Label | |
| $miniCloseBtn.Text = "✕" | |
| $miniCloseBtn.Font = New-Object System.Drawing.Font("Segoe UI", 9, [System.Drawing.FontStyle]::Bold) | |
| $miniCloseBtn.ForeColor = [System.Drawing.Color]::FromArgb(120, 120, 120) | |
| $miniCloseBtn.Location = New-Object System.Drawing.Point(195, 2) | |
| $miniCloseBtn.AutoSize = $true | |
| $miniCloseBtn.Cursor = [System.Windows.Forms.Cursors]::Hand | |
| $miniCloseBtn.Add_MouseEnter({ $miniCloseBtn.ForeColor = [System.Drawing.Color]::Red }) | |
| $miniCloseBtn.Add_MouseLeave({ $miniCloseBtn.ForeColor = [System.Drawing.Color]::FromArgb(120, 120, 120) }) | |
| $miniCloseBtn.Add_Click({ | |
| $miniForm.Hide() | |
| $notifyIcon.Visible = $false | |
| $form.Show() | |
| $form.WindowState = "Normal" | |
| $form.Activate() | |
| }) | |
| $miniForm.Controls.Add($miniCloseBtn) | |
| # Make mini form draggable | |
| $script:miniDragging = $false | |
| $script:miniDragStart = New-Object System.Drawing.Point(0, 0) | |
| $miniForm.Add_MouseDown({ | |
| param($s, $e) | |
| if ($e.Button -eq "Left") { | |
| $script:miniDragging = $true | |
| $script:miniDragStart = $e.Location | |
| } | |
| }) | |
| $miniForm.Add_MouseMove({ | |
| param($s, $e) | |
| if ($script:miniDragging) { | |
| $miniForm.Location = New-Object System.Drawing.Point( | |
| ($miniForm.Location.X + $e.X - $script:miniDragStart.X), | |
| ($miniForm.Location.Y + $e.Y - $script:miniDragStart.Y) | |
| ) | |
| } | |
| }) | |
| $miniForm.Add_MouseUp({ $script:miniDragging = $false }) | |
| # Double click mini form to restore main window | |
| $miniForm.Add_DoubleClick({ | |
| $miniForm.Hide() | |
| $notifyIcon.Visible = $false | |
| $form.Show() | |
| $form.WindowState = "Normal" | |
| $form.Activate() | |
| }) | |
| # ============================================ | |
| # SYSTEM TRAY ICON | |
| # ============================================ | |
| function Create-TrayIcon { | |
| $bitmap = New-Object System.Drawing.Bitmap(16, 16) | |
| $g = [System.Drawing.Graphics]::FromImage($bitmap) | |
| $g.Clear([System.Drawing.Color]::FromArgb(30, 30, 30)) | |
| $greenPen = New-Object System.Drawing.Pen([System.Drawing.Color]::FromArgb(0, 255, 130), 2) | |
| $g.DrawLine($greenPen, 4, 2, 4, 10) | |
| $g.DrawLine($greenPen, 1, 7, 4, 10) | |
| $g.DrawLine($greenPen, 7, 7, 4, 10) | |
| $bluePen = New-Object System.Drawing.Pen([System.Drawing.Color]::FromArgb(100, 180, 255), 2) | |
| $g.DrawLine($bluePen, 12, 14, 12, 6) | |
| $g.DrawLine($bluePen, 9, 9, 12, 6) | |
| $g.DrawLine($bluePen, 15, 9, 12, 6) | |
| $g.Dispose(); $greenPen.Dispose(); $bluePen.Dispose() | |
| return [System.Drawing.Icon]::FromHandle($bitmap.GetHicon()) | |
| } | |
| $notifyIcon = New-Object System.Windows.Forms.NotifyIcon | |
| $notifyIcon.Icon = Create-TrayIcon | |
| $notifyIcon.Text = "Network Speed Monitor" | |
| $notifyIcon.Visible = $false | |
| # Tray context menu | |
| $trayMenu = New-Object System.Windows.Forms.ContextMenuStrip | |
| $trayMenu.BackColor = [System.Drawing.Color]::FromArgb(45, 45, 45) | |
| $trayMenu.ForeColor = [System.Drawing.Color]::White | |
| $trayMenu.Font = New-Object System.Drawing.Font("Segoe UI", 10) | |
| $restoreItem = New-Object System.Windows.Forms.ToolStripMenuItem | |
| $restoreItem.Text = "🖥 Restore Full Window" | |
| $restoreItem.Add_Click({ | |
| $miniForm.Hide() | |
| $notifyIcon.Visible = $false | |
| $form.Show() | |
| $form.WindowState = "Normal" | |
| $form.Activate() | |
| }) | |
| $separatorItem = New-Object System.Windows.Forms.ToolStripSeparator | |
| $exitItem = New-Object System.Windows.Forms.ToolStripMenuItem | |
| $exitItem.Text = "❌ Exit" | |
| $exitItem.Add_Click({ | |
| $miniForm.Close() | |
| $notifyIcon.Visible = $false | |
| $notifyIcon.Dispose() | |
| $form.Close() | |
| }) | |
| $trayMenu.Items.Add($restoreItem) | |
| $trayMenu.Items.Add($separatorItem) | |
| $trayMenu.Items.Add($exitItem) | |
| $notifyIcon.ContextMenuStrip = $trayMenu | |
| $notifyIcon.Add_DoubleClick({ | |
| $miniForm.Hide() | |
| $notifyIcon.Visible = $false | |
| $form.Show() | |
| $form.WindowState = "Normal" | |
| $form.Activate() | |
| }) | |
| # ============================================ | |
| # MINIMIZE TO MINI OVERLAY | |
| # ============================================ | |
| $form.Add_Resize({ | |
| if ($form.WindowState -eq "Minimized") { | |
| $form.Hide() | |
| $notifyIcon.Visible = $true | |
| $miniForm.Show() | |
| } | |
| }) | |
| # ============================================ | |
| # MAIN FORM GUI ELEMENTS | |
| # ============================================ | |
| $titleLabel = New-Object System.Windows.Forms.Label | |
| $titleLabel.Text = "⚡ Live Network Speed Monitor" | |
| $titleLabel.Font = New-Object System.Drawing.Font("Segoe UI", 14, [System.Drawing.FontStyle]::Bold) | |
| $titleLabel.ForeColor = [System.Drawing.Color]::White | |
| $titleLabel.AutoSize = $true | |
| $titleLabel.Location = New-Object System.Drawing.Point(70, 15) | |
| $form.Controls.Add($titleLabel) | |
| # Download section | |
| $dlHeaderLabel = New-Object System.Windows.Forms.Label | |
| $dlHeaderLabel.Text = "⬇ DOWNLOAD SPEED" | |
| $dlHeaderLabel.Font = New-Object System.Drawing.Font("Segoe UI", 10, [System.Drawing.FontStyle]::Bold) | |
| $dlHeaderLabel.ForeColor = [System.Drawing.Color]::FromArgb(0, 200, 100) | |
| $dlHeaderLabel.AutoSize = $true | |
| $dlHeaderLabel.Location = New-Object System.Drawing.Point(30, 70) | |
| $form.Controls.Add($dlHeaderLabel) | |
| $dlSpeedLabel = New-Object System.Windows.Forms.Label | |
| $dlSpeedLabel.Text = "0.00 KB/s" | |
| $dlSpeedLabel.Font = New-Object System.Drawing.Font("Consolas", 24, [System.Drawing.FontStyle]::Bold) | |
| $dlSpeedLabel.ForeColor = [System.Drawing.Color]::FromArgb(0, 255, 130) | |
| $dlSpeedLabel.Size = New-Object System.Drawing.Size(380, 50) | |
| $dlSpeedLabel.Location = New-Object System.Drawing.Point(30, 95) | |
| $form.Controls.Add($dlSpeedLabel) | |
| # Upload section | |
| $ulHeaderLabel = New-Object System.Windows.Forms.Label | |
| $ulHeaderLabel.Text = "⬆ UPLOAD SPEED" | |
| $ulHeaderLabel.Font = New-Object System.Drawing.Font("Segoe UI", 10, [System.Drawing.FontStyle]::Bold) | |
| $ulHeaderLabel.ForeColor = [System.Drawing.Color]::FromArgb(100, 150, 255) | |
| $ulHeaderLabel.AutoSize = $true | |
| $ulHeaderLabel.Location = New-Object System.Drawing.Point(30, 160) | |
| $form.Controls.Add($ulHeaderLabel) | |
| $ulSpeedLabel = New-Object System.Windows.Forms.Label | |
| $ulSpeedLabel.Text = "0.00 KB/s" | |
| $ulSpeedLabel.Font = New-Object System.Drawing.Font("Consolas", 24, [System.Drawing.FontStyle]::Bold) | |
| $ulSpeedLabel.ForeColor = [System.Drawing.Color]::FromArgb(100, 180, 255) | |
| $ulSpeedLabel.Size = New-Object System.Drawing.Size(380, 50) | |
| $ulSpeedLabel.Location = New-Object System.Drawing.Point(30, 185) | |
| $form.Controls.Add($ulSpeedLabel) | |
| # Interface label | |
| $interfaceLabel = New-Object System.Windows.Forms.Label | |
| $interfaceLabel.Text = "Interface: Detecting..." | |
| $interfaceLabel.Font = New-Object System.Drawing.Font("Segoe UI", 9) | |
| $interfaceLabel.ForeColor = [System.Drawing.Color]::Gray | |
| $interfaceLabel.AutoSize = $true | |
| $interfaceLabel.Location = New-Object System.Drawing.Point(30, 250) | |
| $form.Controls.Add($interfaceLabel) | |
| # Total session label | |
| $totalLabel = New-Object System.Windows.Forms.Label | |
| $totalLabel.Text = "Session: ⬇ 0 MB | ⬆ 0 MB" | |
| $totalLabel.Font = New-Object System.Drawing.Font("Segoe UI", 9) | |
| $totalLabel.ForeColor = [System.Drawing.Color]::Gray | |
| $totalLabel.AutoSize = $true | |
| $totalLabel.Location = New-Object System.Drawing.Point(30, 275) | |
| $form.Controls.Add($totalLabel) | |
| # Hint label | |
| $hintLabel = New-Object System.Windows.Forms.Label | |
| $hintLabel.Text = "💡 Minimize to see floating speed widget" | |
| $hintLabel.Font = New-Object System.Drawing.Font("Segoe UI", 8) | |
| $hintLabel.ForeColor = [System.Drawing.Color]::FromArgb(100, 100, 100) | |
| $hintLabel.AutoSize = $true | |
| $hintLabel.Location = New-Object System.Drawing.Point(105, 310) | |
| $form.Controls.Add($hintLabel) | |
| # ============================================ | |
| # HELPER FUNCTIONS | |
| # ============================================ | |
| function Format-Speed { | |
| param([double]$bytesPerSecond) | |
| if ($bytesPerSecond -ge 1073741824) { return "{0:N2} GB/s" -f ($bytesPerSecond / 1073741824) } | |
| elseif ($bytesPerSecond -ge 1048576) { return "{0:N2} MB/s" -f ($bytesPerSecond / 1048576) } | |
| elseif ($bytesPerSecond -ge 1024) { return "{0:N2} KB/s" -f ($bytesPerSecond / 1024) } | |
| else { return "{0:N0} B/s" -f $bytesPerSecond } | |
| } | |
| function Format-SpeedCompact { | |
| param([double]$bytesPerSecond) | |
| if ($bytesPerSecond -ge 1073741824) { return "{0:N1} GB/s" -f ($bytesPerSecond / 1073741824) } | |
| elseif ($bytesPerSecond -ge 1048576) { return "{0:N1} MB/s" -f ($bytesPerSecond / 1048576) } | |
| elseif ($bytesPerSecond -ge 1024) { return "{0:N1} KB/s" -f ($bytesPerSecond / 1024) } | |
| else { return "{0:N0} B/s" -f $bytesPerSecond } | |
| } | |
| function Format-DataSize { | |
| param([double]$bytes) | |
| if ($bytes -ge 1073741824) { return "{0:N2} GB" -f ($bytes / 1073741824) } | |
| elseif ($bytes -ge 1048576) { return "{0:N2} MB" -f ($bytes / 1048576) } | |
| elseif ($bytes -ge 1024) { return "{0:N2} KB" -f ($bytes / 1024) } | |
| else { return "{0:N0} B" -f $bytes } | |
| } | |
| # ============================================ | |
| # NETWORK DETECTION | |
| # ============================================ | |
| $networkInterfaces = [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() | | |
| Where-Object { | |
| $_.OperationalStatus -eq 'Up' -and | |
| $_.NetworkInterfaceType -ne 'Loopback' -and | |
| $_.GetIPv4Statistics().BytesReceived -gt 0 | |
| } | Sort-Object { $_.GetIPv4Statistics().BytesReceived } -Descending | |
| $selectedNIC = $networkInterfaces | Select-Object -First 1 | |
| if (-not $selectedNIC) { | |
| [System.Windows.Forms.MessageBox]::Show("No active network adapter found!", "Error", "OK", "Error") | |
| return | |
| } | |
| $interfaceLabel.Text = "Interface: $($selectedNIC.Name)" | |
| $script:prevBytesReceived = $selectedNIC.GetIPv4Statistics().BytesReceived | |
| $script:prevBytesSent = $selectedNIC.GetIPv4Statistics().BytesSent | |
| $script:totalDownloaded = 0 | |
| $script:totalUploaded = 0 | |
| $script:lastTime = Get-Date | |
| # ============================================ | |
| # TIMER - 1 second updates | |
| # ============================================ | |
| $timer = New-Object System.Windows.Forms.Timer | |
| $timer.Interval = 1000 | |
| $timer.Add_Tick({ | |
| try { | |
| $nic = [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() | | |
| Where-Object { $_.Id -eq $selectedNIC.Id } | Select-Object -First 1 | |
| if ($nic) { | |
| $stats = $nic.GetIPv4Statistics() | |
| $currentTime = Get-Date | |
| $elapsed = ($currentTime - $script:lastTime).TotalSeconds | |
| if ($elapsed -gt 0) { | |
| $bytesReceivedDiff = $stats.BytesReceived - $script:prevBytesReceived | |
| $bytesSentDiff = $stats.BytesSent - $script:prevBytesSent | |
| if ($bytesReceivedDiff -lt 0) { $bytesReceivedDiff = 0 } | |
| if ($bytesSentDiff -lt 0) { $bytesSentDiff = 0 } | |
| $downloadSpeed = $bytesReceivedDiff / $elapsed | |
| $uploadSpeed = $bytesSentDiff / $elapsed | |
| $script:totalDownloaded += $bytesReceivedDiff | |
| $script:totalUploaded += $bytesSentDiff | |
| # Update MAIN window | |
| $dlSpeedLabel.Text = Format-Speed $downloadSpeed | |
| $ulSpeedLabel.Text = Format-Speed $uploadSpeed | |
| $totalLabel.Text = "Session: ⬇ $(Format-DataSize $script:totalDownloaded) | ⬆ $(Format-DataSize $script:totalUploaded)" | |
| # Update MINI overlay | |
| $miniDlLabel.Text = "⬇ $(Format-SpeedCompact $downloadSpeed)" | |
| $miniUlLabel.Text = "⬆ $(Format-SpeedCompact $uploadSpeed)" | |
| # Update tray tooltip | |
| $trayText = "DL: $(Format-SpeedCompact $downloadSpeed) | UL: $(Format-SpeedCompact $uploadSpeed)" | |
| if ($trayText.Length -gt 63) { $trayText = $trayText.Substring(0, 63) } | |
| $notifyIcon.Text = $trayText | |
| $script:prevBytesReceived = $stats.BytesReceived | |
| $script:prevBytesSent = $stats.BytesSent | |
| $script:lastTime = $currentTime | |
| } | |
| } | |
| } | |
| catch { } | |
| }) | |
| # ============================================ | |
| # FORM EVENTS | |
| # ============================================ | |
| $form.Add_Shown({ $timer.Start() }) | |
| $form.Add_FormClosing({ | |
| $timer.Stop() | |
| $timer.Dispose() | |
| $miniForm.Close() | |
| $notifyIcon.Visible = $false | |
| $notifyIcon.Dispose() | |
| }) | |
| [System.Windows.Forms.Application]::Run($form) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment