param ( [Parameter(HelpMessage = "Do not prompt for any user input")] [switch]$Silent = $False, [Parameter(HelpMessage = "Clean unneeded files listed in _delete.txt after update")] [switch]$Clean = $False, [Parameter(HelpMessage = "Only update releases in the verified stream")] [switch]$Verified = $False, [Parameter(HelpMessage = "Directory to install to")] [ValidateScript({ if (-Not($_ | Test-Path)) { throw "File or folder does not exist" } return $true })] [System.IO.FileInfo]$Directory ) Write-Output "=======================================" Write-Output " IW4MAdmin Updater v1 " Write-Output " by XERXES & RaidMax " Write-Output "=======================================" $stopwatch = [system.diagnostics.stopwatch]::StartNew() $repoName = "RaidMax/IW4M-Admin" $assetPattern = "IW4MAdmin-20*.zip" if ($Verified) { $releasesUri = "https://api.github.com/repos/$repoName/releases/latest" } else { $releasesUri = "https://api.github.com/repos/$repoName/releases" } Write-Output "Retrieving latest version info..." $releaseInfo = (Invoke-WebRequest $releasesUri -UseBasicParsing | ConvertFrom-Json) | Select -First 1 $asset = $releaseInfo.assets | Where-Object name -like $assetPattern | Select -First 1 $downloadUri = $asset.browser_download_url $filename = Split-Path $downloadUri -leaf Write-Output "The latest version is $( $releaseInfo.tag_name ) released $( $releaseInfo.published_at )" if (!$Silent) { $stopwatch.Stop() Write-Warning "All IW4MAdmin files will be updated. Your database and configuration will not be modified. Are you sure you want to continue?" -WarningAction Inquire $stopwatch.Start() } Write-Output "Downloading update. This might take a moment..." $fileDownload = Invoke-WebRequest -Uri $downloadUri -UseBasicParsing if ($fileDownload.StatusDescription -ne "OK") { throw "Could not update IW4MAdmin. ($fileDownload.StatusDescription)" } $remoteHash = $fileDownload.Headers['Content-MD5'] $decodedHash = [System.BitConverter]::ToString([System.Convert]::FromBase64String($remoteHash)).replace('-', '') $directoryPath = Get-Location $fullPath = "$directoryPath\$filename" $outputFile = [System.IO.File]::Open($fullPath, 2) $stream = [System.IO.BinaryWriter]::new($outputFile) if ($Directory) { $outputDir = $Directory } else { $outputDir = Get-Location } try { $stream.Write($fileDownload.Content) } finally { $stream.Dispose() $outputFile.Dispose() } $localHash = (Get-FileHash -Path $fullPath -Algorithm MD5).Hash if ($localHash -ne $decodedHash) { throw "Failed to update. File hashes don't match!" } Write-Output "Extracting $filename to $outputDir" Expand-Archive -Path $fullPath -DestinationPath $outputDir -Force if ($Clean) { Write-Output "Running post-update clean..." $DeleteList = Get-Content -Path ./_delete.txt ForEach ($file in $DeleteList) { Write-Output "Deleting $file" Remove-Item -Path $file } } Write-Output "Removing temporary files..." Remove-Item -Force $fullPath $stopwatch.Stop() $executionTime = [math]::Round($stopwatch.Elapsed.TotalSeconds, 0) Write-Output "Update completed successfully in $executionTime seconds!"