├── .github └── workflows │ └── powershell.yml ├── Hellbomb Script.ps1 ├── LICENSE ├── README.md └── SECURITY.MD /.github/workflows/powershell.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | # 6 | # https://github.com/microsoft/action-psscriptanalyzer 7 | # For more information on PSScriptAnalyzer in general, see 8 | # https://github.com/PowerShell/PSScriptAnalyzer 9 | 10 | name: PSScriptAnalyzer 11 | 12 | on: 13 | push: 14 | branches: [ "main" ] 15 | pull_request: 16 | branches: [ "main" ] 17 | schedule: 18 | - cron: '45 11 * * 0' 19 | 20 | permissions: 21 | contents: read 22 | 23 | jobs: 24 | build: 25 | permissions: 26 | contents: read # for actions/checkout to fetch code 27 | security-events: write # for github/codeql-action/upload-sarif to upload SARIF results 28 | actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status 29 | name: PSScriptAnalyzer 30 | runs-on: ubuntu-latest 31 | steps: 32 | - uses: actions/checkout@v4 33 | 34 | - name: Run PSScriptAnalyzer 35 | uses: microsoft/psscriptanalyzer-action@6b2948b1944407914a58661c49941824d149734f 36 | with: 37 | # Check https://github.com/microsoft/action-psscriptanalyzer for more info about the options. 38 | # The below set up runs PSScriptAnalyzer to your entire repository and runs some basic security rules. 39 | path: .\ 40 | recurse: false 41 | # Include your own basic security rules. Removing this option will run all the rules 42 | includeRule: '"PSAvoidGlobalAliases", "PSAvoidUsingConvertToSecureStringWithPlainText"' 43 | repoToken: ${{ secrets.GITHUB_TOKEN }} 44 | output: results.sarif 45 | 46 | # Upload the SARIF file generated in the previous step 47 | - name: Upload SARIF results file 48 | uses: github/codeql-action/upload-sarif@v3 49 | with: 50 | sarif_file: results.sarif 51 | -------------------------------------------------------------------------------- /Hellbomb Script.ps1: -------------------------------------------------------------------------------- 1 | using namespace System.Management.Automation.Host 2 | # Get the current host UI RawUI object 3 | $pshost = Get-Host 4 | $psWindow = $pshost.UI.RawUI 5 | # Set the window size (height and width) 6 | $newWindowSize = $psWindow.WindowSize 7 | $newWindowSize.Height = 50 # Adjust height as needed 8 | $psWindow.WindowSize = $newWindowSize 9 | # Hellbomb Script 10 | # Requires -RunAsAdministrator 11 | $ErrorActionPreference = 'Stop' 12 | Set-StrictMode -Version Latest 13 | $script:Tests = @{ 14 | "IntelMicrocodeCheck" = @{ 15 | 'TestPassed' = $null 16 | 'AffectedModels' = @("13900", "13700", "13790", "13700", "13600", "13500", "13490", "13400", "14900", "14790", "14700", "14600", "14500", "14490", "14400") 17 | 'LatestMicrocode' = '12F' 18 | 'TestFailMsg' = @' 19 | Write-Host "$([Environment]::NewLine)[FAIL] " -ForegroundColor Red -NoNewLine 20 | Write-Host "CPU model with unpatched microcode detected!! " -ForegroundColor Yellow -NoNewLine; Write-Host "$script:myCPU" -ForegroundColor White 21 | Write-Host "$([Environment]::NewLine) WARNING: If you are NOT currently having stability issues, please update $([Environment]::NewLine) your motherboard UEFI (BIOS) ASAP to prevent permanent damage to the CPU." -ForegroundColor Yellow 22 | Write-Host "$([Environment]::NewLine) If you ARE experiencing stability issues, your CPU may be unstable$([Environment]::NewLine) and permanently damaged." -ForegroundColor Red 23 | Write-Host "$([Environment]::NewLine) For more information, visit: $([Environment]::NewLine) https://www.theverge.com/2024/7/26/24206529/intel-13th-14th-gen-crashing-instability-cpu-voltage-q-a" -ForegroundColor Cyan 24 | Pause "$([Environment]::NewLine) Any proposed fixes by this tool may fail to work if your CPU is damaged.$([Environment]::NewLine)Press any key to continue..." -ForegroundColor Yellow 25 | '@ 26 | 'TestPassedMsg' = @' 27 | Write-Host "Your CPU: " -ForegroundColor Cyan -NoNewLine ; Write-Host "$script:myCPU " -NoNewLine 28 | Write-Host "is running the latest 0x12B microcode." -ForegroundColor Green 29 | '@ 30 | 'NotApplicableMsg' = @' 31 | Write-Host "Your CPU model: " -ForegroundColor Cyan -NoNewLine ; Write-Host "$script:myCPU " -NoNewLine 32 | Write-Host "is not affected by the Intel CPU issues." -ForegroundColor Green 33 | '@ 34 | 'ErrorMsg' = @' 35 | Write-Host "Error occured determining microcode version for CPU model: " -ForegroundColor Red -NoNewLine ; Write-Host "$script:myCPU " 36 | '@ 37 | } 38 | "PendingReboot" = @{ 39 | 'TestPassed' = $null 40 | 'rebootRequired' = $false 41 | 'keys' = @( 42 | "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending", 43 | "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootInProgress", 44 | "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackagesPending", 45 | "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired", 46 | "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations") 47 | 'TestFailMsg' = @' 48 | Write-Host "$([Environment]::NewLine)[FAIL] " -ForegroundColor Red -NoNewLine 49 | Write-Host " Windows is reporting a pending reboot is required." -ForegroundColor Yellow -NoNewLine 50 | Write-Host "$([Environment]::NewLine)Please exit the script and reboot your machine..." -ForegroundColor Cyan 51 | '@ 52 | } 53 | "BadPrinter" = @{ 54 | 'TestPassed' = $null 55 | 'TestFailMsg' = @' 56 | Write-Host "$([Environment]::NewLine)[FAIL] " -ForegroundColor Red -NoNewLine 57 | Write-Host "OneNote for Windows 10 printer detected! This can cause crashes on game startup." -ForegroundColor Yellow -NoNewLine 58 | Write-Host "$([Environment]::NewLine) Please remove this printer from your computer." -ForegroundColor Cyan 59 | '@ 60 | } 61 | "LongSysUptime" = @{ 62 | 'TestPassed' = $null 63 | 'TestFailMsg' = @' 64 | Write-Host "$([Environment]::NewLine)[FAIL] " -ForegroundColor Red -NoNewLine 65 | Write-Host "Your computer has not been restarted in $($script:Tests.LongSysUptime.SystemUptime) days." -ForegroundColor Yellow 66 | Write-Host " Please restart your computer. Restart only. Do not use 'Shutdown'." -ForegroundColor Cyan 67 | '@ 68 | } 69 | "AVX2" = @{ 70 | 'TestPassed' = $null 71 | 'TestFailMsg' = @' 72 | Write-Host "$([Environment]::NewLine)[FAIL] " -ForegroundColor Red -NoNewLine 73 | Write-Host " Your CPU does not support the AVX2 instruction set." -ForegroundColor Yellow 74 | '@ 75 | } 76 | "MultiChannelMemory" = @{ 77 | 'TestPassed' = $null 78 | 'TestFailMsg' = @' 79 | Write-Host "$([Environment]::NewLine)[FAIL] " -ForegroundColor Red -NoNewLine 80 | Write-Host "Memory running in single-channel mode. This will hurt performance." -ForegroundColor Yellow 81 | '@ 82 | } 83 | "MatchingMemory" = @{ 84 | 'TestPassed' = $null 85 | 'RAMInfo' = $null 86 | 'TestFailMsg' = @' 87 | Write-Host "$([Environment]::NewLine)[FAIL] " -ForegroundColor Red -NoNewLine 88 | Write-Host "You have mixed memory. This can cause performance and stability issues." -ForegroundColor Yellow 89 | $formattedTable = $script:Tests.MatchingMemory.RAMInfo | Format-Table -AutoSize | Out-String 90 | $indentedTable = $formattedTable -split "$([Environment]::NewLine)" | ForEach-Object { " $_" } 91 | $indentedTable | ForEach-Object { Write-Host $_ -ForegroundColor White } 92 | '@ 93 | } 94 | "DomainTest" = @{ 95 | 'TestPassed' = $null 96 | 'DomainList' = @( 97 | [PSCustomObject]@{ RequiredDomains = 'akamaihd.net'; PassedTest = $null }, 98 | [PSCustomObject]@{ RequiredDomains = 'api.live.prod.thehelldiversgame.com'; PassedTest = $null }, 99 | [PSCustomObject]@{ RequiredDomains = 'cluster-a.playfabapi.com'; PassedTest = $null }, 100 | [PSCustomObject]@{ RequiredDomains = 'gameguard.co.kr'; PassedTest = $null }, 101 | [PSCustomObject]@{ RequiredDomains = 'gameguard.thehelldiversgame.com'; PassedTest = $null }, 102 | [PSCustomObject]@{ RequiredDomains = 'mgr.gameguard.co.kr'; PassedTest = $null }, 103 | [PSCustomObject]@{ RequiredDomains = 'ocsp.digicert.com'; PassedTest = $null }, 104 | [PSCustomObject]@{ RequiredDomains = 'playfabapi.com'; PassedTest = $null }, 105 | [PSCustomObject]@{ RequiredDomains = 'pss-cloud.net'; PassedTest = $null }, 106 | [PSCustomObject]@{ RequiredDomains = 'steamcommunity.com'; PassedTest = $null }, 107 | [PSCustomObject]@{ RequiredDomains = 'steamcontent.com'; PassedTest = $null }, 108 | [PSCustomObject]@{ RequiredDomains = 'steamgames.com'; PassedTest = $null }, 109 | [PSCustomObject]@{ RequiredDomains = 'steampowered.com'; PassedTest = $null }, 110 | [PSCustomObject]@{ RequiredDomains = 'steamstatic.com'; PassedTest = $null }, 111 | [PSCustomObject]@{ RequiredDomains = 'steamusercontent.com'; PassedTest = $null }, 112 | [PSCustomObject]@{ RequiredDomains = 'testament.api.wwsga.me'; PassedTest = $null } 113 | ) 114 | 'TestFailMsg' = @' 115 | Write-Host "$([Environment]::NewLine)[FAIL] " -ForegroundColor Red -NoNewLine 116 | Write-Host "The following URLs failed to resolve with DNS" -ForegroundColor Yellow 117 | $script:Tests.DomainTest.DomainList | Where-Object { $_.PassedTest -ne $true } | ForEach-Object { " $($_.RequiredDomains)" } | Write-Host -ForegroundColor White 118 | '@ 119 | } 120 | "FirewallRules" = @{ 121 | 'TestPassed' = $null 122 | 'Rules' = @( 123 | [PSCustomObject]@{ RuleName = 'Inbound TCP Rule'; PassedTest = $null }, 124 | [PSCustomObject]@{ RuleName = 'Inbound UDP Rule'; PassedTest = $null } 125 | ) 126 | 'TestFailMsg' = @' 127 | Write-Host "$([Environment]::NewLine)[FAIL] " -ForegroundColor Red -NoNewLine 128 | Write-Host "The Windows Firewall is missing the following required rules: " -ForegroundColor Yellow 129 | $script:Tests.FirewallRules.Rules | Where-Object {$_.PassedTest -ne $true } | ForEach-Object { " Helldivers 2 $($_.Rulename)" } | Write-Host -ForegroundColor White 130 | Start-Process wf.msc 131 | '@ 132 | } 133 | "GameMods" = @{ 134 | 'TestPassed' = $null 135 | 'TestFailMsg' = @' 136 | Write-Host "$([Environment]::NewLine)[FAIL] " -ForegroundColor Red -NoNewLine 137 | Write-Host 'Mods were detected!' -ForegroundColor Yellow 138 | Write-Host ' Use option ' -ForegroundColor Cyan -NoNewLine 139 | Write-Host 'Q'-ForegroundColor White -BackgroundColor Black -NoNewLine 140 | Write-Host ' to attempt removal.' -ForegroundColor Cyan 141 | '@ 142 | } 143 | "PageFileEnabled" = @{ 144 | 'TestPassed' = $null 145 | 'TestFailMsg' = @' 146 | Write-Host "$([Environment]::NewLine)[WARNING] " -ForegroundColor Yellow -NoNewLine 147 | Write-Host 'Your page file is set to zero. This may cause the game to crash on launch.' -ForegroundColor Cyan 148 | '@ 149 | } 150 | "SecureBootEnabled" = @{ 151 | 'TestPassed' = $null 152 | 'TestFailMsg' = @' 153 | Write-Host "$([Environment]::NewLine)[WARNING] " -ForegroundColor Yellow -NoNewLine 154 | Write-Host 'Secure Boot is disabled! Can cause GameGuard errors & disables Above 4G Decoding/Nvidia Resizeable BAR/AMD SAM on Windows 11.' -ForegroundColor Cyan 155 | 156 | '@ 157 | } 158 | "SystemClockAccurate" = @{ 159 | 'TestPassed' = $null 160 | 'TestFailMsg' = @' 161 | Write-Host "$([Environment]::NewLine)[FAIL] " -ForegroundColor Red -NoNewLine 162 | Write-Host 'Your time and/or date is inaccurate. This will cause connection issues.' -ForegroundColor Cyan 163 | '@ 164 | } 165 | "VSyncDisabled" = @{ 166 | 'TestPassed' = $null 167 | 'TestFailMsg' = @' 168 | Write-Host "$([Environment]::NewLine)[WARNING] " -ForegroundColor Yellow -NoNewLine 169 | Write-Host 'V-Sync is enabled in game settings. This may cause framerate issues.' -ForegroundColor Cyan 170 | '@ 171 | } 172 | } 173 | Function Show-Variables { 174 | If ($script:AppIDFound -eq $true) { 175 | Clear-Host 176 | Write-Host "AppID: $AppID is located in directory:" -ForegroundColor Green 177 | Write-Host $script:AppInstallPath -ForegroundColor White 178 | Write-Host "Current build of AppID $AppID is: $script:BuildID" -ForegroundColor Cyan 179 | } 180 | Else { 181 | Write-Host 'Error. AppID was not found.' -ForegroundColor Red 182 | } 183 | Return 184 | } 185 | # Function adapted from: https://stackoverflow.com/questions/20886243/press-any-key-to-continue#:~:text=Function%20pause%20(%24message) 186 | Function pause ($message) { 187 | # Check if running Powershell ISE 188 | If (Test-Path variable:global:psISE) { 189 | Add-Type -AssemblyName System.Windows.Forms 190 | [System.Windows.Forms.MessageBox]::Show("$message") 191 | } 192 | Else { 193 | Write-Host "$message"$([Environment]::NewLine) -ForegroundColor Yellow 194 | $x = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyDown") 195 | } 196 | } 197 | 198 | Function Install-EXE { 199 | param ( 200 | [Parameter(Mandatory = $true, Position = 0)] 201 | [ValidateNotNullOrEmpty()] 202 | [string] $DownloadURL, 203 | [Parameter(Mandatory = $true, Position = 1)] 204 | [ValidateNotNullOrEmpty()] 205 | [string] $DownloadPath, 206 | [Parameter(Mandatory = $true, Position = 2)] 207 | [ValidateNotNullOrEmpty()] 208 | [string] $FileName, 209 | [Parameter(Mandatory = $true, Position = 3)] 210 | [ValidateNotNullOrEmpty()] 211 | [string] $SHA256Hash, 212 | [Parameter(Mandatory = $true, Position = 4)] 213 | [ValidateNotNullOrEmpty()] 214 | [string] $CommonName 215 | ) 216 | # Turn off progress bar to speed up download 217 | $ProgressPreference = 'SilentlyContinue' 218 | Write-Host "$([Environment]::NewLine)Downloading $CommonName..." -ForegroundColor Cyan 219 | Invoke-WebRequest $DownloadURL -OutFile ($DownloadPath + $FileName) 220 | If ( (Get-FileHash ($DownloadPath + $FileName)).Hash -eq $SHA256Hash) { 221 | Write-Host 'Installing... look for UAC prompts' -ForegroundColor Cyan 222 | $Error.Clear() 223 | Try { 224 | $installProcess = Start-Process ($DownloadPath + $FileName) -ArgumentList "/q" -PassThru -Wait 225 | 226 | If ( $installProcess.ExitCode -ne 0) { 227 | Write-Host "$([Environment]::NewLine)UAC prompt was canceled, or another error occurred installing $CommonName$([Environment]::NewLine)" -ForegroundColor Red 228 | Remove-Item -Path $DownloadPath$FileName 229 | # Re-enable Progress Bar 230 | $ProgressPreference = 'Continue' 231 | Return 232 | } 233 | } 234 | Catch { Write-Host "Error occurred installing $CommonName" -ForegroundColor Red } 235 | If (!$Error) { 236 | Write-Host "$CommonName installed successfully!" -ForegroundColor Green 237 | } 238 | } 239 | Else { 240 | Write-Host "Installer file hash verification failed. Aborting $CommonName" -ForegroundColor Yellow 241 | } 242 | Remove-Item -Path $DownloadPath$FileName 243 | # Re-enable Progress Bar 244 | $ProgressPreference = 'Continue' 245 | } 246 | 247 | Function Reset-GameGuard { 248 | # Delete GameGuard files 249 | $Error.Clear() 250 | Try { Remove-Item -Path $script:AppInstallPath\bin\GameGuard\*.* } 251 | Catch { 252 | Write-Host ("Error occurred deleting GameGuard files in " + 253 | $script:AppInstallPath + "\bin\GameGuard") -ForegroundColor Red 254 | } 255 | If (!$Error) { Write-Host "Helldivers 2\bin\GameGuard cleared successfully!" -ForegroundColor Green } 256 | # Uninstall GameGuard 257 | $Error.Clear() 258 | Try { Start-Process $script:AppInstallPath\tools\gguninst.exe -Wait } 259 | Catch { Write-Host "Error occurred uninstalling GameGuard" -ForegroundColor Red } 260 | If (!$Error) { Write-Host "GameGuard Uninstalled Successfully" -ForegroundColor Green } 261 | # Install GameGuard 262 | $Error.Clear() 263 | Try { Start-Process $script:AppInstallPath\tools\GGSetup.exe -Wait } 264 | Catch { Write-Host "Error occurred installing GameGuard" -ForegroundColor Red } 265 | If (!$Error) { Write-Host "GameGuard installed successfully"$([Environment]::NewLine) -ForegroundColor Green } 266 | Return 267 | } 268 | Function Remove-HD2AppData { 269 | $Error.Clear() 270 | Try { Remove-Item -Path $env:APPDATA\Arrowhead\Helldivers2\* -Recurse } 271 | Catch { Write-Host "Error occurred deleting contents of $env:APPDATA\Arrowhead\Helldivers2\" -ForegroundColor Red } 272 | If (!$Error) { 273 | Write-Host "Helldivers 2 AppData has been cleared successfully!" -ForegroundColor Green 274 | Write-Host "Now please use Steam's " -NoNewLine -ForegroundColor Cyan 275 | Write-Host 'Verify Integrity of Game Files ' -NoNewLine 276 | Write-Host 'function.' -ForegroundColor Cyan 277 | } 278 | Menu 279 | } 280 | 281 | Function Get-IsProcessRunning { 282 | [CmdletBinding()] 283 | Param( 284 | [Parameter(Mandatory = $True)] 285 | [Object[]]$InputObject 286 | ) 287 | If (Get-Process -ProcessName $InputObject.ProcessName -ErrorAction SilentlyContinue) { 288 | Write-Host $InputObject.ErrorMsg -ForegroundColor Red 289 | Pause 'Press any key to Exit...' 290 | Exit 291 | } 292 | } 293 | Function Uninstall-VCRedist { 294 | # List of Visual C++ Redistributables to uninstall 295 | $redistributables = @( 296 | 'Microsoft Visual C++ 2012 Redistributable (x64)', 297 | 'Microsoft Visual C++ 2013 Redistributable (x64)', 298 | 'Microsoft Visual C++ 2015-2022 Redistributable (x64)' 299 | ) 300 | 301 | ForEach ($programName in $redistributables) { 302 | $programlist = @($script:InstalledProgramsList | Where-Object { $_.DisplayName -like "$programName*" }) 303 | Write-Host "$([Environment]::NewLine)⚠️ Please restart the computer once this process completes." -ForegroundColor Yellow 304 | If ($programlist.Count -gt 0) { 305 | ForEach ( $program in $programlist ) 306 | { Write-Host $program.QuietUninstallString -ForegroundColor Cyan 307 | Try { 308 | Invoke-Expression "& $($program.QuietUninstallString.ToString())" 309 | Write-Host "Uninstallation of $programName completed." 310 | } Catch { 311 | Write-Host "Failed to uninstall $programName $_" -ForegroundColor Red 312 | } 313 | } 314 | } Else { 315 | Write-Host "Program $programName not found." 316 | } 317 | } 318 | } 319 | Function Install-VCRedist { 320 | Pause "$([Environment]::NewLine) ⚠️ Make sure you used option U to uninstall current VC++ Redists before using this option..." -ForegroundColor Yellow 321 | Pause "$([Environment]::NewLine) This function will likely cause your computer to restart. Save any work before continuing..." -ForegroundColor Cyan 322 | Install-EXE -DownloadURL 'https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe' ` 323 | -DownloadPath ((New-Object -ComObject Shell.Application).Namespace('shell:Downloads').Self.Path) -FileName 'VisualC++Redist2012.exe' ` 324 | -SHA256Hash '681BE3E5BA9FD3DA02C09D7E565ADFA078640ED66A0D58583EFAD2C1E3CC4064' -CommonName '2012 Visual C++ Redistributable' 325 | 326 | Install-EXE -DownloadURL 'https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe' ` 327 | -DownloadPath ((New-Object -ComObject Shell.Application).Namespace('shell:Downloads').Self.Path) -FileName 'VisualC++Redist2013.exe' ` 328 | -SHA256Hash 'E554425243E3E8CA1CD5FE550DB41E6FA58A007C74FAD400274B128452F38FB8' -CommonName '2013 Visual C++ Redistributable' 329 | 330 | Install-EXE -DownloadURL 'https://download.visualstudio.microsoft.com/download/pr/1754ea58-11a6-44ab-a262-696e194ce543/3642E3F95D50CC193E4B5A0B0FFBF7FE2C08801517758B4C8AEB7105A091208A/VC_redist.x64.exe' ` 331 | -DownloadPath ((New-Object -ComObject Shell.Application).Namespace('shell:Downloads').Self.Path) -FileName 'VisualC++Redist2019.exe' ` 332 | -SHA256Hash '3642E3F95D50CC193E4B5A0B0FFBF7FE2C08801517758B4C8AEB7105A091208A' -CommonName '2019 Visual C++ Redistributable' 333 | 334 | Pause "$([Environment]::NewLine)Please restart the computer before continuing." -ForegroundColor Yellow 335 | Exit 336 | } 337 | Function Find-BlacklistedDrivers { 338 | $BadDeviceList = @('A-Volute', 'Hamachi', 'Nahimic', 'LogMeIn Hamachi', 'Sonic') 339 | $FoundBlacklistedDevice = $false 340 | Write-Host "$([Environment]::NewLine)Checking for devices that are known to cause issues..." -ForegroundColor Cyan 341 | $DeviceDatabase = Get-PnpDevice 342 | # Check for blacklisted devices 343 | ForEach ($device in $DeviceDatabase) { 344 | ForEach ($badDevice in $BadDeviceList) { 345 | If ($device.FriendlyName -like "$badDevice*" -and $device.Status -eq "OK") { 346 | Write-Host ("⚠️ " + $device.FriendlyName + " device detected! Known compatibility issues! Please disable using Device Manager.") -ForegroundColor Red 347 | $FoundBlacklistedDevice = $true 348 | Break # Exit the inner loop if a bad device is found 349 | } 350 | } 351 | } 352 | If (-not $FoundBlacklistedDevice) { 353 | Write-Host "No problematic devices found." -ForegroundColor Green 354 | } 355 | # Check for missing critical drivers (AMD and Intel only) 356 | $MissingDriverPresentCounter = ($DeviceDatabase | Where-Object { 357 | $_.Present -eq $true -and $_.InstanceId -match "VEN_1022|VEN_8086" -and 358 | ( $_.FriendlyName -match "Base System Device|Unknown" -or $_.Status -eq 'Unknown' ) 359 | } | Measure-Object).Count 360 | $MissingDriverDisconnectedCounter = ($DeviceDatabase | Where-Object { 361 | $_.Present -eq $false -and $_.InstanceId -match "VEN_1022|VEN_8086" -and 362 | ( $_.FriendlyName -match "Base System Device|Unknown" -or $_.Status -eq 'Unknown' ) 363 | } | Measure-Object).Count 364 | If ( $MissingDriverPresentCounter -gt 0 ) { 365 | Write-Host "$([Environment]::NewLine)⚠️You are missing critical AMD and/or Intel drivers." -ForegroundColor Yellow 366 | Write-Host "Please install them from your motherboard manufacturer or OEM system support site." -ForegroundColor Yellow 367 | } 368 | If ( $MissingDriverDisconnectedCounter -gt 2 ) { 369 | Write-Host "$([Environment]::NewLine)ℹ️ It appears your motherboard/CPU was upgraded without re-installing Windows." -ForegroundColor Yellow 370 | Write-Host "If this applies to you, recommend using the Reset Windows feature or re-installing Windows." -ForegroundColor Yellow 371 | } 372 | Return 373 | } 374 | Function Test-BadPrinters { 375 | # Get the Print Spooler service status 376 | $spoolerService = Get-Service -Name "Spooler" 377 | 378 | If ($spoolerService.StartType -ne "Disabled") { 379 | If ($spoolerService.Status -ne "Running") { 380 | # Restart the Print Spooler service if it's not running and not disabled 381 | Start-Service -Name "Spooler" 382 | } 383 | 384 | Get-Printer | ForEach-Object { 385 | If ($_.Name -eq 'OneNote for Windows 10') { 386 | $script:Tests.BadPrinter.TestPassed = $false 387 | } 388 | } 389 | $script:Tests.BadPrinter.TestPassed = $script:Tests.BadPrinter.TestPassed -ne $false 390 | } 391 | Else { $script:Tests.BadPrinter.TestPassed = $true } 392 | } 393 | 394 | Function Find-CPUInfo { 395 | $script:myCPU = (Get-CimInstance -ClassName Win32_Processor).Name.Trim() 396 | If ( $script:myCPU.Contains('Intel') ) { 397 | ForEach ($cpuModel in $script:Tests.IntelMicrocodeCheck.AffectedModels) { 398 | If (($script:myCPU).Contains($cpuModel)) { 399 | # Check Microcode; adapted from: https://www.xf.is/2018/06/28/view-cpu-microcode-revision-from-powershell/ 400 | $registrypath = "Registry::HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0\" 401 | $CPUProperties = Get-ItemProperty -Path $registrypath 402 | $runningMicrocode = $CPUProperties."Update Revision" 403 | # Convert to string and remove leading zeros 404 | Try { $runningMicrocodeInHex = ('0x'+(-join ( $runningMicrocode[0..4] | ForEach-Object { $_.ToString("X2") } )).TrimStart('0')) 405 | If ( ($runningMicrocodeInHex -contains $script:Tests.IntelMicrocodeCheck.LatestMicrocode) ) { 406 | $script:Tests.IntelMicrocodeCheck.TestPassed = $true 407 | Invoke-Expression $script:Tests.IntelMicrocodeCheck.TestPassedMsg 408 | Return 409 | } 410 | Else { 411 | $script:Tests.IntelMicrocodeCheck.TestPassed = $false 412 | Return 413 | } 414 | } 415 | Catch { 416 | Invoke-Expression $script:Tests.IntelMicrocodeCheck.ErrorMsg 417 | $script:Tests.IntelMicrocodeCheck.TestPassed = $false 418 | Return 419 | } 420 | } 421 | } 422 | } 423 | $script:Tests.IntelMicrocodeCheck.TestPassed = $true 424 | Invoke-Expression $script:Tests.IntelMicrocodeCheck.NotApplicableMsg 425 | Return 426 | } 427 | Function Show-MotherboardInfo { 428 | $motherboardInfo = @( 429 | [pscustomobject]@{ 'Motherboard Info' = 'Manufacturer: '+(Get-CimInstance -ClassName Win32_BaseBoard).Manufacturer.Trim(); 430 | 'UEFI Info' = 'SMBIOS Version: '+(Get-CimInstance -ClassName Win32_BIOS).SMBIOSBIOSVersion.Trim() } 431 | [pscustomobject]@{ 'Motherboard Info' = 'Product: '+(Get-CimInstance -ClassName Win32_BaseBoard).Product.Trim(); 432 | 'UEFI Info' = 'Manufacturer: '+(Get-CimInstance -ClassName Win32_BIOS).Manufacturer.Trim() } 433 | [pscustomobject]@{ 'Motherboard Info' = ''; 434 | 'UEFI Info' = 'BIOS Version: '+(Get-CimInstance -ClassName Win32_BIOS).Name.Trim() } 435 | ) 436 | $motherboardInfo | Format-Table 'Motherboard Info', 'UEFI Info' -AutoSize 437 | } 438 | Function Show-GPUInfo { 439 | $GPUS = Get-CimInstance -ClassName Win32_VideoController 440 | 441 | # Print GPU information 442 | ForEach ($gpu in $gpus) { 443 | $OEMDriverVersionNum = $gpu.DriverVersion 444 | If ( $gpu.Name.Contains( 'AMD' ) ) { 445 | Try { 446 | $OEMDriverVersionNum = (Get-ItemProperty -Path "HKLM:\SOFTWARE\ATI Technologies\Install" -Name RadeonSoftwareVersion).RadeonSoftwareVersion 447 | } Catch { 448 | $OEMDriverVersionNum = $gpu.DriverVersion + ' ( Windows Driver Version Format ) ' 449 | } 450 | } 451 | If ( $gpu.Name.Contains( 'NVIDIA' ) ) { 452 | Try { 453 | $process = New-Object System.Diagnostics.Process 454 | $process.StartInfo = New-Object System.Diagnostics.ProcessStartInfo 455 | $process.StartInfo.FileName = "nvidia-smi" 456 | $process.StartInfo.Arguments = "--query-gpu=driver_version --format=csv,noheader" 457 | $process.StartInfo.RedirectStandardOutput = $true 458 | $process.StartInfo.UseShellExecute = $false 459 | $process.StartInfo.CreateNoWindow = $true 460 | # Start the process 461 | $process.Start() | Out-Null 462 | # Read the output as a string 463 | $OEMDriverVersionNum = New-Object System.IO.StreamReader($process.StandardOutput.BaseStream, [System.Text.Encoding]::UTF8) 464 | $OEMDriverVersionNum = $OEMDriverVersionNum.ReadToEnd().Trim() 465 | $process.WaitForExit() 466 | } Catch { 467 | $OEMDriverVersionNum = $gpu.DriverVersion + ' ( Windows Driver Version Format ) ' 468 | } 469 | } 470 | Write-Host "-------------------------------------" 471 | Write-Host " GPU Model: $($gpu.Name)" 472 | Write-Host " Drvr Ver.: $OEMDriverVersionNum" 473 | Write-Host " Status: " -NoNewLine 474 | If ( $gpu.Status -ne 'OK' ) { 475 | Write-Host $gpu.Status -ForegroundColor Red 476 | } 477 | Else { Write-Host $gpu.Status -ForegroundColor Green } 478 | Write-Host "-------------------------------------" 479 | } 480 | } 481 | Function Show-OSInfo { 482 | $script:OSVersion = (Get-CimInstance -ClassName Win32_OperatingSystem).Caption 483 | Write-Host ($([Environment]::NewLine)+'Operating System:').Trim() -NoNewLine -ForegroundColor Cyan 484 | Write-Host '' $script:OSversion -ForegroundColor Magenta 485 | } 486 | Function Test-AVX2 { 487 | # Check for AVX2 488 | # Define the pattern to match the line 489 | $pattern = "^\tInstructions\ssets\t.*AVX2" 490 | # Search for the line that matches the pattern 491 | $match = $script:HardwareInfoText | Select-String -Pattern $pattern 492 | If ($match) { 493 | $script:Tests.AVX2.TestPassed = $true 494 | } Else { 495 | $script:Tests.AVX2.TestPassed = $false 496 | } 497 | } 498 | Function Get-MemorySpeed { 499 | # RAM Speed 500 | $pattern = '^Memory Frequency.*$' 501 | # Find and display lines matching the pattern 502 | $match = $script:HardwareInfoText | Select-String -Pattern $pattern 503 | $null = If ($match) { 504 | $pattern = '\d\d\d\d.\d' 505 | $match -match $pattern 506 | $RAMFrequency = [int]$Matches[0] 507 | Write-Host "$([Environment]::NewLine)RAM is currently running at " -NoNewLine -ForegroundColor Cyan 508 | Write-Host ([string]::Concat(($RAMFrequency * 2), ' MHz')) -ForegroundColor White 509 | } 510 | } 511 | Function Get-MemoryPartNumber{ 512 | # Load DIMM Data 513 | $dimmData = @() 514 | # Temporary storage for the current DIMM data 515 | $currentDimm = @{} 516 | $skipDimm = $false 517 | 518 | # Iterate through each line 519 | foreach ($line in $script:HardwareInfoText) { 520 | If ($line -match "^DIMM #\s+(\d+)") { 521 | # Save the current DIMM data if it exists 522 | If ($currentDimm.Count -gt 0 -and -not $skipDimm) { 523 | $dimmData += [PSCustomObject]@{ 524 | DIMM = $currentDimm['DIMM'] 525 | Size = $currentDimm['Size'] 526 | PartNumber = $currentDimm['Part Number'] 527 | } 528 | } 529 | # Reset for the new DIMM 530 | $currentDimm = @{} 531 | $skipDimm = $false 532 | 533 | # Add the DIMM number 534 | $currentDimm['DIMM'] = $Matches[1] 535 | } ElseIf ($line -match "^\s*SPD Registers") { 536 | # Skip processing this DIMM if "SPD Registers" is the first line after "DIMM #" 537 | $skipDimm = $true 538 | } ElseIf (-not $skipDimm) { 539 | If ($line -match "^\s+Size\s+(.+)") { 540 | $currentDimm["Size"] = $Matches[1] 541 | } ElseIf ($line -match "^\s+Part number\s+(.+)") { 542 | $currentDimm['Part Number'] = $Matches[1] 543 | } 544 | } 545 | } 546 | # Save the last DIMM data if it wasn't skipped 547 | If ($currentDimm.Count -gt 0 -and -not $skipDimm) { 548 | $dimmData += [PSCustomObject]@{ 549 | DIMM = $currentDimm['DIMM'] 550 | Size = $currentDimm['Size'] 551 | PartNumber = $currentDimm['Part Number'] 552 | } 553 | } 554 | $script:Tests.MatchingMemory.RAMInfo = $dimmData 555 | If ( ($dimmData.PartNumber | Select-Object -Unique | Measure-Object).Count -eq 1 -and 556 | ($dimmData.Size | Select-Object -Unique | Measure-Object).Count -eq 1 ) { 557 | $script:Tests.MatchingMemory.TestPassed = $true 558 | } Else { 559 | $script:Tests.MatchingMemory.TestPassed = $false 560 | } 561 | } 562 | Function Get-HardwareInfo { 563 | $workingDirectory = (New-Object -ComObject Shell.Application).Namespace('shell:Downloads').Self.Path 564 | # Define URLs and paths 565 | $CPUZUrl = "https://download.cpuid.com/cpu-z/cpu-z_2.15-en.zip" 566 | $CPUZZip = "$workingDirectory\cpu-z_2.15-en.zip" 567 | $CPUZExe = "$workingDirectory\cpuz_x64.exe" 568 | $CPUZFile = "cpuz_x64.exe" 569 | # Download and extract CPU-Z if it does not exist 570 | If (-Not (Test-Path $CPUZExe)) { 571 | If (-Not (Test-Path $CPUZZip)) { 572 | Try { 573 | Invoke-WebRequest -Uri $CPUZUrl -OutFile $CPUZZip -ErrorAction Continue 574 | } Catch { 575 | Return Write-Error "Failed to download cpuz_2.15-en.zip: $_" -ForegroundColor Red 576 | } 577 | } 578 | If ( (Get-FileHash $CPUZZip) -ne 'C8461D995D77A8FE1E8C5823403E88B04B733165CC151083B26379F1FE4B9501' ) { 579 | Remove-Item $CPUZZip 580 | Invoke-WebRequest -Uri $CPUZUrl -OutFile $CPUZZip -ErrorAction Continue 581 | } 582 | Try { 583 | Get-CPUZ -zipPath $CPUZZip -extractTo $workingDirectory -targetFile $CPUZFile 584 | } 585 | Catch { 586 | Return Write-Error 'CPU-Z extraction failed. Download cpuz_2.15-en.zip from https://download.cpuid.com/cpu-z/cpu-z_2.15-en.zip and place in your Downloads.' 587 | } 588 | } 589 | $CPUZSHA256 = (Get-FileHash $workingDirectory\cpuz_x64.exe).Hash 590 | If ( $CPUZSHA256 -ne 'FCAC6AA0D82943D6BB40D07FDA5C1A1573D7EA9259B9403F3607304ED345DBB9' ) { 591 | Return Write-Error 'cpuz_x64.exe failed hash verification... cannot scan hardware.' 592 | } 593 | 594 | # Run CPU-Z and dump report to file 595 | Write-Host "$([Environment]::NewLine)Scanning hardware using CPU-Z. Please wait..." -ForegroundColor Cyan -NoNewline 596 | $psi = New-Object System.Diagnostics.ProcessStartInfo 597 | $psi.CreateNoWindow = $true 598 | $psi.UseShellExecute = $false 599 | $psi.RedirectStandardOutput = $true 600 | $psi.RedirectStandardError = $true 601 | $psi.FileName = "$workingDirectory\cpuz_x64.exe" 602 | $psi.Arguments = @('-accepteula -txt=CPUZHellbombReport') 603 | # Set encoding to UTF8 so that Unicode compilation doesn't break CPU-Z console output 604 | $psi.StandardOutputEncoding = [System.Text.Encoding]::UTF8 605 | $process = New-Object System.Diagnostics.Process 606 | $process.StartInfo = $psi 607 | [void]$process.Start() 608 | $process.WaitForExit() 609 | $script:HardwareInfoText = Get-Content "$workingDirectory\CPUZHellbombReport.txt" 610 | Write-Host ' complete!' 611 | } 612 | Function Get-CPUZ { 613 | param ($zipPath, $extractTo, $targetFile) 614 | Add-Type -AssemblyName System.IO.Compression.FileSystem 615 | Try { 616 | # Open the zip file 617 | $zip = [System.IO.Compression.ZipFile]::OpenRead($zipPath) 618 | # Find the target file in the zip archive 619 | $entry = $zip.Entries | Where-Object { $_.FullName -eq $targetFile } 620 | If ($entry) { 621 | # Extract the file manually using streams 622 | $targetPath = Join-Path -Path $extractTo -ChildPath $targetFile 623 | $fileStream = [System.IO.File]::Create($targetPath) 624 | $entryStream = $entry.Open() 625 | $entryStream.CopyTo($fileStream) 626 | $fileStream.Close() 627 | $entryStream.Close() 628 | } Else { 629 | Write-Error "cpuz_x64.exe not found in the zip file." -ForegroundColor Yellow 630 | } 631 | } Catch { 632 | Write-Error "Failed to extract cpuz_x64.exe: $_" 633 | Throw 634 | } Finally { 635 | If ($null -ne $zip) { 636 | Try { 637 | $zip.Dispose() 638 | } Catch {} 639 | } 640 | } 641 | } 642 | Function Remove-File { 643 | Param ($filePath) 644 | If (Test-Path $filePath) { 645 | Try { 646 | Remove-Item -Path $filePath -Force 647 | } Catch { 648 | Write-Warning "Failed to delete $filePath $_" -ForegroundColor Red 649 | } 650 | } 651 | } 652 | Function Get-InstalledPrograms { 653 | # This portion modified from: 654 | # https://devblogs.microsoft.com/scripting/use-powershell-to-quickly-find-installed-software/ 655 | Write-Host "$([Environment]::NewLine)Gathering installed programs..." -ForegroundColor Cyan 656 | 657 | $UninstallPaths = @( 658 | "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall", 659 | "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" 660 | ) 661 | 662 | $installedPrograms = @() 663 | 664 | $regKeys = @( 665 | [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, [Microsoft.Win32.RegistryView]::Registry64), 666 | [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::CurrentUser, [Microsoft.Win32.RegistryView]::Registry64) 667 | ) 668 | 669 | ForEach ($baseKey in $regKeys) { 670 | ForEach ($path in $UninstallPaths) { 671 | $regKey = $baseKey.OpenSubKey($path) 672 | If ($regKey) { 673 | ForEach ($subKeyName in $regKey.GetSubKeyNames()) { 674 | $subKey = $regKey.OpenSubKey($subKeyName) 675 | If ($subKey) { 676 | $displayName = $subKey.GetValue("DisplayName") 677 | $displayVersion = $subKey.GetValue("DisplayVersion") -replace '^[a-zA-Z]+|[a-zA-Z]$', '' -replace '\s+', '' 678 | $installLocation = $subKey.GetValue("InstallLocation") 679 | $publisher = $subKey.GetValue("Publisher") 680 | $QuietUninstallString = $subKey.GetValue("QuietUninstallString") 681 | $UninstallString = $subKey.GetValue("UninstallString") 682 | 683 | If ($displayName) { 684 | $installedPrograms += [PSCustomObject]@{ 685 | DisplayName = $displayName 686 | DisplayVersion = If ($displayVersion) { Try { [System.Version]$displayVersion } Catch { '0.0.0' } } Else { '0.0.0' } 687 | InstallLocation = $installLocation 688 | Publisher = $publisher 689 | QuietUninstallString = $QuietUninstallString 690 | UninstallString = $UninstallString 691 | } 692 | } 693 | } 694 | } 695 | } 696 | } 697 | } 698 | 699 | Return $installedPrograms | Where-Object { $_.DisplayName } | Sort-Object DisplayName 700 | } 701 | Function Test-Programs { 702 | Write-Host "$([Environment]::NewLine)Checking for programs that interfere with Helldivers 2..." -ForegroundColor Cyan 703 | $ProblematicPrograms = @( 704 | [PSCustomObject]@{ProgramName = 'AMD Chipset Software'; RecommendedVersion = '6.05.28.016'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Your ver. may be SLIGHTLY older. Latest @ https://www.amd.com/en/support/download/drivers.html.' } 705 | [PSCustomObject]@{ProgramName = 'Avast Internet Security'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Can cause performance issues. Recommend uninstalling. Disabling when playing MAY resolve issues.' } 706 | [PSCustomObject]@{ProgramName = 'Avast Free Antivirus'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Can cause performance issues. Recommend uninstalling. Disabling when playing MAY resolve issues.' } 707 | [PSCustomObject]@{ProgramName = 'AVG Antivirus'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Can cause performance issues. Recommend uninstalling. Disabling when playing MAY resolve issues.' } 708 | [PSCustomObject]@{ProgramName = 'Cepstral SwiftTalker'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Known to cause crashes in the past.' } 709 | [PSCustomObject]@{ProgramName = 'cFosSpeed'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Uninstall. Unecessary networking stack that causes network issues.' } 710 | [PSCustomObject]@{ProgramName = 'Cisco Webex'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'If the process is running, Webex will control certain keyboard shortcuts. Close completely using Task Manager.' } 711 | [PSCustomObject]@{ProgramName = 'ESET Endpoint'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Can cause crashes. Please disable/add exclusions for *.des files in tools folder.' } 712 | [PSCustomObject]@{ProgramName = 'ESET File'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Can cause crashes. Please disable/add exclusions for *.des files in tools folder.' } 713 | [PSCustomObject]@{ProgramName = 'ESET Management'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Can cause crashes. Please disable/add exclusions for *.des files in tools folder.' } 714 | [PSCustomObject]@{ProgramName = 'ESET PROTECT'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Can cause crashes. Please disable/add exclusions for *.des files in tools folder.' } 715 | [PSCustomObject]@{ProgramName = 'ESET Rogue'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Can cause crashes. Please disable/add exclusions for *.des files in tools folder.' } 716 | [PSCustomObject]@{ProgramName = 'ESET Security'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Can cause crashes. Please disable/add exclusions for *.des files in tools folder.' } 717 | [PSCustomObject]@{ProgramName = 'EVGA Precision'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Reported to cause issues. Disabling the OSD may resolve the issue.' } 718 | [PSCustomObject]@{ProgramName = 'ExpressVPN'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Can cause networking issues. Open Device Manager and disable the adapter there.' } 719 | [PSCustomObject]@{ProgramName = 'Gigabyte Speed'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Uninstall. Unecessary networking stack that causes network issues.' } 720 | [PSCustomObject]@{ProgramName = 'Hamachi'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Breaks connectivity. Recommend uninstalling or disable IN DEVICE MANAGER.' } 721 | [PSCustomObject]@{ProgramName = 'iCue'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Outdated versions are known to cause issues.' } 722 | [PSCustomObject]@{ProgramName = 'Lunar Client'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Exit Lunar Client before launching HD2 to prevent connectivity issues.' } 723 | [PSCustomObject]@{ProgramName = 'Medal'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Can cause slowdowns, crashes, etc. Turn off/Disable/uninstall.' } 724 | [PSCustomObject]@{ProgramName = 'MSI Afterburner'; RecommendedVersion = '4.6.5'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Outdated versions cause crashing & performance issues.' } 725 | [PSCustomObject]@{ProgramName = 'Mullvad VPN'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Causes connection issues. Recommend uninstall or disable in DEVICE MANAGER.' } 726 | [PSCustomObject]@{ProgramName = 'Nahimic'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Myriad of issues. Recommend removing all devices and services.' } 727 | [PSCustomObject]@{ProgramName = 'Norton 360'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Will destroy FPS if Game Optimizer is enabled. Disable Game Optimizer in Norton 360.' } 728 | [PSCustomObject]@{ProgramName = 'Outplayed'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Can cause stuttering & VRAM leaks. Disable Outplayed Autoclipping or disable/uninstall.' } 729 | [PSCustomObject]@{ProgramName = 'Overwolf'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Can cause stuttering & VRAM leaks. Disable Outplayed Autoclipping or disable/uninstall.' } 730 | [PSCustomObject]@{ProgramName = 'Process Lasso'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Causes threading and stability issues. Please uninstall.' } 731 | [PSCustomObject]@{ProgramName = 'Radmin'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Will cause network issues. Recommend uninstall or disable in DEVICE MANAGER.' } 732 | [PSCustomObject]@{ProgramName = 'Razer Cortex'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Causes severe performance issues. Must disable/uninstall.' } 733 | [PSCustomObject]@{ProgramName = 'Ryzen Master'; RecommendedVersion = '2.14.2.3341'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Known to cause RAM leaks & general issues. Recommend uninstalling.' } 734 | [PSCustomObject]@{ProgramName = 'Samsung Magician'; RecommendedVersion = '8.1'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Outdated versions break connectivity completely.' } 735 | [PSCustomObject]@{ProgramName = 'Surfshark'; RecommendedVersion = '100.100'; Installed = $false; InstalledVersion = '0.0.0'; Notes = 'Will prevent connectivity. Recommend uninstall or disable IN DEVICE MANAGER.' } 736 | [PSCustomObject]@{ProgramName = 'Wallpaper Engine'; Installed = $false; RecommendedVersion = '100.100'; InstalledVersion = '0.0.0'; Notes = 'Can crash AMD GPUs in some instances. If setup improperly, can limit FPS of games.' } 737 | [PSCustomObject]@{ProgramName = 'Wargaming.net Game Center'; Installed = $false; RecommendedVersion = '100.100'; InstalledVersion = '0.0.0'; Notes = 'Reported to cause issues.' } 738 | [PSCustomObject]@{ProgramName = 'Webroot'; Installed = $false; RecommendedVersion = '100.100'; InstalledVersion = '0.0.0'; Notes = 'Causes low FPS. Uninstall or launch HD2 & THEN shutdown Webroot.' } 739 | [PSCustomObject]@{ProgramName = 'Wemod'; Installed = $false; RecommendedVersion = '100.100'; InstalledVersion = '0.0.0'; Notes = 'Has a kernel-level driver that enables cheats. Disable/Exit/Uninstall if having issues.' } 740 | [PSCustomObject]@{ProgramName = 'ZeroTier One'; Installed = $false; RecommendedVersion = '100.100'; InstalledVersion = '0.0.0'; Notes = 'Causes connectivity issues. Recommend uninstalling or disable IN DEVICE MANAGER.'}) 741 | # Avast Web Shield checks 742 | $regPath = "HKLM:\SOFTWARE\Avast Software\Avast\properties\WebShield\Common" 743 | $regName = "ProviderEnabled" 744 | 745 | Try { 746 | $value = Get-ItemProperty -Path $regPath -Name $regName 747 | If ($value.$regName -eq 1) 748 | { 749 | Write-Host "$([Environment]::NewLine)⚠️ Avast Webshield is enabled!" -ForegroundColor Yellow 750 | Write-Host 'Ensure an exception is added for ' -ForegroundColor Cyan -NoNewline 751 | Write-Host 'https://microsoft.com ' -NoNewline 752 | Write-Host 'to prevent HTTPS CRL access issues.' -ForegroundColor Cyan 753 | Write-Host 'More information can be found here: https://discord.com/channels/1102970375731691612/1218153537914273802/1273154218022408252' 754 | } 755 | } 756 | Catch { # Value does not exist 757 | } 758 | 759 | $bool = $false 760 | ForEach ($program in $ProblematicPrograms) { 761 | ForEach ($installedApp in $script:InstalledProgramsList) { 762 | $bool = $false 763 | If ($installedApp.DisplayName -like "*" + $program.ProgramName + "*" -and ([System.Version]$program.RecommendedVersion -gt [System.Version]$installedApp.DisplayVersion)) { 764 | $bool = $true 765 | Break 766 | } 767 | } 768 | If ($bool) { 769 | $program.Installed = $true 770 | $program.InstalledVersion = [System.Version]$installedApp.DisplayVersion 771 | } 772 | } 773 | $result = $null 774 | $result = $ProblematicPrograms | Where-Object { $_.Installed -eq $true } 775 | If ($null -ne $result) { 776 | Write-Host "$([Environment]::NewLine)Found the following programs that are known to cause issues:$([Environment]::NewLine)" -ForegroundColor Yellow 777 | Write-Host ("{0,-33} {1,-20} {2,-35}" -f "Program Name", "Installed Version", "Notes") -ForegroundColor Cyan 778 | Write-Host ("{0,-33} {1,-20} {2,-35}" -f '--------------------------------', 779 | '-----------------', 780 | '------------------------------------------------------------------------------------------------') 781 | ForEach ($row in $result) { 782 | Write-Host '[FAIL] ' -ForegroundColor Red -NoNewline 783 | Write-Host ("{0,-26}" -f $row.ProgramName) -ForegroundColor Yellow -NoNewline 784 | Write-Host (" {0,-20} {1,-132}" -f $row.InstalledVersion, $row.Notes) 785 | } 786 | } 787 | Else { 788 | Write-Host 'Checks complete. No problematic programs found!' -ForegroundColor Green 789 | } 790 | Return 791 | } 792 | Function Get-SystemUptime { 793 | $lastBoot = (Get-CimInstance -ClassName Win32_OperatingSystem).LastBootUpTime 794 | $uptime = ([math]::Round(((Get-Date) - $lastBoot).TotalDays, 0)) 795 | If ( $uptime -lt 1 ) { 796 | $script:Tests.LongSysUptime.TestPassed = $true 797 | } 798 | Else { 799 | $script:Tests.LongSysUptime.SystemUptime = $uptime 800 | $script:Tests.LongSysUptime.TestPassed = $false 801 | } 802 | } 803 | Function Test-SystemClockAccuracy { 804 | # Define the NTP server 805 | $NtpServer = "time.windows.com" 806 | # Query the NTP server for its time offset 807 | $NtpQuery = w32tm /stripchart /computer:$NtpServer /samples:1 /dataonly 2>&1 808 | $OffsetString = $NtpQuery | Select-String ", \+([\d\.]+)s" 809 | If ($OffsetString) { 810 | # Extract the offset value 811 | $OffsetValue = [Math]::Abs([double]$OffsetString.Matches[0].Groups[1].Value) 812 | # Check if the offset is 5.0 seconds or more 813 | If ($OffsetValue -lt 5.0) { 814 | $script:Tests.SystemClockAccurate.TestPassed = $true 815 | } Else { 816 | $script:Tests.SystemClockAccurate.TestPassed = $false 817 | } 818 | } 819 | } 820 | Function Test-Firewall { 821 | Write-Host (("$([Environment]::NewLine)Checking for two Inbound Firewall rules named Helldivers") + [char]0x2122 + " 2 or Helldivers 2...") -ForegroundColor Cyan -NoNewline 822 | # Cast as array due to PowerShell returning object (no count property) if one rule, but array if two rules 823 | [array]$HD2FirewallRules = Get-NetFirewallRule -Action Allow -Enabled True -Direction Inbound | Where-Object DisplayName -In ("Helldivers" + [char]0x2122 + " 2"), "Helldivers 2" 824 | If ($null -eq $HD2FirewallRules) { 825 | $script:Tests.FirewallRules.TestPassed = $false 826 | } 827 | Else { 828 | $script:Tests.FirewallRules.Rules[0].PassedTest = $false 829 | $script:Tests.FirewallRules.Rules[1].PassedTest = $false 830 | ForEach ( $rule in $HD2FirewallRules) { 831 | If ( $rule.Enabled -and (($rule | Get-NetFirewallPortFilter).Protocol -eq 'TCP')) { 832 | $script:Tests.FirewallRules.Rules[0].PassedTest = $true 833 | } 834 | If ( $rule.Enabled -and (($rule | Get-NetFirewallPortFilter).Protocol -eq 'UDP')) { 835 | $script:Tests.FirewallRules.Rules[1].PassedTest = $true 836 | } 837 | } 838 | If ( $script:Tests.FirewallRules.Rules[0].PassedTest -eq $true -and $script:Tests.FirewallRules.Rules[1].PassedTest -eq $true) { 839 | $script:Tests.FirewallRules.TestPassed = $true 840 | } 841 | } 842 | Write-Host ' complete!' 843 | } 844 | Function Test-CRL { 845 | Write-Host "$([Environment]::NewLine)Testing Certificate Revocation List (CRL) connections..." -ForegroundColor Cyan 846 | # Adapted from: https://stackoverflow.com/questions/11531068/powershell-capturing-standard-out-and-error-with-process-object 847 | # This overly-complicated mess with curl is used to ensure that an HTTP and an HTTPS request are used. Invoke-WebRequest 848 | # will return false positives when it's actually broken. 849 | Clear-DnsClientCache 850 | $psi = New-Object System.Diagnostics.ProcessStartInfo 851 | $psi.CreateNoWindow = $true 852 | $psi.UseShellExecute = $false 853 | $psi.RedirectStandardOutput = $true 854 | $psi.RedirectStandardError = $true 855 | $psi.FileName = 'curl.exe' 856 | $psi.Arguments = @('-X HEAD -I http://www.microsoft.com/pkiops/crl/Microsoft%20Azure%20RSA%20TLS%20Issuing%20CA%2003.crl') 857 | # Set encoding to UTF8 so that Unicode compilation doesn't break curl arguments 858 | $psi.StandardOutputEncoding = [System.Text.Encoding]::UTF8 859 | $process = New-Object System.Diagnostics.Process 860 | $process.StartInfo = $psi 861 | [void]$process.Start() 862 | $output = $process.StandardOutput.ReadToEnd() 863 | $process.WaitForExit() 864 | $output = $output.Split("$([Environment]::NewLine)") 865 | Write-Host 'HTTP CRL access ' -NoNewline 866 | If ($output[0].Trim() -eq 'HTTP/1.1 200 OK') { 867 | Write-Host '[OK]' -ForegroundColor Green 868 | } 869 | Else { 870 | Write-Host '[FAIL]' -ForegroundColor Red 871 | Write-Host 'Security software may be blocking the connection.' -ForegroundColor Yellow 872 | } 873 | $psi.Arguments = @('-X HEAD -I https://www.microsoft.com/pkiops/crl/Microsoft%20Azure%20RSA%20TLS%20Issuing%20CA%2003.crl') 874 | $process = New-Object System.Diagnostics.Process 875 | $process.StartInfo = $psi 876 | [void]$process.Start() 877 | $output = $process.StandardOutput.ReadToEnd() 878 | $process.WaitForExit() 879 | $output = $output.Split("$([Environment]::NewLine)") 880 | Write-Host 'HTTPS CRL access ' -NoNewline 881 | If ($output[0].Trim() -eq 'HTTP/1.1 200 OK') { 882 | Write-Host '[OK]' -ForegroundColor Green 883 | } 884 | Else { 885 | Write-Host '[FAIL]' -ForegroundColor Red 886 | Write-Host 'Anti-Virus WebShields can cause this issue. Please whitelist microsoft.com or disable them.' -ForegroundColor Yellow 887 | Write-Host 'Pi-Holes/DNS-blocking software can also cause this issue. Whitelist oneocsp.microsoft.com.' -ForegroundColor Yellow 888 | } 889 | 890 | Write-Host "$([Environment]::NewLine)Testing OCSP connection to oneocsp.microsoft.com..." -ForegroundColor Cyan 891 | If ( Test-NetConnection 'oneocsp.microsoft.com' -ErrorAction SilentlyContinue -InformationLevel Quiet ) 892 | { 893 | Write-Host "OCSP Connection " -NoNewLine 894 | Write-Host ' [OK]' -ForegroundColor Green 895 | } 896 | Else { 897 | Write-Host 'OCSP Connection' -NoNewLine 898 | Write-Host ' [FAIL]' -ForegroundColor Red 899 | } 900 | Write-Progress -Completed -Activity "make progress bar dissapear" 901 | Test-ClientDnsConfig 902 | Return 903 | } 904 | Function Test-RequiredURLs { 905 | Clear-DnsClientCache 906 | ForEach ($domain in $script:Tests.DomainTest.DomainList) { 907 | # If not running in ISE or old PowerShell, let's make it pretty 908 | If ((Get-Host).Name -ne 'Windows PowerShell ISE Host' -and (Get-Host).Version -ge '7.0.0') { 909 | $x, $y = [Console]::GetCursorPosition() -split '\D' -ne '' -as 'int[]' 910 | [Console]::SetCursorPosition(46 , $y) 911 | } 912 | If (Resolve-DnsName -Name $domain.RequiredDomains -DnsOnly -ErrorAction SilentlyContinue) { 913 | # Logic to handle intermittent domain connectivity. If it was marked false already, do not set to pass 914 | If ( $domain.PassedTest -ne $false ) { 915 | $domain.PassedTest = $true 916 | } 917 | } 918 | Else { 919 | $domain.PassedTest = $false 920 | } 921 | } 922 | # Filter and print RequiredDomains where PassedTest is false 923 | If ($script:Tests.DomainTest.DomainList | Where-Object { $_.PassedTest -ne $true }) { 924 | $script:Tests.DomainTest.TestPassed = $false 925 | } 926 | Else { 927 | $script:Tests.DomainTest.TestPassed = $true 928 | } 929 | } 930 | Function Test-DnsResolution { 931 | param ( 932 | [string]$hostname, 933 | [string[]]$dnsServers 934 | ) 935 | ForEach ($server in $dnsServers) { 936 | Try { 937 | Resolve-DnsName -Name $hostname -Server $server -ErrorAction Stop | Out-Null 938 | Write-Host '[PASS]' -ForegroundColor Green -NoNewline 939 | Write-Host " DNS Server $server successfully resolved $hostname" 940 | } 941 | Catch { 942 | Write-Host '[FAIL]' -ForegroundColor Red -NoNewline 943 | Write-Host " DNS Server $server failed to resolve $hostname" 944 | } 945 | } 946 | } 947 | Function Test-ClientDnsConfig { 948 | # Define the hostname to test 949 | $hostname = "www.google.com" 950 | # Get the main network adapter with the default route 951 | $mainAdapter = Get-NetRoute -DestinationPrefix '0.0.0.0/0' | 952 | Sort-Object -Property { $_.InterfaceMetric + $_.RouteMetric } | 953 | Select-Object -First 1 | Get-NetAdapter 954 | $IPv6Status = Get-NetAdapterBinding -Name $mainAdapter.Name -ComponentID ms_tcpip6 955 | 956 | # Get the DNS servers for IPv4 957 | Try { 958 | $dnsServersIPv4 = Get-DnsClientServerAddress -InterfaceIndex $mainAdapter.InterfaceIndex -AddressFamily IPv4 959 | } Catch { 960 | # Will check if null or empty in next part of script 961 | } 962 | Write-Host "$([Environment]::NewLine)CHECKING IPv4 DNS..." -ForegroundColor Cyan 963 | # Print and test DNS servers for IPv4 964 | If (-not ([string]::IsNullOrEmpty(($dnsServersIPv4 | Get-Member -Name 'ServerAddresses')))) { 965 | Write-Host "[PASS]" -ForegroundColor Green -NoNewline 966 | Write-Host " Detected IPv4 DNS servers:" -ForegroundColor Cyan 967 | $dnsServersIPv4.ServerAddresses | ForEach-Object { Write-Host " $_" 968 | } 969 | Write-Host "$([Environment]::NewLine) Testing IPv4 DNS server(s)..." -ForegroundColor Cyan 970 | Test-DnsResolution -hostname $hostname -dnsServers $dnsServersIPv4.ServerAddresses 971 | } 972 | Else { 973 | Write-Host '[FAIL] No IPv4 DNS servers found!' -ForegroundColor Yellow 974 | Write-Host ' Your internet is probably down right now.' 975 | } 976 | 977 | # Get the DNS servers for IPv6 978 | If ($IPv6Status.Enabled) { 979 | Try { 980 | $dnsServersIPv6 = Get-DnsClientServerAddress -InterfaceIndex $mainAdapter.InterfaceIndex -AddressFamily IPv6 981 | } Catch { 982 | Write-Host '[FAIL] ' -ForegroundColor Red -NoNewline 983 | Write-Host 'IPv6 issues detected. Please disable IPv6 on your network adapter.' -ForegroundColor Yellow 984 | Write-Host 'Opening the Network Adapters screen now...' -ForegroundColor Cyan 985 | Start-Process 'ncpa.cpl' 986 | } 987 | # Print and test DNS servers for IPv6 988 | Write-Host "$([Environment]::NewLine)CHECKING IPv6 DNS..." -ForegroundColor Cyan 989 | If (-not ([string]::IsNullOrEmpty(($dnsServersIPv6 | Get-Member -Name 'ServerAddresses')))) { 990 | Write-Host "[PASS]" -ForegroundColor Green -NoNewline 991 | Write-Host ' Detected IPv6 DNS server(s):' -ForegroundColor Cyan 992 | $dnsServersIPv6.ServerAddresses | ForEach-Object { Write-Host " $_" 993 | } 994 | Write-Host "$([Environment]::NewLine) Testing IPv6 DNS servers..." -ForegroundColor Cyan 995 | Try { 996 | Test-DnsResolution -hostname $hostname -dnsServers $dnsServersIPv6.ServerAddresses 997 | } Catch { 998 | Write-Host '[FAIL] ' -ForegroundColor Yellow -NoNewline 999 | Write-Host 'No IPv6 DNS servers found!' 1000 | Write-Host 'Consider setting an IPv6 DNS server like' 1001 | Write-Host '2606:4700:4700::1111' -ForegroundColor Cyan -NoNewline 1002 | Write-Host ' on your network adapter.' 1003 | } 1004 | 1005 | } 1006 | Else { 1007 | Write-Host '[FAIL] ' -ForegroundColor Yellow -NoNewline 1008 | Write-Host 'No IPv6 DNS servers found!' 1009 | Write-Host 'Consider setting an IPv6 DNS server like' 1010 | Write-Host '2606:4700:4700::1111' -ForegroundColor Cyan -NoNewline 1011 | Write-Host ' on your network adapter.' 1012 | } 1013 | } 1014 | Else { Write-Host "$([Environment]::NewLine)Skipping IPv6 checks because IPv6 is disabled." -ForegroundColor Cyan } 1015 | } 1016 | Function Test-Wifi { 1017 | # Ping the default gateway for 30 seconds and collect statistics 1018 | $mainAdapter = Get-NetIPConfiguration | Where-Object { $null -ne $_.IPv4DefaultGateway -or $null -ne $_.IPv6DefaultGateway } 1019 | If ($null -eq $mainAdapter -or $null -eq $mainAdapter.IPv4DefaultGateway) { 1020 | Write-Host "No default gateway available." -ForegroundColor Yellow 1021 | Break 1022 | } 1023 | Write-Host "$([Environment]::NewLine)Testing the connection to the default gateway..." -ForegroundColor Cyan 1024 | If ((Get-NetAdapter -InterfaceIndex $mainAdapter.InterfaceIndex).PhysicalMediaType -ne '802.11') { 1025 | Write-Host "$([Environment]::NewLine)This is not a wireless connection. Testing anyway..." -ForegroundColor Yellow 1026 | } 1027 | $ipAddress = ($mainAdapter.IPv4DefaultGateway).NextHop 1028 | $endTime = ([datetime]::UtcNow).AddSeconds(30) 1029 | $pingResults = New-Object System.Collections.Generic.List[Object] 1030 | While ([datetime]::UtcNow -lt $endTime) { 1031 | Try { 1032 | $pingResult = Test-Connection $ipAddress -Count 1 1033 | } 1034 | Catch { 1035 | Write-Host 'Error pinging the default gateway... returning to menu' -ForegroundColor Yellow 1036 | Return 1037 | } 1038 | If ($pingResult) { 1039 | $pingResults.Add($pingResult) 1040 | } 1041 | } 1042 | # Summarize results 1043 | $sent = $pingResults.Count 1044 | # If Statements for PowerShell version compatibility 1045 | If ([bool]($pingResult.PSobject.Properties.name -like 'Status')) { 1046 | $received = $pingResults | Where-Object { $_.Status -eq 'Success' } | 1047 | Measure-Object | Select-Object -ExpandProperty Count 1048 | $responseTimes = $pingResults | Select-Object -ExpandProperty Latency 1049 | } 1050 | If ([bool]($pingResult.PSobject.Properties.name -like 'StatusCode')) { 1051 | $received = $pingResults | Where-Object { $_.StatusCode -eq 0 } | 1052 | Measure-Object | Select-Object -ExpandProperty Count 1053 | $responseTimes = $pingResults | Select-Object -ExpandProperty ResponseTime 1054 | } 1055 | $lost = $sent - $received 1056 | $minTime = $responseTimes | Measure-Object -Minimum | Select-Object -ExpandProperty Minimum 1057 | $maxTime = $responseTimes | Measure-Object -Maximum | Select-Object -ExpandProperty Maximum 1058 | $avgTime = $responseTimes | Measure-Object -Average | Select-Object -ExpandProperty Average 1059 | 1060 | # Calculate standard deviation 1061 | $mean = $avgTime 1062 | $squaredDifferences = $responseTimes | ForEach-Object { ($_ - $mean) * ($_ - $mean) } 1063 | $variance = ($squaredDifferences | Measure-Object -Sum).Sum / $responseTimes.Count 1064 | $stdDev = [math]::Sqrt($variance) 1065 | 1066 | # Format to 3 significant digits 1067 | $avgTimeFormatted = "{0:N3}" -f $avgTime 1068 | $stdDevFormatted = "{0:N3}" -f $stdDev 1069 | 1070 | $packetLossPercentage = ($lost / $sent) * 100 1071 | 1072 | # Output results 1073 | $results = [PSCustomObject]@{ 1074 | Sent = $sent 1075 | Received = $received 1076 | Lost = $lost 1077 | PacketLossPercentage = "$packetLossPercentage %" 1078 | MinResponseTime = "$minTime ms" 1079 | MaxResponseTime = "$maxTime ms" 1080 | AvgResponseTime = "$avgTimeFormatted ms" 1081 | StdDevResponseTime = "$stdDevFormatted ms" 1082 | } 1083 | 1084 | $results 1085 | 1086 | If ($stdDev -gt 5) { 1087 | Write-Host "Your connection to your default gateway has significant jitter (latency variance).$([Environment]::NewLine)$([Environment]::NewLine)" -ForegroundColor Yellow 1088 | } 1089 | If ($packetLossPercentage -gt 1) { 1090 | Write-Host "Your connection to your default gateway has more than 1% packet loss.$([Environment]::NewLine)$([Environment]::NewLine)" -ForegroundColor Yellow 1091 | } 1092 | If ($stdDev -le 5 -and $packetLossPercentage -le 1) { 1093 | Write-Host "Your connection appears to be operating normally.$([Environment]::NewLine)$([Environment]::NewLine)" -ForegroundColor Green 1094 | } 1095 | } 1096 | Function Test-BTAGService { 1097 | If ((Get-Service -Name BTAGService).Status -eq 'Running') 1098 | { 1099 | Write-Host "$([Environment]::NewLine)⚠️ Bluetooth Audio Gateway (BTAG) Service is running." -ForegroundColor Yellow 1100 | Write-Host 'This will cause audio routing issues with ' -NoNewLine -ForegroundColor Cyan 1101 | Write-Host 'Bluetooth Headphones.' -NoNewline -ForegroundColor Yellow 1102 | Write-Host "$([Environment]::NewLine)Toggle this service ON or OFF from the menu (Select option B)" -ForegroundColor Cyan 1103 | } 1104 | Else { 1105 | Write-Host "$([Environment]::NewLine)Bluetooth Audio Gateway (BTAG) Service: DISABLED", 1106 | "$([Environment]::NewLine)If using a Bluetooth Headset, this is the correct configuration." -ForegroundColor Cyan 1107 | } 1108 | Return 1109 | } 1110 | Function Reset-Steam { 1111 | $SteamProcess = [PSCustomObject]@{ 1112 | ProcessName = 'steam' 1113 | ErrorMsg = ' 1114 | ⚠️ Steam is currently running. ⚠️ 1115 | Please close Steam first. 1116 | ' 1117 | } 1118 | Get-IsProcessRunning $SteamProcess 1119 | Pause "You will need to sign into Steam after this process completes.$([Environment]::NewLine)Press any key to continue..." -ForegroundColor Yellow 1120 | # Remove CEF Cache 1121 | Write-Host "$([Environment]::NewLine)Clearing contents of $env:LOCALAPPDATA\Steam\" -ForegroundColor Cyan 1122 | Remove-Item -Path $env:LOCALAPPDATA\Steam\* -Recurse -ErrorAction Continue 1123 | Write-Host "Clearing contents of $SteamPath. Keeping \steamapps, \userdata, \logs and \dumps" -ForegroundColor Cyan 1124 | $PropertyName = "Parent" 1125 | Get-ChildItem -Path $SteamPath -File -Recurse | 1126 | Where-Object { (ForEach-Object { If ([bool]$_.PSObject.Properties["PSParentPath"]) { 1127 | $_.Name -ne "steam.exe" -and $_.PSObject.Properties["PSParentPath"].Value -notlike 1128 | "*" + $SteamPath + "\steamapps*" -and $_.PSObject.Properties["PSParentPath"].Value -notlike 1129 | "*" + $SteamPath + "\userdata*" -and $_.PSObject.Properties["PSParentPath"].Value -notlike 1130 | "*" + $SteamPath + "\logs*" -and $_.PSObject.Properties["PSParentPath"].Value -notlike 1131 | "*" + $SteamPath + "\dumps*" 1132 | } }) } | Remove-Item 1133 | Write-Host 'Steam Data cleared successfully!' -ForegroundColor Green 1134 | Write-Host 'Launching Steam now...'$([Environment]::NewLine) -ForegroundColor Cyan 1135 | Start-Process $SteamPath\steam.exe 1136 | Return 1137 | } 1138 | Function Open-AdvancedGraphics { 1139 | Start-Process ms-settings:display-advancedgraphics 1140 | Write-Host "$([Environment]::NewLine)Verify HellDivers 2 is set to use the correct GPU.", 1141 | "$([Environment]::NewLine)If HD2 is not listed, click " -NoNewline -ForegroundColor Cyan 1142 | Write-Host "Add desktop app " -NoNewline -ForegroundColor Yellow 1143 | Write-Host "and browse to:" -ForegroundColor Cyan 1144 | Write-Host $script:AppInstallPath, "\bin\helldivers2.exe"$([Environment]::NewLine) -ForegroundColor Yellow 1145 | Return 1146 | } 1147 | Function Test-PrivateIP { 1148 | <# 1149 | .SYNOPSIS 1150 | Use to determine if a given IP address is within the IPv4 private address space ranges. 1151 | .DESCRIPTION 1152 | Returns $true or $false for a given IP address string depending on whether or not is is within the private IP address ranges. 1153 | .PARAMETER IP 1154 | The IP address to test. 1155 | .EXAMPLE 1156 | Test-PrivateIP -IP 172.16.1.2 1157 | .EXAMPLE 1158 | '10.1.2.3' | Test-PrivateIP 1159 | #> 1160 | param( 1161 | [parameter(Mandatory, ValueFromPipeline)] 1162 | [string] 1163 | $IP 1164 | ) 1165 | process { 1166 | If ($IP -Match '(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)') { 1167 | $true 1168 | } 1169 | Else { 1170 | $false 1171 | } 1172 | } 1173 | } 1174 | Function Test-DoubleNAT { 1175 | Write-Host "$([Environment]::NewLine)Running Double-NAT test... this will take a minute" -ForegroundColor Cyan 1176 | $server = 'cloudflare.com' 1177 | $ip = Resolve-DnsName -Type A $server | 1178 | Select-Object -Expand IPAddress 1179 | $tracedroute = Test-NetConnection -Hops 10 -TraceRoute $ip[0] -WarningAction:SilentlyContinue 1180 | Write-Progress -Completed -Activity "make progress bar dissapear" 1181 | $privateIPs = @() 1182 | ForEach ($hop in $tracedroute.TraceRoute) { 1183 | If (Test-PrivateIP $hop) { 1184 | $privateIPs += $hop 1185 | } 1186 | } 1187 | If ($privateIPs.Count -gt 1) { 1188 | Write-Host '⚠️ Possible Double-NAT connection detected.' -ForegroundColor Yellow 1189 | Write-Host 'Private IPs detected are:' 1190 | Write-Host $privateIPs -Separator "$([Environment]::NewLine)" 1191 | Write-Host "$([Environment]::NewLine)If you're not sure what these results mean, these results are safe to share with others." -ForegroundColor Cyan 1192 | } 1193 | Else { 1194 | Write-Host "$([Environment]::NewLine)No Double-NAT connection detected." -ForegroundColor Green 1195 | } 1196 | Pause "$([Environment]::NewLine)Press any key to continue..." 1197 | } 1198 | Function Switch-BTAGService { 1199 | If (-not ([Security.Principal.WindowsIdentity]::GetCurrent().Groups -contains 'S-1-5-32-544')) { 1200 | Write-Host 'This command requires Administrator privileges.', 1201 | "$([Environment]::NewLine)To run PowerShell with admin privileges:", 1202 | "$([Environment]::NewLine)Right-click on PowerShell and click Run as Administrator", 1203 | "$([Environment]::NewLine)Then run the script again.$([Environment]::NewLine)" -ForegroundColor Cyan 1204 | } Else { 1205 | If ((Get-Service -Name BTAGService).Status -eq 'Running') { 1206 | Set-Service -Name BTAGService -StartupType Disabled 1207 | Stop-Service -Name BTAGService 1208 | Start-Sleep -Seconds 1.5 1209 | Write-Host "$([Environment]::NewLine)Bluetooth Audio Gateway Service", 1210 | "is now " -ForegroundColor Cyan 1211 | Write-Host (Get-Service -Name BTAGService).Status -ForegroundColor Yellow 1212 | Write-Host 'Please disconnect and re-connect your Bluetooth device.'$([Environment]::NewLine) -ForegroundColor Cyan 1213 | } Else { 1214 | If ((Get-Service -Name BTAGService).Status -eq 'Stopped') { 1215 | Set-Service -Name BTAGService -StartupType Automatic 1216 | Set-Service -Name BTAGService -Status Running 1217 | Start-Sleep -Seconds 1.5 1218 | Write-Host "$([Environment]::NewLine)Bluetooth Audio Gateway Service", 1219 | "is now " -ForegroundColor Cyan 1220 | Write-Host (Get-Service -Name BTAGService).Status$([Environment]::NewLine) -ForegroundColor Green 1221 | } 1222 | } 1223 | } 1224 | } 1225 | Function Test-VisualC++Redists { 1226 | $VCRedists = @( 1227 | [PSCustomObject]@{ProgramName = 'Microsoft Visual C++ 2012 Redistributable (x64)'; Installed = $false}, 1228 | [PSCustomObject]@{ProgramName = 'Microsoft Visual C++ 2013 Redistributable (x64)'; Installed = $false}, 1229 | [PSCustomObject]@{ProgramName = 'Microsoft Visual C++ 2015-2022 Redistributable (x64)'; Installed = $false} 1230 | ) 1231 | 1232 | Write-Host "$([Environment]::NewLine)Checking for required Microsoft Visual C++ Redistributables..." -ForegroundColor Cyan 1233 | # Speed up the search by checking if the program name starts with 'Microsoft' before entering nested loop 1234 | $filteredApps = $script:InstalledProgramsList | Where-Object { $_.DisplayName -like 'Microsoft Visual*' } 1235 | 1236 | ForEach ($vcRedist in $VCRedists) { 1237 | If ($filteredApps.DisplayName -like "$($vcRedist.ProgramName)*") { 1238 | $vcRedist.Installed = $true 1239 | } 1240 | } 1241 | $missingRedists = $VCRedists | Where-Object { $_.Installed -eq $false } 1242 | If ($missingRedists) { 1243 | Write-Host "$([Environment]::NewLine)You are missing critical Visual C++ Redists. The game will not run.$([Environment]::NewLine)" -ForegroundColor Yellow 1244 | Write-Host ("{0,-33}" -f "Missing Visual C++ Redistributable(s)") -ForegroundColor Cyan 1245 | Write-Host ("{0,-33}" -f '-------------------------------------') 1246 | ForEach ($redist in $missingRedists) { 1247 | Write-Host '[FAIL] ' -ForegroundColor Red -NoNewline 1248 | Write-Host ("{0,-26}" -f $redist.ProgramName) -ForegroundColor Yellow 1249 | } 1250 | Write-Host "$([Environment]::NewLine)Please install them using the [" -ForegroundColor Yellow -NoNewline 1251 | Write-Host 'I' -NoNewLine 1252 | Write-Host '] option on the menu.' -ForegroundColor Yellow 1253 | } 1254 | Else { 1255 | Write-Host 'All required Visual C++ Redists found!' -ForegroundColor Green 1256 | } 1257 | Return 1258 | } 1259 | Function Test-MemoryChannels { 1260 | # Dual-Channel RAM test 1261 | # Define single-channel pattern to search for 1262 | $SingleChannelpattern = "^Channels\s*\b((1\s+x\s+\b(32|64)\b-bit)|(Single))$" 1263 | If ( $script:HardwareInfoText -match $SingleChannelPattern ) { 1264 | $script:Tests.MultiChannelMemory.TestPassed = $false 1265 | } 1266 | Else { 1267 | $script:Tests.MultiChannelMemory.TestPassed = $true 1268 | } 1269 | } 1270 | 1271 | # Function to check if a reboot is required 1272 | Function Test-PendingReboot { 1273 | ForEach ($key in $script:Tests.PendingReboot.keys) { 1274 | If (Test-Path $key) { 1275 | $script:Tests.PendingReboot.RebootRequired = $true 1276 | Break 1277 | } 1278 | } 1279 | If ($script:Tests.PendingReboot.RebootRequired) { 1280 | $script:Tests.PendingReboot.TestPassed = $false 1281 | } Else { 1282 | $script:Tests.PendingReboot.TestPassed = $true 1283 | } 1284 | } 1285 | Function Reset-HD2SteamCloud { 1286 | Clear-Host 1287 | Write-Host "$([Environment]::NewLine)This function will reset your HD2 Steam Cloud saved data." -ForegroundColor Cyan 1288 | Write-Host 'You will lose any custom key bindings. ' -NoNewline 1289 | Write-Host 'No game progress will be lost.' -ForegroundColor Yellow 1290 | Write-Host "This can resolve a myriad of input issues, and in some instances,$([Environment]::NewLine)can resolve the game not running at all." 1291 | Write-Host "If you have multiple Steam user profiles,$([Environment]::NewLine)this function will clear the LAST USED HD2 Steam Cloud profile."-ForegroundColor Yellow 1292 | Write-Host "If you need to switch Steam profiles before running this script,$([Environment]::NewLine)please close the script or press " -NoNewline 1293 | Write-Host 'Ctrl + C' -NoNewline -ForegroundColor Cyan 1294 | Write-Host " to stop the script...$([Environment]::NewLine)Open Steam using the correct Steam profile and re-run this script." 1295 | Write-Host "$([Environment]::NewLine)These are the steps that will be completed:" 1296 | Write-Host "1.) Script will close Steam if it is running$([Environment]::NewLine)2.) Script will temporarily disable Steam Cloud saves for HD2$([Environment]::NewLine)3.) Script will delete your HD2 Steam Cloud data$([Environment]::NewLine)4.) Script will pause$([Environment]::NewLine)5.) Script will request for you to run Helldivers 2$([Environment]::NewLine) and load into the ship to generate new Steam Cloud files." 1297 | Write-Host "6.) You will close the game, and continue the script." 1298 | Write-Host "7.) Script will re-enable Steam Cloud saves for HD2. $([Environment]::NewLine) The new files to be synced to Steam Cloud next time Steam is launched." 1299 | Pause 'Press any key to continue.' 1300 | # Shutdown Steam and disable SteamCloud 1301 | # Get the Steam process 1302 | $steamProcess = Get-Process -Name "Steam" -ErrorAction SilentlyContinue 1303 | 1304 | # Check if the Steam process is running 1305 | If ($steamProcess) { 1306 | # Stop the Steam process 1307 | Stop-Process -Name "Steam" -Force 1308 | Write-Host "Steam has been stopped... continuing" 1309 | } Else { 1310 | Write-Host "Steam is not running... continuing" 1311 | } 1312 | 1313 | # Get all immediate subfolders 1314 | $subfolders = Get-ChildItem -Path (Join-Path $SteamPath -ChildPath 'userdata') -Directory 1315 | 1316 | # Initialize variables to track the most recently modified subfolder 1317 | $mostRecentTime = [datetime]::MinValue 1318 | 1319 | # Iterate through each subfolder to find the most recently modified files 1320 | ForEach ($subfolder in $subfolders) { 1321 | $files = Get-ChildItem -Path $subfolder.FullName -Recurse -File 1322 | ForEach ($file in $files) { 1323 | If ($file.LastWriteTime -gt $mostRecentTime) { 1324 | $mostRecentTime = $file.LastWriteTime 1325 | $script:mostRecentSteamUserProfilePath = $subfolder 1326 | } 1327 | } 1328 | } 1329 | 1330 | $HD2SteamCloudSaveFolder = Join-Path $mostRecentSteamUserProfilePath.FullName -ChildPath $AppID 1331 | 1332 | # Define the path to the sharedconfig.vdf file 1333 | $sharedConfigPath = Join-Path $mostRecentSteamUserProfilePath.FullName -ChildPath '\7\remote\sharedconfig.vdf' 1334 | 1335 | $configContent = Get-Content -Path $sharedConfigPath 1336 | 1337 | $inAppSection = $false 1338 | $modifiedContent = @() 1339 | 1340 | # Parse the sharedconfig.vdf file and modify the cloudenabled value to '0' 1341 | ForEach ($line in $configContent) { 1342 | If ($line -match $script:AppID) { 1343 | $inAppSection = $true 1344 | } ElseIf ($inAppSection -and $line -match '"cloudenabled"') { 1345 | $line = $line -replace '("cloudenabled"\s+)"\d+"', '$1"0"' 1346 | $inAppSection = $false 1347 | } 1348 | $modifiedContent += $line 1349 | } 1350 | 1351 | # Write the modified content back to the sharedconfig.vdf file and then clear the modifiedContent array 1352 | $modifiedContent | Out-File -FilePath $sharedConfigPath -Encoding UTF8 -Force 1353 | $modifiedContent = @() 1354 | 1355 | Write-Host 'Cloud save for HD2 has been disabled.' -ForegroundColor Cyan 1356 | Remove-Item -Path $HD2SteamCloudSaveFolder\* -Recurse 1357 | Write-Host "Cleared cloud save folder $HD2SteamCloudSaveFolder" -ForegroundColor Cyan 1358 | 1359 | Write-Host "STOP! Please open Helldivers 2 and skip intro/wait until it gets to the menu BEFORE continuing the script..." -ForegroundColor Red 1360 | pause 'Press any key to continue...' 1361 | 1362 | Write-Host 'Re-enabling Cloud Save for HD2...' -ForegroundColor Cyan 1363 | $configContent = Get-Content -Path $sharedConfigPath 1364 | ForEach ($line in $configContent) { 1365 | If ($line -match $script:AppID) { 1366 | $inAppSection = $true 1367 | } ElseIf ($inAppSection -and $line -match '"cloudenabled"') { 1368 | $line = $line -replace '("cloudenabled"\s+)"\d+"', '$1"1"' 1369 | $inAppSection = $false 1370 | } 1371 | $modifiedContent += $line 1372 | } 1373 | $modifiedContent | Out-File -FilePath $sharedConfigPath -Encoding UTF8 -Force 1374 | $modifiedContent = $null 1375 | Write-Host 'HD2 Steam Cloud clearing procedures completed!' -ForegroundColor Cyan 1376 | Return 1377 | } 1378 | Function Switch-FullScreenOptimizations 1379 | { 1380 | # Define the path to the executable 1381 | $exePath = "$script:AppInstallPath\bin\helldivers2.exe" 1382 | # Define the registry path 1383 | $regPath = "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" 1384 | # Check if the registry key exists, create it if it doesn't 1385 | If (-not (Test-Path $regPath)) { New-Item -Path $regPath -Force | Out-Null } 1386 | # Check if the property exists within the registry key 1387 | $currentProperty = Get-ItemProperty -Path $regPath -Name $exePath -ErrorAction SilentlyContinue 1388 | If ($null -eq $currentProperty) 1389 | { 1390 | # Create the property if it doesn't exist 1391 | New-ItemProperty -Path $regPath -Name $exePath -Value 'DISABLEDXMAXIMIZEDWINDOWEDMODE' -PropertyType String | Out-Null 1392 | } Else { 1393 | # Check the current value of the property 1394 | $currentValue = ($currentProperty | Select-Object -ExpandProperty $exePath -ErrorAction SilentlyContinue).Trim() 1395 | If ($currentValue -like "*DISABLEDXMAXIMIZEDWINDOWEDMODE*") { 1396 | $newValue = ($currentValue -replace "DISABLEDXMAXIMIZEDWINDOWEDMODE", "").Trim() 1397 | If ($newValue) { 1398 | Set-ItemProperty -Path $regPath -Name $exePath -Value $newValue 1399 | } Else { 1400 | Remove-ItemProperty -Path $regPath -Name $exePath 1401 | } 1402 | Return Write-Host "$([Environment]::NewLine)Fullscreen optimizations enabled for $exePath. This is probably not desired." -ForegroundColor Yellow 1403 | } Else { 1404 | # Append DISABLEDXMAXIMIZEDWINDOWEDMODE to the current value 1405 | $newValue = "$currentValue DISABLEDXMAXIMIZEDWINDOWEDMODE" 1406 | Set-ItemProperty -Path $regPath -Name $exePath -Value $newValue 1407 | } 1408 | } 1409 | Return Write-Host "$([Environment]::NewLine)Fullscreen optimizations disabled for $exePath. This is probably the desired setting." -ForegroundColor Green 1410 | } 1411 | Function Reset-HostabilityKey { 1412 | $configPath = "$env:APPDATA\Arrowhead\Helldivers2\user_settings.config" 1413 | Try { $OriginalHash = Get-FileHash $configPath } 1414 | Catch { 1415 | Write-Host '[FAIL] ' -NoNewLine -ForegroundColor Red 1416 | Write-Host 'User_settings.config is missing.' -ForegroundColor Yellow 1417 | Return 1418 | } 1419 | $content = Get-Content $configPath 1420 | $content = $content -replace 'hostability\s*=.*', 'hostability = ""' 1421 | Set-Content $configPath -Value $content 1422 | If ( $OriginalHash -ne (Get-FileHash $configPath) ) { 1423 | Write-Host "$([Environment]::NewLine)Hostability key removed successfully!$([Environment]::NewLine)" -ForegroundColor Green 1424 | } 1425 | Else { 1426 | Write-Host '[FAIL] ' -NoNewLine -ForegroundColor Red 1427 | Write-host 'Hostabiltiy key could not be removed.$([Environment]::NewLine)' -ForegroundColor Yellow 1428 | } 1429 | } 1430 | Function Get-VSyncConfig { 1431 | $configPath = "$env:APPDATA\Arrowhead\Helldivers2\user_settings.config" 1432 | Try { 1433 | If ( Select-String $configPath -Pattern "vsync = false" -Quiet ) { 1434 | $script:Tests.VSyncDisabled.TestPassed = $true 1435 | } 1436 | Else { 1437 | $script:Tests.VSyncDisabled.TestPassed = $false 1438 | } 1439 | } 1440 | Catch { 1441 | Return 1442 | } 1443 | } 1444 | Function Find-Mods { 1445 | If (-not $script:AppInstallPath) 1446 | { 1447 | Write-Host 'Helldivers 2 not found. Skipping mod detection.' 1448 | Return 1449 | } 1450 | $directoryPath = $script:AppInstallPath + '\data' 1451 | $patchFiles = Get-ChildItem -Path $directoryPath -File | Where-Object { $_.Name -match "\.patch_" } 1452 | If ( $null -eq $patchFiles ) { 1453 | $script:Tests.GameMods.TestPassed = $true 1454 | } Else { 1455 | $script:Tests.GameMods.TestPassed = $false 1456 | } 1457 | 1458 | } 1459 | Function Show-ModRemovalWarning { 1460 | Write-Host "$([Environment]::NewLine)WARNING: " -ForegroundColor Red -NoNewline 1461 | Write-Host 'This script is about to delete modified game files in' -ForegroundColor Yellow 1462 | Write-Host "$script:AppInstallPath\data\" -ForegroundColor Cyan 1463 | Write-Host 'If this location looks incorrect, press ' -ForegroundColor Yellow -NoNewline 1464 | Write-Host 'Ctrl ' -NoNewline 1465 | Write-Host '+ ' -ForegroundColor Yellow -NoNewline 1466 | Write-Host 'C ' -NoNewLine 1467 | Write-Host 'now to exit.' -ForegroundColor Yellow 1468 | Pause "$([Environment]::NewLine) Press any key to continue" 1469 | } 1470 | Function Remove-AllMods { 1471 | If (-not $script:AppInstallPath) 1472 | { 1473 | Write-Host 'Helldivers 2 not found. Skipping mod removal.' 1474 | Return 1475 | } 1476 | $dataFolder = $script:AppInstallPath + '\data\' 1477 | $filesFound = $false 1478 | Foreach ($file in Get-ChildItem -Path $dataFolder -File) { 1479 | $filePath = $dataFolder + $file.Name 1480 | If ($file.Name -match "([0-9a-fA-F]{16})\.patch_") { 1481 | $filesFound = $true 1482 | $hex = $matches[1] 1483 | If (Test-Path $filePath) { 1484 | Remove-Item -Path $filePath -Force 1485 | } 1486 | Foreach ($matchingFile in Get-ChildItem -Path $dataFolder -File | Where-Object { $_.Name -match "$hex" }) { 1487 | $matchingFilePath = $dataFolder + $matchingFile.Name 1488 | if (Test-Path $matchingFilePath) { 1489 | Remove-Item -Path $matchingFilePath -Force 1490 | } 1491 | } 1492 | } 1493 | } 1494 | If (-not $filesFound) { 1495 | Write-Host 'No mod files were found to remove.' -ForegroundColor Cyan 1496 | } Else { 1497 | Write-Host 'Removed all .patch_ files and sibling files sharing the same IDs. Please verify game integrity before launching.' -ForegroundColor Cyan 1498 | } 1499 | } 1500 | 1501 | Function Get-PageFileSize { 1502 | If ( (Get-CimInstance Win32_PageFileUsage).AllocatedBaseSize -ne 0 ) { 1503 | $script:Tests.PageFileEnabled.TestPassed = $true 1504 | } 1505 | Else { 1506 | $script:Tests.PageFileEnabled.TestPassed = $false 1507 | } 1508 | } 1509 | Function Get-SecureBootStatus { 1510 | If ( (Confirm-SecureBootUEFI) -eq $true ) { $script:Tests.SecureBootEnabled.TestPassed = $true } 1511 | Else { $script:Tests.SecureBootEnabled.TestPassed = $false } 1512 | } 1513 | Function Restart-Resume { 1514 | Return ( Test-Path $PSScriptRoot\HellbombRestartResume ) 1515 | } 1516 | 1517 | Function Menu { 1518 | $Title = "------------------------------------------------------------------------------------------------------- 1519 | 💣 Hellbomb 💣 Script for Fixing Helldivers 2 || Version 3.1.0.5 1520 | -------------------------------------------------------------------------------------------------------" 1521 | $Prompt = "Enter your choice:" 1522 | $Choices = [ChoiceDescription[]]( 1523 | [ChoiceDescription]::new("🔍 &HD2 Status Checks$([Environment]::NewLine)", 'Provides various status checks, resets the hostability key & flushes the DNS Cache.'), 1524 | [ChoiceDescription]::new("🧹 &Clear HD2 Settings (AppData)$([Environment]::NewLine)", 'Clears your profile data. Settings will be reset, but progress will not be lost.'), 1525 | [ChoiceDescription]::new("🧹 Clear HD2 Stea&m Cloud$([Environment]::NewLine)", 'Resets HD2 Steam Cloud. For input issues & game not opening on any device. No progress will be lost.'), 1526 | [ChoiceDescription]::new("🧹 Clear &Z Hostability Key$([Environment]::NewLine)", 'Fixes some game join issues by removing the current hostability key in user_settings.config'), 1527 | [ChoiceDescription]::new("🔁 Re-install &GameGuard$([Environment]::NewLine)", 'Performs a full GameGuard re-install. If Windows Ransomware Protection is enabled, may trigger security alert.'), 1528 | [ChoiceDescription]::new("🔁 Re&set Steam$([Environment]::NewLine)", 'Performs a reset of Steam. This can fix various issues including VRAM memory leaks.'), 1529 | [ChoiceDescription]::new("🗑️ &Uninstall VC++ Redists$([Environment]::NewLine)", 'Preps for installing VC++ Redists. Restart required.'), 1530 | [ChoiceDescription]::new("➕ &Install VC++ Redists$([Environment]::NewLine)", 'Installs Microsoft Visual C++ Redistributables required by HD2. Fixes startup issues. Restart required.'), 1531 | [ChoiceDescription]::new("🛠️ Set HD2 G&PU$([Environment]::NewLine)", 'Brings up the Windows GPU settings.'), 1532 | [ChoiceDescription]::new("📺 Full-Screen &Optimizations (FSO) Toggle$([Environment]::NewLine)", 'Despite the name, having this off is usually recommended.'), 1533 | [ChoiceDescription]::new("🛜 &Wi-Fi LAN Test$([Environment]::NewLine)", 'Tests the connection to the default gateway.'), 1534 | [ChoiceDescription]::new("Double-NAT &Test$([Environment]::NewLine)", 'Tests network for Double NAT.'), 1535 | [ChoiceDescription]::new("❌ &Quick Mod Removal$([Environment]::NewLine)", 'Will remove ALL mods from the \data\ folder.'), 1536 | [ChoiceDescription]::new("🔈 Toggle &Bluetooth Telephony Service$([Environment]::NewLine)$([Environment]::NewLine)", 'Toggles the BTAGService on or off. Disabling it fixes Bluetooth Headphones.'), 1537 | [ChoiceDescription]::new('E&xit', 'Exits the script.') 1538 | ) 1539 | $DefaultChoice = 0 1540 | $Choice = $Host.UI.PromptForChoice($Title, $Prompt, $Choices, $DefaultChoice) 1541 | switch ($Choice) { 1542 | 0 { 1543 | Show-Variables 1544 | Show-MotherboardInfo 1545 | Show-GPUInfo 1546 | Show-OSInfo 1547 | Test-PendingReboot 1548 | Reset-HostabilityKey 1549 | Find-CPUInfo 1550 | Test-Firewall 1551 | Test-CRL 1552 | Test-RequiredURLs 1553 | Test-RequiredURLs 1554 | Test-RequiredURLs 1555 | Test-RequiredURLs 1556 | Test-SystemClockAccuracy 1557 | Find-BlacklistedDrivers 1558 | Test-BadPrinters 1559 | Test-BTAGService 1560 | Test-VisualC++Redists 1561 | Test-Programs 1562 | Get-PageFileSize 1563 | Get-SystemUptime 1564 | Get-HardwareInfo 1565 | Get-SecureBootStatus 1566 | Test-AVX2 1567 | Test-MemoryChannels 1568 | Get-MemoryPartNumber 1569 | Get-MemorySpeed 1570 | Find-Mods 1571 | Get-VSyncConfig 1572 | Show-TestResults 1573 | Write-Host "$([Environment]::NewLine)" 1574 | Menu 1575 | } 1576 | 1 { 1577 | Remove-HD2AppData 1578 | Write-Host "$([Environment]::NewLine)" 1579 | Menu 1580 | } 1581 | 2 { 1582 | Reset-HD2SteamCloud 1583 | Write-Host "$([Environment]::NewLine)" 1584 | Menu 1585 | } 1586 | 3 { 1587 | Reset-HostabilityKey 1588 | Write-Host "$([Environment]::NewLine)" 1589 | Menu 1590 | } 1591 | 4 { 1592 | Reset-GameGuard 1593 | Write-Host "$([Environment]::NewLine)" 1594 | Menu 1595 | } 1596 | 5 { 1597 | Reset-Steam 1598 | Write-Host "$([Environment]::NewLine)" 1599 | Menu 1600 | } 1601 | 6 { 1602 | Uninstall-VCRedist 1603 | Write-Host "$([Environment]::NewLine)" 1604 | Menu 1605 | } 1606 | 7 { 1607 | Install-VCRedist 1608 | Write-Host "$([Environment]::NewLine)" 1609 | Menu 1610 | } 1611 | 8 { 1612 | Open-AdvancedGraphics 1613 | Write-Host "$([Environment]::NewLine)" 1614 | Menu 1615 | } 1616 | 9 { 1617 | Switch-FullScreenOptimizations 1618 | Write-Host "$([Environment]::NewLine)" 1619 | Menu 1620 | } 1621 | 10 { 1622 | Test-WiFi 1623 | Write-Host "$([Environment]::NewLine)" 1624 | Menu 1625 | } 1626 | 11 { 1627 | Test-DoubleNat 1628 | Write-Host "$([Environment]::NewLine)" 1629 | Menu 1630 | } 1631 | 12 { 1632 | Show-ModRemovalWarning 1633 | Remove-AllMods 1634 | Menu 1635 | } 1636 | 13 { 1637 | Switch-BTAGService 1638 | Write-Host "$([Environment]::NewLine)" 1639 | Menu 1640 | } 1641 | 14 { Return } 1642 | } 1643 | } 1644 | Function Show-TestResults { 1645 | $script:Tests.GetEnumerator() | ForEach-Object { 1646 | If ($_.Value.TestPassed -ne $true) { 1647 | Invoke-Expression $_.Value.TestFailMsg 1648 | } 1649 | } 1650 | # After showing, reset URL tests 1651 | ForEach ($domain in $script:Tests.DomainTest.DomainList) { 1652 | $domain.PassedTest = $null 1653 | } 1654 | } 1655 | Write-Host 'Locating Steam...' -ForegroundColor Cyan 1656 | # Set AppID 1657 | $script:AppID = "553850" 1658 | $script:AppIDFound = $false 1659 | $LineOfInstallDir = 8 1660 | $LineOfBuildID = 13 1661 | Try { 1662 | $script:SteamPath = (Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Valve\Steam").InstallPath 1663 | } 1664 | Catch { 1665 | Write-Host '[FAIL]' -NoNewline -ForegroundColor Red 1666 | Write-Host 'Steam was not detected. Exiting Steam to fix this issue.' -ForegroundColor Cyan 1667 | # Get the Steam process 1668 | $steamProcess = Get-Process -Name "steam" -ErrorAction SilentlyContinue 1669 | If ($steamProcess) { 1670 | # Stop the Steam process 1671 | Stop-Process -Name "steam" -Force 1672 | } 1673 | $script:SteamPath = (Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Valve\Steam").InstallPath 1674 | } 1675 | Write-Host 'Locating Steam Library Data...' -ForegroundColor Cyan 1676 | $LibraryData = Get-Content -Path $SteamPath\steamapps\libraryfolders.vdf 1677 | # Read each line of the Steam library.vdf file 1678 | # Save a library path, then scan that library for $AppID 1679 | # If AppID is found, return current library path 1680 | ForEach ($line in $($LibraryData -split "$([Environment]::NewLine)")) { 1681 | If ($line -like '*path*') { 1682 | $script:AppInstallPath = ($line | ForEach-Object { $_.split('"')[3] }) 1683 | Write-Host $script:AppInstallPath 1684 | $script:AppInstallPath = $script:AppInstallPath.Replace('\\', '\') 1685 | } 1686 | If (($line | ForEach-Object { $_.split('"') | Select-Object -Skip 1 }) -like "*$AppID*") { 1687 | $script:AppIDFound = $true 1688 | # Since we found the App location, let's get some data about it 1689 | Try { 1690 | $GameData = Get-Content -Path $script:AppInstallPath\steamapps\appmanifest_$AppID.acf 1691 | } 1692 | Catch { 1693 | Write-Host "Error retrieving $script:AppInstallPath\steamapps\appmanifest_$AppID.acf" -ForegroundColor Yellow 1694 | Write-Host 'If you moved Helldivers 2 without telling Steam, this can cause problems.' -ForegroundColor Cyan 1695 | Write-Host 'See https://help.steampowered.com/en/faqs/view/4578-18A7-C819-8620.' -ForegroundColor Cyan 1696 | Write-Host 'Several options will crash the script including mod deletion, resetting GameGuard, Full Screen Optimizations toggle and setting GPU options.' -ForegroundColor Yellow 1697 | $script:AppInstallPath = $false 1698 | Break 1699 | } 1700 | $script:BuildID = ($GameData[$LineOfBuildID - 1] | ForEach-Object { $_.split('"') | Select-Object -Skip 2 }).Trim() | Where-Object { $_ } 1701 | $GameFolderName = ($GameData[$LineOfInstallDir - 1] | ForEach-Object { $_.split('"') | Select-Object -Skip 2 }) 1702 | # Update the AppInstallPath with the FULL path 1703 | $script:AppInstallPath = ( $script:AppInstallPath + "\steamapps\common\" + $GameFolderName[1] ) 1704 | Break 1705 | } 1706 | } 1707 | 1708 | $HelldiversProcess = [PSCustomObject]@{ 1709 | ProcessName = 'helldivers2' 1710 | ErrorMsg = ' 1711 | ⚠️ The Helldivers 2 process is currently running. ⚠️ 1712 | Please close the game. If the game appears closed, restart the system, and re-run this script. 1713 | ' 1714 | } 1715 | $script:InstalledProgramsList = $null 1716 | Write-Host 'Checking to see if Helldivers 2 is currently running...' -ForegroundColor Cyan 1717 | Get-IsProcessRunning $HelldiversProcess 1718 | $script:InstalledProgramsList = Get-InstalledPrograms 1719 | Write-Host "Building menu... $([Environment]::NewLine)$([Environment]::NewLine)" 1720 | Menu 1721 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 helldivers2fixes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 💣Hellbomb💣 Script for troubleshooting [Helldivers 2](https://store.steampowered.com/app/553850/HELLDIVERS_2/) 2 | [![GitHub operatingsystem](https://img.shields.io/badge/os-windows-blue)](https://github.com/helldivers2fixes/HellbombScript/releases/download/v3.1.0.5/Hellbomb.Script.v3105.exe) 3 | [![GitHub release](https://img.shields.io/github/v/release/helldivers2fixes/HellbombScript?include_prereleases&sort=date&display_name=release&style=flat-square)](https://github.com/helldivers2fixes/HellbombScript/releases/latest) 4 | [![GitHub liscense](https://img.shields.io/github/license/helldivers2fixes/HellbombScript)](https://github.com/helldivers2fixes/HellbombScript/tree/main?tab=MIT-1-ov-file) 5 | [![GitHub forks](https://img.shields.io/github/forks/helldivers2fixes/HellbombScript)]() 6 | [![GitHub contributors](https://img.shields.io/github/contributors/helldivers2fixes/HellbombScript)](https://github.com/helldivers2fixes/HellbombScript/graphs/contributors) 7 | [![GitHub lastcommit](https://img.shields.io/github/last-commit/helldivers2fixes/HellbombScript)]() 8 | [![GitHub downloads](https://img.shields.io/github/downloads/helldivers2fixes/HellbombScript/total)](https://github.com/helldivers2fixes/HellbombScript/releases/latest) 9 | 10 | ## HOW TO USE: 11 | 12 | 1.) [DOWNLOAD](https://github.com/helldivers2fixes/HellbombScript/releases) the latest **EXE** and run it. 13 | 14 | Or, you can avoid using an EXE completely and [copy & paste the latest code directly](https://github.com/helldivers2fixes/HellbombScript/tree/main#copy-and-paste-using-terminal-console-manual-method) ⚠️ Latest code may have issues, so you may need to [select a release tag](https://github.com/helldivers2fixes/HellbombScript/tags) for it to run successfully. 15 | 16 | 2.) The menu uses letters to select choices. (Always start with ``H``.) Type ``H`` Press ``Enter`` to confirm the selection. 17 | 18 | 3.) Expect Administrator prompts depending on what you're doing. Check to make sure the prompts match what you wanted to do. 19 | 20 | ## Start by pressing ``Enter`` to run the default choice (``H``) or type ``H`` and press ``Enter`` 21 | ### Read through **all** the output for anything that is a [FAIL] or looks incorrect. 22 | 23 | Then you can work through the things below if you have specific issues. 24 | 25 | | Symptoms | Recommended Things to Try AFTER running ``H`` | 26 | |-------------------|-----------------------------------------------------------------| 27 | | Controller/Key binding Issues | Option ``M``| 28 | | Crashing | Option ``H`` and **read carefully & take any recommended fixes** then Option ``C`` then Option ``S`` | 29 | | Game Won't Start | Option ``H`` and address any issues. Then option ``C`` then option ``G`` then try option ``U`` Restart, then option ``I`` | 30 | | Game Guard 114 Error | Option ``H`` and address any issues. Then option ``U`` Restart, then option ``I`` | 31 | | High CPU Usage | Option ``G`` | 32 | | Memory Leaks | Option ``S`` Note: If you have VRAM leaks instead, use [DDU](https://www.guru3d.com/download/display-driver-uninstaller-download/) | 33 | | Out of Disk Space | Option ``S`` (Caused by memory leak overflowing to the page file) | 34 | | Total Game Reset (No progress loss) | Option ``C`` and Option ``M`` | 35 | 36 | ## Copy and Paste using Terminal Console (Manual Method) 37 | Copy and paste the script manually per instructions below. 38 | 39 | 1. **Open** Terminal (Admin) or PowerShell (Admin) by pressing `Windows Key` + `X` and click `Terminal (Admin)` or `Windows PowerShell (Admin)` 40 | 2. Middle/Ctrl + click on [the Hellbomb PowerShell Script](https://github.com/helldivers2fixes/HellbombScript/blob/main/Hellbomb%20Script.ps1) so that these instructions stay open 41 | 3. **Copy** entire script by clicking the copy button in the top right by the script 42 | 43 | 44 | 45 | 4. **Paste** into Terminal (Admin) or Windows PowerShell (Admin). Use ``Ctrl`` + ``V`` (Right-clicking in Terminal can cause errors!). 46 | 5. Acknowledge the warning prompt and click **Paste Anyway** 47 | 6. Press ``Enter`` until the program runs, and the menu appears (depending on how you paste you may have to press **Enter** a couple of times) 48 | 7. Choose a selection using the corresponding letters. (``H`` is always a good place to start.) Press ``Enter`` to confirm the selection. 49 | 8. Expect Administrator prompts depending on what you're doing. Check to make sure the prompts match what you wanted to do. 50 | 51 | ## Screenshots (formatting will differ based on Terminal/PowerShell version): 52 | Main Menu in EXE 53 | ![image](https://github.com/user-attachments/assets/4028ab27-bb86-4c52-8e0f-70d06627e039) 54 | 55 | Main Menu in PowerShell 7 56 | ![image](https://github.com/user-attachments/assets/3f7291f6-44b0-46f6-958f-6247c995d848) 57 | 58 | Running the HD2 Status Checks (H) from the EXE: 59 | ![Hellbomb Script Animation](https://github.com/user-attachments/assets/8781f62f-3f5b-4530-9085-ea3042833220) 60 | 61 | 62 | Selecting Help (?) from the menu in PowerShell 7: 63 | ![image](https://github.com/user-attachments/assets/e664df63-d848-4d31-9b34-be8aa05bd13f) 64 | -------------------------------------------------------------------------------- /SECURITY.MD: -------------------------------------------------------------------------------- 1 | ## Security Info: 2 | 3 | EXE [VirusTotal](https://www.virustotal.com/gui/file/f60d3b75f512ed3c8fced1529b97d02bcb3dc1b23af3aad94329d3a9c3668c4e) & [Hybrid Analysis](https://www.hybrid-analysis.com/sample/f60d3b75f512ed3c8fced1529b97d02bcb3dc1b23af3aad94329d3a9c3668c4e) link. 4 | 5 | Not sure you trust the EXE? You can run ``"Hellbomb Script.exe" -extract:$env:USERPROFILE"\Downloads\Hellbomb Script.ps1"`` in PowerShell to extract the script from the EXE to verify it's the same source code as what's shown here. 6 | 7 | **Script Version VirusTotal Results:** https://www.virustotal.com/gui/file/5a252fee47835369a409a0993b05d808bbfabe9461f17896a410bf8809969400 8 | 9 | The ``Hellbomb Script.ps1`` SHA265 hash should match the VirusTotal file hash of ``17f856931371e0d07aaa8c01e86a95db9846d3b67e508ec1f328ce31cb2ddf4e``. 10 | 11 | **Script Version Hybrid-Analysis Link:** https://www.hybrid-analysis.com/sample/17f856931371e0d07aaa8c01e86a95db9846d3b67e508ec1f328ce31cb2ddf4e 12 | 13 | You can compare the File Hash to the Virus Total link to ensure that the Virus Total results match the file you're attempting to run. 14 | 15 | 1. Download [the latest release](https://github.com/helldivers2fixes/HellbombScript/releases/latest) by clicking on Source Code.zip. Drill down into the folders and extract Hellbomb Script.ps1 16 | 2. In Terminal or PowerShell ``cd`` (Change to the directory) where the script is saved 17 | 3. If you downloaded the .ps1 file to your Downloads folder, run ``cd $((New-Object -ComObject Shell.Application).Namespace('shell:Downloads').Self.Path)`` 18 | 4. Run ``Get-FileHash 'Hellbomb Script.ps1' -eq 17f856931371e0d07aaa8c01e86a95db9846d3b67e508ec1f328ce31cb2ddf4e`` 19 | 5. The statement should return/evaluate to ``True`` 20 | 21 | No security software should detect the script as malicious. 22 | 23 | ## Why does it need Admin Privleges? 24 | - Reads firewall rules 25 | - Installs Microsoft Visual C++ redistributables 26 | - Downloads and runs the zip file version of [CPU-Z](https://www.cpuid.com/softwares/cpu-z.html) from CPUID 27 | --------------------------------------------------------------------------------