Public/Server/Update-SteamServer.ps1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
function Update-SteamServer { <# .SYNOPSIS Update a Steam based game server. .DESCRIPTION This cmdlet presents a workflow to keep a steam based game server up to date. The server is expecting the game server to be running as a Windows Service. .PARAMETER AppID Enter the application ID you wish to install. .PARAMETER ServiceName Specify the Windows Service Name. You can get a list of services with Get-Service. .PARAMETER IPAddress Enter the IP address of the Steam based server. .PARAMETER Port Enter the port number of the Steam based server. .PARAMETER Path Install location of the game server. .PARAMETER Credential If the app requires login to install or update, enter your Steam username and password. .PARAMETER Arguments Enter any additional arguments here. .PARAMETER LogPath Specify the directory of the log files. .PARAMETER DiscordWebhookUri Enter a Discord Webhook Uri if you wish to get notifications about the server update. .PARAMETER AlwaysNotify Always receive a notification when a server has been updated. Default is only to send on errors. .PARAMETER TimeoutLimit Number of times the cmdlet checks if the server is online or offline. When the limit is reached an error is thrown. .EXAMPLE Update-SteamServer -AppID 476400 -ServiceName GB-PG10 -IPAddress '185.15.73.207' -Port 27015 .NOTES Author: Frederik Hjorslev Nylander .LINK https://hjorslev.github.io/SteamPS/Update-SteamServer.html #> # TODO: Implement support for ShouldContinue. Due to compatibility we wait with this. [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] param ( [Parameter(Mandatory = $true)] [int]$AppID, [Parameter(Mandatory = $true)] [ValidateScript( { Get-Service -Name $_ })] [string]$ServiceName, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [System.Net.IPAddress]$IPAddress, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int]$Port, [Parameter(Mandatory = $false)] [Alias('ApplicationPath')] [string]$Path = "C:\DedicatedServers\$ServiceName", [Parameter(Mandatory = $false)] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty, [Parameter(Mandatory = $false)] [string]$Arguments, [Parameter(Mandatory = $false)] [Alias('LogLocation')] [string]$LogPath = "C:\DedicatedServers\Logs", [Parameter(Mandatory = $false)] [string]$DiscordWebhookUri, [Parameter(Mandatory = $false)] [string]$AlwaysNotify, [Parameter(Mandatory = $false)] [int]$TimeoutLimit = 10 ) begin { if ($null -eq (Get-SteamPath)) { throw 'SteamCMD could not be found in the env:Path. Have you executed Install-SteamCMD?' } # Log settings $PSFLoggingProvider = @{ Name = 'logfile' InstanceName = '<taskname>' FilePath = "$LogPath\$ServiceName\$ServiceName-%Date%.csv" Enabled = $true LogRotatePath = "$LogPath\$ServiceName\$ServiceName-*.csv" } Set-PSFLoggingProvider @PSFLoggingProvider # Variable that stores how many times the cmdlet has checked whether the # server is offline or online. $TimeoutCounter = 0 } process { # Get server status and output it. $ServerStatus = Get-SteamServerInfo -IPAddress $IPAddress -Port $Port -ErrorAction SilentlyContinue # If server is alive we check it is empty before updating it. if ($ServerStatus) { Write-PSFMessage -Level Host -Message $ServerStatus -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" # Waiting to server is empty. Checking every 60 seconds. while ($ServerStatus.Players -ne 0) { Write-PSFMessage -Level Host -Message 'Awaiting that the server is empty before updating.' -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" $ServerStatus = Get-SteamServerInfo -IPAddress $IPAddress -Port $Port -ErrorAction SilentlyContinue Write-PSFMessage -Level Host -Message $($ServerStatus | Select-Object -Property ServerName, Port, Players) -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" Start-Sleep -Seconds 60 } # Server is now empty and we stop, update and start the server. Write-PSFMessage -Level Host -Message "Stopping $ServiceName..." -Tag 'ServerUpdate' -ModuleName 'SteamPS' -Target $ServiceName Stop-Service -Name $ServiceName Write-PSFMessage -Level Host -Message "$($ServiceName): $((Get-Service -Name $ServiceName).Status)." -Tag 'ServerUpdate' -ModuleName 'SteamPS' -Target $ServiceName } else { Write-PSFMessage -Level Host -Message 'Server could not be reached.' -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" Write-PSFMessage -Level Host -Message 'Continuing with updating server.' -Tag 'ServerUpdate' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" } Write-PSFMessage -Level Host -Message "Updating $ServiceName..." -Tag 'ServerUpdate' -ModuleName 'SteamPS' -Target $ServiceName if ($null -ne $Credential) { Update-SteamApp -AppID $AppID -Path $Path -Credential $Credential -Arguments "$Arguments" -Force } else { Update-SteamApp -AppID $AppID -Path $Path -Arguments "$Arguments" -Force } Write-PSFMessage -Level Host -Message "Starting $ServiceName" -Tag 'ServerUpdate' -ModuleName 'SteamPS' -Target $ServiceName Start-Service -Name $ServiceName Write-PSFMessage -Level Host -Message "$($ServiceName): $((Get-Service -Name $ServiceName).Status)." -Tag 'ServerUpdate' -ModuleName 'SteamPS' -Target $ServiceName do { $TimeoutCounter++ # Add +1 for every loop. Write-PSFMessage -Level Host -Message 'Waiting for server to come online again.' -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" Start-Sleep -Seconds 60 # Getting new server information. $ServerStatus = Get-SteamServerInfo -IPAddress $IPAddress -Port $Port -ErrorAction SilentlyContinue | Select-Object -Property ServerName, Port, Players Write-PSFMessage -Level Host -Message $ServerStatus -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" Write-PSFMessage -Level Host -Message "No response from $($IPAddress):$($Port)." -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" Write-PSFMessage -Level Host -Message "TimeoutCounter: $TimeoutCounter/$TimeoutLimit" -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" if ($TimeoutCounter -ge $TimeoutLimit) { break } } until ($null -ne $ServerStatus.ServerName) if ($null -ne $ServerStatus.ServerName) { Write-PSFMessage -Level Host -Message "$($ServerStatus.ServerName) is now ONLINE." -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" $ServerState = 'ONLINE' $Color = 'Green' } else { Write-PSFMessage -Level Critical -Message "Server seems to be OFFLINE after the update..." -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" $ServerState = 'OFFLINE' $Color = 'Red' } } # Process end { if ($null -ne $DiscordWebhookUri -and ($ServerState -eq 'OFFLINE' -or $AlwaysNotify -eq $true)) { # Send Message to Discord about the update. $ServerFact = New-DiscordFact -Name 'Game Server Info' -Value $(Get-SteamServerInfo -IPAddress $IPAddress -Port $Port -ErrorAction SilentlyContinue | Select-Object -Property ServerName, IP, Port, Players | Out-String) $ServerStateFact = New-DiscordFact -Name 'Server State' -Value $(Write-Output -InputObject "Server is $ServerState!") $LogFact = New-DiscordFact -Name 'Log Location' -Value "$LogPath\$ServiceName\$ServiceName-%Date%.csv" $Section = New-DiscordSection -Title "$ServiceName - Update Script Executed" -Facts $ServerStateFact, $ServerFact, $LogFact -Color $Color Send-DiscordMessage -WebHookUrl $DiscordWebhookUri -Sections $Section } } # End } # Cmdlet |