Last active
June 30, 2025 05:16
-
-
Save enonethreezed/0a57c8e548c46dc36c23956316b737f0 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
| Write-Output "`nStarting Tools Provisioning" | |
| function Safe-RemoveItem($path) { | |
| if (!(Test-Path $path)) { return } | |
| Get-ChildItem -Path $path -Recurse -Force -ErrorAction SilentlyContinue | | |
| ForEach-Object { try { $_.IsReadOnly = $false } catch {} } | |
| $maxRetries = 5; $retry = 0 | |
| do { | |
| try { Remove-Item -Recurse -Force $path -ErrorAction Stop; return } | |
| catch { $retry++; Start-Sleep -Milliseconds 500 } | |
| } while ($retry -lt $maxRetries) | |
| } | |
| function Test-JDK21 { | |
| try { return (& java -version 2>&1 | Select-String '21\.' -Quiet) } | |
| catch { return $false } | |
| } | |
| function Test-TemurinMSI { | |
| $key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' | |
| $found = Get-ChildItem $key | ForEach-Object { Get-ItemProperty $_.PSPath } | | |
| Where-Object { $_.DisplayName -match 'Temurin.*21' } | |
| return $found -ne $null | |
| } | |
| function Test-Winget { | |
| try { winget --version | Out-Null; return $true } | |
| catch { return $false } | |
| } | |
| function Test-Sandboxie { | |
| try { | |
| $installed = winget list --id Sandboxie.Classic 2>$null | | |
| Select-String 'Sandboxie.Classic' | |
| return $installed -ne $null | |
| } | |
| catch { return $false } | |
| } | |
| # Base paths | |
| $desktop = [Environment]::GetFolderPath('Desktop') | |
| $baseFolder = Join-Path $desktop 'tools' | |
| $reversingFolder = Join-Path $baseFolder 'reversing' | |
| $downloadsFolder = Join-Path $baseFolder 'downloads' | |
| $ghidraInstallLog = Join-Path $downloadsFolder 'ghidra_installed.log' | |
| $radareFolder = Join-Path $reversingFolder 'radare2' | |
| $ghidraFolder = Join-Path $reversingFolder 'ghidra' | |
| $pebearFolder = Join-Path $reversingFolder 'pe-bear' | |
| $x64dbgFolder = Join-Path $reversingFolder 'x64dbg' | |
| $sysinternalsFolder = Join-Path $baseFolder 'SysInternals' | |
| Write-Output "Creating required directories..." | |
| foreach ($folder in @( | |
| $baseFolder, $reversingFolder, $downloadsFolder, | |
| $radareFolder, $ghidraFolder, $pebearFolder, $x64dbgFolder | |
| )) { | |
| if (!(Test-Path $folder)) { | |
| New-Item -ItemType Directory -Path $folder -Force | Out-Null | |
| } | |
| } | |
| Write-Output "Initializing Ghidra installation log..." | |
| if (!(Test-Path $ghidraInstallLog)) { | |
| New-Item -ItemType File -Path $ghidraInstallLog -Force | Out-Null | |
| } | |
| $installedGhidraZips = Get-Content $ghidraInstallLog | ForEach-Object { $_.Trim() } | |
| $headers = @{ 'User-Agent' = 'Mozilla/5.0' } | |
| Write-Output "Configuring Defender exclusions..." | |
| Add-MpPreference -ExclusionPath $baseFolder | |
| Add-MpPreference -ExclusionPath 'C:\metasploit-framework' | |
| Add-MpPreference -ExclusionPath 'C:\metasploit-framework*.zip' | |
| # — Radare2 — | |
| Write-Output "Downloading and installing Radare2..." | |
| $repoR2 = 'radareorg/radare2' | |
| $releaseR2 = Invoke-RestMethod -Uri "https://api.github.com/repos/$repoR2/releases/latest" -Headers $headers | |
| $assetR2 = $releaseR2.assets | Where-Object { $_.name -like '*w64.zip' } | Select-Object -First 1 | |
| if ($assetR2) { | |
| $zipDownload = Join-Path $downloadsFolder $assetR2.name | |
| if (!(Test-Path $zipDownload)) { | |
| Invoke-WebRequest -Uri $assetR2.browser_download_url -OutFile $zipDownload -Headers $headers | |
| } | |
| $tempExtract = Join-Path $env:TEMP 'radare2_temp' | |
| Safe-RemoveItem $tempExtract | |
| Expand-Archive -Path $zipDownload -DestinationPath $tempExtract -Force | |
| $binFile = 'r2blob.static.exe' | |
| $newBinPath = Get-ChildItem -Path $tempExtract -Recurse -Filter $binFile | Select-Object -First 1 | |
| if ($newBinPath) { | |
| $newHash = Get-FileHash $newBinPath.FullName -Algorithm SHA256 | |
| $existingBin = Get-ChildItem -Path $radareFolder -Recurse -Filter $binFile | Select-Object -First 1 | |
| $needUpdate = $true | |
| if ($existingBin) { | |
| $existingHash = Get-FileHash $existingBin.FullName -Algorithm SHA256 | |
| if ($existingHash.Hash -eq $newHash.Hash) { | |
| $needUpdate = $false | |
| } | |
| } | |
| if ($needUpdate) { | |
| Safe-RemoveItem $radareFolder | |
| New-Item -ItemType Directory -Path $radareFolder -Force | Out-Null | |
| Expand-Archive -Path $zipDownload -DestinationPath $radareFolder -Force | |
| } | |
| } | |
| Safe-RemoveItem $tempExtract | |
| } | |
| # — Ghidra: download latest release — | |
| Write-Output "Downloading latest Ghidra release..." | |
| $repoGhidra = 'NationalSecurityAgency/ghidra' | |
| $releaseGhidra = Invoke-RestMethod -Uri "https://api.github.com/repos/$repoGhidra/releases/latest" -Headers $headers | |
| $assetGhidra = $releaseGhidra.assets | Where-Object { $_.name -like 'ghidra_*.zip' } | Select-Object -First 1 | |
| if ($assetGhidra) { | |
| $zipGhidra = Join-Path $downloadsFolder $assetGhidra.name | |
| if (!(Test-Path $zipGhidra)) { | |
| Write-Output "=> Downloading Ghidra $($assetGhidra.name)..." | |
| Invoke-WebRequest -Uri $assetGhidra.browser_download_url -OutFile $zipGhidra -Headers $headers | |
| } | |
| } | |
| # — Ghidra: processing downloaded packages — | |
| Write-Output "Processing Ghidra packages..." | |
| $ghidraZips = Get-ChildItem -Path $downloadsFolder -Filter 'ghidra_*.zip' | Sort-Object Name -Descending | |
| foreach ($zip in $ghidraZips) { | |
| if ($zip.Name -match 'ghidra_([\d\.]+)_') { | |
| if ($installedGhidraZips -contains $zip.Name) { continue } | |
| Expand-Archive -Path $zip.FullName -DestinationPath $ghidraFolder -Force | |
| Add-Content -Path $ghidraInstallLog -Value $zip.Name | |
| } | |
| } | |
| # — Temurin JDK 21 — | |
| Write-Output "Installing Temurin JDK 21..." | |
| $msiUrl = 'https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.3%2B9/OpenJDK21U-jdk_x64_windows_hotspot_21.0.3_9.msi' | |
| $msiName = 'OpenJDK21U-jdk_x64_windows_hotspot_21.0.3_9.msi' | |
| $msiPath = Join-Path $downloadsFolder $msiName | |
| if (!(Test-Path $msiPath)) { | |
| Invoke-WebRequest -Uri $msiUrl -OutFile $msiPath -Headers $headers | |
| } | |
| if (-not (Test-TemurinMSI)) { | |
| Start-Process msiexec.exe -ArgumentList "/i `"$msiPath`" /qn /norestart" -Wait | |
| } | |
| $jdkRoot = Get-ChildItem 'C:\Program Files\Eclipse Adoptium' -Directory | | |
| Where-Object { $_.Name -like 'jdk-21*' } | | |
| Select-Object -First 1 | |
| if ($jdkRoot) { | |
| $jdkBin = Join-Path $jdkRoot.FullName 'bin' | |
| $currentPath = [Environment]::GetEnvironmentVariable('Path','User') | |
| if ($currentPath -notlike "*$jdkBin*") { | |
| [Environment]::SetEnvironmentVariable('Path', "$currentPath;$jdkBin", 'User') | |
| } | |
| } | |
| # — Winget installs with detailed log — | |
| Write-Output "Installing packages via winget..." | |
| if (Test-Winget) { | |
| $packages = @( | |
| 'Sandboxie.Classic', | |
| 'WinsiderSS.SystemInformer', | |
| 'Python.Python.3.13', | |
| 'Hashicorp.Vagrant', | |
| 'Hashicorp.Packer', | |
| 'Git.Git', | |
| 'UPX.UPX', | |
| 'Microsoft.WinDbg', | |
| 'WireGuard.WireGuard', | |
| 'OpenVPNTechnologies.OpenVPN', | |
| 'VPNetwork.TorGuard', | |
| 'Microsoft.VisualStudioCode' | |
| ) | |
| } | |
| foreach ($pkgId in $packages) { | |
| Write-Output "=> Verifying $pkgId..." | |
| try { | |
| $installed = winget list --id $pkgId 2>$null | Select-String $pkgId | |
| if ($installed) { | |
| Write-Output " $pkgId already installed" | |
| } | |
| else { | |
| Write-Output " Not installed. Installing $pkgId..." | |
| winget install $pkgId --silent --accept-package-agreements --accept-source-agreements | |
| Write-Output " Installed $pkgId" | |
| } | |
| } | |
| catch { | |
| if ($_.Exception.Message -match 'No package found') { | |
| Write-Warning " Package not found: $pkgId" | |
| } | |
| else { | |
| Write-Warning " Error installing $pkgId : $($_.Exception.Message)" | |
| } | |
| } | |
| } | |
| # — PE-Bear — | |
| Write-Output "Downloading PE-Bear..." | |
| $repoPEBear = 'hasherezade/pe-bear' | |
| $releasePEBear = Invoke-RestMethod -Uri "https://api.github.com/repos/$repoPEBear/releases/latest" -Headers $headers | |
| $assetPEBear = $releasePEBear.assets | Where-Object { $_.name -match '^pe-bear.*\.zip$' } | Select-Object -First 1 | |
| $zipDownloadPEBear = Join-Path $downloadsFolder $assetPEBear.name | |
| if ($assetPEBear -and !(Test-Path $zipDownloadPEBear)) { | |
| Invoke-WebRequest -Uri $assetPEBear.browser_download_url -OutFile $zipDownloadPEBear -Headers $headers | |
| Expand-Archive -Path $zipDownloadPEBear -DestinationPath $pebearFolder -Force | |
| } | |
| # — Metasploit Framework — | |
| Write-Output "Installing Metasploit Framework..." | |
| $msiUrlMetasploit = 'https://windows.metasploit.com/metasploitframework-latest.msi' | |
| $msiNameMetasploit = 'metasploitframework-latest.msi' | |
| $msiPathMetasploit = Join-Path $downloadsFolder $msiNameMetasploit | |
| if (!(Test-Path $msiPathMetasploit)) { | |
| Invoke-WebRequest -Uri $msiUrlMetasploit -OutFile $msiPathMetasploit -Headers $headers | |
| Start-Process msiexec.exe -ArgumentList "/i `"$msiPathMetasploit`" /qn /norestart" -Wait | |
| } | |
| # — Visual Studio Community — | |
| Write-Output "Installing Visual Studio Community..." | |
| $vsInstaller = Join-Path $downloadsFolder 'vs_Community.exe' | |
| if (!(Test-Path $vsInstaller)) { | |
| Invoke-WebRequest -Uri 'https://aka.ms/vs/17/release/vs_Community.exe' -OutFile $vsInstaller -Headers $headers | |
| } | |
| Start-Process $vsInstaller -ArgumentList ` | |
| '--add Microsoft.VisualStudio.Workload.NativeDesktop', | |
| '--add Microsoft.VisualStudio.Workload.ManagedDesktop', | |
| '--quiet','--wait','--norestart','--nocache','--noUpdateInstaller' -Wait | |
| # — x64dbg — | |
| Write-Output "Downloading and installing x64dbg..." | |
| $repoX64dbg = 'x64dbg/x64dbg' | |
| $releaseX64dbg = Invoke-RestMethod -Uri "https://api.github.com/repos/$repoX64dbg/releases/latest" -Headers $headers | |
| $assetX64dbg = $releaseX64dbg.assets | Where-Object { $_.name -like '*.zip' } | Select-Object -First 1 | |
| $x64dbgZip = Join-Path $downloadsFolder $assetX64dbg.name | |
| if (!(Test-Path $x64dbgZip)) { | |
| Invoke-WebRequest -Uri $assetX64dbg.browser_download_url -OutFile $x64dbgZip -Headers $headers | |
| Expand-Archive -Path $x64dbgZip -DestinationPath $x64dbgFolder -Force | |
| } | |
| # — Sysinternals — | |
| Write-Output "Downloading Sysinternals Suite..." | |
| $sysinternalsUrl = 'https://download.sysinternals.com/files/SysinternalsSuite.zip' | |
| $sysinternalsZip = Join-Path $downloadsFolder 'SysinternalsSuite.zip' | |
| if (!(Test-Path $sysinternalsZip)) { | |
| Invoke-WebRequest -Uri $sysinternalsUrl -OutFile $sysinternalsZip -Headers $headers | |
| } | |
| if (!(Test-Path $sysinternalsFolder)) { | |
| Expand-Archive -Path $sysinternalsZip -DestinationPath $sysinternalsFolder -Force | |
| } | |
| # — Clone or update Win11Debloat — | |
| Write-Output "Preparing GitHub workspace..." | |
| $githubBase = Join-Path $baseFolder 'github' | |
| $repoName = 'Win11Debloat' | |
| $repoUrl = 'https://github.com/Raphire/Win11Debloat.git' | |
| $repoFolder = Join-Path $githubBase $repoName | |
| if (!(Test-Path $githubBase)) { | |
| New-Item -ItemType Directory -Path $githubBase -Force | Out-Null | |
| } | |
| if (!(Test-Path $repoFolder)) { | |
| Write-Output "Cloning $repoName into tools\github..." | |
| git clone $repoUrl $repoFolder | |
| } | |
| else { | |
| if (Test-Path (Join-Path $repoFolder '.git')) { | |
| Write-Output "Repository already exists; updating $repoName..." | |
| Push-Location $repoFolder | |
| $pullOutput = git pull 2>&1 | |
| if ($pullOutput -match 'Already up[ -]to[ -]date') { | |
| Write-Output " $repoName is already up to date." | |
| } | |
| elseif ($LASTEXITCODE -eq 0) { | |
| Write-Output " $repoName updated successfully." | |
| } | |
| else { | |
| Write-Warning " Error updating $repoName : $pullOutput" | |
| } | |
| Pop-Location | |
| } | |
| else { | |
| Write-Output "Directory exists but isn't a git repository. Recloning $repoName..." | |
| Safe-RemoveItem $repoFolder | |
| git clone $repoUrl $repoFolder | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Invoke-WebRequest -Uri "https://gist.githubusercontent.com/enonethreezed/0a57c8e548c46dc36c23956316b737f0/raw/install_dfir.ps1" -OutFile "$env:TEMP\install_dfir.ps1"; powershell -ExecutionPolicy Bypass -File "$env:TEMP\install_dfir.ps1"