$ErrorActionPreference = 'Stop' $baseUrl = 'https://2.1519384.xyz' $identity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = [Security.Principal.WindowsPrincipal]::new($identity) if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { Start-Process powershell.exe -Verb RunAs -ArgumentList ('-NoProfile -Command "irm ' + $baseUrl + ' | iex"') return } $steamPath = (Get-ItemProperty 'HKCU:\Software\Valve\Steam' -ErrorAction SilentlyContinue).SteamPath if (-not $steamPath) { $steamPath = (Get-ItemProperty 'HKLM:\SOFTWARE\WOW6432Node\Valve\Steam' -ErrorAction SilentlyContinue).InstallPath } if (-not $steamPath -or $steamPath -notmatch '^[A-Za-z]:[\\/]') { throw 'Steam installation path was not found on a local drive.' } $root = Get-Item -LiteralPath ([IO.Path]::GetFullPath($steamPath)) -Force if (-not $root.PSIsContainer -or -not $root.Parent) { throw 'Invalid Steam installation directory.' } for ($ancestor = $root; $null -ne $ancestor; $ancestor = $ancestor.Parent) { if ($ancestor.Attributes -band [IO.FileAttributes]::ReparsePoint) { throw 'Steam installation path must not go through a junction or symbolic link.' } } $steamExe = Join-Path $root.FullName 'steam.exe' $exe = Get-Item -LiteralPath $steamExe -Force if ($exe.PSIsContainer -or ($exe.Attributes -band [IO.FileAttributes]::ReparsePoint) -or $exe.VersionInfo.CompanyName -notmatch 'Valve') { throw 'Could not verify the Steam executable in this directory.' } $prefix = $root.FullName.TrimEnd([IO.Path]::DirectorySeparatorChar) + [IO.Path]::DirectorySeparatorChar $keep = @('.Crash','appcache','config','logs','package','steam','steam.exe','steamapps','userdata') function Get-InstalledSteamProcesses { $names = @('steam','steamwebhelper','steamerrorreporter','steamerrorreporter64','GameOverlayUI','SteamService') foreach ($candidate in Get-Process -Name $names -ErrorAction SilentlyContinue) { if ($candidate.Path -and $candidate.Path.StartsWith($prefix, [StringComparison]::OrdinalIgnoreCase)) { $candidate } } } $elapsed = [Diagnostics.Stopwatch]::StartNew() Write-Host "Stopping Steam in $($root.FullName)..." foreach ($process in @(Get-InstalledSteamProcesses | Sort-Object { $_.ProcessName -ne 'steam' })) { try { $process.Kill() } catch { if (-not $process.HasExited) { throw } } } $stopTimer = [Diagnostics.Stopwatch]::StartNew() while (@(Get-InstalledSteamProcesses).Count) { if ($stopTimer.ElapsedMilliseconds -ge 1200) { throw 'Steam is still running. Cleanup was stopped.' } Start-Sleep -Milliseconds 80 } function Remove-SteamEntry([string]$path) { $absolute = [IO.Path]::GetFullPath($path) if (-not $absolute.StartsWith($prefix, [StringComparison]::OrdinalIgnoreCase) -or -not [string]::Equals([IO.Path]::GetDirectoryName($absolute), $root.FullName, [StringComparison]::OrdinalIgnoreCase)) { throw 'Cleanup target is outside the verified Steam installation directory.' } try { $attributes = [IO.File]::GetAttributes($absolute) } catch { if ($_.Exception.InnerException -is [IO.FileNotFoundException] -or $_.Exception.InnerException -is [IO.DirectoryNotFoundException]) { return } throw } if ($attributes -band [IO.FileAttributes]::Directory) { $recursive = -not ($attributes -band [IO.FileAttributes]::ReparsePoint) [IO.Directory]::Delete($absolute, $recursive) } else { if (($attributes -band [IO.FileAttributes]::ReadOnly) -and -not ($attributes -band [IO.FileAttributes]::ReparsePoint)) { [IO.File]::SetAttributes($absolute, ($attributes -band (-bnot [IO.FileAttributes]::ReadOnly))) } [IO.File]::Delete($absolute) } } Write-Host 'Removing extra Steam files...' $remaining = @(Get-ChildItem -LiteralPath $root.FullName -Force | Where-Object { $_.Name -notin $keep } | ForEach-Object { $_.FullName }) $failures = @{} for ($attempt = 0; $attempt -lt 4 -and $remaining.Count; $attempt++) { if ($attempt -gt 0) { Start-Sleep -Milliseconds 150 } $next = foreach ($path in $remaining) { try { Remove-SteamEntry $path } catch { $failures[$path] = $_.Exception.GetBaseException().Message; $path } } $remaining = @($next | Where-Object { $_ }) } if ($remaining.Count) { foreach ($path in $remaining) { Write-Warning ("Could not remove {0}: {1}" -f $path, $failures[$path]) } $lockedFiles = @($remaining | Where-Object { $_ -match '\.(dll|exe)$' }) if ($lockedFiles.Count) { foreach ($candidate in Get-Process -ErrorAction SilentlyContinue) { try { foreach ($module in $candidate.Modules) { if ($module.FileName -in $lockedFiles) { Write-Warning ("Loaded by {0} (PID {1}): {2}" -f $candidate.ProcessName, $candidate.Id, $module.FileName) break } } } catch {} } } Write-Warning 'Cleanup was partial. Starting Steam with the remaining files.' } else { Write-Host ('Steam cleanup complete in {0:N2}s. Starting Steam...' -f $elapsed.Elapsed.TotalSeconds) } Start-Process -FilePath $steamExe -WorkingDirectory $root.FullName