diff --git a/CHANGELOG.md b/CHANGELOG.md index 294169c..c10d7d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/). ## Unreleased +### Added + +- Update-SteamServer + - Added `-Credential` parameter (#16). +- Update-SteamApp + - Output ExitCode from SteamCMD if it is not 0. + ### Changed - Improving structure / format of the code. - Remove the subexpression where they are not needed. - Dependencies are now handled in the module manifest instead of using custom cmdlet `Use-Module`. +- Update-SteamServer + - Fix minor issue with TimeoutLimit being hardcoded when writing to the log + instead of using the value defined in the parameter $TimeoutLimit. ### Removed diff --git a/SteamPS/Private/Add-EnvPath.ps1 b/SteamPS/Private/Add-EnvPath.ps1 index 29e5ab8..3c5c22f 100644 --- a/SteamPS/Private/Add-EnvPath.ps1 +++ b/SteamPS/Private/Add-EnvPath.ps1 @@ -13,23 +13,29 @@ [string] $Container = 'Session' ) - if ($Container -ne 'Session') { - $containerMapping = @{ - Machine = [EnvironmentVariableTarget]::Machine - User = [EnvironmentVariableTarget]::User - } - $containerType = $containerMapping[$Container] + process { + Write-Verbose -Message "Container is set to: $Container" + if ($Container -ne 'Session') { + $containerMapping = @{ + Machine = [EnvironmentVariableTarget]::Machine + User = [EnvironmentVariableTarget]::User + } + $containerType = $containerMapping[$Container] - $persistedPaths = [Environment]::GetEnvironmentVariable('Path', $containerType) -split ';' - if ($persistedPaths -notcontains $Path) { - $persistedPaths = $persistedPaths + $Path | Where-Object { $_ } - [Environment]::SetEnvironmentVariable('Path', $persistedPaths -join ';', $containerType) + $persistedPaths = [Environment]::GetEnvironmentVariable('Path', $containerType) -split ';' + if ($persistedPaths -notcontains $Path) { + $persistedPaths = $persistedPaths + $Path | Where-Object { $_ } + [Environment]::SetEnvironmentVariable('Path', $persistedPaths -join ';', $containerType) + } + Write-Verbose -Message "Adding $Path to environment path." } - } - $envPaths = $env:Path -split ';' - if ($envPaths -notcontains $Path) { - $envPaths = $envPaths + $Path | Where-Object { $_ } - $env:Path = $envPaths -join ';' - } -} \ No newline at end of file + $envPaths = $env:Path -split ';' + Write-Verbose -Message "Current environment paths: $envPaths" + if ($envPaths -notcontains $Path) { + $envPaths = $envPaths + $Path | Where-Object { $_ } + $env:Path = $envPaths -join ';' + Write-Verbose -Message "Adding $Path to environment path." + } + } # Process +} # Cmdlet \ No newline at end of file diff --git a/SteamPS/Public/Update-SteamApp.ps1 b/SteamPS/Public/Update-SteamApp.ps1 index f727630..af36aa8 100644 --- a/SteamPS/Public/Update-SteamApp.ps1 +++ b/SteamPS/Public/Update-SteamApp.ps1 @@ -80,6 +80,7 @@ function Update-SteamApp { })] [string]$Path, + [Parameter(Mandatory = $false)] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] @@ -97,13 +98,6 @@ function Update-SteamApp { throw 'SteamCMD could not be found in the env:Path. Have you executed Install-SteamCMD?' } - # Make Secure.String to plain text string. - if ($null -eq $Credential) { - $SecureString = $Credential | Select-Object -ExpandProperty Password - $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString) - $PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) - } - # Install SteamCMD if it is missing. if (-not (Test-Path -Path (Get-SteamPath).Executable)) { Start-Process powershell -ArgumentList '-NoExit -Command "Install-SteamCMD; exit"' -Verb RunAs @@ -117,12 +111,18 @@ function Update-SteamApp { # If Steam username and Steam password are not empty we use them for logging in. if ($null -ne $Credential.UserName) { Write-Verbose -Message "Logging into Steam as $($Credential | Select-Object -ExpandProperty UserName)." - Start-Process -FilePath (Get-SteamPath).Executable -NoNewWindow -ArgumentList "+login $($Credential | Select-Object -ExpandProperty UserName) $PlainPassword +force_install_dir `"$Path`" +app_update $SteamAppID $Arguments validate +quit" -Wait + $SteamCMDProcess = Start-Process -FilePath (Get-SteamPath).Executable -NoNewWindow -ArgumentList "+login $($Credential.UserName) $($Credential.GetNetworkCredential().Password) +force_install_dir `"$Path`" +app_update $SteamAppID $Arguments validate +quit" -Wait -PassThru + if ($SteamCMDProcess.ExitCode -ne 0) { + Write-Error -Message ("SteamCMD closed with ExitCode {0}" -f $SteamCMDProcess.ExitCode) -Category CloseError + } } # If Steam username and Steam password are empty we use anonymous login. elseif ($null -eq $Credential.UserName) { Write-Verbose -Message 'Using SteamCMD as anonymous.' - Start-Process -FilePath (Get-SteamPath).Executable -NoNewWindow -ArgumentList "+login anonymous +force_install_dir `"$Path`" +app_update $SteamAppID $Arguments validate +quit" -Wait + $SteamCMDProcess = Start-Process -FilePath (Get-SteamPath).Executable -NoNewWindow -ArgumentList "+login anonymous +force_install_dir `"$Path`" +app_update $SteamAppID $Arguments validate +quit" -Wait -PassThru + if ($SteamCMDProcess.ExitCode -ne 0) { + Write-Error -Message ("SteamCMD closed with ExitCode {0}" -f $SteamCMDProcess.ExitCode) -Category CloseError + } } } @@ -147,7 +147,7 @@ function Update-SteamApp { try { $SteamAppID = $AppID # Install selected Steam application. - if ($Force -or $PSCmdlet.ShouldContinue("Do you want to install or update $SteamAppID?", "Update SteamApp $SteamAppID?")) { + if ($Force -or $PSCmdlet.ShouldContinue("Do you want to install or update $($SteamAppID)?", "Update SteamApp $($SteamAppID)?")) { Write-Verbose -Message "The application with AppID $SteamAppID is being updated. Please wait for SteamCMD to finish." Use-SteamCMD -SteamAppID $SteamAppID } # Should Continue diff --git a/SteamPS/Public/Update-SteamServer.ps1 b/SteamPS/Public/Update-SteamServer.ps1 index d38824b..a6c5860 100644 --- a/SteamPS/Public/Update-SteamServer.ps1 +++ b/SteamPS/Public/Update-SteamServer.ps1 @@ -13,18 +13,21 @@ .PARAMETER ServiceName Specify the Windows Service Name. You can get a list of services with Get-Service. - .PARAMETER Path - Install location of the game server. - - .PARAMETER Arguments - Enter any additional arguments here. - .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 location of the log files. @@ -73,6 +76,12 @@ [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, @@ -87,10 +96,14 @@ [string]$AlwaysNotify, [Parameter(Mandatory = $false)] - [string]$TimeoutLimit = 10 + [int]$TimeoutLimit = 10 ) begin { + if ($null -eq (Get-SteamPath)) { + throw 'SteamCMD could not be found in the env:Path. Have you executed Install-SteamCMD?' + } + # Create a log file with information about the operation. Set-LoggingDefaultLevel -Level 'INFO' Add-LoggingTarget -Name Console @@ -108,18 +121,22 @@ # Waiting to server is empty. Checking every 60 seconds. while ($ServerStatus.Players -ne 0) { - Write-Log -Message "Awaiting that the server is empty." + Write-Log -Message "Awaiting that the server is empty before updating." $ServerStatus = Get-SteamServerInfo -IPAddress $IPAddress -Port $Port Write-Log -Message $ServerStatus | Select-Object -Property ServerName, Port, Players Start-Sleep -Seconds 60 } # Server is now empty and we stop, update and start the server. - Write-Log -Message "Stopping $ServiceName)" + Write-Log -Message "Stopping $ServiceName" Stop-Service -Name $ServiceName Write-Log -Message "$($ServiceName): $((Get-Service -Name $ServiceName).Status)." Write-Log -Message "Updating $ServiceName..." - Update-SteamApp -AppID $AppID -Path $Path -Arguments "$Arguments" -Force -Verbose + 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-Log -Message "Starting $ServiceName" Start-Service -Name $ServiceName @@ -132,7 +149,7 @@ # Getting new server information. $ServerStatus = Get-SteamServerInfo -IPAddress $IPAddress -Port $Port | Select-Object -Property ServerName, Port, Players Write-Log -Message $ServerStatus - Write-Log -Message "TimeoutCounter: $($TimeoutCounter)/10" + Write-Log -Message "TimeoutCounter: $TimeoutCounter/$TimeoutLimit" if ($TimeoutCounter -ge $TimeoutLimit) { break } @@ -156,7 +173,7 @@ $ServerStateFact = New-DiscordFact -Name 'Server State' -Value $(Write-Output -InputObject "Server is $ServerState!") $LogFact = New-DiscordFact -Name 'Log Location' -Value $LogPath $Section = New-DiscordSection -Title "$ServiceName - Update Script Executed" -Facts $ServerStateFact, $ServerFact, $LogFact -Color $Color - Send-DiscordMessage -WebHookUrl $DiscordWebhookUri -Sections $Section -Verbose + Send-DiscordMessage -WebHookUrl $DiscordWebhookUri -Sections $Section } } # End } # Cmdlet \ No newline at end of file diff --git a/Tests/PSScriptAnalyzer.Tests.ps1 b/Tests/PSScriptAnalyzer.Tests.ps1 deleted file mode 100644 index edb67ad..0000000 --- a/Tests/PSScriptAnalyzer.Tests.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -$ScriptAnalyzerRules = Get-ScriptAnalyzerRule -$PowerShellFiles = Get-ChildItem $env:BHProjectPath -Recurse -Filter *.ps*1 - -foreach ($PowerShellFile in $PowerShellFiles) { - Describe "File $($PowerShellFile) should not produce any PSScriptAnalyzer warnings" -Tag 'PSScriptAnalyzer' { - $Analysis = Invoke-ScriptAnalyzer -Path $PowerShellFile.FullName -Settings "$env:BHProjectPath\PSScriptAnalyzerSettings.psd1" - - foreach ($Rule in $ScriptAnalyzerRules) { - It "Should pass $Rule" { - if ($Analysis.RuleName -contains $Rule) { - $Analysis | Where-Object -FilterScript { $_.RuleName -eq $Rule } -OutVariable Failures | Out-Default - $Failures.Count | Should -Be 0 - } - } # It - } # foreach - } # Describe -} # foreach \ No newline at end of file diff --git a/Tests/SteamPS.Tests.ps1 b/Tests/SteamPS.Tests.ps1 index 08a9316..e727208 100644 --- a/Tests/SteamPS.Tests.ps1 +++ b/Tests/SteamPS.Tests.ps1 @@ -6,20 +6,20 @@ } } -InModuleScope SteamPS { - Describe "Get-SteamServerInfo" { - It "Finds information about a Steam based game server" { - $ServerInfo = Get-SteamServerInfo -IPAddress '185.15.73.207' -Port 27015 - $ServerInfo.ServerName | Should -Be 'SAS Proving Ground 10 (EU)' - } +Describe "Get-SteamServerInfo" { + It "Finds information about a Steam based game server" { + $ServerInfo = Get-SteamServerInfo -IPAddress '185.15.73.207' -Port 27015 + $ServerInfo.ServerName | Should -Be 'SAS Proving Ground 10 (EU)' } } Describe "Test SteamCMD cmdlets" { - . "$env:BHModulePath\Private\Add-EnvPath.ps1" - Add-EnvPath -Path 'TestDrive:\Test\SteamCMD' -Container Session + BeforeAll { + . "$env:BHModulePath\Private\Add-EnvPath.ps1" + Add-EnvPath -Path 'TestDrive:\Test\SteamCMD' -Container Session - Install-SteamCMD -InstallPath 'TestDrive:\Test' -Force + Install-SteamCMD -InstallPath 'TestDrive:\Test' -Force + } Context "Install and update applications" { It "Finds steamcmd.exe" { @@ -42,6 +42,8 @@ Describe "Test SteamCMD cmdlets" { } } - # Wait for the process steamerrorreporter to be closed - else test folder wont be deleted. - Wait-Process -Name 'steamerrorreporter' -ErrorAction SilentlyContinue + AfterAll { + # Wait for the process steamerrorreporter to be closed - else test folder wont be deleted. + Wait-Process -Name 'steamerrorreporter' -ErrorAction SilentlyContinue + } } \ No newline at end of file