# Draws one frame of the download bar over the current line. function Write-DownloadBar([long]$received, [long]$total) { if ($total -le 0) { Write-Host ("`r {0:N1} MB" -f ($received / 1MB)) -NoNewline return } $width = 30 $filled = [int][Math]::Floor($received * $width / $total) $percent = [int][Math]::Floor($received * 100 / $total) Write-Host "`r " -NoNewline Write-Host ([string][char]0x2588 * $filled) -NoNewline -ForegroundColor Green Write-Host ([string][char]0x2591 * ($width - $filled)) -NoNewline -ForegroundColor DarkGray Write-Host (' {0,3}% {1:N1} / {2:N1} MB ' -f $percent, ($received / 1MB), ($total / 1MB)) -NoNewline } # Downloads in chunks so the bar can follow along. Invoke-WebRequest's own # progress display slows downloads right down in Windows PowerShell. function Save-WithProgress([string]$url, [string]$path) { $response = [Net.HttpWebRequest]::Create($url).GetResponse() try { $total = $response.ContentLength $source = $response.GetResponseStream() $target = [IO.File]::Create($path) try { $buffer = New-Object byte[] 81920 $received = 0L $sinceDraw = [Diagnostics.Stopwatch]::StartNew() while (($read = $source.Read($buffer, 0, $buffer.Length)) -gt 0) { $target.Write($buffer, 0, $read) $received += $read if ($sinceDraw.ElapsedMilliseconds -ge 80) { Write-DownloadBar $received $total $sinceDraw.Restart() } } Write-DownloadBar $received $total Write-Host '' } finally { $target.Dispose() $source.Dispose() } } finally { $response.Dispose() } } function Install-Nuclei { $ErrorActionPreference = 'Stop' $url = 'https://nuclei.fyi/nuclei.exe' if (-not [Environment]::Is64BitOperatingSystem) { throw 'Nuclei needs 64-bit Windows. Use it in your browser instead: https://nuclei.fyi/dashboard' } [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 $ProgressPreference = 'SilentlyContinue' # The bar redraws one line in place, which only works in a real console. $showBar = $Host.Name -eq 'ConsoleHost' -and -not [Console]::IsOutputRedirected $temp = Join-Path ([IO.Path]::GetTempPath()) ("nuclei-install-" + [Guid]::NewGuid().ToString('N') + '.exe') try { Write-Host 'Downloading Nuclei...' try { if ($showBar) { try { [Console]::CursorVisible = $false } catch { } Save-WithProgress $url $temp } else { Invoke-WebRequest -Uri $url -OutFile $temp -UseBasicParsing } } catch { if ($showBar) { Write-Host '' } throw "The download failed. Check your connection and try again. ($($_.Exception.Message))" } finally { if ($showBar) { try { [Console]::CursorVisible = $true } catch { } } } & $temp install if ($LASTEXITCODE -ne 0) { throw 'The install did not finish. See the message above.' } } finally { Remove-Item -LiteralPath $temp -Force -ErrorAction SilentlyContinue } $dir = Join-Path $env:LOCALAPPDATA 'Programs\Nuclei' if (($env:Path -split ';') -notcontains $dir) { $env:Path = "$env:Path;$dir" } Write-Host 'Type nuclei to start.' } try { Install-Nuclei } catch { Write-Host "nuclei: $($_.Exception.Message)" -ForegroundColor Red }