<# .SYNOPSIS Installs and maintains a curated arsenal of PowerShell modules from the PowerShell Gallery and GitHub. .DESCRIPTION This script automates the provisioning of a complete security research and administration environment. It intelligently installs modules from two sources: 1. A curated list of modules from the official PowerShell Gallery. 2. A specialized list of security tools from trusted GitHub repositories. The script is idempotent: it checks for existing modules and only installs what's missing or out-of-date, making it fast and efficient to run multiple times. It includes pre-flight checks to validate that modules and repositories exist before attempting installation. .PARAMETER ForceUpdate A switch parameter that, if present, will bypass the installation check and force a re-installation and update of all modules to their latest versions. .EXAMPLE .\PowerLoader.ps1 Runs the script in its default mode, installing only missing modules and updating outdated ones. .EXAMPLE .\PowerLoader.ps1 -ForceUpdate Forces a re-installation of every module in the list, ensuring you have the latest versions. .NOTES Author: Andreas Nilsen Email: adde88@gmail.com GitHub: www.github.com/adde88 Date: 2025-08-21 - Run this script in a PowerShell 5.1 or newer console. - An internet connection is required. - WARNING: This script downloads and executes code from GitHub. Only run it if you trust the repositories listed in the script. .LICENSE MIT License Copyright (c) 2025 Andreas Nilsen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #> [CmdletBinding()] param ( [Switch]$ForceUpdate ) # --- SCRIPT CONFIGURATION --- $ErrorActionPreference = 'Stop' # --- MAIN SCRIPT --- try { # --- STARTUP HEADER --- Clear-Host Write-Host @" ____ _ _ | _ \ _____ _____ _ __| | ___ __ _ __| | ___ _ __ | |_) / _ \ \ /\ / / _ \ '__| | / _ \ / _` |/ _` |/ _ \ '__| | __/ (_) \ V V / __/ | | |__| (_) | (_| | (_| | __/ | |_| \___/ \_/\_/ \___|_| |_____\___/ \__,_|\__,_|\___|_| "@ -ForegroundColor Cyan Write-Host " Author: Andreas Nilsen (github.com/adde88)" -ForegroundColor Gray Write-Host " License: MIT License" -ForegroundColor Gray Write-Host "" Start-Sleep -Milliseconds 3000 Clear-Host # --- STEP 1: MODULES FROM POWERSHELL GALLERY --- $galleryModules = @( # System Administration & Core Utilities "Pester", "PSScriptAnalyzer", "PSFramework", "PSWindowsUpdate", "Carbon", "NTFSSecurity", "BurntToast", "PSKoans", "PlatyPS", "PSWriteHTML", "PSWritePDF", "DbaTools", "DbaChecks", "PSDesiredStateConfiguration", "GPOZaurr", "DellBIOSProvider", "PSScriptTools", "Microsoft.PowerShell.SecretManagement", # Cloud & DevOps "Az", "AWSPowerShell.NetCore", "AWS.Tools.Installer", "GoogleCloud", "DockerMsftProvider", "Terraform", "Chocolatey", "PSake", "InvokeBuild", "PowerShellForGitHub", "Microsoft.Graph", # Active Directory "DSInternals", # Networking & APIs "Posh-SSH", "PSWSMan", "PowerShell-JWT", "PSHTML", "Polaris", "ThreadJob", "PSExcel", # Security & Compliance "Posh-VirusTotal", "AuditPolicyDsc", "SecurityPolicyDsc", "PSSlack", "Selenium", "PESecurity", "Powershellery", # Virtualization & Configuration Management "VMware.PowerCLI", "Lability", "AutomatedLab", "xDscResourceDesigner", "SimplySql", # Fun & User Experience "Oh-My-Posh", "Terminal-Icons", "Pastel", "Z", "ZLocation", "PSFzf", # Miscellaneous & Niche "Evergreen", "PSPDF", "CredentialManager", "PSLogging", "PSCode", "Pode", "UniversalDashboard", "WinGet", "EZOut", "MarkdownPS", "PSIni", "ISESteroids", "SystemLocaleDsc", "PSGraph" ) Write-Host "------------------------------------------------------------" -ForegroundColor Green Write-Host "STEP 1: Processing modules from the PowerShell Gallery..." -ForegroundColor Green Write-Host "------------------------------------------------------------" foreach ($moduleName in $galleryModules) { try { $installedModule = Get-Module -ListAvailable -Name $moduleName | Sort-Object Version -Descending | Select-Object -First 1 if ($installedModule -and (-not $ForceUpdate)) { Write-Host "[CHECK] Verifying version for '$moduleName'..." -ForegroundColor Gray $galleryModule = Find-Module -Name $moduleName -Repository PSGallery -ErrorAction SilentlyContinue if ($galleryModule -and ([version]$galleryModule.Version -gt [version]$installedModule.Version)) { Write-Host "[UPDATE] Found newer version of '$($moduleName)'. Updating from $($installedModule.Version) to $($galleryModule.Version)..." -ForegroundColor Cyan Install-Module -Name $moduleName -Scope CurrentUser -Repository PSGallery -Force -AllowClobber -AcceptLicense -SkipPublisherCheck Write-Host "[SUCCESS] '$moduleName' updated successfully." -ForegroundColor Green } else { Write-Host "[UP-TO-DATE] Module '$moduleName' is already the latest version." -ForegroundColor Yellow } } elseif (-not $installedModule) { Write-Host "[CHECK] Verifying '$moduleName' in the PSGallery..." -ForegroundColor Gray if (Find-Module -Name $moduleName -Repository PSGallery -ErrorAction SilentlyContinue) { Write-Host "[INSTALL] Installing new module '$moduleName'..." -ForegroundColor Cyan Install-Module -Name $moduleName -Scope CurrentUser -Repository PSGallery -Force -AllowClobber -AcceptLicense -SkipPublisherCheck Write-Host "[SUCCESS] '$moduleName' installed successfully." -ForegroundColor Green } else { Write-Warning "[NOT FOUND] Module '$moduleName' could not be found in the PowerShell Gallery." } } elseif ($ForceUpdate) { Write-Host "[FORCE] Forcing update for '$moduleName'..." -ForegroundColor Magenta Install-Module -Name $moduleName -Scope CurrentUser -Repository PSGallery -Force -AllowClobber -AcceptLicense -SkipPublisherCheck Write-Host "[SUCCESS] '$moduleName' force-updated successfully." -ForegroundColor Green } } catch { Write-Warning "[FAIL] Could not process module '$moduleName'. Error: $($_.Exception.Message)" } } Write-Host "`nPowerShell Gallery module processing complete." -ForegroundColor Green # --- STEP 2: AUTOMATED INSTALLATION FROM GITHUB --- Write-Host "`n------------------------------------------------------------" -ForegroundColor Cyan Write-Host "STEP 2: Processing modules from GitHub..." -ForegroundColor Cyan Write-Host "------------------------------------------------------------" $userModulePath = ($env:PSModulePath -split ';')[0] if (-not (Test-Path -Path $userModulePath)) { New-Item -Path $userModulePath -ItemType Directory | Out-Null } $githubModules = @{ "PowerSploit" = "https://github.com/PowerShellMafia/PowerSploit/archive/refs/heads/master.zip" "Nishang" = "https://github.com/samratashok/nishang/archive/refs/heads/master.zip" "SharpHound" = "https://github.com/BloodHoundAD/SharpHound/archive/refs/heads/master.zip" "Kansa" = "https://github.com/davehull/Kansa/archive/refs/heads/master.zip" "PSReflect" = "https://github.com/mattifestation/PSReflect/archive/refs/heads/master.zip" "Seatbelt" = "https://github.com/GhostPack/Seatbelt/archive/refs/heads/master.zip" "NetworkRecon" = "https://github.com/secabstraction/NetworkRecon/archive/refs/heads/master.zip" "PSAmsi" = "https://github.com/cobbr/PSAmsi/archive/refs/heads/master.zip" "PSAISuite" = "https://github.com/dfinke/psaisuite/archive/refs/heads/main.zip" "WslManagementPS" = "https://github.com/SvenGroot/WslManagementPS/archive/refs/heads/main.zip" "PowerUpSQL" = "https://github.com/NetSPI/PowerUpSQL/archive/refs/heads/master.zip" "MailSniper" = "https://github.com/dafthack/MailSniper/archive/refs/heads/master.zip" } foreach ($name in $githubModules.Keys) { $destinationPath = Join-Path $userModulePath $name if ((Test-Path $destinationPath) -and (-not $ForceUpdate)) { Write-Host "[SKIP] Module '$name' from GitHub is already installed." -ForegroundColor Yellow continue } $url = $githubModules[$name] $tempZip = Join-Path $env:TEMP "$($name).zip" $extractPath = Join-Path $env:TEMP $name try { Write-Host "[CHECK] Verifying URL for '$name'..." -ForegroundColor Gray Invoke-WebRequest -Uri $url -Method Head -ErrorAction Stop | Out-Null Write-Host "[INSTALL] Installing '$name' from GitHub..." -ForegroundColor Cyan Write-Host " - Downloading..." Invoke-WebRequest -Uri $url -OutFile $tempZip -UseBasicParsing Unblock-File -Path $tempZip if (Test-Path -Path $extractPath) { Remove-Item -Path $extractPath -Recurse -Force } Write-Host " - Extracting..." Expand-Archive -Path $tempZip -DestinationPath $extractPath -Force $sourceFolder = Get-ChildItem -Path $extractPath | Select-Object -First 1 if (!$sourceFolder) { throw "Could not find source folder in ZIP for $name" } if (Test-Path -Path $destinationPath) { Remove-Item -Path $destinationPath -Recurse -Force } Write-Host " - Installing to module path..." Move-Item -Path $sourceFolder.FullName -Destination $destinationPath Write-Host "[SUCCESS] '$name' installed successfully." -ForegroundColor Green } catch { Write-Warning "[FAIL] Could not install module '$name' from GitHub. Error: $($_.Exception.Message)" } finally { if (Test-Path -Path $tempZip) { Remove-Item $tempZip -Force } if (Test-Path -Path $extractPath) { Remove-Item $extractPath -Recurse -Force } } } # --- STEP 3: BUILT-IN OR WINDOWS FEATURE MODULES --- Write-Host "`n------------------------------------------------------------" -ForegroundColor Magenta Write-Host "STEP 3: Built-in or Windows Feature Modules" -ForegroundColor Magenta Write-Host "------------------------------------------------------------" Write-Host "- PSReadLine, PowerShellGet, Microsoft.PowerShell.Security, Microsoft.PowerShell.Archive" Write-Host "- NetTCPIP, DNSClient, Tee-Object (cmdlet), PackageManagement, SpeculationControl" Write-Host "- ActiveDirectory, DnsServer, DHCPServer (Enable via RSAT / Windows Features)" Write-Host "- Hyper-V (Enable via 'Turn Windows features on or off')" Write-Host "`n`n------------------------------------------------------------" -ForegroundColor Green Write-Host "Script finished!" -ForegroundColor Green Write-Host "Run 'Get-InstalledModule' to see all installed modules." Write-Host "------------------------------------------------------------" Write-Host "`nThank you for using PowerLoader by Andreas Nilsen." -ForegroundColor Gray } catch { Write-Host "`nAn error occurred:" -ForegroundColor Red Write-Host $_.Exception.Message -ForegroundColor Red Write-Host "Script execution halted." -ForegroundColor Red }