├── docs ├── _config.yml ├── index.md ├── Connect-SteamAPI.md ├── Disconnect-SteamAPI.md ├── Resolve-VanityURL.md ├── Get-SteamPlayerBan.md ├── Get-SteamFriendList.md ├── Install-SteamCMD.md ├── Get-SteamNews.md ├── Get-SteamServerInfo.md ├── Get-SteamApp.md ├── Get-SteamPlayerSummary.md ├── Update-SteamApp.md ├── Update-SteamServer.md └── CHANGELOG.md ├── .markdownlint.json ├── assets └── images │ ├── update-steamapp.gif │ ├── install-steamcmd.gif │ ├── select-application.png │ └── SteamPS-icon.svg ├── .gitignore ├── .vscode ├── settings.json ├── launch.json └── tasks.json ├── SteamPS ├── Private │ ├── Server │ │ ├── Get-SteamPath.ps1 │ │ ├── Get-PacketString.ps1 │ │ ├── Add-EnvPath.ps1 │ │ └── Test-Admin.ps1 │ └── API │ │ └── Get-SteamAPIKey.ps1 ├── Enum │ └── Enum.ps1 ├── Public │ ├── API │ │ ├── Disconnect-SteamAPI.ps1 │ │ ├── Connect-SteamAPI.ps1 │ │ ├── Get-SteamFriendList.ps1 │ │ ├── Resolve-VanityURL.ps1 │ │ ├── Get-SteamPlayerBan.ps1 │ │ ├── Get-SteamNews.ps1 │ │ ├── Get-SteamApp.ps1 │ │ └── Get-SteamPlayerSummary.ps1 │ └── Server │ │ ├── Install-SteamCMD.ps1 │ │ ├── Get-SteamServerInfo.ps1 │ │ ├── Update-SteamApp.ps1 │ │ └── Update-SteamServer.ps1 └── SteamPS.psd1 ├── .github ├── pull_request_template.md ├── ISSUE_TEMPLATE │ ├── module-suggestion.md │ └── module-issue.md ├── stale.yml ├── release.yml └── workflows │ └── CI.yml ├── Tests ├── Unit │ ├── Public │ │ ├── Disconnect-SteamAPI.Tests.ps1 │ │ ├── Get-SteamApp.Tests.ps1 │ │ ├── Resolve-VanityURL.Tests.ps1 │ │ ├── Update-SteamServer.Tests.ps1 │ │ ├── Get-SteamPlayerBan.Tests.ps1 │ │ ├── Get-SteamFriendList.Tests.ps1 │ │ ├── Get-SteamPlayerSummary.Tests.ps1 │ │ └── Get-SteamNews.Tests.ps1 │ └── Private │ │ ├── Test-Admin.Tests.ps1 │ │ ├── Get-SteamAPIKey.Tests.ps1 │ │ ├── Get-PacketString.Tests.ps1 │ │ └── Add-EnvPath.Tests.ps1 ├── Integration │ └── Public │ │ ├── Install-SteamCMD.Tests.ps1 │ │ ├── Update-SteamApp.Tests.ps1 │ │ └── Get-SteamServerInfo.Tests.ps1 ├── ModuleValidation.Tests.ps1 └── Help.Tests.ps1 ├── Tools ├── requiredModules.psd1 └── PesterTest.ps1 ├── .editorconfig ├── LICENSE.md ├── PSScriptAnalyzerSettings.psd1 ├── SteamPS.build.ps1 ├── CHANGELOG.md └── README.md /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "default": true, 3 | "MD024": false, 4 | "MD033": false 5 | } 6 | -------------------------------------------------------------------------------- /assets/images/update-steamapp.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hjorslev/SteamPS/HEAD/assets/images/update-steamapp.gif -------------------------------------------------------------------------------- /assets/images/install-steamcmd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hjorslev/SteamPS/HEAD/assets/images/install-steamcmd.gif -------------------------------------------------------------------------------- /assets/images/select-application.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hjorslev/SteamPS/HEAD/assets/images/select-application.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | coverage.xml 2 | testResults.xml 3 | # OS generated files # 4 | ###################### 5 | .DS_Store 6 | .DS_Store? 7 | ._* 8 | .Spotlight-V100 9 | .Trashes 10 | ehthumbs.db 11 | Thumbs.db 12 | 13 | ### Custom entries ### 14 | output/ 15 | tools/Modules 16 | test.settings.json 17 | tests/integration/.vagrant 18 | tests/integration/cert_setup -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 4, 3 | "editor.autoIndent": "full", 4 | "editor.insertSpaces": true, 5 | "editor.formatOnPaste": true, 6 | "editor.formatOnSave": false, 7 | "editor.renderWhitespace": "boundary", 8 | "editor.detectIndentation": true, 9 | "files.trimTrailingWhitespace": true, 10 | "powershell.codeFormatting.preset": "OTBS", 11 | "powershell.scriptAnalysis.settingsPath": ".\\PSScriptAnalyzerSettings.psd1", 12 | "powershell.codeFormatting.addWhitespaceAroundPipe": true, 13 | "cSpell.words": [ 14 | "cmdlet", 15 | "cmdlets" 16 | ] 17 | } -------------------------------------------------------------------------------- /SteamPS/Private/Server/Get-SteamPath.ps1: -------------------------------------------------------------------------------- 1 | function Get-SteamPath { 2 | [CmdletBinding()] 3 | param ( 4 | ) 5 | 6 | process { 7 | $SteamCMDPath = $env:Path.Split([System.IO.Path]::PathSeparator) | 8 | Where-Object -FilterScript { $_ -like '*SteamCMD*' } 9 | 10 | if ($null -ne $SteamCMDPath) { 11 | [PSCustomObject]@{ 12 | 'Path' = $SteamCMDPath 13 | 'Executable' = "$SteamCMDPath\steamcmd.exe" 14 | } 15 | } else { 16 | Write-Verbose -Message 'SteamCMD where not found on the environment path.' 17 | } 18 | } # Process 19 | } # Cmdlet -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | 4 | 5 | ## Type of change 6 | 7 | 8 | 9 | - [ ] 📖 [Docs] 10 | - [ ] 🪲 [Fix] 11 | - [ ] ⚠️ [Security fix] 12 | - [ ] ♻️ [Refactor] 13 | - [ ] 🎉 [Feature] 14 | - [ ] ✨ Enhancement 15 | - [ ] 🌟 [Breaking change] 16 | 17 | ## Checklist 18 | 19 | 20 | 21 | - [ ] I have performed a self-review of my own code 22 | - [ ] I have commented my code, particularly in hard-to-understand areas 23 | - [ ] I have added Pester tests that covers the added cmdlets -------------------------------------------------------------------------------- /Tests/Unit/Public/Disconnect-SteamAPI.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe 'Disconnect-SteamAPI Tests' { 2 | Context 'When Force is specified and API key is found' { 3 | BeforeAll { 4 | Mock -CommandName Test-Path -ModuleName SteamPS -MockWith { return $true } -Verifiable -ParameterFilter { $Path -eq "$env:AppData\SteamPS\SteamPSKey.json" } 5 | Mock -CommandName Remove-Item -ModuleName SteamPS -MockWith {} -Verifiable -ParameterFilter { $Path -eq "$env:AppData\SteamPS\SteamPSKey.json" } 6 | } 7 | It 'Deletes the Steam API key file' { 8 | Disconnect-SteamAPI -Force | Should -InvokeVerifiable 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/module-suggestion.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "✨ Module Suggestion" 3 | about: Suggest new module functionality, or enhancements to existing functionality. 4 | labels: Category-Module, Issue-Suggestion 5 | 6 | --- 7 | 8 | # Describe "Functionality" 9 | 10 | 11 | 12 | ## Context "Private or Public? What are the use cases? Parameters? Options?" 13 | 14 | 15 | 16 | ## Context "Additional Information" 17 | 18 | 19 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 400 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 14 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - "Pinned 📌" 8 | - "Security 🔒" 9 | # Label to use when marking an issue as stale 10 | staleLabel: "Resolution-WontFix 🚫" 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /Tools/requiredModules.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | InvokeBuild = @{ 3 | Priority = 3 4 | Version = '5.10.3' 5 | } 6 | platyPS = @{ 7 | Priority = 3 8 | Version = '0.14.2' 9 | } 10 | PSScriptAnalyzer = @{ 11 | Priority = 3 12 | Version = '1.21.0' 13 | } 14 | Configuration = @{ 15 | Priority = 2 16 | Version = '1.5.1' 17 | } 18 | ModuleBuilder = @{ 19 | Priority = 3 20 | Version = '3.0.0' 21 | } 22 | Metadata = @{ 23 | Priority = 1 24 | Version = '1.5.7' 25 | } 26 | Pester = @{ 27 | Priority = 3 28 | Version = '5.4.1' 29 | } 30 | PSFramework = @{ 31 | Priority = 3 32 | Version = '1.10.318' 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Tests/Integration/Public/Install-SteamCMD.Tests.ps1: -------------------------------------------------------------------------------- 1 | 2 | Describe 'Install-SteamCMD Tests' -Tag 'Integration' { 3 | BeforeAll { 4 | . "$($SteamPSModulePath)\Private\Server\Add-EnvPath.ps1" 5 | Add-EnvPath -Path 'TestDrive:\Test\SteamCMD' 6 | } 7 | 8 | Context 'When executing Install-SteamCMD' { 9 | It 'Should install SteamCMD' { 10 | Install-SteamCMD -InstallPath 'TestDrive:\Test' -Force 11 | } 12 | 13 | It 'Should find steamcmd.exe' { 14 | Test-Path -Path "$TestDrive\Test\SteamCMD\steamcmd.exe" | Should -BeTrue 15 | } 16 | } 17 | 18 | AfterAll { 19 | # Wait for the process steamerrorreporter to be closed - else test folder wont be deleted. 20 | Wait-Process -Name 'steamerrorreporter' -ErrorAction SilentlyContinue 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Tests/Unit/Private/Test-Admin.Tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | . $SteamPSModulePath\Private\Server\Test-Admin.ps1 3 | } 4 | 5 | Describe 'Test-Admin Tests' { 6 | Context 'Function: Test-Admin' { 7 | It 'Should not throw' { 8 | { Test-Admin } | Should -Not -Throw 9 | } 10 | 11 | It 'Should return for based runners' -ForEach @( 12 | @{ 13 | Expected = if ($IsLinux -or $IsMacOS) { 14 | $false 15 | } else { 16 | $true 17 | } 18 | OS = if ($IsLinux -or $IsMacOS) { 19 | 'Unix' 20 | } else { 21 | 'Windows' 22 | } 23 | } 24 | ) { 25 | Test-Admin | Should -Be $Expected 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes#configuring-automatically-generated-release-notes 2 | # https://raw.githubusercontent.com/PSModule 3 | 4 | changelog: 5 | exclude: 6 | labels: 7 | - Category-Tests ✅ 8 | - Category-Build 🚀 9 | - ignore-for-release 10 | categories: 11 | - title: 🌟 Breaking Changes 12 | labels: 13 | - Breaking 🌟 14 | - title: 🎉 New Features 15 | labels: 16 | - Issue-Feature 🎉 17 | - title: ✨ Enhancements 18 | labels: 19 | - Issue-Enhancement ✨ 20 | - title: 🐛 Bug Fixes 21 | labels: 22 | - Issue-Bug 🐛 23 | - title: ♻️ Refactored 24 | labels: 25 | - Refactor ♻️ 26 | - title: Security Fixes 🔒 27 | labels: 28 | - Security 🔒 29 | - title: Other Changes 30 | labels: 31 | - '*' 32 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "PowerShell launch", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "program": "pwsh", 12 | "args": [ 13 | "-NoExit", 14 | "-NoProfile", 15 | "-Command", 16 | "Import-Module ./output/SteamPS" 17 | ], 18 | "cwd": "${workspaceFolder}", 19 | "stopAtEntry": false, 20 | "console": "externalTerminal", 21 | "windows": {} 22 | }, 23 | { 24 | "name": "PowerShell Launch Current File", 25 | "type": "PowerShell", 26 | "request": "launch", 27 | "script": "${file}", 28 | "cwd": "${workspaceFolder}" 29 | } 30 | ] 31 | } -------------------------------------------------------------------------------- /SteamPS/Enum/Enum.ps1: -------------------------------------------------------------------------------- 1 | enum ServerType { 2 | Dedicated = 0x64 #d 3 | NonDedicated = 0x6C #l 4 | SourceTV = 0x70 #p 5 | } 6 | enum OSType { 7 | Linux = 108 #l 8 | Windows = 119 #w 9 | Mac = 109 #m 10 | MacOsX = 111 #o 11 | } 12 | enum VAC { 13 | Unsecured = 0 14 | Secured = 1 15 | } 16 | enum Visibility { 17 | Public = 0 18 | Private = 1 19 | } 20 | 21 | enum PersonaState { 22 | Offline = 0 23 | Online = 1 24 | Busy = 2 25 | Away = 3 26 | Snooze = 4 27 | LookingToTrade = 5 28 | } 29 | enum CommunityVisibilityState { 30 | Private = 1 31 | FriendsOnly = 2 32 | Public = 3 33 | } 34 | 35 | if ($PSVersionTable.PSVersion.Major -le 5 -and $PSVersionTable.PSVersion.Minor -le 1) { 36 | Write-Warning -Message "The support for Windows PowerShell (v5) will be deprecated in the next major version of SteamPS. Please ensure your system supports PowerShell 7." 37 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/module-issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "💥 Module Issue or Bug" 3 | about: File an issue or bug report about the module features/functions themselves. 4 | labels: Category-Module, Issue-Discussion 5 | --- 6 | 7 | # Describe "Module Bug or Issue" 8 | 9 | 10 | 11 | ## Context "The Problem" 12 | 13 | 14 | 15 | ## Context "Expected Behavior" 16 | 17 | 18 | 19 | ## Context "Additional Information" 20 | 21 | 22 | 23 | ```powershell 24 | Get-Module -Name SteamPS -ListAvailable | 25 | Select-Object -Property Name, Version 26 | 27 | $PSVersionTable | Out-String 28 | ``` 29 | 30 | 31 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | # .NET coding convention settings for EditorConfig 3 | # https://docs.microsoft.com/visualstudio/ide/editorconfig-code-style-settings-reference 4 | # 5 | # This file comes from dotnet repositories: 6 | # https://github.com/dotnet/runtime/blob/master/.editorconfig 7 | # https://github.com/dotnet/roslyn/blob/master/.editorconfig 8 | 9 | # Top-most EditorConfig file 10 | root = true 11 | 12 | [*] 13 | charset = utf-8-bom 14 | # indent_size intentionally not specified in this section 15 | indent_style = space 16 | 17 | # Source code 18 | [*.{cs,ps1,psd1,psm1}] 19 | indent_size = 4 20 | 21 | # Shell scripts 22 | [*.sh] 23 | indent_size = 4 24 | 25 | # Xml project files 26 | [*.{csproj,resx,ps1xml}] 27 | indent_size = 2 28 | 29 | # Data serialization 30 | [*.{json,yaml,yml}] 31 | indent_size = 2 32 | 33 | # Markdown 34 | [*.md] 35 | indent_size = 2 36 | 37 | # Xml files 38 | [*.{resx,ruleset,stylecop,xml,xsd,xsl}] 39 | indent_size = 2 40 | 41 | # Xml config files 42 | [*.{props,targets,config,nuspec}] 43 | indent_size = 2 44 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2018 Frederik Hjorslev Nylander 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 | -------------------------------------------------------------------------------- /Tests/Unit/Public/Get-SteamApp.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe 'Get-SteamApp Tests' { 2 | Context 'When searching for a single application using ApplicationName' { 3 | It 'Should return the correct AppID and name' { 4 | $SteamApp = Get-SteamApp -ApplicationName 'Ground Branch Dedicated Server' 5 | $SteamApp.ApplicationName | Should -BeExactly 'GROUND BRANCH Dedicated Server' 6 | $SteamApp.ApplicationID | Should -BeExactly 476400 7 | } 8 | } 9 | Context 'When searching for a single application using ApplicationID' { 10 | It 'Should return the correct AppID and name' { 11 | $SteamApp = Get-SteamApp -ApplicationID 440 12 | $SteamApp.ApplicationName | Should -BeExactly 'Team Fortress 2' 13 | $SteamApp.ApplicationID | Should -BeExactly 440 14 | } 15 | } 16 | 17 | Context 'When no application is found' { 18 | It 'Should write an error when no application name were found' { 19 | { Get-SteamApp -ApplicationName 'Nonexistent Application' -ErrorAction Stop } | Should -Throw 20 | } 21 | It 'Should write an error when no application ID were found' { 22 | { Get-SteamApp -ApplicationID '1234567' -ErrorAction Stop } | Should -Throw 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SteamPS/Private/Server/Get-PacketString.ps1: -------------------------------------------------------------------------------- 1 | function Get-PacketString { 2 | <# 3 | .SYNOPSIS 4 | Get a string in a byte stream. 5 | 6 | .DESCRIPTION 7 | Get a string in a byte stream. 8 | 9 | .PARAMETER Stream 10 | Accepts BinaryReader. 11 | 12 | .EXAMPLE 13 | Get-PacketString -Stream $Stream 14 | 15 | Assumes that you already have a byte stream. See more detailed usage in 16 | Get-SteamServerInfo. 17 | 18 | .NOTES 19 | Author: Jordan Borean and Chris Dent 20 | #> 21 | 22 | [CmdletBinding()] 23 | param ( 24 | [Parameter(Mandatory = $true)] 25 | [System.IO.BinaryReader]$Stream 26 | ) 27 | 28 | process { 29 | # Check if the stream has any bytes available 30 | if ($Stream.BaseStream.Length -gt 0) { 31 | # Find the end of the string, terminated with \0 and convert that byte range to a string. 32 | $stringBytes = while ($true) { 33 | $byte = $Stream.ReadByte() 34 | if ($byte -eq 0) { 35 | break 36 | } 37 | $byte 38 | } 39 | } 40 | 41 | if ($stringBytes.Count -gt 0) { 42 | [System.Text.Encoding]::UTF8.GetString($stringBytes) 43 | } 44 | } # Process 45 | } # Cmdlet -------------------------------------------------------------------------------- /Tests/Unit/Private/Get-SteamAPIKey.Tests.ps1: -------------------------------------------------------------------------------- 1 | [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'Does not hold any real secret.')] 2 | param() 3 | 4 | BeforeAll { 5 | . $SteamPSModulePath\Private\API\Get-SteamAPIKey.ps1 6 | } 7 | 8 | Describe "Get-SteamAPIKey Tests" { 9 | Context "When SteamPSKey.json exists" { 10 | BeforeAll { 11 | # Create a dummy SteamPSKey.json file 12 | $SteamPSKeyLocation = "$env:AppData\SteamPS\SteamPSKey.json" 13 | New-Item -Path $SteamPSKeyLocation -ItemType File -Force 14 | $dummyKey = ConvertTo-SecureString -String "dummyKey" -AsPlainText -Force 15 | $dummyKey | ConvertFrom-SecureString | Set-Content -Path $SteamPSKeyLocation 16 | } 17 | 18 | AfterAll { 19 | # Remove the dummy SteamPSKey.json file 20 | Remove-Item -Path "$env:AppData\SteamPS\SteamPSKey.json" -Force 21 | } 22 | 23 | It "Should return the API key in plain text" { 24 | $apiKey = Get-SteamAPIKey 25 | $apiKey | Should -BeExactly "dummyKey" 26 | } 27 | } 28 | 29 | Context "When SteamPSKey.json does not exist" { 30 | It "Should throw an error" { 31 | { Get-SteamAPIKey } | Should -Throw 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Tests/ModuleValidation.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe 'Static Analysis: Module & Repository Files' -Tags 'Module' { 2 | #region Discovery 3 | $FileSearch = @{ 4 | Path = $ReleasePath 5 | Include = '*.ps1', '*.psm1', '*.psd1' 6 | Recurse = $true 7 | } 8 | $Scripts = Get-ChildItem @FileSearch 9 | 10 | # TestCases are splatted to the script so we need hashtables 11 | $TestCases = $Scripts | ForEach-Object { @{File = $_ } } 12 | #endregion Discovery 13 | 14 | Context 'Repository Code' { 15 | It 'has no invalid syntax errors in ' -TestCases $TestCases { 16 | $File.FullName | Should -Exist 17 | 18 | $FileContents = Get-Content -Path $File.FullName -ErrorAction Stop 19 | $Errors = $null 20 | [System.Management.Automation.PSParser]::Tokenize($FileContents, [ref]$Errors) > $null 21 | $Errors.Count | Should -Be 0 22 | } 23 | } 24 | 25 | Context 'Module Import' { 26 | It 'cleanly imports the module' { 27 | { Import-Module "$($ReleasePath)\SteamPS.psd1" -Force } | Should -Not -Throw 28 | } 29 | 30 | It 'removes and re-imports the module without errors' { 31 | $Script = { 32 | Remove-Module SteamPS 33 | Import-Module "$($ReleasePath)\SteamPS.psd1" 34 | } 35 | 36 | $Script | Should -Not -Throw 37 | } 38 | } 39 | } # Describe -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | Module Name: steamps 3 | Module Guid: 4 | Download Help Link: 5 | Help Version: 6 | Locale: 7 | --- 8 | 9 | # steamps Module 10 | ## Description 11 | 12 | 13 | ## steamps Cmdlets 14 | ### [Connect-SteamAPI](Connect-SteamAPI.md) 15 | Create or update the Steam Web API config file. 16 | 17 | ### [Disconnect-SteamAPI](Disconnect-SteamAPI.md) 18 | Disconnects from the Steam API by removing the stored API key. 19 | 20 | ### [Find-SteamAppID](Find-SteamAppID.md) 21 | Find a Steam AppID by searching the name of the application. 22 | 23 | ### [Get-SteamFriendList](Get-SteamFriendList.md) 24 | Returns the friend list of any Steam user. 25 | 26 | ### [Get-SteamNews](Get-SteamNews.md) 27 | Returns the latest news of a game specified by its AppID. 28 | 29 | ### [Get-SteamPlayerBan](Get-SteamPlayerBan.md) 30 | Returns Community, VAC, and Economy ban statuses for given players. 31 | 32 | ### [Get-SteamPlayerSummary](Get-SteamPlayerSummary.md) 33 | Returns basic profile information for a list of 64-bit Steam IDs. 34 | 35 | ### [Get-SteamServerInfo](Get-SteamServerInfo.md) 36 | Query a running steam based game server. 37 | 38 | ### [Install-SteamCMD](Install-SteamCMD.md) 39 | Install SteamCMD. 40 | 41 | ### [Resolve-VanityURL](Resolve-VanityURL.md) 42 | Resolve a vanity URL (also named custom URL). 43 | 44 | ### [Update-SteamApp](Update-SteamApp.md) 45 | Install or update a Steam application using SteamCMD. 46 | 47 | ### [Update-SteamServer](Update-SteamServer.md) 48 | Update a Steam based game server. 49 | 50 | -------------------------------------------------------------------------------- /Tests/Unit/Public/Resolve-VanityURL.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe 'Resolve-VanityURL Tests' -Tag 'Unit' { 2 | BeforeAll { 3 | . $SteamPSModulePath\Private\API\Get-SteamAPIKey.ps1 4 | Mock -CommandName Get-SteamAPIKey -ModuleName SteamPS -MockWith { 5 | return $true 6 | } 7 | } 8 | 9 | Context 'When resolving a valid VanityURL' { 10 | BeforeAll { 11 | Mock -CommandName Invoke-RestMethod -ModuleName SteamPS -MockWith { 12 | return '{"response":{"steamid":"7656119711117235","success": 1}}' | ConvertFrom-Json 13 | } # Mock 14 | } 15 | It 'Should return a PSCustomObject with SteamID64' { 16 | (Resolve-VanityURL -VanityURL 'Toby').SteamID64 | Should -BeExactly 7656119711117235 17 | } 18 | } 19 | 20 | Context 'When resolving an invalid VanityURL' { 21 | BeforeAll { 22 | Mock -CommandName Invoke-RestMethod -ModuleName SteamPS -MockWith { 23 | return '{"response":{"success": 42,"message": "No match"}}' | ConvertFrom-Json 24 | } # Mock 25 | } 26 | 27 | It 'Should throw an error' { 28 | { Resolve-VanityURL -VanityURL 'invalidVanityURL' -ErrorAction Stop } | Should -Throw 29 | } 30 | } 31 | 32 | Context 'When resolving an invalid, fully qualified VanityURL' { 33 | It 'Should throw an error' { 34 | { Resolve-VanityURL -VanityURL 'https://steamcommunity.com/id/test' } | Should -Throw 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SteamPS/Private/Server/Add-EnvPath.ps1: -------------------------------------------------------------------------------- 1 | function Add-EnvPath { 2 | <# 3 | .LINK 4 | https://gist.github.com/mkropat/c1226e0cc2ca941b23a9 5 | #> 6 | 7 | [CmdletBinding()] 8 | param ( 9 | [Parameter(Mandatory = $true)] 10 | [string]$Path, 11 | 12 | [ValidateSet('Machine', 'User', 'Session')] 13 | [string]$Container = 'Session' 14 | ) 15 | 16 | process { 17 | Write-Verbose -Message "Container is set to: $Container" 18 | $Path = $Path.Trim() 19 | 20 | $containerMapping = @{ 21 | Machine = [EnvironmentVariableTarget]::Machine 22 | User = [EnvironmentVariableTarget]::User 23 | Session = [EnvironmentVariableTarget]::Process 24 | } 25 | 26 | $containerType = $containerMapping[$Container] 27 | $persistedPaths = [Environment]::GetEnvironmentVariable('Path', $containerType). 28 | Split([System.IO.Path]::PathSeparator).Trim() -ne '' 29 | 30 | if ($persistedPaths -notcontains $Path) { 31 | # previous step with `Trim()` + `-ne ''` already takes care of empty tokens, 32 | # no need to filter again here 33 | $persistedPaths = ($persistedPaths + $Path) -join [System.IO.Path]::PathSeparator 34 | [Environment]::SetEnvironmentVariable('Path', $persistedPaths, $containerType) 35 | 36 | Write-Verbose -Message "Adding $Path to environment path." 37 | } else { 38 | Write-Verbose -Message "$Path is already located in env:Path." 39 | } 40 | } # Process 41 | } # Cmdlet -------------------------------------------------------------------------------- /Tests/Integration/Public/Update-SteamApp.Tests.ps1: -------------------------------------------------------------------------------- 1 | 2 | Describe 'Update-SteamApp Tests' -Tag 'Integration' { 3 | BeforeAll { 4 | . "$($SteamPSModulePath)\Private\Server\Add-EnvPath.ps1" 5 | Add-EnvPath -Path 'TestDrive:\Test\SteamCMD' 6 | 7 | if ((Test-Path -Path "$TestDrive\Test\SteamCMD\steamcmd.exe") -eq $false) { 8 | Install-SteamCMD -InstallPath 'TestDrive:\Test' -Force 9 | } 10 | } 11 | 12 | Context 'When executing Update-SteamApp' { 13 | It 'Installs Ground Branch Dedicated Server using AppID' { 14 | Update-SteamApp -AppID 476400 -Path "$TestDrive\GB-AppID" -Force 15 | Test-Path -Path "$TestDrive\GB-AppID\GroundBranchServer.exe" | Should -BeTrue 16 | } 17 | 18 | It 'Installs Ground Branch Dedicated Server using Application Name' { 19 | Update-SteamApp -ApplicationName 'Ground Branch D' -Path "$TestDrive\GB-AppName" -Force 20 | Test-Path -Path "$TestDrive\GB-AppName\GroundBranchServer.exe" | Should -BeTrue 21 | } 22 | 23 | It 'Passes custom argument and installs prerelase branch of Counter-Strike: Source Dedicated Server' { 24 | Update-SteamApp -AppID 232330 -Path "$TestDrive\CSS-prerelease" -Arguments "-beta prerelease" -Force 25 | Test-Path -Path "$TestDrive\CSS-prerelease\srcds.exe" | Should -BeTrue 26 | } 27 | } 28 | 29 | AfterAll { 30 | # Wait for the process steamerrorreporter to be closed - else test folder wont be deleted. 31 | Wait-Process -Name 'steamerrorreporter' -ErrorAction SilentlyContinue 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "build", 8 | "command": "pwsh", 9 | "type": "shell", 10 | "args": [ 11 | "-File", 12 | "${workspaceFolder}/build.ps1" 13 | ], 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | }, 18 | "problemMatcher": "$msCompile" 19 | }, 20 | { 21 | "label": "update docs", 22 | "command": "pwsh", 23 | "type": "shell", 24 | "args": [ 25 | "-Command", 26 | "Import-Module ${workspaceFolder}/output/SteamPS; Import-Module ${workspaceFolder}/tools/Modules/platyPS; Update-MarkdownHelpModule ${workspaceFolder}/docs/en-US -AlphabeticParamsOrder -RefreshModulePage -UpdateInputOutput" 27 | ], 28 | "problemMatcher": [], 29 | "dependsOn": [ 30 | "build" 31 | ] 32 | }, 33 | { 34 | "label": "test", 35 | "command": "pwsh", 36 | "type": "shell", 37 | "args": [ 38 | "-File", 39 | "${workspaceFolder}/build.ps1", 40 | "-Task", 41 | "Test" 42 | ], 43 | "problemMatcher": [], 44 | "dependsOn": [ 45 | "build" 46 | ] 47 | } 48 | ] 49 | } -------------------------------------------------------------------------------- /PSScriptAnalyzerSettings.psd1: -------------------------------------------------------------------------------- 1 | # Use the PowerShell extension setting `powershell.scriptAnalysis.settingsPath` to get the current workspace 2 | # to use this PSScriptAnalyzerSettings.psd1 file to configure code analysis in Visual Studio Code. 3 | # This setting is configured in the workspace's `.vscode\settings.json`. 4 | # 5 | # For more information on PSScriptAnalyzer settings see: 6 | # https://github.com/PowerShell/PSScriptAnalyzer/blob/master/README.md#settings-support-in-scriptanalyzer 7 | # 8 | # You can see the predefined PSScriptAnalyzer settings here: 9 | # https://github.com/PowerShell/PSScriptAnalyzer/tree/master/Engine/Settings 10 | @{ 11 | # Only diagnostic records of the specified severity will be generated. 12 | # Uncomment the following line if you only want Errors and Warnings but 13 | # not Information diagnostic records. 14 | #Severity = @('Error','Warning') 15 | 16 | # Analyze **only** the following rules. Use IncludeRules when you want 17 | # to invoke only a small subset of the default rules. 18 | 19 | # Do not analyze the following rules. Use ExcludeRules when you have 20 | # commented out the IncludeRules settings above and want to include all 21 | # the default rules except for those you exclude below. 22 | # Note: if a rule is in both IncludeRules and ExcludeRules, the rule 23 | # will be excluded. 24 | ExcludeRules = @('PSAvoidUsingWriteHost', 'PSAvoidUsingComputerNameHardcoded', 'PSReviewUnusedParameter') 25 | 26 | # You can use rule configuration to configure rules that support it: 27 | #Rules = @{ 28 | # PSAvoidUsingCmdletAliases = @{ 29 | # Whitelist = @("cd") 30 | # } 31 | #} 32 | } -------------------------------------------------------------------------------- /SteamPS/Private/Server/Test-Admin.ps1: -------------------------------------------------------------------------------- 1 | function Test-Admin { 2 | <# 3 | .SYNOPSIS 4 | Checks whether the current user has administrator privileges. 5 | 6 | .DESCRIPTION 7 | This cmdlet verifies if the current user has administrator privileges on the system. 8 | 9 | .EXAMPLE 10 | PS C:\> Test-Admin 11 | True 12 | This example checks if the current user has administrator privileges and returns True if they do. 13 | 14 | .NOTES 15 | Author: Marius Storhaug 16 | #> 17 | 18 | [OutputType([System.Boolean])] 19 | [CmdletBinding()] 20 | [Alias('Test-Administrator', 'IsAdmin', 'IsAdministrator')] 21 | param ( 22 | ) 23 | 24 | begin { 25 | Write-Verbose -Message "[BEGIN ] Starting: $($MyInvocation.MyCommand)" 26 | } 27 | 28 | process { 29 | $IsUnix = $PSVersionTable.Platform -eq 'Unix' 30 | if ($IsUnix) { 31 | Write-Verbose -Message "Running on Unix, checking if user is root." 32 | $whoAmI = $(whoami) 33 | Write-Verbose -Message "whoami: $whoAmI" 34 | $IsRoot = $whoAmI -eq 'root' 35 | Write-Verbose -Message "IsRoot: $IsRoot" 36 | $IsRoot 37 | } else { 38 | Write-Verbose -Message "Running on Windows, checking if user is an Administrator." 39 | $User = [Security.Principal.WindowsIdentity]::GetCurrent() 40 | $Principal = New-Object Security.Principal.WindowsPrincipal($User) 41 | $isAdmin = $Principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) 42 | Write-Verbose -Message "IsAdmin: $isAdmin" 43 | $isAdmin 44 | } 45 | } 46 | 47 | end { 48 | Write-Verbose -Message "[END ] Ending: $($MyInvocation.MyCommand)" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Tests/Unit/Public/Update-SteamServer.Tests.ps1: -------------------------------------------------------------------------------- 1 | 2 | Describe 'Update-SteamServer Tests' -Tag 'Unit' { 3 | Context 'When executing Update-SteamServer without SteamCMD installed' { 4 | BeforeAll { 5 | Mock -CommandName Test-Admin -ModuleName SteamPS -MockWith { 6 | return $true 7 | } 8 | Mock -CommandName Get-SteamPath -ModuleName SteamPS -MockWith { 9 | return $null 10 | } 11 | Mock -CommandName Get-Service -ModuleName SteamPS -MockWith { 12 | return @{ Name = 'GB-PG10' } 13 | } 14 | } 15 | It 'Should throw an error' { 16 | { Update-SteamServer -AppID 476400 -ServiceName 'GB-PG10' -IPAddress '1.1.1.1' -Port 27015 } | Should -Throw 'SteamCMD could not be found in the env:Path. Have you executed Install-SteamCMD?' 17 | } 18 | } 19 | 20 | Context 'When executing Update-SteamServer with insufficient permissions' { 21 | BeforeAll { 22 | Mock -CommandName Test-Admin -ModuleName SteamPS -MockWith { 23 | return $false 24 | } 25 | Mock -CommandName Get-SteamPath -ModuleName SteamPS -MockWith { 26 | return [PSCustomObject]@{ 27 | 'Path' = 'C:\Program Files\' 28 | 'Executable' = 'C:\Program Files\steamcmd.exe' 29 | } 30 | } 31 | Mock -CommandName Get-Service -ModuleName SteamPS -MockWith { 32 | return @{ Name = 'GB-PG10' } 33 | } 34 | } 35 | It 'Should throw an error' { 36 | { Update-SteamServer -AppID 476400 -ServiceName 'GB-PG10' -IPAddress '1.1.1.1' -Port 27015 } | Should -Throw 'The current PowerShell session is not running as Administrator. Start PowerShell by using the Run as Administrator option, and then try running the script again.' 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /docs/Connect-SteamAPI.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: SteamPS-help.xml 3 | Module Name: SteamPS 4 | online version: https://hjorslev.github.io/SteamPS/Connect-SteamAPI.html 5 | schema: 2.0.0 6 | --- 7 | 8 | # Connect-SteamAPI 9 | 10 | ## SYNOPSIS 11 | Create or update the Steam Web API config file. 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Connect-SteamAPI [-ProgressAction ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | Create or update the Steam Web API config file which contains the API key 21 | used to authenticate to those Steam Web API's that require authentication. 22 | 23 | ## EXAMPLES 24 | 25 | ### EXAMPLE 1 26 | ``` 27 | Connect-SteamAPI 28 | ``` 29 | 30 | Prompts the user for a Steam Web API key and sets the specified input within 31 | the config file. 32 | 33 | ## PARAMETERS 34 | 35 | ### -ProgressAction 36 | {{ Fill ProgressAction Description }} 37 | 38 | ```yaml 39 | Type: ActionPreference 40 | Parameter Sets: (All) 41 | Aliases: proga 42 | 43 | Required: False 44 | Position: Named 45 | Default value: None 46 | Accept pipeline input: False 47 | Accept wildcard characters: False 48 | ``` 49 | 50 | ### CommonParameters 51 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 52 | 53 | ## INPUTS 54 | 55 | ### None. You cannot pipe objects to Connect-SteamAPI. 56 | ## OUTPUTS 57 | 58 | ### None. Nothing is returned when calling Connect-SteamAPI. 59 | ## NOTES 60 | Author: sysgoblin (https://github.com/sysgoblin) and Frederik Hjorslev Nylander 61 | 62 | ## RELATED LINKS 63 | 64 | [https://hjorslev.github.io/SteamPS/Connect-SteamAPI.html](https://hjorslev.github.io/SteamPS/Connect-SteamAPI.html) 65 | 66 | -------------------------------------------------------------------------------- /assets/images/SteamPS-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 11 | 12 | 13 | 15 | 19 | 21 | 22 | -------------------------------------------------------------------------------- /Tests/Unit/Public/Get-SteamPlayerBan.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe 'Get-SteamPlayerBan Tests' { 2 | BeforeAll { 3 | . $SteamPSModulePath\Private\API\Get-SteamAPIKey.ps1 4 | Mock -CommandName Get-SteamAPIKey -ModuleName SteamPS -MockWith { 5 | return $true 6 | } 7 | } 8 | 9 | Context 'With valid Steam ID' { 10 | BeforeAll { 11 | Mock -CommandName Invoke-RestMethod -ModuleName SteamPS -MockWith { 12 | return '{ 13 | "players": [ 14 | { 15 | "SteamId": "76561197983367235", 16 | "CommunityBanned": false, 17 | "VACBanned": false, 18 | "NumberOfVACBans": 0, 19 | "DaysSinceLastBan": 0, 20 | "NumberOfGameBans": 0, 21 | "EconomyBan": "none" 22 | } 23 | ] 24 | }' | ConvertFrom-Json 25 | } 26 | } 27 | 28 | It 'Should return ban information' { 29 | $result = Get-SteamPlayerBan -SteamID64 76561197983367235 30 | $result | Should -Not -BeNullOrEmpty 31 | $result.SteamID64 | Should -BeExactly 76561197983367235 32 | $result.CommunityBanned | Should -Be $false 33 | $result.VACBanned | Should -Be $false 34 | $result.NumberOfVACBans | Should -Be 0 35 | $result.DaysSinceLastBan | Should -Be 0 36 | $result.NumberOfGameBans | Should -Be 0 37 | $result.EconomyBan | Should -Be 'none' 38 | } 39 | } 40 | 41 | Context 'With invalid Steam ID' { 42 | BeforeAll { 43 | Mock -CommandName Invoke-RestMethod -ModuleName SteamPS -MockWith { 44 | return '{"players":[{}]}' | ConvertFrom-Json 45 | } 46 | } 47 | It 'Should throw an error' { 48 | { Get-SteamPlayerBan -SteamID64 12345 -ErrorAction Stop } | Should -Throw 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Tests/Unit/Public/Get-SteamFriendList.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe 'Get-SteamFriendList Tests' -Tag 'Unit' { 2 | BeforeAll { 3 | . $SteamPSModulePath\Private\API\Get-SteamAPIKey.ps1 4 | Mock -CommandName Get-SteamAPIKey -ModuleName SteamPS -MockWith { 5 | return $true 6 | } 7 | } 8 | 9 | Context 'When retrieving friend list' { 10 | BeforeAll { 11 | Mock -CommandName Invoke-RestMethod -ModuleName SteamPS -MockWith { 12 | return '{ "friendslist": { "friends":[ { "steamid":"11111197987580876", "relationship":"friend", "friend_since":1454562868 }, { "steamid":"99991197997032827", "relationship":"friend", "friend_since":1614836906 }] } }' | ConvertFrom-Json 13 | } # Mock 14 | } # Context 15 | 16 | It 'Retrieves friend list correctly' { 17 | $FriendList = Get-SteamFriendList -SteamID64 123456789 18 | 19 | # Check if the FriendList is not null 20 | $FriendList | Should -Not -BeNullOrEmpty 21 | 22 | $FriendList[0].SteamID64 | Should -Be '11111197987580876' 23 | $FriendList[0].Relationship | Should -Be 'friend' 24 | $FriendList[0].FriendSince | Should -Be '2016-02-04 05:14:28' 25 | 26 | $FriendList[1].SteamID64 | Should -Be '99991197997032827' 27 | $FriendList[1].Relationship | Should -Be 'friend' 28 | $FriendList[1].FriendSince | Should -Be '2021-03-04 05:48:26' 29 | } 30 | 31 | Context 'With invalid SteamID64' { 32 | It 'Throws an error' { 33 | { Get-SteamFriendList -SteamID64 'invalidID' } | Should -Throw 34 | } 35 | } 36 | } 37 | 38 | Context 'With a private profile' { 39 | BeforeAll { 40 | Mock -CommandName Invoke-RestMethod -ModuleName SteamPS -MockWith { 41 | return $null 42 | } # Mock 43 | } 44 | It 'Writes an error' { 45 | { Get-SteamFriendList -SteamID64 1234567890 -ErrorAction Stop } | Should -Throw 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /docs/Disconnect-SteamAPI.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: SteamPS-help.xml 3 | Module Name: SteamPS 4 | online version: https://hjorslev.github.io/SteamPS/Disconnect-SteamAPI.html 5 | schema: 2.0.0 6 | --- 7 | 8 | # Disconnect-SteamAPI 9 | 10 | ## SYNOPSIS 11 | Disconnects from the Steam API by removing the stored API key. 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Disconnect-SteamAPI [-Force] [-ProgressAction ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | The Disconnect-SteamAPI cmdlet removes the stored Steam API key from the system. 21 | This effectively disconnects the current session from the Steam API. 22 | 23 | ## EXAMPLES 24 | 25 | ### EXAMPLE 1 26 | ``` 27 | Disconnect-SteamAPI -Force 28 | ``` 29 | 30 | This command will remove the stored Steam API key without asking for confirmation. 31 | 32 | ## PARAMETERS 33 | 34 | ### -Force 35 | When the Force switch is used, the cmdlet will skip the confirmation prompt and directly remove the API key. 36 | 37 | ```yaml 38 | Type: SwitchParameter 39 | Parameter Sets: (All) 40 | Aliases: 41 | 42 | Required: False 43 | Position: Named 44 | Default value: False 45 | Accept pipeline input: False 46 | Accept wildcard characters: False 47 | ``` 48 | 49 | ### -ProgressAction 50 | {{ Fill ProgressAction Description }} 51 | 52 | ```yaml 53 | Type: ActionPreference 54 | Parameter Sets: (All) 55 | Aliases: proga 56 | 57 | Required: False 58 | Position: Named 59 | Default value: None 60 | Accept pipeline input: False 61 | Accept wildcard characters: False 62 | ``` 63 | 64 | ### CommonParameters 65 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 66 | 67 | ## INPUTS 68 | 69 | ### None. You cannot pipe objects to Disconnect-SteamAPI. 70 | ## OUTPUTS 71 | 72 | ### None. Nothing is returned when calling Disconnect-SteamAPI. 73 | ## NOTES 74 | Author: Frederik Hjorslev Nylander 75 | 76 | ## RELATED LINKS 77 | 78 | [https://hjorslev.github.io/SteamPS/Disconnect-SteamAPI.html](https://hjorslev.github.io/SteamPS/Disconnect-SteamAPI.html) 79 | 80 | -------------------------------------------------------------------------------- /Tests/Unit/Private/Get-PacketString.Tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | . $SteamPSModulePath\Private\Server\Get-PacketString.ps1 3 | } 4 | 5 | Describe "Get-PacketString Cmdlet" { 6 | Context "When using a valid stream" { 7 | It "Returns the correct string" { 8 | # Prepare test data 9 | $stream = New-Object System.IO.MemoryStream 10 | $binaryWriter = New-Object System.IO.BinaryWriter $stream 11 | $expectedString = "Hello, World!" 12 | $expectedStringBytes = [System.Text.Encoding]::UTF8.GetBytes($expectedString) 13 | $binaryWriter.Write($expectedStringBytes) 14 | $binaryWriter.Write([byte]0) # Append null terminator 15 | $stream.Position = 0 16 | 17 | # Execute the cmdlet 18 | $result = Get-PacketString -Stream (New-Object System.IO.BinaryReader $stream) 19 | 20 | # Assert 21 | $result | Should -BeExactly $expectedString 22 | 23 | # Cleanup 24 | $binaryWriter.Dispose() 25 | $stream.Dispose() 26 | } 27 | } 28 | 29 | Context "When using an empty stream" { 30 | It "Returns nothing" { 31 | # Prepare test data 32 | $stream = New-Object System.IO.MemoryStream 33 | 34 | # Execute the cmdlet 35 | $result = Get-PacketString -Stream (New-Object System.IO.BinaryReader $stream) 36 | 37 | # Assert 38 | $result | Should -BeNullOrEmpty 39 | 40 | # Cleanup 41 | $stream.Dispose() 42 | } 43 | } 44 | 45 | Context "When using a stream with only null terminator" { 46 | It "Returns an empty string" { 47 | # Prepare test data 48 | $stream = New-Object System.IO.MemoryStream 49 | $binaryWriter = New-Object System.IO.BinaryWriter $stream 50 | $binaryWriter.Write([byte]0) # Only null terminator 51 | $stream.Position = 0 52 | 53 | # Execute the cmdlet 54 | $result = Get-PacketString -Stream (New-Object System.IO.BinaryReader $stream) 55 | 56 | # Assert 57 | $result | Should -BeNullOrEmpty 58 | 59 | # Cleanup 60 | $binaryWriter.Dispose() 61 | $stream.Dispose() 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /SteamPS/Public/API/Disconnect-SteamAPI.ps1: -------------------------------------------------------------------------------- 1 | function Disconnect-SteamAPI { 2 | <# 3 | .SYNOPSIS 4 | Disconnects from the Steam API by removing the stored API key. 5 | 6 | .DESCRIPTION 7 | The Disconnect-SteamAPI cmdlet removes the stored Steam API key from the system. This effectively disconnects the current session from the Steam API. 8 | 9 | .PARAMETER Force 10 | When the Force switch is used, the cmdlet will skip the confirmation prompt and directly remove the API key. 11 | 12 | .EXAMPLE 13 | Disconnect-SteamAPI -Force 14 | 15 | This command will remove the stored Steam API key without asking for confirmation. 16 | 17 | .INPUTS 18 | None. You cannot pipe objects to Disconnect-SteamAPI. 19 | 20 | .OUTPUTS 21 | None. Nothing is returned when calling Disconnect-SteamAPI. 22 | 23 | .NOTES 24 | Author: Frederik Hjorslev Nylander 25 | 26 | .LINK 27 | https://hjorslev.github.io/SteamPS/Disconnect-SteamAPI.html 28 | #> 29 | 30 | [CmdletBinding()] 31 | param ( 32 | [Parameter(Mandatory = $false, 33 | HelpMessage = 'Skip the confirmation prompt.')][switch]$Force 34 | ) 35 | 36 | begin { 37 | Write-Verbose -Message "[BEGIN ] Starting: $($MyInvocation.MyCommand)" 38 | $SteamAPIKey = "$env:AppData\SteamPS\SteamPSKey.json" 39 | } 40 | 41 | process { 42 | if ($Force -or $PSCmdlet.ShouldContinue($SteamAPIKey, 'Do you want to continue removing the API key?')) { 43 | if (Test-Path -Path $SteamAPIKey) { 44 | Remove-Item -Path $SteamAPIKey -Force 45 | Write-Verbose -Message "$SteamAPIKey were deleted." 46 | } else { 47 | $Exception = [Exception]::new("Steam Web API configuration file not found in '$env:AppData\SteamPS\SteamPSKey.json'.") 48 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 49 | $Exception, 50 | 'SteamAPIKeyNotFound', 51 | [System.Management.Automation.ErrorCategory]::ObjectNotFound, 52 | $SteamPSKey 53 | ) 54 | $PSCmdlet.ThrowTerminatingError($ErrorRecord) 55 | } 56 | } 57 | } 58 | 59 | end { 60 | Write-Verbose -Message "[END ] Ending: $($MyInvocation.MyCommand)" 61 | } 62 | } -------------------------------------------------------------------------------- /SteamPS/Public/API/Connect-SteamAPI.ps1: -------------------------------------------------------------------------------- 1 | function Connect-SteamAPI { 2 | <# 3 | .SYNOPSIS 4 | Create or update the Steam Web API config file. 5 | 6 | .DESCRIPTION 7 | Create or update the Steam Web API config file which contains the API key 8 | used to authenticate to those Steam Web API's that require authentication. 9 | 10 | .EXAMPLE 11 | Connect-SteamAPI 12 | 13 | Prompts the user for a Steam Web API key and sets the specified input within 14 | the config file. 15 | 16 | .INPUTS 17 | None. You cannot pipe objects to Connect-SteamAPI. 18 | 19 | .OUTPUTS 20 | None. Nothing is returned when calling Connect-SteamAPI. 21 | 22 | .NOTES 23 | Author: sysgoblin (https://github.com/sysgoblin) and Frederik Hjorslev Nylander 24 | 25 | .LINK 26 | https://hjorslev.github.io/SteamPS/Connect-SteamAPI.html 27 | #> 28 | 29 | [CmdletBinding()] 30 | param ( 31 | ) 32 | 33 | begin { 34 | Write-Verbose -Message "[BEGIN ] Starting: $($MyInvocation.MyCommand)" 35 | } 36 | 37 | process { 38 | if (-not (Test-Path -Path "$env:AppData\SteamPS\SteamPSKey.json")) { 39 | try { 40 | $TargetObject = New-Item -Path "$env:AppData\SteamPS\SteamPSKey.json" -Force 41 | Write-Verbose -Message "Created config file at $env:AppData\SteamPS\SteamPSKey.json" 42 | } catch { 43 | $Exception = [Exception]::new("Unable to create file $env:AppData\SteamPS\SteamPSKey.json") 44 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 45 | $Exception, 46 | "CreateSteamAPIKeyFailed", 47 | [System.Management.Automation.ErrorCategory]::WriteError, 48 | $TargetObject # usually the object that triggered the error, if possible 49 | ) 50 | $PSCmdlet.ThrowTerminatingError($ErrorRecord) 51 | } 52 | } 53 | 54 | $APIKey = Read-Host -Prompt 'Enter your Steam Web API key' -AsSecureString 55 | $Key = ConvertFrom-SecureString -SecureString $APIKey 56 | $Key | Out-File "$($env:AppData)\SteamPS\SteamPSKey.json" -Force 57 | Write-Verbose -Message "Saved key as secure string to config file." 58 | } # Process 59 | 60 | end { 61 | Write-Verbose -Message "[END ] Ending: $($MyInvocation.MyCommand)" 62 | } 63 | } # Cmdlet -------------------------------------------------------------------------------- /SteamPS/Private/API/Get-SteamAPIKey.ps1: -------------------------------------------------------------------------------- 1 | function Get-SteamAPIKey { 2 | <# 3 | .SYNOPSIS 4 | Grabs API key secure string from file and converts back to plaintext. 5 | 6 | .DESCRIPTION 7 | Grabs API key secure string from file and converts back to plaintext. 8 | 9 | .EXAMPLE 10 | Get-SteamAPIKey 11 | 12 | Returns the API key secure string in plain text. 13 | 14 | .NOTES 15 | Author: sysgoblin (https://github.com/sysgoblin) and Frederik Hjorslev Poulsen 16 | #> 17 | 18 | [CmdletBinding()] 19 | Param ( 20 | ) 21 | 22 | begin { 23 | Write-Verbose -Message "[BEGIN ] Starting: $($MyInvocation.MyCommand)" 24 | } 25 | 26 | process { 27 | $SteamPSKey = Test-Path -Path "$env:AppData\SteamPS\SteamPSKey.json" 28 | if (-not $SteamPSKey) { 29 | $Exception = [Exception]::new("Steam Web API configuration file not found in '$env:AppData\SteamPS\SteamPSKey.json'. Run Connect-SteamAPI to configure an API key.") 30 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 31 | $Exception, 32 | 'SteamAPIKeyNotFound', 33 | [System.Management.Automation.ErrorCategory]::ObjectNotFound, 34 | $SteamPSKey # usually the object that triggered the error, if possible 35 | ) 36 | $PSCmdlet.ThrowTerminatingError($ErrorRecord) 37 | } 38 | # cmdlet terminates here, no need for an `else`, only possible way to be here is 39 | # if previous condition was false 40 | try { 41 | $Config = Get-Content "$env:AppData\SteamPS\SteamPSKey.json" 42 | $APIKeySecString = $Config | ConvertTo-SecureString 43 | [System.Net.NetworkCredential]::new('', $APIKeySecString).Password 44 | } catch { 45 | $Exception = [Exception]::new("Could not decrypt API key from configuration file not found in '$env:AppData\SteamPS\SteamPSKey.json'. Run Connect-SteamAPI to configure an API key.") 46 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 47 | $Exception, 48 | 'InvalidAPIKey', 49 | [System.Management.Automation.ErrorCategory]::ParserError, 50 | $APIKey # usually the object that triggered the error, if possible 51 | ) 52 | $PSCmdlet.ThrowTerminatingError($ErrorRecord) 53 | } 54 | } # Process 55 | 56 | end { 57 | Write-Verbose -Message "[END ] Ending: $($MyInvocation.MyCommand)" 58 | } 59 | } # Cmdlet -------------------------------------------------------------------------------- /docs/Resolve-VanityURL.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: SteamPS-help.xml 3 | Module Name: SteamPS 4 | online version: https://hjorslev.github.io/SteamPS/Resolve-VanityURL.html 5 | schema: 2.0.0 6 | --- 7 | 8 | # Resolve-VanityURL 9 | 10 | ## SYNOPSIS 11 | Resolve a vanity URL (also named custom URL). 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Resolve-VanityURL [-VanityURL] [[-UrlType] ] [-ProgressAction ] 17 | [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | Resolve a vanity URL (also named custom URL) and return the 64 bit SteamID 22 | that belongs to said URL. 23 | 24 | ## EXAMPLES 25 | 26 | ### EXAMPLE 1 27 | ``` 28 | Resolve-VanityURL -VanityURL hjorslev 29 | ``` 30 | 31 | Returns a 64 bit Steam ID. 32 | 33 | ## PARAMETERS 34 | 35 | ### -ProgressAction 36 | {{ Fill ProgressAction Description }} 37 | 38 | ```yaml 39 | Type: ActionPreference 40 | Parameter Sets: (All) 41 | Aliases: proga 42 | 43 | Required: False 44 | Position: Named 45 | Default value: None 46 | Accept pipeline input: False 47 | Accept wildcard characters: False 48 | ``` 49 | 50 | ### -UrlType 51 | The type of vanity URL. 52 | 1 (default): Individual profile, 2: Group, 3: Official game group 53 | 54 | ```yaml 55 | Type: Int32 56 | Parameter Sets: (All) 57 | Aliases: 58 | 59 | Required: False 60 | Position: 2 61 | Default value: 1 62 | Accept pipeline input: False 63 | Accept wildcard characters: False 64 | ``` 65 | 66 | ### -VanityURL 67 | Enter the vanity URL (also named custom URL) to get a SteamID for. 68 | Do not enter 69 | the fully qualified URL, but just the ID e.g. 70 | hjorslev instead of 71 | "https://steamcommunity.com/id/hjorslev/" 72 | 73 | ```yaml 74 | Type: String[] 75 | Parameter Sets: (All) 76 | Aliases: 77 | 78 | Required: True 79 | Position: 1 80 | Default value: None 81 | Accept pipeline input: False 82 | Accept wildcard characters: False 83 | ``` 84 | 85 | ### CommonParameters 86 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 87 | 88 | ## INPUTS 89 | 90 | ### The VanityURL parameter accepts string input. 91 | ## OUTPUTS 92 | 93 | ### The cmdlet returns a custom object containing the VanityURL and its associated SteamID64. 94 | ## NOTES 95 | Author: Frederik Hjorslev Nylander 96 | 97 | ## RELATED LINKS 98 | 99 | [https://hjorslev.github.io/SteamPS/Resolve-VanityURL.html](https://hjorslev.github.io/SteamPS/Resolve-VanityURL.html) 100 | 101 | -------------------------------------------------------------------------------- /docs/Get-SteamPlayerBan.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: SteamPS-help.xml 3 | Module Name: SteamPS 4 | online version: https://hjorslev.github.io/SteamPS/Get-SteamPlayerBan.html 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-SteamPlayerBan 9 | 10 | ## SYNOPSIS 11 | Returns Community, VAC, and Economy ban statuses for given players. 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Get-SteamPlayerBan [-SteamID64] [-ProgressAction ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | Returns Community, VAC, and Economy ban statuses for given players. 21 | 22 | ## EXAMPLES 23 | 24 | ### EXAMPLE 1 25 | ``` 26 | Get-SteamPlayerBan -SteamID64 76561197960435530, 76561197960434622 27 | ``` 28 | 29 | ## PARAMETERS 30 | 31 | ### -ProgressAction 32 | {{ Fill ProgressAction Description }} 33 | 34 | ```yaml 35 | Type: ActionPreference 36 | Parameter Sets: (All) 37 | Aliases: proga 38 | 39 | Required: False 40 | Position: Named 41 | Default value: None 42 | Accept pipeline input: False 43 | Accept wildcard characters: False 44 | ``` 45 | 46 | ### -SteamID64 47 | Comma-delimited list of 64 bit Steam IDs to return player ban information for. 48 | 49 | ```yaml 50 | Type: Int64[] 51 | Parameter Sets: (All) 52 | Aliases: 53 | 54 | Required: True 55 | Position: 1 56 | Default value: None 57 | Accept pipeline input: True (ByPropertyName) 58 | Accept wildcard characters: False 59 | ``` 60 | 61 | ### CommonParameters 62 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 63 | 64 | ## INPUTS 65 | 66 | ### int64[]: Specifies an array of 64-bit integers representing Steam IDs. 67 | ## OUTPUTS 68 | 69 | ### Returns a PSCustomObject with the following properties: 70 | ### - SteamID64: The player's 64-bit ID. 71 | ### - CommunityBanned: A boolean indicating whether the player is banned from the Steam Community. 72 | ### - VACBanned: A boolean indicating whether the player has VAC bans on record. 73 | ### - NumberOfVACBans: The number of VAC bans on record. 74 | ### - DaysSinceLastBan: The number of days since the last ban. 75 | ### - NumberOfGameBans: The number of bans in games, including CS:GO Overwatch bans. 76 | ### - EconomyBan: The player's ban status in the economy. If the player has no bans on record, the string will be "none". If the player is on probation, it will say "probation", etc. 77 | ## NOTES 78 | Author: Frederik Hjorslev Nylander 79 | 80 | ## RELATED LINKS 81 | 82 | [https://hjorslev.github.io/SteamPS/Get-SteamPlayerBan.html](https://hjorslev.github.io/SteamPS/Get-SteamPlayerBan.html) 83 | 84 | -------------------------------------------------------------------------------- /Tests/Unit/Private/Add-EnvPath.Tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | . $SteamPSModulePath\Private\Server\Add-EnvPath.ps1 3 | } 4 | 5 | Describe "Add-EnvPath Tests" { 6 | Context "When adding a new path to the session environment" { 7 | It "Should add the path to the session environment" { 8 | $originalPath = [Environment]::GetEnvironmentVariable('Path', 'Process') 9 | $newPath = "C:\NewPath" 10 | 11 | Add-EnvPath -Path $newPath 12 | 13 | $updatedPath = [Environment]::GetEnvironmentVariable('Path', 'Process') 14 | 15 | $updatedPath.Split([System.IO.Path]::PathSeparator) | Should -Contain $newPath 16 | 17 | # Cleanup 18 | [Environment]::SetEnvironmentVariable('Path', $originalPath, 'Process') 19 | } 20 | } 21 | 22 | Context "When adding an existing path to the session environment" { 23 | It "Should not add the path again" { 24 | $originalPath = [Environment]::GetEnvironmentVariable('Path', 'Process') 25 | $existingPath = $originalPath.Split([System.IO.Path]::PathSeparator)[0] # Taking the first existing path for testing 26 | 27 | Add-EnvPath -Path $existingPath 28 | 29 | $updatedPath = [Environment]::GetEnvironmentVariable('Path', 'Process') 30 | 31 | $updatedPath.Split([System.IO.Path]::PathSeparator) | Should -Contain $existingPath 32 | 33 | # Cleanup 34 | [Environment]::SetEnvironmentVariable('Path', $originalPath, 'Process') 35 | } 36 | } 37 | 38 | Context "When adding a new path to the user environment" { 39 | It "Should add the path to the user environment" { 40 | $originalPath = [Environment]::GetEnvironmentVariable('Path', 'User') 41 | $newPath = "C:\NewPath" 42 | 43 | Add-EnvPath -Path $newPath -Container 'User' 44 | 45 | $updatedPath = [Environment]::GetEnvironmentVariable('Path', 'User') 46 | 47 | $updatedPath.Split([System.IO.Path]::PathSeparator) | Should -Contain $newPath 48 | 49 | # Cleanup 50 | [Environment]::SetEnvironmentVariable('Path', $originalPath, 'User') 51 | } 52 | } 53 | 54 | Context "When adding a new path to the machine environment" { 55 | It "Should add the path to the machine environment" { 56 | $originalPath = [Environment]::GetEnvironmentVariable('Path', 'Machine') 57 | $newPath = "C:\NewPath" 58 | 59 | Add-EnvPath -Path $newPath -Container 'Machine' 60 | 61 | $updatedPath = [Environment]::GetEnvironmentVariable('Path', 'Machine') 62 | 63 | $updatedPath.Split([System.IO.Path]::PathSeparator) | Should -Contain $newPath 64 | 65 | # Cleanup 66 | [Environment]::SetEnvironmentVariable('Path', $originalPath, 'Machine') 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Tests/Integration/Public/Get-SteamServerInfo.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe "Get-SteamServerInfo Tests" { 2 | Context "When querying a valid server" { 3 | It "Should return server information" { 4 | # Mocking the Get-SteamServerInfo function 5 | Mock Get-SteamServerInfo { 6 | [PSCustomObject]@{ 7 | Protocol = 17 8 | ServerName = "SAS Proving Ground 10 (EU)" 9 | Map = "TH-SmallTown" 10 | InstallDir = "groundbranch" 11 | GameName = "Ground Branch" 12 | AppID = 16900 13 | Players = 6 14 | MaxPlayers = 10 15 | Bots = 0 16 | ServerType = "Dedicated" 17 | Environment = "Windows" 18 | Visibility = "Public" 19 | VAC = "Unsecured" 20 | Version = "1.0.0.0" 21 | ExtraDataFlag = 177 22 | IPAddress = "135.239.211.40" 23 | Port = 27015 24 | Ping = 65 25 | } 26 | } 27 | 28 | # Invoke the function under test 29 | $result = Get-SteamServerInfo -IPAddress '135.239.211.40' -Port 27015 30 | 31 | # Assertions 32 | $result | Should -Not -BeNullOrEmpty 33 | $result.ServerName | Should -Be "SAS Proving Ground 10 (EU)" 34 | $result.Map | Should -Be "TH-SmallTown" 35 | $result.InstallDir | Should -Be "groundbranch" 36 | $result.GameName | Should -Be "Ground Branch" 37 | $result.AppID | Should -Be 16900 38 | $result.Players | Should -Be 6 39 | $result.MaxPlayers | Should -Be 10 40 | $result.Bots | Should -Be 0 41 | $result.ServerType | Should -Be "Dedicated" 42 | $result.Environment | Should -Be "Windows" 43 | $result.Visibility | Should -Be "Public" 44 | $result.VAC | Should -Be "Unsecured" 45 | $result.Version | Should -Be "1.0.0.0" 46 | $result.IPAddress | Should -Be "135.239.211.40" 47 | $result.Port | Should -Be 27015 48 | $result.Ping | Should -Be 65 49 | } 50 | } 51 | 52 | Context "When querying an invalid server" { 53 | It "Should throw an error" { 54 | # Mocking the Get-SteamServerInfo function to simulate failure 55 | Mock Get-SteamServerInfo { 56 | throw "Server not found" 57 | } 58 | 59 | # Invoke the function under test and capture the exception 60 | $errorActionPreference = 'Stop' 61 | { Get-SteamServerInfo -IPAddress 'invalid' -Port 1234 } | Should -Throw 62 | $errorActionPreference = 'Continue' 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /docs/Get-SteamFriendList.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: SteamPS-help.xml 3 | Module Name: SteamPS 4 | online version: https://hjorslev.github.io/SteamPS/Get-SteamFriendList.html 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-SteamFriendList 9 | 10 | ## SYNOPSIS 11 | Returns the friend list of any Steam user. 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Get-SteamFriendList [-SteamID64] [[-Relationship] ] [-ProgressAction ] 17 | [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | Returns the friend list of any Steam user, provided their Steam Community 22 | profile visibility is set to "Public". 23 | 24 | ## EXAMPLES 25 | 26 | ### EXAMPLE 1 27 | ``` 28 | Get-SteamFriendList -SteamID64 76561197960435530 29 | ``` 30 | 31 | Outputs the user's friends list, as an array of friends. 32 | 33 | ### EXAMPLE 2 34 | ``` 35 | Get-SteamFriendList -SteamID64 76561197960435530 | ConvertFrom-Json 36 | ``` 37 | 38 | Outputs the user's friends list, as an array of friends and converts it from 39 | Json to PSCustomObjects. 40 | 41 | ## PARAMETERS 42 | 43 | ### -ProgressAction 44 | {{ Fill ProgressAction Description }} 45 | 46 | ```yaml 47 | Type: ActionPreference 48 | Parameter Sets: (All) 49 | Aliases: proga 50 | 51 | Required: False 52 | Position: Named 53 | Default value: None 54 | Accept pipeline input: False 55 | Accept wildcard characters: False 56 | ``` 57 | 58 | ### -Relationship 59 | Relationship filter. 60 | Possibles values: all, friend. 61 | 62 | ```yaml 63 | Type: String 64 | Parameter Sets: (All) 65 | Aliases: 66 | 67 | Required: False 68 | Position: 2 69 | Default value: None 70 | Accept pipeline input: False 71 | Accept wildcard characters: False 72 | ``` 73 | 74 | ### -SteamID64 75 | 64 bit Steam ID to return friend list for. 76 | 77 | ```yaml 78 | Type: Int64 79 | Parameter Sets: (All) 80 | Aliases: 81 | 82 | Required: True 83 | Position: 1 84 | Default value: 0 85 | Accept pipeline input: True (ByPropertyName) 86 | Accept wildcard characters: False 87 | ``` 88 | 89 | ### CommonParameters 90 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 91 | 92 | ## INPUTS 93 | 94 | ### System.Int64 95 | ## OUTPUTS 96 | 97 | ### PSCustomObject. It returns the following properties: 98 | ### - SteamID64: The friend's 64-bit Steam ID. 99 | ### - Relationship: The qualifier of the relationship. 100 | ### - FriendSince: The Unix timestamp indicating when the relationship was established. 101 | ## NOTES 102 | Author: Frederik Hjorslev Nylander 103 | 104 | ## RELATED LINKS 105 | 106 | [https://hjorslev.github.io/SteamPS/Get-SteamFriendList.html](https://hjorslev.github.io/SteamPS/Get-SteamFriendList.html) 107 | 108 | -------------------------------------------------------------------------------- /docs/Install-SteamCMD.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: SteamPS-help.xml 3 | Module Name: SteamPS 4 | online version: https://hjorslev.github.io/SteamPS/Install-SteamCMD.html 5 | schema: 2.0.0 6 | --- 7 | 8 | # Install-SteamCMD 9 | 10 | ## SYNOPSIS 11 | Install SteamCMD. 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Install-SteamCMD [[-InstallPath] ] [-Force] [-ProgressAction ] [-WhatIf] [-Confirm] 17 | [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | This cmdlet downloads SteamCMD and configures it in a custom or 22 | predefined location (C:\Program Files\SteamCMD). 23 | 24 | ## EXAMPLES 25 | 26 | ### EXAMPLE 1 27 | ``` 28 | Install-SteamCMD 29 | ``` 30 | 31 | Installs SteamCMD in C:\Program Files\SteamCMD. 32 | 33 | ### EXAMPLE 2 34 | ``` 35 | Install-SteamCMD -InstallPath 'C:' 36 | ``` 37 | 38 | Installs SteamCMD in C:\SteamCMD. 39 | 40 | ## PARAMETERS 41 | 42 | ### -Force 43 | The Force parameter allows the user to skip the "Should Continue" box. 44 | 45 | ```yaml 46 | Type: SwitchParameter 47 | Parameter Sets: (All) 48 | Aliases: 49 | 50 | Required: False 51 | Position: Named 52 | Default value: False 53 | Accept pipeline input: False 54 | Accept wildcard characters: False 55 | ``` 56 | 57 | ### -InstallPath 58 | Specifiy the install location of SteamCMD. 59 | 60 | ```yaml 61 | Type: String 62 | Parameter Sets: (All) 63 | Aliases: 64 | 65 | Required: False 66 | Position: 1 67 | Default value: "$env:ProgramFiles" 68 | Accept pipeline input: False 69 | Accept wildcard characters: False 70 | ``` 71 | 72 | ### -ProgressAction 73 | {{ Fill ProgressAction Description }} 74 | 75 | ```yaml 76 | Type: ActionPreference 77 | Parameter Sets: (All) 78 | Aliases: proga 79 | 80 | Required: False 81 | Position: Named 82 | Default value: None 83 | Accept pipeline input: False 84 | Accept wildcard characters: False 85 | ``` 86 | 87 | ### -Confirm 88 | Prompts you for confirmation before running the cmdlet. 89 | 90 | ```yaml 91 | Type: SwitchParameter 92 | Parameter Sets: (All) 93 | Aliases: cf 94 | 95 | Required: False 96 | Position: Named 97 | Default value: None 98 | Accept pipeline input: False 99 | Accept wildcard characters: False 100 | ``` 101 | 102 | ### -WhatIf 103 | Shows what would happen if the cmdlet runs. 104 | The cmdlet is not run. 105 | 106 | ```yaml 107 | Type: SwitchParameter 108 | Parameter Sets: (All) 109 | Aliases: wi 110 | 111 | Required: False 112 | Position: Named 113 | Default value: None 114 | Accept pipeline input: False 115 | Accept wildcard characters: False 116 | ``` 117 | 118 | ### CommonParameters 119 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 120 | 121 | ## INPUTS 122 | 123 | ## OUTPUTS 124 | 125 | ## NOTES 126 | Author: Frederik Hjorslev Nylander 127 | 128 | ## RELATED LINKS 129 | 130 | [https://hjorslev.github.io/SteamPS/Install-SteamCMD.html](https://hjorslev.github.io/SteamPS/Install-SteamCMD.html) 131 | 132 | -------------------------------------------------------------------------------- /SteamPS/Public/API/Get-SteamFriendList.ps1: -------------------------------------------------------------------------------- 1 | function Get-SteamFriendList { 2 | <# 3 | .SYNOPSIS 4 | Fetches the friend list of the specified Steam user. 5 | 6 | .DESCRIPTION 7 | This cmdlet fetches the friend list of a Steam user using the provided SteamID64. It retrieves data only from public profiles. 8 | 9 | .PARAMETER SteamID64 10 | The 64-bit Steam ID of the user whose friend list is to be fetched. 11 | 12 | .PARAMETER Relationship 13 | The relationship type used to filter the friend list. The possible values are 'all' or 'friend'. The default is 'friend'. 14 | 15 | .EXAMPLE 16 | Get-SteamFriendList -SteamID64 76561197960435530 17 | 18 | This example fetches the friend list of the user with the specified SteamID64. 19 | 20 | .INPUTS 21 | System.Int64 22 | 23 | .OUTPUTS 24 | PSCustomObject. It returns the following properties: 25 | - SteamID64: The friend's 64-bit Steam ID. 26 | - Relationship: The qualifier of the relationship. 27 | - FriendSince: The Unix timestamp indicating when the relationship was established. 28 | 29 | .NOTES 30 | Author: Frederik Hjorslev Nylander 31 | 32 | .LINK 33 | https://hjorslev.github.io/SteamPS/Get-SteamFriendList.html 34 | #> 35 | 36 | [CmdletBinding()] 37 | param ( 38 | [Parameter(Mandatory = $true, 39 | HelpMessage = 'Specifies the 64-bit Steam ID of the user whose friend list will be retrieved.', 40 | ValueFromPipelineByPropertyName = $true)] 41 | [int64]$SteamID64, 42 | 43 | [Parameter(Mandatory = $false, 44 | HelpMessage = 'Specifies the relationship type to filter the friend list. Possible values are "all" or "friend". Default is "friend".')] 45 | [ValidateSet('all', 'friend')] 46 | [string]$Relationship = 'friend' 47 | ) 48 | 49 | begin { 50 | Write-Verbose -Message "[BEGIN ] Starting: $($MyInvocation.MyCommand)" 51 | } 52 | 53 | process { 54 | $Request = Invoke-RestMethod -Uri 'https://api.steampowered.com/ISteamUser/GetFriendList/v1/' -UseBasicParsing -ErrorAction SilentlyContinue -Body @{ 55 | key = Get-SteamAPIKey 56 | steamid = $SteamID64 57 | relationship = $Relationship 58 | } 59 | 60 | if ($Request) { 61 | foreach ($Item in $Request.friendslist.friends) { 62 | [PSCustomObject]@{ 63 | SteamID64 = [int64]$Item.steamid 64 | Relationship = $Item.relationship 65 | FriendSince = ((Get-Date "01.01.1970") + ([System.TimeSpan]::FromSeconds($Item.friend_since))).ToString("yyyy-MM-dd HH:mm:ss") 66 | } 67 | } 68 | } elseif ($null -eq $Request) { 69 | $Exception = [Exception]::new("No friend list found for $SteamID64. This might be because the profile is private.") 70 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 71 | $Exception, 72 | 'NoFriendsListFound', 73 | [System.Management.Automation.ErrorCategory]::ObjectNotFound, 74 | $Request 75 | ) 76 | $PSCmdlet.WriteError($ErrorRecord) 77 | } 78 | } # Process 79 | 80 | end { 81 | Write-Verbose -Message "[END ] Ending: $($MyInvocation.MyCommand)" 82 | } 83 | } # Cmdlet 84 | -------------------------------------------------------------------------------- /Tests/Unit/Public/Get-SteamPlayerSummary.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe 'Get-SteamPlayerSummary Tests' -Tag 'Unit' { 2 | BeforeAll { 3 | . $SteamPSModulePath\Private\API\Get-SteamAPIKey.ps1 4 | Mock -CommandName Get-SteamAPIKey -ModuleName SteamPS -MockWith { 5 | return $true 6 | } 7 | } 8 | 9 | Context 'With a valid SteamID64' { 10 | BeforeAll { 11 | Mock -CommandName Invoke-RestMethod -ModuleName SteamPS -MockWith { 12 | return '{ 13 | "response": { 14 | "players": [ 15 | { 16 | "steamid": "12345678901234567", 17 | "communityvisibilitystate": 3, 18 | "profilestate": 1, 19 | "personaname": "TestUser", 20 | "commentpermission": 1, 21 | "profileurl": "https://steamcommunity.com/id/testuser/", 22 | "avatar": "https://example.com/avatar.jpg", 23 | "avatarmedium": "https://example.com/avatar_medium.jpg", 24 | "avatarfull": "https://example.com/avatar_full.jpg", 25 | "avatarhash": "abcdef123456", 26 | "lastlogoff": 1712083677, 27 | "personastate": 1, 28 | "realname": "John Doe", 29 | "primaryclanid": "987654321098765432", 30 | "timecreated": 1577836800, 31 | "gameid": 16900, 32 | "gameserverip": "1.2.3.4", 33 | "gameextrainfo": "Test Game", 34 | "personastateflags": 0, 35 | "loccountrycode": "US", 36 | "locstatecode": "CA", 37 | "loccityid": 54321 38 | } 39 | ] 40 | } 41 | }' | ConvertFrom-Json 42 | } 43 | } 44 | 45 | It 'Should return player summary' { 46 | $PlayerSummary = Get-SteamPlayerSummary -SteamID64 12345678901234567 47 | $PlayerSummary.SteamID64 | Should -Be '12345678901234567' 48 | $PlayerSummary.PersonaState | Should -BeExactly 'Online' 49 | $PlayerSummary.CommunityVisibilityState | Should -BeExactly 'Public' 50 | $PlayerSummary.LastLogOff | Should -BeExactly '2024-04-02 18:47:57' 51 | $PlayerSummary.TimeCreated | Should -BeExactly '2020-01-01 00:00:00' 52 | $PlayerSummary.GameServerIP | Should -BeExactly '1.2.3.4' 53 | $PlayerSummary.GameServerIP | Should -BeOfType ipaddress 54 | } 55 | } 56 | 57 | Context 'With an invalid SteamID64' { 58 | BeforeAll { 59 | Mock -CommandName Invoke-RestMethod -ModuleName SteamPS -MockWith { 60 | return '{"response":{"players":[]}}' | ConvertFrom-Json 61 | } 62 | } 63 | 64 | It 'Should throw an error' { 65 | { Get-SteamPlayerSummary -SteamID64 1234567890 -ErrorAction Stop } | Should -Throw "SteamID 1234567890 couldn't be found." 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Tests/Unit/Public/Get-SteamNews.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe 'Get-SteamNews Tests' -Tag 'Unit' { 2 | Context 'When providing valid input' { 3 | BeforeAll { 4 | Mock -CommandName Invoke-RestMethod -ModuleName SteamPS -MockWith { 5 | return '{ 6 | "appnews": { 7 | "newsitems": [ 8 | { 9 | "gid": 123, 10 | "title": "Test News", 11 | "url": "https://example.com", 12 | "is_external_url": false, 13 | "author": "Test Author", 14 | "contents": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi tincidunt justo feugiat, pulvinar mi eu, lacinia turpis.", 15 | "feedlabel": "Test Feed", 16 | "date": "1706900040", 17 | "feedname": "Test Feed", 18 | "feed_type": "Test", 19 | "appid": 440 20 | }, 21 | { 22 | "gid": 456, 23 | "title": "Test 2", 24 | "url": "https://test.com", 25 | "is_external_url": true, 26 | "author": "Test Author", 27 | "contents": "This is a test news content.", 28 | "feedlabel": "Test Feed", 29 | "date": "1706900040", 30 | "feedname": "Feed Test", 31 | "feed_type": "Test", 32 | "appid": 440 33 | } 34 | ] 35 | } 36 | }' | ConvertFrom-Json 37 | } 38 | } 39 | It 'Should return news items for a given AppID' { 40 | $SteamNews = Get-SteamNews -AppID 440 41 | 42 | $SteamNews[0].GID | Should -Be 123 43 | $SteamNews[0].Title | Should -Be 'Test News' 44 | $SteamNews[0].Url | Should -Be 'https://example.com' 45 | $SteamNews[0].IsExternalUrl | Should -Be $false 46 | $SteamNews[0].Author | Should -Be 'Test Author' 47 | $SteamNews[0].Contents | Should -Be 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi tincidunt justo feugiat, pulvinar mi eu, lacinia turpis.' 48 | $SteamNews[0].FeedLabel | Should -Be 'Test Feed' 49 | $SteamNews[0].Date | Should -Be '2024-02-02 18:54:00' 50 | $SteamNews[0].FeedName | Should -Be 'Test Feed' 51 | $SteamNews[0].FeedType | Should -Be 'Test' 52 | $SteamNews[0].AppID | Should -Be 440 53 | } 54 | It 'Should return 2 news item for a given appID.' { 55 | (Get-SteamNews -AppID 440 -Count 2 | Measure-Object).Count | Should -BeExactly 2 56 | } 57 | } 58 | 59 | Context 'When no news found for the given AppID' { 60 | BeforeAll { 61 | Mock -CommandName Invoke-RestMethod -ModuleName SteamPS -MockWith { 62 | return $null 63 | } 64 | } 65 | It 'Should throw an error' { 66 | { Get-SteamNews -AppID 123 -ErrorAction Stop } | Should -Throw 'No news found for 123.' 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /docs/Get-SteamNews.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: SteamPS-help.xml 3 | Module Name: SteamPS 4 | online version: https://hjorslev.github.io/SteamPS/Get-SteamNews.html 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-SteamNews 9 | 10 | ## SYNOPSIS 11 | Returns the latest news of a game specified by its AppID. 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Get-SteamNews [-AppID] [[-Count] ] [[-MaxLength] ] [-ProgressAction ] 17 | [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | Returns the latest news of a game specified by its AppID. 22 | 23 | ## EXAMPLES 24 | 25 | ### EXAMPLE 1 26 | ``` 27 | Get-SteamNews -AppID 440 28 | ``` 29 | 30 | Lists number of news that are available for the AppID. 31 | 32 | ### EXAMPLE 2 33 | ``` 34 | Get-SteamNews -AppID 440 -Count 1 35 | ``` 36 | 37 | Retrieves 1 (the latest) news item for the AppID 440. 38 | 39 | ## PARAMETERS 40 | 41 | ### -AppID 42 | AppID of the game you want the news of. 43 | 44 | ```yaml 45 | Type: Int32 46 | Parameter Sets: (All) 47 | Aliases: 48 | 49 | Required: True 50 | Position: 1 51 | Default value: 0 52 | Accept pipeline input: False 53 | Accept wildcard characters: False 54 | ``` 55 | 56 | ### -Count 57 | How many news entries you want to get returned. 58 | 59 | ```yaml 60 | Type: Int32 61 | Parameter Sets: (All) 62 | Aliases: 63 | 64 | Required: False 65 | Position: 2 66 | Default value: 0 67 | Accept pipeline input: False 68 | Accept wildcard characters: False 69 | ``` 70 | 71 | ### -MaxLength 72 | Maximum length of each news entry. 73 | 74 | ```yaml 75 | Type: Int32 76 | Parameter Sets: (All) 77 | Aliases: 78 | 79 | Required: False 80 | Position: 3 81 | Default value: 0 82 | Accept pipeline input: False 83 | Accept wildcard characters: False 84 | ``` 85 | 86 | ### -ProgressAction 87 | {{ Fill ProgressAction Description }} 88 | 89 | ```yaml 90 | Type: ActionPreference 91 | Parameter Sets: (All) 92 | Aliases: proga 93 | 94 | Required: False 95 | Position: Named 96 | Default value: None 97 | Accept pipeline input: False 98 | Accept wildcard characters: False 99 | ``` 100 | 101 | ### CommonParameters 102 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 103 | 104 | ## INPUTS 105 | 106 | ### System.Int32 107 | ## OUTPUTS 108 | 109 | ### Outputs an object containing: 110 | ### - GID: The ID of the news item. 111 | ### - Title: The title of the news item. 112 | ### - Url: The URL of the news item. 113 | ### - IsExternalUrl: A boolean indicating if the URL is external. 114 | ### - Author: The author of the news item. 115 | ### - Contents: The content of the news item. 116 | ### - FeedLabel: The label of the news feed. 117 | ### - Date: The date and time when the news item was published. 118 | ### - FeedName: The name of the news feed. 119 | ### - FeedType: The type of the news feed. 120 | ### - AppID: The AppID of the game associated with the news item. 121 | ## NOTES 122 | Author: Frederik Hjorslelv Nylander 123 | 124 | ## RELATED LINKS 125 | 126 | [https://hjorslev.github.io/SteamPS/Get-SteamNews.html](https://hjorslev.github.io/SteamPS/Get-SteamNews.html) 127 | 128 | -------------------------------------------------------------------------------- /docs/Get-SteamServerInfo.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: SteamPS-help.xml 3 | Module Name: SteamPS 4 | online version: https://hjorslev.github.io/SteamPS/Get-SteamServerInfo.html 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-SteamServerInfo 9 | 10 | ## SYNOPSIS 11 | Query a running steam based game server. 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Get-SteamServerInfo [-IPAddress] [-Port] [[-Timeout] ] 17 | [-ProgressAction ] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | The cmdlet fetches server information from a running game server using UDP/IP packets. 22 | It will return information ServerName, Map, InstallDir, GameName, AppID, Players 23 | MaxPlayers, Bots, ServerType, Environment, Visibility, VAC andVersion. 24 | 25 | ## EXAMPLES 26 | 27 | ### EXAMPLE 1 28 | ``` 29 | Get-SteamServerInfo -IPAddress '185.15.73.207' -Port 27015 30 | ``` 31 | 32 | \`\`\` 33 | Protocol : 17 34 | ServerName : SAS Proving Ground 10 (EU) 35 | Map : TH-SmallTown 36 | InstallDir : groundbranch 37 | GameName : Ground Branch 38 | AppID : 16900 39 | Players : 6 40 | MaxPlayers : 10 41 | Bots : 0 42 | ServerType : Dedicated 43 | Environment : Windows 44 | Visibility : Public 45 | VAC : Unsecured 46 | Version : 1.0.0.0 47 | ExtraDataFlag : 177 48 | IPAddress : 185.15.73.207 49 | Port : 27015 50 | \`\`\` 51 | 52 | ## PARAMETERS 53 | 54 | ### -IPAddress 55 | Enter the IP address of the Steam based server. 56 | 57 | ```yaml 58 | Type: IPAddress 59 | Parameter Sets: (All) 60 | Aliases: 61 | 62 | Required: True 63 | Position: 1 64 | Default value: None 65 | Accept pipeline input: False 66 | Accept wildcard characters: False 67 | ``` 68 | 69 | ### -Port 70 | Enter the port number of the Steam based server. 71 | 72 | ```yaml 73 | Type: Int32 74 | Parameter Sets: (All) 75 | Aliases: 76 | 77 | Required: True 78 | Position: 2 79 | Default value: 0 80 | Accept pipeline input: False 81 | Accept wildcard characters: False 82 | ``` 83 | 84 | ### -ProgressAction 85 | {{ Fill ProgressAction Description }} 86 | 87 | ```yaml 88 | Type: ActionPreference 89 | Parameter Sets: (All) 90 | Aliases: proga 91 | 92 | Required: False 93 | Position: Named 94 | Default value: None 95 | Accept pipeline input: False 96 | Accept wildcard characters: False 97 | ``` 98 | 99 | ### -Timeout 100 | Timeout in milliseconds before giving up querying the server. 101 | 102 | ```yaml 103 | Type: Int32 104 | Parameter Sets: (All) 105 | Aliases: 106 | 107 | Required: False 108 | Position: 3 109 | Default value: 5000 110 | Accept pipeline input: False 111 | Accept wildcard characters: False 112 | ``` 113 | 114 | ### CommonParameters 115 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 116 | 117 | ## INPUTS 118 | 119 | ## OUTPUTS 120 | 121 | ## NOTES 122 | Author: Jordan Borean, Chris Dent and Frederik Hjorslev Nylander 123 | 124 | ## RELATED LINKS 125 | 126 | [https://hjorslev.github.io/SteamPS/Get-SteamServerInfo.html](https://hjorslev.github.io/SteamPS/Get-SteamServerInfo.html) 127 | 128 | -------------------------------------------------------------------------------- /SteamPS/Public/API/Resolve-VanityURL.ps1: -------------------------------------------------------------------------------- 1 | function Resolve-VanityURL { 2 | <# 3 | .SYNOPSIS 4 | Retrieves the SteamID64 linked to a specified vanity URL (custom URL) from the Steam Community. 5 | 6 | .DESCRIPTION 7 | Using the Steam Web API, this cmdlet fetches the SteamID64 that corresponds to a provided vanity URL (custom URL) from the Steam Community. 8 | 9 | .PARAMETER VanityURL 10 | This parameter specifies the vanity URL (custom URL) for which the SteamID64 is to be retrieved. 11 | 12 | .PARAMETER UrlType 13 | This parameter defines the type of vanity URL. The valid values are: 1 (default) for an individual profile, 2 for a group, and 3 for an official game group. 14 | 15 | .EXAMPLE 16 | Resolve-VanityURL -VanityURL user 17 | 18 | This example retrieves the SteamID64 linked to the vanity URL 'user'. 19 | 20 | .EXAMPLE 21 | Resolve-VanityURL -VanityURL user1, user2 22 | This example retrieves the SteamID64s linked to the vanity URLs 'user1' and 'user2'. 23 | 24 | .INPUTS 25 | The VanityURL parameter accepts string input. 26 | 27 | .OUTPUTS 28 | The cmdlet returns a custom object containing the VanityURL and its associated SteamID64. 29 | 30 | .NOTES 31 | Author: Frederik Hjorslev Nylander 32 | 33 | .LINK 34 | https://hjorslev.github.io/SteamPS/Resolve-VanityURL.html 35 | #> 36 | 37 | [CmdletBinding()] 38 | param ( 39 | [Parameter(Mandatory = $true, 40 | HelpMessage = 'Enter the vanity URL (custom URL) for which the SteamID64 is to be retrieved.')] 41 | [ValidateScript( { 42 | if (([System.URI]$_ ).IsAbsoluteUri -eq $true) { 43 | throw "Do not enter the fully qualified URL, but just the ID (e.g.) everything after https://steamcommunity.com/id/" 44 | } 45 | $true 46 | })] 47 | [string[]]$VanityURL, 48 | 49 | [Parameter(Mandatory = $false, 50 | HelpMessage = 'The type of vanity URL. 1 (default): Individual profile, 2: Group, 3: Official game group.')] 51 | [ValidateSet(1, 2, 3)] 52 | [int]$UrlType = 1 53 | ) 54 | 55 | begin { 56 | Write-Verbose -Message "[BEGIN ] Starting: $($MyInvocation.MyCommand)" 57 | } 58 | 59 | process { 60 | foreach ($Item in $VanityURL) { 61 | $Request = Invoke-RestMethod -Uri 'https://api.steampowered.com/ISteamUser/ResolveVanityURL/v1/' -UseBasicParsing -Body @{ 62 | key = Get-SteamAPIKey 63 | vanityurl = $Item 64 | url_type = $UrlType 65 | } 66 | 67 | if ($Request.response.success -eq '1') { 68 | [PSCustomObject]@{ 69 | 'VanityURL' = $Item 70 | 'SteamID64' = ([int64]$Request.response.steamid) 71 | } 72 | } elseif ($Request.response.success -eq '42') { 73 | $Exception = [Exception]::new("Unable to find $Item.") 74 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 75 | $Exception, 76 | "VanityURLNotFound", 77 | [System.Management.Automation.ErrorCategory]::ObjectNotFound, 78 | $Request.response.success 79 | ) 80 | $PSCmdlet.WriteError($ErrorRecord) 81 | } 82 | } 83 | } # Process 84 | 85 | end { 86 | Write-Verbose -Message "[END ] Ending: $($MyInvocation.MyCommand)" 87 | } 88 | } # Cmdlet -------------------------------------------------------------------------------- /docs/Get-SteamApp.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: SteamPS-help.xml 3 | Module Name: SteamPS 4 | online version: https://hjorslev.github.io/SteamPS/Get-SteamApp.html 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-SteamApp 9 | 10 | ## SYNOPSIS 11 | Retrieves the name and ID of a Steam application by searching the name or 12 | ID of the application. 13 | 14 | ## SYNTAX 15 | 16 | ### ApplicationName (Default) 17 | ``` 18 | Get-SteamApp [-ApplicationName] [-ProgressAction ] [] 19 | ``` 20 | 21 | ### ApplicationID 22 | ``` 23 | Get-SteamApp [-ApplicationID] [-ProgressAction ] [] 24 | ``` 25 | 26 | ## DESCRIPTION 27 | This function searches for a Steam application by name or ID and returns the 28 | corresponding application ID and name. 29 | If multiple applications are found, 30 | the user can select the correct one from a list. 31 | 32 | ## EXAMPLES 33 | 34 | ### EXAMPLE 1 35 | ``` 36 | Get-SteamApp -ApplicationName 'Ground Branch' 37 | ``` 38 | 39 | Searches for applications with names that start with 'Ground Branch'. 40 | If multiple applications are found, the user can choose between them, such as the game 'Ground Branch' or 'Ground Branch Dedicated Server'. 41 | 42 | ### EXAMPLE 2 43 | ``` 44 | Get-SteamApp -ApplicationID 440 45 | ``` 46 | 47 | Searches for the application with the AppID 440 and returns its name and ID. 48 | 49 | ## PARAMETERS 50 | 51 | ### -ApplicationID 52 | The unique identifier for a Steam application. 53 | Use this parameter to search for an application by its ID. 54 | 55 | ```yaml 56 | Type: Int32 57 | Parameter Sets: ApplicationID 58 | Aliases: GameID 59 | 60 | Required: True 61 | Position: 1 62 | Default value: 0 63 | Accept pipeline input: True (ByPropertyName) 64 | Accept wildcard characters: False 65 | ``` 66 | 67 | ### -ApplicationName 68 | The name of the application to search for. 69 | If multiple applications are found, 70 | the user will be presented with a list from which they can select the correct application. 71 | 72 | ```yaml 73 | Type: String 74 | Parameter Sets: ApplicationName 75 | Aliases: GameName 76 | 77 | Required: True 78 | Position: 1 79 | Default value: None 80 | Accept pipeline input: True (ByPropertyName) 81 | Accept wildcard characters: False 82 | ``` 83 | 84 | ### -ProgressAction 85 | {{ Fill ProgressAction Description }} 86 | 87 | ```yaml 88 | Type: ActionPreference 89 | Parameter Sets: (All) 90 | Aliases: proga 91 | 92 | Required: False 93 | Position: Named 94 | Default value: None 95 | Accept pipeline input: False 96 | Accept wildcard characters: False 97 | ``` 98 | 99 | ### CommonParameters 100 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 101 | 102 | ## INPUTS 103 | 104 | ### System.String or System.Int32. Get-SteamApp accepts either a string value for the application name or an integer value for the application ID. 105 | ## OUTPUTS 106 | 107 | ### PSCustomObject. This function returns a custom object with the application name and application ID. 108 | ## NOTES 109 | Author: Frederik Hjorslev Nylander 110 | 111 | ## RELATED LINKS 112 | 113 | [https://hjorslev.github.io/SteamPS/Get-SteamApp.html](https://hjorslev.github.io/SteamPS/Get-SteamApp.html) 114 | 115 | -------------------------------------------------------------------------------- /Tests/Help.Tests.ps1: -------------------------------------------------------------------------------- 1 | # By Joel Sallow - https://github.com/vexx32/ 2 | 3 | BeforeAll { 4 | Import-Module "$($ReleasePath)\SteamPS.psm1" 5 | } 6 | 7 | Describe "Sanity Tests - Help Content" -Tags 'Module' { 8 | 9 | #region Discovery 10 | 11 | # The module will need to be imported during Discovery since we're using it to generate test cases / Context blocks 12 | Import-Module "$($ReleasePath)\SteamPS.psm1" 13 | 14 | $ShouldProcessParameters = 'WhatIf', 'Confirm' 15 | 16 | # Generate command list for generating Context / TestCases 17 | $CommandList = (Get-ChildItem "$($SteamPSModulePath)\Public\" -Recurse | Where-Object { -not $_.PSIsContainer }).BaseName 18 | 19 | #endregion Discovery 20 | 21 | foreach ($Command in $CommandList) { 22 | Context "$Command - Help Content" { 23 | 24 | #region Discovery 25 | 26 | $Help = @{ Help = Get-Help -Name $Command -Full } 27 | $Parameters = Get-Help -Name $Command -Parameter * -ErrorAction Ignore | 28 | Where-Object { $_.Name -and $_.Name -notin $ShouldProcessParameters } | 29 | ForEach-Object { 30 | @{ 31 | Name = $_.name 32 | Description = $_.Description.Text 33 | } 34 | } 35 | $Ast = @{ 36 | # Ast will be $null if the command is a compiled cmdlet 37 | Ast = (Get-Content -Path "function:/$Command" -ErrorAction Ignore).Ast 38 | Parameters = $Parameters 39 | } 40 | $Examples = $Help.Help.Examples.Example | ForEach-Object { @{ Example = $_ } } 41 | 42 | #endregion Discovery 43 | 44 | It "has help content for $Command" -TestCases $Help { 45 | $Help | Should -Not -BeNullOrEmpty 46 | } 47 | 48 | It "contains a synopsis for $Command" -TestCases $Help { 49 | $Help.Synopsis | Should -Not -BeNullOrEmpty 50 | } 51 | 52 | It "contains a description for $Command" -TestCases $Help { 53 | $Help.Description | Should -Not -BeNullOrEmpty 54 | } 55 | 56 | It "lists the function author in the Notes section for $Command" -TestCases $Help { 57 | $Notes = $Help.AlertSet.Alert.Text -split '\n' 58 | $Notes[0].Trim() | Should -BeLike "Author: *" 59 | } 60 | 61 | # This will be skipped for compiled commands ($Ast.Ast will be $null) 62 | It "has a help entry for all parameters of $Command" -TestCases $Ast -Skip:(-not ($Parameters -and $Ast.Ast)) { 63 | ($Parameters | Measure-Object).Count | Should -Be $Ast.Body.ParamBlock.Parameters.Count -Because 'the number of parameters in the help should match the number in the function script' 64 | } 65 | 66 | It "has a description for $Command parameter -" -TestCases $Parameters -Skip:(-not $Parameters) { 67 | $Description | Should -Not -BeNullOrEmpty -Because "parameter $Name should have a description" 68 | } 69 | 70 | It "has at least one usage example for $Command" -TestCases $Help { 71 | $Help.Examples.Example.Code.Count | Should -BeGreaterOrEqual 1 72 | } 73 | 74 | It "lists a description for $Command example: " -TestCases $Examples { 75 | $Example.Remarks | Should -Not -BeNullOrEmpty -Because "example $($Example.Title) should have a description!" 76 | } 77 | } 78 | } 79 | } # Describe -------------------------------------------------------------------------------- /SteamPS/Public/API/Get-SteamPlayerBan.ps1: -------------------------------------------------------------------------------- 1 | function Get-SteamPlayerBan { 2 | <# 3 | .SYNOPSIS 4 | Fetches ban information for Steam players. 5 | 6 | .DESCRIPTION 7 | This cmdlet fetches ban information about Steam players. The information includes whether the players are banned from the Steam Community, have VAC bans, the number of VAC bans, days since the last ban, number of game bans, and economy ban status. 8 | 9 | .PARAMETER SteamID64 10 | Specifies one or more 64-bit Steam IDs for which to fetch ban information. Enter the Steam IDs as a comma-separated list. 11 | 12 | .EXAMPLE 13 | Get-SteamPlayerBan -SteamID64 76561197960435530,76561197960434622 14 | 15 | This example fetches ban information for the players with the specified Steam IDs. 16 | 17 | .INPUTS 18 | int64[]: Specifies an array of 64-bit integers representing Steam IDs. 19 | 20 | .OUTPUTS 21 | Returns a PSCustomObject with the following properties: 22 | 23 | - SteamID64: The player's 64-bit ID. 24 | - CommunityBanned: A boolean indicating whether the player is banned from the Steam Community. 25 | - VACBanned: A boolean indicating whether the player has VAC bans on record. 26 | - NumberOfVACBans: The number of VAC bans on record. 27 | - DaysSinceLastBan: The number of days since the last ban. 28 | - NumberOfGameBans: The number of bans in games, including CS:GO Overwatch bans. 29 | - EconomyBan: The player's ban status in the economy. If the player has no bans on record, the string will be "none". If the player is on probation, it will say "probation", etc. 30 | 31 | .NOTES 32 | Author: Frederik Hjorslev Nylander 33 | 34 | .LINK 35 | https://hjorslev.github.io/SteamPS/Get-SteamPlayerBan.html 36 | #> 37 | 38 | [CmdletBinding()] 39 | param ( 40 | [Parameter(Mandatory = $true, 41 | HelpMessage = '64 bit Steam ID to return player bans for.', 42 | ValueFromPipelineByPropertyName = $true)] 43 | [int64[]]$SteamID64 44 | ) 45 | 46 | begin { 47 | Write-Verbose -Message "[BEGIN ] Starting: $($MyInvocation.MyCommand)" 48 | } 49 | 50 | process { 51 | $Request = Invoke-RestMethod -Uri 'https://api.steampowered.com/ISteamUser/GetPlayerBans/v1/' -UseBasicParsing -Body @{ 52 | key = Get-SteamAPIKey 53 | steamids = ($SteamID64 -join ',') 54 | } 55 | 56 | if (-not [string]::IsNullOrEmpty($Request.players.SteamId)) { 57 | foreach ($Item in $Request.players) { 58 | [PSCustomObject]@{ 59 | SteamID64 = [int64]$Item.SteamId 60 | CommunityBanned = $Item.CommunityBanned 61 | VACBanned = $Item.VACBanned 62 | NumberOfVACBans = $Item.NumberOfVACBans 63 | DaysSinceLastBan = $Item.DaysSinceLastBan 64 | NumberOfGameBans = $Item.NumberOfGameBans 65 | EconomyBan = $Item.EconomyBan 66 | } 67 | } 68 | } elseif ([string]::IsNullOrEmpty($Request.players)) { 69 | $Exception = [Exception]::new("SteamID $SteamID64 couldn't be found.") 70 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 71 | $Exception, 72 | 'PlayerNotFound', 73 | [System.Management.Automation.ErrorCategory]::ObjectNotFound, 74 | $Request 75 | ) 76 | $PSCmdlet.WriteError($ErrorRecord) 77 | } 78 | } # Process 79 | 80 | end { 81 | Write-Verbose -Message "[END ] Ending: $($MyInvocation.MyCommand)" 82 | } 83 | } # Cmdlet -------------------------------------------------------------------------------- /Tools/PesterTest.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param ( 3 | # The path where the Pester Tests are 4 | [Parameter(Mandatory)] 5 | [String] $TestPath, 6 | 7 | # The path where we export the Pester Results (Pester.xml, Coverage.xml, Coverage.json) 8 | [Parameter(Mandatory)] 9 | [String] $ResultPath, 10 | 11 | # The path to the Source Code 12 | [Parameter(Mandatory)] 13 | [string] $SourceRoot, 14 | 15 | # The path to the built Module 16 | [Parameter(Mandatory)] 17 | [string] $ReleasePath 18 | ) 19 | 20 | $ErrorActionPreference = 'Stop' 21 | 22 | $requirements = Import-PowerShellDataFile ([IO.Path]::Combine($PSScriptRoot, 'requiredModules.psd1')) 23 | foreach ($req in $requirements.GetEnumerator() | Sort-Object { $_.Value['Priority'] }) { 24 | $importModuleSplat = @{ 25 | Name = ([IO.Path]::Combine($PSScriptRoot, 'Modules', $req.Key)) 26 | Force = $true 27 | DisableNameChecking = $true 28 | } 29 | 30 | Write-Host "Importing: $($importModuleSplat['Name'])" 31 | Import-Module @importModuleSplat 32 | } 33 | 34 | [PSCustomObject] $PSVersionTable | 35 | Select-Object -Property *, @{ 36 | Name = 'Architecture' 37 | Expression = { 38 | switch ([IntPtr]::Size) { 39 | 4 { 40 | 'x86' 41 | } 42 | 8 { 43 | 'x64' 44 | } 45 | default { 46 | 'Unknown' 47 | } 48 | } 49 | } 50 | } | 51 | Format-List | 52 | Out-Host 53 | 54 | $configuration = [PesterConfiguration]::Default 55 | $configuration.Output.Verbosity = 'Detailed' 56 | $configuration.Run.PassThru = $true 57 | $configuration.CodeCoverage.Enabled = $true 58 | $configuration.CodeCoverage.Path = $ReleasePath 59 | $configuration.CodeCoverage.OutputPath = [IO.Path]::Combine($ResultPath, 'Coverage.xml') 60 | $configuration.Run.Throw = $true 61 | $configuration.Run.Path = $TestPath 62 | $configuration.TestResult.Enabled = $true 63 | $configuration.TestResult.OutputPath = [IO.Path]::Combine($ResultPath, 'Pester.xml') 64 | $configuration.TestResult.OutputFormat = 'NUnitXml' 65 | 66 | $pesterResult = Invoke-Pester -Configuration $configuration -WarningAction Ignore 67 | 68 | Push-Location $SourceRoot 69 | 70 | $out = [ordered]@{ 71 | coverage = [ordered]@{} 72 | messages = [ordered]@{} 73 | } 74 | 75 | $coverageReults = @( 76 | $pesterResult.CodeCoverage.CommandsMissed 77 | $pesterResult.CodeCoverage.CommandsExecuted 78 | ) | Convert-LineNumber -Passthru 79 | 80 | $groups = $coverageReults | Group-Object SourceFile | ForEach-Object { 81 | $out['coverage'][$_.Name] = [System.Collections.Generic.List[Object]]::new((, $null)) 82 | $out['messages'][$_.Name] = [ordered]@{} 83 | $_ 84 | } 85 | 86 | foreach ($group in $groups) { 87 | $map = $group.Group | Group-Object SourceLineNumber -AsHashTable -AsString 88 | $totalLines = [System.Linq.Enumerable]::Count( 89 | [System.IO.File]::ReadLines((Get-Item $group.Name).FullName)) 90 | 91 | foreach ($line in 1..$totalLines) { 92 | $line = $line.ToString() 93 | if ($map.ContainsKey($line)) { 94 | $out['coverage'][$group.Name].Add($map[$line].HitCount) 95 | $out['messages'][$group.Name][$line] = $map[$line].Command 96 | continue 97 | } 98 | 99 | $out['coverage'][$group.Name].Add($null) 100 | } 101 | } 102 | 103 | $out | ConvertTo-Json -Depth 99 | 104 | Set-Content ([IO.Path]::Combine($ResultPath, 'Coverage.json')) 105 | 106 | Pop-Location 107 | -------------------------------------------------------------------------------- /SteamPS/Public/API/Get-SteamNews.ps1: -------------------------------------------------------------------------------- 1 | function Get-SteamNews { 2 | <# 3 | .SYNOPSIS 4 | Fetches the latest news for a game using its AppID. 5 | 6 | .DESCRIPTION 7 | Fetches the latest news for a game using its AppID from the Steam API. 8 | 9 | .PARAMETER AppID 10 | The AppID of the game for which the news is to be fetched. 11 | 12 | .PARAMETER Count 13 | The number of news entries to fetch. By default, it fetches all news entries. 14 | 15 | .PARAMETER MaxLength 16 | The maximum length for each news entry. Entries longer than this will be truncated. By default, there is no truncation. 17 | 18 | .EXAMPLE 19 | Get-SteamNews -AppID 440 20 | 21 | This example fetches all available news entries for the game with AppID 440. 22 | 23 | .EXAMPLE 24 | Get-SteamNews -AppID 440 -Count 1 25 | 26 | This example fetches the most recent news entry for the game with AppID 440. 27 | 28 | .EXAMPLE 29 | Get-SteamNews -AppID 440 -MaxLength 100 30 | 31 | This example fetches all available news entries for the game with AppID 440 and truncates the news content to 100 characters. 32 | 33 | .INPUTS 34 | System.Int32 35 | 36 | .OUTPUTS 37 | Outputs an object containing: 38 | - GID: The ID of the news item. 39 | - Title: The title of the news item. 40 | - Url: The URL of the news item. 41 | - IsExternalUrl: A boolean indicating if the URL is external. 42 | - Author: The author of the news item. 43 | - Contents: The content of the news item. 44 | - FeedLabel: The label of the news feed. 45 | - Date: The date and time when the news item was published. 46 | - FeedName: The name of the news feed. 47 | - FeedType: The type of the news feed. 48 | - AppID: The AppID of the game associated with the news item. 49 | 50 | .NOTES 51 | Author: Frederik Hjorslev Nylander 52 | 53 | .LINK 54 | https://hjorslev.github.io/SteamPS/Get-SteamNews.html 55 | #> 56 | 57 | [CmdletBinding()] 58 | param ( 59 | [Parameter(Mandatory = $true, 60 | HelpMessage = 'Specifies the AppID of the game for which you want to retrieve news.')] 61 | [int]$AppID, 62 | 63 | [Parameter(Mandatory = $false, 64 | HelpMessage = 'Specifies the number of news entries to retrieve.')] 65 | [int]$Count, 66 | 67 | [Parameter(Mandatory = $false, 68 | HelpMessage = 'Specifies the maximum length of each news entry.')] 69 | [int]$MaxLength 70 | ) 71 | 72 | 73 | begin { 74 | Write-Verbose -Message "[BEGIN ] Starting: $($MyInvocation.MyCommand)" 75 | } 76 | 77 | process { 78 | # TODO: When only supporting pwsh use null coalescing operator (??) 79 | # to handle the case when $Count or $MaxLength is not defined 80 | $Body = @{ 81 | appid = $AppID 82 | } 83 | if ($Count) { 84 | $Body.Add('count', $Count) 85 | } 86 | if ($MaxLength) { 87 | $Body.Add('maxlength', $MaxLength) 88 | } 89 | $Request = Invoke-RestMethod -Uri 'http://api.steampowered.com/ISteamNews/GetNewsForApp/v0002/' -UseBasicParsing -Body $Body 90 | 91 | if ($Request) { 92 | foreach ($Item in $Request.appnews.newsitems) { 93 | [PSCustomObject]@{ 94 | GID = [int64]$Item.gid 95 | Title = $Item.title 96 | Url = $Item.url 97 | IsExternalUrl = [bool]$Item.is_external_url 98 | Author = $Item.author 99 | Contents = $Item.contents 100 | FeedLabel = $Item.feedlabel 101 | Date = ((Get-Date "01.01.1970") + ([System.TimeSpan]::FromSeconds($Item.date))).ToString("yyyy-MM-dd HH:mm:ss") 102 | FeedName = $Item.feedname 103 | FeedType = $Item.feed_type 104 | AppID = $Item.appid 105 | } 106 | } 107 | } elseif ($null -eq $Request) { 108 | $Exception = [Exception]::new("No news found for $AppID.") 109 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 110 | $Exception, 111 | 'NoNewsFound', 112 | [System.Management.Automation.ErrorCategory]::ObjectNotFound, 113 | $Request 114 | ) 115 | $PSCmdlet.WriteError($ErrorRecord) 116 | } 117 | } # Process 118 | 119 | end { 120 | Write-Verbose -Message "[END ] Ending: $($MyInvocation.MyCommand)" 121 | } 122 | } # Cmdlet -------------------------------------------------------------------------------- /SteamPS/Public/Server/Install-SteamCMD.ps1: -------------------------------------------------------------------------------- 1 | function Install-SteamCMD { 2 | <# 3 | .SYNOPSIS 4 | Install SteamCMD. 5 | 6 | .DESCRIPTION 7 | This cmdlet downloads SteamCMD and configures it in a custom or 8 | predefined location (C:\Program Files\SteamCMD). 9 | 10 | .PARAMETER InstallPath 11 | Specify the install location of SteamCMD. 12 | 13 | .PARAMETER Force 14 | The Force parameter allows the user to skip the "Should Continue" box. 15 | 16 | .EXAMPLE 17 | Install-SteamCMD 18 | 19 | Installs SteamCMD in C:\Program Files\SteamCMD. 20 | 21 | .EXAMPLE 22 | Install-SteamCMD -InstallPath 'C:' 23 | 24 | Installs SteamCMD in C:\SteamCMD. 25 | 26 | .NOTES 27 | Author: Frederik Hjorslev Nylander 28 | 29 | .LINK 30 | https://hjorslev.github.io/SteamPS/Install-SteamCMD.html 31 | #> 32 | 33 | [CmdletBinding(SupportsShouldProcess = $true, 34 | ConfirmImpact = 'Medium')] 35 | param ( 36 | [Parameter(Mandatory = $false)] 37 | [ValidateScript( { 38 | if ($_.Substring(($_.Length -1)) -eq '\') { 39 | throw "InstallPath may not end with a trailing slash." 40 | } 41 | $true 42 | })] 43 | [string]$InstallPath = "$env:ProgramFiles", 44 | 45 | [Parameter(Mandatory = $false)] 46 | [switch]$Force 47 | ) 48 | 49 | begin { 50 | $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") 51 | if ($isAdmin -eq $false) { 52 | $Exception = [Exception]::new('The current PowerShell session is not running as Administrator. Start PowerShell by using the Run as Administrator option, and then try running the script again.') 53 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 54 | $Exception, 55 | 'MissingUserPermissions', 56 | [System.Management.Automation.ErrorCategory]::PermissionDenied, 57 | $isAdmin 58 | ) 59 | $PSCmdlet.ThrowTerminatingError($ErrorRecord) 60 | } 61 | } 62 | 63 | process { 64 | if ($Force -or $PSCmdlet.ShouldContinue('Would you like to continue?', 'Install SteamCMD')) { 65 | # Ensures that SteamCMD is installed in a folder named SteamCMD. 66 | $InstallPath = $InstallPath + '\SteamCMD' 67 | 68 | if (-not ((Get-SteamPath).Path -eq $InstallPath)) { 69 | Write-Verbose -Message "Adding $InstallPath to Environment Variable PATH." 70 | Add-EnvPath -Path $InstallPath -Container Machine 71 | } else { 72 | Write-Verbose -Message "Path $((Get-SteamPath).Path) already exists." 73 | } 74 | 75 | $TempDirectory = 'C:\Temp' 76 | if (-not (Test-Path -Path $TempDirectory)) { 77 | Write-Verbose -Message 'Creating Temp directory.' 78 | New-Item -Path 'C:\' -Name 'Temp' -ItemType Directory | Write-Verbose 79 | } 80 | 81 | # Download SteamCMD. 82 | Invoke-WebRequest -Uri 'https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip' -OutFile "$TempDirectory\steamcmd.zip" -UseBasicParsing 83 | 84 | # Create SteamCMD directory if necessary. 85 | if (-not (Test-Path -Path $InstallPath)) { 86 | Write-Verbose -Message "Creating SteamCMD directory: $InstallPath" 87 | New-Item -Path $InstallPath -ItemType Directory | Write-Verbose 88 | Expand-Archive -Path "$TempDirectory\steamcmd.zip" -DestinationPath $InstallPath 89 | } 90 | 91 | # Doing some initial configuration of SteamCMD. The first time SteamCMD is launched it will need to do some updates. 92 | Write-Host -Object 'Configuring SteamCMD for the first time. This might take a little while.' 93 | Write-Host -Object 'Please wait' -NoNewline 94 | Start-Process -FilePath "$InstallPath\steamcmd.exe" -ArgumentList 'validate +quit' -WindowStyle Hidden 95 | do { 96 | Write-Host -Object "." -NoNewline 97 | Start-Sleep -Seconds 3 98 | } 99 | until (-not (Get-Process -Name "*steamcmd*")) 100 | } 101 | } # Process 102 | 103 | end { 104 | if (Test-Path -Path "$TempDirectory\steamcmd.zip") { 105 | Remove-Item -Path "$TempDirectory\steamcmd.zip" -Force 106 | } 107 | 108 | if (Test-Path -Path (Get-SteamPath).Executable) { 109 | Write-Output -InputObject "SteamCMD is now installed. Please close/open your PowerShell host." 110 | } 111 | } # End 112 | } # Cmdlet -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | name: SteamPS CI/CD workflow 2 | on: 3 | push: 4 | branches: 5 | - main 6 | - master 7 | 8 | pull_request: 9 | branches: 10 | - main 11 | - master 12 | 13 | release: 14 | types: 15 | - published 16 | 17 | env: 18 | DOTNET_CLI_TELEMETRY_OPTOUT: 1 19 | POWERSHELL_TELEMETRY_OPTOUT: 1 20 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 21 | DOTNET_NOLOGO: true 22 | BUILD_CONFIGURATION: ${{ fromJSON('["Debug", "Release"]')[startsWith(github.ref, 'refs/tags/v')] }} 23 | 24 | jobs: 25 | build: 26 | name: 👷 Build 27 | runs-on: windows-latest 28 | steps: 29 | - name: 🚚 Check out repository 30 | uses: actions/checkout@v4 31 | 32 | - name: 🐛 Build module - Debug 33 | shell: pwsh 34 | run: ./build.ps1 -Configuration $env:BUILD_CONFIGURATION -Task Build 35 | if: ${{ env.BUILD_CONFIGURATION == 'Debug' }} 36 | 37 | - name: 🚀 Build module - Publish 38 | shell: pwsh 39 | run: ./build.ps1 -Configuration $env:BUILD_CONFIGURATION -Task Build 40 | if: ${{ env.BUILD_CONFIGURATION == 'Release' }} 41 | 42 | - name: 📦 Capture PowerShell Module 43 | uses: actions/upload-artifact@v4 44 | with: 45 | name: PSModule 46 | path: output/*.nupkg 47 | 48 | test: 49 | name: 🧪 Test 50 | needs: 51 | - build 52 | runs-on: ${{ matrix.info.os }} 53 | strategy: 54 | fail-fast: false 55 | matrix: 56 | info: 57 | - name: 🪟 Win2019_PS-5.1 58 | psversion: '5.1' 59 | os: windows-2019 60 | - name: 🪟 Win2019_PS-7 61 | psversion: '7' 62 | os: windows-2019 63 | - name: 🪟 Win2022_PS-5.1 64 | psversion: '5.1' 65 | os: windows-latest 66 | - name: 🪟 Win2022_PS-7 67 | psversion: '7' 68 | os: windows-latest 69 | 70 | steps: 71 | - name: 🚚 Checkout 72 | uses: actions/checkout@v4 73 | 74 | - name: ➕ Restore Built PowerShell Module 75 | uses: actions/download-artifact@v4 76 | with: 77 | name: PSModule 78 | path: output 79 | 80 | - name: 📦 Install Built PowerShell Module 81 | shell: pwsh 82 | run: | 83 | # Get the manifest from the newly built module. 84 | $manifestItem = Get-Item ([IO.Path]::Combine('SteamPS', '*.psd1')) 85 | $moduleName = $manifestItem.BaseName 86 | $Manifest = Test-ModuleManifest -Path $manifestItem.FullName -ErrorAction SilentlyContinue -WarningAction Ignore 87 | 88 | if ($env:BUILD_CONFIGURATION -eq 'Release') { 89 | $Version = $env:GITHUB_REF -replace '^refs/tags/v(\d+\.\d+\.\d+)', '$1' 90 | } else { 91 | $Version = $Manifest.Version 92 | } 93 | 94 | $destPath = [IO.Path]::Combine('output', $moduleName, $Version) 95 | if (-not (Test-Path -LiteralPath $destPath)) { 96 | New-Item -Path $destPath -ItemType Directory | Out-Null 97 | } 98 | 99 | Get-ChildItem output/*.nupkg | Rename-Item -NewName { $_.Name -replace '.nupkg', '.zip' } 100 | 101 | Expand-Archive -Path output/*.zip -DestinationPath $destPath -Force -ErrorAction Stop 102 | 103 | - name: 🧪 Run Tests - Windows PowerShell 104 | if: ${{ matrix.info.psversion == '5.1' }} 105 | shell: powershell 106 | run: ./build.ps1 -Configuration $env:BUILD_CONFIGURATION -Task Test 107 | 108 | - name: 🧪 Run Tests - PowerShell 109 | if: ${{ matrix.info.psversion != '5.1' }} 110 | shell: pwsh 111 | run: ./build.ps1 -Configuration $env:BUILD_CONFIGURATION -Task Test 112 | 113 | - name: ⬆️ Upload Test Results 114 | if: always() 115 | uses: actions/upload-artifact@v4 116 | with: 117 | name: Unit Test Results (${{ matrix.info.name }}) 118 | path: ./output/TestResults/Pester.xml 119 | 120 | - name: ⬆️ Upload Coverage Results 121 | if: always() && !startsWith(github.ref, 'refs/tags/v') 122 | uses: actions/upload-artifact@v4 123 | with: 124 | name: Coverage Results (${{ matrix.info.name }}) 125 | path: ./output/TestResults/Coverage.xml 126 | 127 | - name: ⬆️ Upload Coverage to codecov 128 | if: always() && !startsWith(github.ref, 'refs/tags/v') 129 | uses: codecov/codecov-action@v4 130 | with: 131 | files: ./output/TestResults/Coverage.json 132 | flags: ${{ matrix.info.name }} 133 | token: ${{ secrets.CODECOV_TOKEN }} 134 | 135 | publish: 136 | name: 🚀 Deploy 137 | if: startsWith(github.ref, 'refs/tags/v') 138 | needs: 139 | - build 140 | - test 141 | runs-on: windows-latest 142 | steps: 143 | - name: ➕ Restore Built PowerShell Module 144 | uses: actions/download-artifact@v4 145 | with: 146 | name: PSModule 147 | path: ./ 148 | 149 | - name: 🚀 Publish to Gallery 150 | if: github.event_name == 'release' 151 | shell: pwsh 152 | run: >- 153 | dotnet nuget push '*.nupkg' 154 | --api-key $env:PSGALLERY_TOKEN 155 | --source 'https://www.powershellgallery.com/api/v2/package' 156 | --no-symbols 157 | env: 158 | PSGALLERY_TOKEN: ${{ secrets.PS_GALLERY_KEY }} 159 | -------------------------------------------------------------------------------- /docs/Get-SteamPlayerSummary.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: SteamPS-help.xml 3 | Module Name: SteamPS 4 | online version: https://hjorslev.github.io/SteamPS/Get-SteamPlayerSummary.html 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-SteamPlayerSummary 9 | 10 | ## SYNOPSIS 11 | Returns basic profile information for a list of 64-bit Steam IDs. 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Get-SteamPlayerSummary [-SteamID64] <Int64[]> [-ProgressAction <ActionPreference>] [<CommonParameters>] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | Returns basic profile information for a list of 64-bit Steam IDs. 21 | 22 | ## EXAMPLES 23 | 24 | ### EXAMPLE 1 25 | ``` 26 | Get-SteamPlayerSummary -SteamID64 76561197960435530, 76561197960434622 27 | ``` 28 | 29 | ## PARAMETERS 30 | 31 | ### -ProgressAction 32 | {{ Fill ProgressAction Description }} 33 | 34 | ```yaml 35 | Type: ActionPreference 36 | Parameter Sets: (All) 37 | Aliases: proga 38 | 39 | Required: False 40 | Position: Named 41 | Default value: None 42 | Accept pipeline input: False 43 | Accept wildcard characters: False 44 | ``` 45 | 46 | ### -SteamID64 47 | Comma-delimited list of 64 bit Steam IDs to return profile information for. 48 | Up to 100 Steam IDs can be requested. 49 | 50 | ```yaml 51 | Type: Int64[] 52 | Parameter Sets: (All) 53 | Aliases: 54 | 55 | Required: True 56 | Position: 1 57 | Default value: None 58 | Accept pipeline input: True (ByPropertyName) 59 | Accept wildcard characters: False 60 | ``` 61 | 62 | ### CommonParameters 63 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 64 | 65 | ## INPUTS 66 | 67 | ### int64[]: Specifies an array of 64-bit integers representing Steam IDs. 68 | ## OUTPUTS 69 | 70 | ### Returns a custom object with the properties listed below. 71 | ### Some data associated with a Steam account may be hidden if the user has their profile visibility set to "Friends Only" or "Private". In that case, only public data will be returned. 72 | ### Public Data 73 | ### - steamid: 64-bit SteamID of the user. 74 | ### - personaname: The player's persona name (display name). 75 | ### - profileurl: The full URL of the player's Steam Community profile. 76 | ### - avatar: The full URL of the player's 32x32px avatar. If the user hasn't configured an avatar, this will be the default ? avatar. 77 | ### - avatarmedium: The full URL of the player's 64x64px avatar. If the user hasn't configured an avatar, this will be the default ? avatar. 78 | ### - avatarfull: The full URL of the player's 184x184px avatar. If the user hasn't configured an avatar, this will be the default ? avatar. 79 | ### - personastate: The user's current status. 0 - Offline, 1 - Online, 2 - Busy, 3 - Away, 4 - Snooze, 5 - looking to trade, 6 - looking to play. If the player's profile is private, this will always be "0", except if the user has set their status to looking to trade or looking to play, because a bug makes those status appear even if the profile is private. 80 | ### - communityvisibilitystate: This represents whether the profile is visible or not, and if it is visible, why you are allowed to see it. Note that because this WebAPI does not use authentication, there are only two possible values returned: 1 - the profile is not visible to you (Private, Friends Only, etc), 3 - the profile is "Public", and the data is visible. Mike Blaszczak's post on Steam forums says, "The community visibility state this API returns is different than the privacy state. It's the effective visibility state from the account making the request to the account being viewed given the requesting account's relationship to the viewed account." 81 | ### - profilestate: If set, indicates the user has a community profile configured (will be set to '1') 82 | ### - lastlogoff: The last time the user was online, in unix time. Only available when you are friends with the requested user (since Feb, 4). 83 | ### - commentpermission: If set, indicates the profile allows public comments. 84 | ### Private Data 85 | ### - realname: The player's "Real Name", if they have set it. 86 | ### - primaryclanid: The player's primary group, as configured in their Steam Community profile. 87 | ### - timecreated: The time the player's account was created. 88 | ### - gameid: If the user is currently in-game, this value will be returned and set to the gameid of that game. 89 | ### - gameserverip: The ip and port of the game server the user is currently playing on, if they are playing on-line in a game using Steam matchmaking. Otherwise will be set to "0.0.0.0:0". 90 | ### - gameextrainfo: If the user is currently in-game, this will be the name of the game they are playing. This may be the name of a non-Steam game shortcut. 91 | ### - cityid: This value will be removed in a future update (see loccityid) 92 | ### - loccountrycode: If set on the user's Steam Community profile, The user's country of residence, 2-character ISO country code 93 | ### - locstatecode: If set on the user's Steam Community profile, The user's state of residence 94 | ### - loccityid: An internal code indicating the user's city of residence. A future update will provide this data in a more useful way. steam_location gem/package makes player location data readable for output. 95 | ## NOTES 96 | Author: Frederik Hjorslev Nylander 97 | 98 | ## RELATED LINKS 99 | 100 | [https://hjorslev.github.io/SteamPS/Get-SteamPlayerSummary.html](https://hjorslev.github.io/SteamPS/Get-SteamPlayerSummary.html) 101 | 102 | -------------------------------------------------------------------------------- /SteamPS/SteamPS.psd1: -------------------------------------------------------------------------------- 1 | # 2 | # Module manifest for module 'SteamPS' 3 | # 4 | # Generated by: Frederik Hjorslev Nylander 5 | # 6 | # Generated on: 7/17/2019 7 | # 8 | 9 | @{ 10 | 11 | # Script module or binary module file associated with this manifest. 12 | RootModule = 'SteamPS.psm1' 13 | 14 | # Version number of this module. 15 | ModuleVersion = '3.2.3' 16 | 17 | # Supported PSEditions 18 | # CompatiblePSEditions = @() 19 | 20 | # ID used to uniquely identify this module 21 | GUID = '1043b347-925c-4b8b-9cd9-075bc9f9a153' 22 | 23 | # Author of this module 24 | Author = 'Frederik Hjorslev Nylander' 25 | 26 | # Company or vendor of this module 27 | CompanyName = 'hjorslev' 28 | 29 | # Copyright statement for this module 30 | Copyright = '(c) 2019-2024 Frederik Hjorslev Nylander. All rights reserved.' 31 | 32 | # Description of the functionality provided by this module 33 | Description = 'Module that utilizes PowerShell as a wrapper for SteamCMD and interacts with various Steam APIs.' 34 | 35 | # Minimum version of the Windows PowerShell engine required by this module 36 | PowerShellVersion = '5.1' 37 | 38 | # Name of the Windows PowerShell host required by this module 39 | # PowerShellHostName = '' 40 | 41 | # Minimum version of the Windows PowerShell host required by this module 42 | # PowerShellHostVersion = '' 43 | 44 | # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 45 | # DotNetFrameworkVersion = '' 46 | 47 | # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 48 | # CLRVersion = '' 49 | 50 | # Processor architecture (None, X86, Amd64) required by this module 51 | # ProcessorArchitecture = '' 52 | 53 | # Modules that must be imported into the global environment prior to importing this module 54 | # RequiredModules = @(@{ ModuleName = 'PSFramework'; GUID = '8028b914-132b-431f-baa9-94a6952f21ff'; ModuleVersion = '1.10.318' }) 55 | 56 | # Assemblies that must be loaded prior to importing this module 57 | # RequiredAssemblies = @() 58 | 59 | # Script files (.ps1) that are run in the caller's environment prior to importing this module. 60 | # ScriptsToProcess = @('') 61 | 62 | # Type files (.ps1xml) to be loaded when importing this module 63 | # TypesToProcess = @() 64 | 65 | # Format files (.ps1xml) to be loaded when importing this module 66 | # FormatsToProcess = @() 67 | 68 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 69 | # NestedModules = @() 70 | 71 | # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. 72 | FunctionsToExport = @('Connect-SteamAPI','Find-SteamAppID','Get-SteamFriendList','Get-SteamNews','Get-SteamPlayerBan','Get-SteamPlayerSummary','Get-SteamServerInfo','Install-SteamCMD','Resolve-VanityURL','Update-SteamApp','Update-SteamServer') 73 | 74 | # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. 75 | # CmdletsToExport = @() 76 | 77 | # Variables to export from this module 78 | # VariablesToExport = @() 79 | 80 | # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. 81 | # AliasesToExport = @() 82 | 83 | # DSC resources to export from this module 84 | # DscResourcesToExport = @() 85 | 86 | # List of all modules packaged with this module 87 | # ModuleList = @() 88 | 89 | # List of all files packaged with this module 90 | # FileList = @() 91 | 92 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. 93 | PrivateData = @{ 94 | 95 | PSData = @{ 96 | 97 | # Tags applied to this module. These help with module discovery in online galleries. 98 | Tags = 'Steam', 'SteamCMD' 99 | 100 | # A URL to the license for this module. 101 | LicenseUri = 'https://github.com/hjorslev/SteamPS/blob/master/LICENSE.md' 102 | 103 | # A URL to the main website for this project. 104 | ProjectUri = 'https://github.com/hjorslev/SteamPS' 105 | 106 | # A URL to an icon representing this module. 107 | IconUri = 'https://raw.githubusercontent.com/hjorslev/SteamPS/master/assets/images/SteamPS-icon.svg' 108 | 109 | # ReleaseNotes of this module 110 | ReleaseNotes = 'https://github.com/hjorslev/SteamPS/releases' 111 | 112 | # Prerelease string of this module 113 | # Prerelease = '' 114 | 115 | # Flag to indicate whether the module requires explicit user acceptance for install/update 116 | # RequireLicenseAcceptance = $false 117 | 118 | # External dependent modules of this module 119 | # ExternalModuleDependencies = @() 120 | 121 | } # End of PSData hashtable 122 | 123 | } # End of PrivateData hashtable 124 | 125 | # HelpInfo URI of this module 126 | # HelpInfoURI = '' 127 | 128 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 129 | # DefaultCommandPrefix = '' 130 | 131 | } 132 | -------------------------------------------------------------------------------- /SteamPS/Public/API/Get-SteamApp.ps1: -------------------------------------------------------------------------------- 1 | function Get-SteamApp { 2 | <# 3 | .SYNOPSIS 4 | Retrieves the name and ID of a Steam application by searching the name or 5 | ID of the application. 6 | 7 | .DESCRIPTION 8 | This function searches for a Steam application by name or ID and returns the 9 | corresponding application ID and name. If multiple applications are found, 10 | the user can select the correct one from a list. 11 | 12 | .PARAMETER ApplicationName 13 | The name of the application to search for. If multiple applications are found, 14 | the user will be presented with a list from which they can select the correct application. 15 | 16 | .PARAMETER ApplicationID 17 | The unique identifier for a Steam application. Use this parameter to search for an application by its ID. 18 | 19 | .EXAMPLE 20 | Get-SteamApp -ApplicationName 'Ground Branch' 21 | 22 | Searches for applications with names that start with 'Ground Branch'. If multiple applications are found, the user can choose between them, such as the game 'Ground Branch' or 'Ground Branch Dedicated Server'. 23 | 24 | .EXAMPLE 25 | Get-SteamApp -ApplicationID 440 26 | 27 | Searches for the application with the AppID 440 and returns its name and ID. 28 | 29 | .INPUTS 30 | System.String or System.Int32. Get-SteamApp accepts either a string value for the application name or an integer value for the application ID. 31 | 32 | .OUTPUTS 33 | PSCustomObject. This function returns a custom object with the application name and application ID. 34 | 35 | .NOTES 36 | Author: Frederik Hjorslev Nylander 37 | 38 | .LINK 39 | https://hjorslev.github.io/SteamPS/Get-SteamApp.html 40 | #> 41 | 42 | [CmdletBinding(DefaultParameterSetName = 'ApplicationName')] 43 | [Alias('Find-SteamAppID')] 44 | param ( 45 | [Parameter(ParameterSetName = 'ApplicationName', 46 | Position = 0, 47 | Mandatory = $true, 48 | ValueFromPipelineByPropertyName = $true 49 | )] 50 | [Alias('GameName')] 51 | [string]$ApplicationName, 52 | 53 | [Parameter(ParameterSetName = 'ApplicationID', 54 | Position = 0, 55 | Mandatory = $true, 56 | ValueFromPipelineByPropertyName = $true 57 | )] 58 | [Alias('GameID')] 59 | [int]$ApplicationID 60 | ) 61 | 62 | begin { 63 | Write-Verbose -Message 'Fetching app list from Steam Web API.' 64 | $SteamApps = (Invoke-RestMethod -Uri 'https://api.steampowered.com/ISteamApps/GetAppList/v2/' -UseBasicParsing).applist.apps 65 | } 66 | 67 | process { 68 | # ParameterSet ApplicationName 69 | if ($PSCmdlet.ParameterSetName -eq 'ApplicationName') { 70 | Write-Verbose -Message 'ParameterSetName is ApplicationName' 71 | # Filter on ApplicationName. Might result in multiple hits. 72 | # The user can then later choose their preference. 73 | $FilteredApps = $SteamApps.Where({ $_.name -match "^$ApplicationName" }) 74 | # If only one application is found when searching by application name. 75 | if (($FilteredApps | Measure-Object).Count -eq 1 -and $null -ne $FilteredApps) { 76 | Write-Verbose -Message "Only one application found: $($FilteredApps.name) - $($FilteredApps.appid)." 77 | [PSCustomObject]@{ 78 | ApplicationID = $FilteredApps.appid 79 | ApplicationName = $FilteredApps.name 80 | } 81 | } 82 | # If more than one application is found, the user is prompted to select the exact application. 83 | elseif (($FilteredApps | Measure-Object).Count -ge 1) { 84 | # An Out-GridView is presented to the user where the exact AppID can be located. This variable contains the AppID selected in the Out-GridView. 85 | $SteamApp = $FilteredApps | Select-Object @{Name = 'appid'; Expression = { $_.appid.toString() } }, name | Out-GridView -Title 'Select application' -PassThru 86 | if ($SteamApp) { 87 | Write-Verbose -Message "$(($SteamApp).name) - $(($SteamApp).appid) selected from Out-GridView." 88 | [PSCustomObject]@{ 89 | ApplicationID = $SteamApp.appid 90 | ApplicationName = $SteamApp.name 91 | } 92 | } 93 | } 94 | if (-not $FilteredApps) { 95 | $Exception = [Exception]::new("$ApplicationName could not be found.") 96 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 97 | $Exception, 98 | 'ApplicationNotFound', 99 | [System.Management.Automation.ErrorCategory]::ObjectNotFound, 100 | $FilteredApps 101 | ) 102 | $PSCmdlet.WriteError($ErrorRecord) 103 | } 104 | } 105 | # ParameterSet ApplicationID 106 | elseif ($PSCmdlet.ParameterSetName -eq 'ApplicationID') { 107 | Write-Verbose -Message 'ParameterSetName is ApplicationID.' 108 | $SteamApp = $SteamApps.Where({ $_.appid -eq $ApplicationID }) 109 | if ($SteamApp) { 110 | [PSCustomObject]@{ 111 | ApplicationID = $SteamApp.appid 112 | ApplicationName = $SteamApp.name 113 | } 114 | } else { 115 | $Exception = [Exception]::new("$ApplicationID could not be found.") 116 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 117 | $Exception, 118 | 'ApplicationNotFound', 119 | [System.Management.Automation.ErrorCategory]::ObjectNotFound, 120 | $SteamApp 121 | ) 122 | $PSCmdlet.WriteError($ErrorRecord) 123 | } 124 | } 125 | } # Process 126 | } # Cmdlet 127 | -------------------------------------------------------------------------------- /docs/Update-SteamApp.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: SteamPS-help.xml 3 | Module Name: SteamPS 4 | online version: https://hjorslev.github.io/SteamPS/Update-SteamApp.html 5 | schema: 2.0.0 6 | --- 7 | 8 | # Update-SteamApp 9 | 10 | ## SYNOPSIS 11 | Install or update a Steam application using SteamCMD. 12 | 13 | ## SYNTAX 14 | 15 | ### ApplicationName 16 | ``` 17 | Update-SteamApp [-ApplicationName] <String> -Path <String> [-Credential <PSCredential>] [-Arguments <String>] 18 | [-Force] [-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>] 19 | ``` 20 | 21 | ### ApplicationID 22 | ``` 23 | Update-SteamApp [-ApplicationID] <Int32> -Path <String> [-Credential <PSCredential>] [-Arguments <String>] 24 | [-Force] [-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>] 25 | ``` 26 | 27 | ## DESCRIPTION 28 | Install or update a Steam application using SteamCMD. 29 | If SteamCMD is missing, it will be installed first. 30 | You can either search for the application by name or enter the specific Application ID. 31 | 32 | ## EXAMPLES 33 | 34 | ### EXAMPLE 1 35 | ``` 36 | Update-SteamApp -ApplicationName 'Arma 3' -Credential 'Toby' -Path 'C:\DedicatedServers\Arma3' 37 | ``` 38 | 39 | Because there are multiple hits when searching for Arma 3, the user will be promoted to select the right application. 40 | 41 | ### EXAMPLE 2 42 | ``` 43 | Update-SteamApp -AppID 376030 -Path 'C:\DedicatedServers\ARK-SurvivalEvolved' 44 | ``` 45 | 46 | Here we use anonymous login because the particular application (ARK: Survival Evolved Dedicated Server) doesn't require login. 47 | 48 | ## PARAMETERS 49 | 50 | ### -ApplicationID 51 | Enter the application ID you wish to install. 52 | 53 | ```yaml 54 | Type: Int32 55 | Parameter Sets: ApplicationID 56 | Aliases: AppID 57 | 58 | Required: True 59 | Position: 1 60 | Default value: 0 61 | Accept pipeline input: True (ByPropertyName) 62 | Accept wildcard characters: False 63 | ``` 64 | 65 | ### -ApplicationName 66 | Enter the name of the app to make a wildcard search for the application. 67 | 68 | ```yaml 69 | Type: String 70 | Parameter Sets: ApplicationName 71 | Aliases: GameName 72 | 73 | Required: True 74 | Position: 1 75 | Default value: None 76 | Accept pipeline input: True (ByPropertyName) 77 | Accept wildcard characters: False 78 | ``` 79 | 80 | ### -Arguments 81 | Enter any additional arguments here. 82 | 83 | Beware, the following arguments are already used: 84 | 85 | If you use Steam login to install/upload the app the following arguments are already used: "+login $SteamUserName $SteamPassword +force_install_dir $Path +app_update $SteamAppID $Arguments +quit" 86 | 87 | If you use anonymous login to install/upload the app the following arguments are already used: "+login anonymous +force_install_dir $Path +app_update $SteamAppID $Arguments +quit" 88 | 89 | ```yaml 90 | Type: String 91 | Parameter Sets: (All) 92 | Aliases: 93 | 94 | Required: False 95 | Position: Named 96 | Default value: None 97 | Accept pipeline input: False 98 | Accept wildcard characters: False 99 | ``` 100 | 101 | ### -Credential 102 | If the app requires login to install or update, enter your Steam username and password. 103 | 104 | ```yaml 105 | Type: PSCredential 106 | Parameter Sets: (All) 107 | Aliases: 108 | 109 | Required: False 110 | Position: Named 111 | Default value: [System.Management.Automation.PSCredential]::Empty 112 | Accept pipeline input: False 113 | Accept wildcard characters: False 114 | ``` 115 | 116 | ### -Force 117 | The Force parameter allows the user to skip the "Should Continue" box. 118 | 119 | ```yaml 120 | Type: SwitchParameter 121 | Parameter Sets: (All) 122 | Aliases: 123 | 124 | Required: False 125 | Position: Named 126 | Default value: False 127 | Accept pipeline input: False 128 | Accept wildcard characters: False 129 | ``` 130 | 131 | ### -Path 132 | Path to installation folder. 133 | 134 | ```yaml 135 | Type: String 136 | Parameter Sets: (All) 137 | Aliases: 138 | 139 | Required: True 140 | Position: Named 141 | Default value: None 142 | Accept pipeline input: False 143 | Accept wildcard characters: False 144 | ``` 145 | 146 | ### -ProgressAction 147 | {{ Fill ProgressAction Description }} 148 | 149 | ```yaml 150 | Type: ActionPreference 151 | Parameter Sets: (All) 152 | Aliases: proga 153 | 154 | Required: False 155 | Position: Named 156 | Default value: None 157 | Accept pipeline input: False 158 | Accept wildcard characters: False 159 | ``` 160 | 161 | ### -Confirm 162 | Prompts you for confirmation before running the cmdlet. 163 | 164 | ```yaml 165 | Type: SwitchParameter 166 | Parameter Sets: (All) 167 | Aliases: cf 168 | 169 | Required: False 170 | Position: Named 171 | Default value: None 172 | Accept pipeline input: False 173 | Accept wildcard characters: False 174 | ``` 175 | 176 | ### -WhatIf 177 | Shows what would happen if the cmdlet runs. 178 | The cmdlet is not run. 179 | 180 | ```yaml 181 | Type: SwitchParameter 182 | Parameter Sets: (All) 183 | Aliases: wi 184 | 185 | Required: False 186 | Position: Named 187 | Default value: None 188 | Accept pipeline input: False 189 | Accept wildcard characters: False 190 | ``` 191 | 192 | ### CommonParameters 193 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 194 | 195 | ## INPUTS 196 | 197 | ## OUTPUTS 198 | 199 | ## NOTES 200 | Author: Frederik Hjorslev Nylander 201 | 202 | SteamCMD CLI parameters: https://developer.valvesoftware.com/wiki/Command_Line_Options#Command-line_parameters_4 203 | 204 | ## RELATED LINKS 205 | 206 | [https://hjorslev.github.io/SteamPS/Update-SteamApp.html](https://hjorslev.github.io/SteamPS/Update-SteamApp.html) 207 | 208 | -------------------------------------------------------------------------------- /SteamPS/Public/Server/Get-SteamServerInfo.ps1: -------------------------------------------------------------------------------- 1 | function Get-SteamServerInfo { 2 | <# 3 | .SYNOPSIS 4 | Query a running steam based game server. 5 | 6 | .DESCRIPTION 7 | The cmdlet fetches server information from a running game server using UDP/IP packets. 8 | It will return information ServerName, Map, InstallDir, GameName, AppID, Players 9 | MaxPlayers, Bots, ServerType, Environment, Visibility, VAC andVersion. 10 | 11 | .PARAMETER IPAddress 12 | Enter the IP address of the Steam based server. 13 | 14 | .PARAMETER Port 15 | Enter the port number of the Steam based server. 16 | 17 | .PARAMETER Timeout 18 | Timeout in milliseconds before giving up querying the server. 19 | 20 | .EXAMPLE 21 | Get-SteamServerInfo -IPAddress '185.15.73.207' -Port 27015 22 | 23 | ``` 24 | Protocol : 17 25 | ServerName : SAS Proving Ground 10 (EU) 26 | Map : TH-SmallTown 27 | InstallDir : groundbranch 28 | GameName : Ground Branch 29 | AppID : 16900 30 | Players : 6 31 | MaxPlayers : 10 32 | Bots : 0 33 | ServerType : Dedicated 34 | Environment : Windows 35 | Visibility : Public 36 | VAC : Unsecured 37 | Version : 1.0.0.0 38 | ExtraDataFlag : 177 39 | IPAddress : 185.15.73.207 40 | Port : 27015 41 | Ping : 65 42 | ``` 43 | 44 | .NOTES 45 | Author: Jordan Borean, Chris Dent and Frederik Hjorslev Nylander 46 | 47 | .LINK 48 | https://hjorslev.github.io/SteamPS/Get-SteamServerInfo.html 49 | #> 50 | 51 | [CmdletBinding()] 52 | param ( 53 | [Parameter(Mandatory = $true, 54 | HelpMessage = 'Enter the IP address of the Steam based server.')] 55 | [System.Net.IPAddress]$IPAddress, 56 | 57 | [Parameter(Mandatory = $true, 58 | HelpMessage = 'Enter the port number of the Steam based server.')] 59 | [int]$Port, 60 | 61 | [Parameter(Mandatory = $false, 62 | HelpMessage = 'Timeout in milliseconds before giving up querying the server.')] 63 | [int]$Timeout = 5000 64 | ) 65 | 66 | begin { 67 | # A2S_INFO: Retrieves information about the server including, but not limited to: its name, the map currently being played, and the number of players. 68 | # https://developer.valvesoftware.com/wiki/Server_queries#A2S_INFO 69 | $A2S_INFO = [byte]0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x20, 0x45, 0x6E, 0x67, 0x69, 0x6E, 0x65, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x00 70 | } 71 | 72 | process { 73 | try { 74 | # Instantiate client and endpoint 75 | $Client = New-Object -TypeName Net.Sockets.UDPClient(0) 76 | $Client.Client.SendTimeout = $Timeout 77 | $Client.Client.ReceiveTimeout = $Timeout 78 | $IPEndpoint = New-Object -TypeName Net.IPEndpoint([Net.IPAddress]::Any, 0) 79 | $Stopwatch = [System.Diagnostics.Stopwatch]::StartNew() 80 | [void]$Client.Send($A2S_INFO, $A2S_INFO.Length, $IPAddress, $Port) 81 | 82 | # The first 4 bytes are 255 which seems to be some sort of header. 83 | $ReceivedData = $Client.Receive([Ref]$IPEndpoint) | Select-Object -Skip 4 84 | $Ping = $Stopwatch.ElapsedMilliseconds 85 | $Stream = [System.IO.BinaryReader][System.IO.MemoryStream][Byte[]]$ReceivedData 86 | 87 | # Challenge: 88 | if ($Stream.ReadByte() -eq 65) { 89 | # If the response is a challenge, resend query with last 4 bytes of the challenge 90 | $challenge = while ($Stream.BaseStream.Position -lt $Stream.BaseStream.Length) { 91 | $Stream.ReadByte() 92 | } 93 | $newQuery = $A2S_INFO + $challenge 94 | 95 | [void]$Client.Send($newQuery, $newQuery.Length, $IPAddress, $Port) 96 | # The first 4 bytes are 255 which seems to be some sort of header. 97 | $ReceivedData = $Client.Receive([Ref]$IPEndpoint) | Select-Object -Skip 4 98 | $Stream = [System.IO.BinaryReader][System.IO.MemoryStream][Byte[]]$ReceivedData 99 | } else { 100 | $Stream.BaseStream.Position = 0 101 | } 102 | 103 | $Client.Close() 104 | } catch { 105 | $Exception = [Exception]::new("Could not reach server {0}:{1}.") -f $IPAddress, $Port 106 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 107 | $Exception, 108 | "ServerNotFound", 109 | [System.Management.Automation.ErrorCategory]::ConnectionError, 110 | $ReceivedData 111 | ) 112 | $PSCmdlet.WriteError($ErrorRecord) 113 | } 114 | 115 | # If we cannot reach the server we will not display the empty object. 116 | if ($Stream) { 117 | # This is also a header - that will always be equal to 'I' (0x49). 118 | $Stream.ReadByte() | Out-Null 119 | [PSCustomObject]@{ 120 | Protocol = [int]$Stream.ReadByte() 121 | ServerName = Get-PacketString -Stream $Stream 122 | Map = Get-PacketString -Stream $Stream 123 | InstallDir = Get-PacketString -Stream $Stream 124 | GameName = Get-PacketString -Stream $Stream 125 | AppID = [int]$Stream.ReadUInt16() 126 | Players = [int]$Stream.ReadByte() 127 | MaxPlayers = [int]$Stream.ReadByte() 128 | Bots = $Stream.ReadByte() 129 | ServerType = [ServerType]$Stream.ReadByte() 130 | Environment = [OSType]$Stream.ReadByte() 131 | Visibility = [Visibility]$Stream.ReadByte() 132 | VAC = [VAC]$Stream.ReadByte() 133 | Version = Get-PacketString -Stream $Stream 134 | ExtraDataFlag = $Stream.ReadByte() 135 | IPAddress = $IPAddress 136 | Port = $Port 137 | Ping = $Ping 138 | } # PSCustomObject 139 | } 140 | } # Process 141 | } # Cmdlet -------------------------------------------------------------------------------- /docs/Update-SteamServer.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: SteamPS-help.xml 3 | Module Name: SteamPS 4 | online version: https://hjorslev.github.io/SteamPS/Update-SteamServer.html 5 | schema: 2.0.0 6 | --- 7 | 8 | # Update-SteamServer 9 | 10 | ## SYNOPSIS 11 | Update a Steam based game server. 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Update-SteamServer [-AppID] <Int32> [-ServiceName] <String> [-IPAddress] <IPAddress> [-Port] <Int32> 17 | [[-Path] <String>] [[-Credential] <PSCredential>] [[-Arguments] <String>] [[-LogPath] <String>] 18 | [[-DiscordWebhookUri] <String>] [[-AlwaysNotify] <String>] [[-TimeoutLimit] <Int32>] 19 | [-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>] 20 | ``` 21 | 22 | ## DESCRIPTION 23 | This cmdlet presents a workflow to keep a steam based game server up to date. 24 | The server is expecting the game server to be running as a Windows Service. 25 | 26 | ## EXAMPLES 27 | 28 | ### EXAMPLE 1 29 | ``` 30 | Update-SteamServer -AppID 476400 -ServiceName GB-PG10 -IPAddress '185.15.73.207' -Port 27015 31 | ``` 32 | 33 | ## PARAMETERS 34 | 35 | ### -AlwaysNotify 36 | Always receive a notification when a server has been updated. 37 | Default is 38 | only to send on errors. 39 | 40 | ```yaml 41 | Type: String 42 | Parameter Sets: (All) 43 | Aliases: 44 | 45 | Required: False 46 | Position: 10 47 | Default value: None 48 | Accept pipeline input: False 49 | Accept wildcard characters: False 50 | ``` 51 | 52 | ### -AppID 53 | Enter the application ID you wish to install. 54 | 55 | ```yaml 56 | Type: Int32 57 | Parameter Sets: (All) 58 | Aliases: 59 | 60 | Required: True 61 | Position: 1 62 | Default value: 0 63 | Accept pipeline input: False 64 | Accept wildcard characters: False 65 | ``` 66 | 67 | ### -Arguments 68 | Enter any additional arguments here. 69 | 70 | ```yaml 71 | Type: String 72 | Parameter Sets: (All) 73 | Aliases: 74 | 75 | Required: False 76 | Position: 7 77 | Default value: None 78 | Accept pipeline input: False 79 | Accept wildcard characters: False 80 | ``` 81 | 82 | ### -Credential 83 | If the app requires login to install or update, enter your Steam username and password. 84 | 85 | ```yaml 86 | Type: PSCredential 87 | Parameter Sets: (All) 88 | Aliases: 89 | 90 | Required: False 91 | Position: 6 92 | Default value: [System.Management.Automation.PSCredential]::Empty 93 | Accept pipeline input: False 94 | Accept wildcard characters: False 95 | ``` 96 | 97 | ### -DiscordWebhookUri 98 | Enter a Discord Webhook Uri if you wish to get notifications about the server 99 | update. 100 | 101 | ```yaml 102 | Type: String 103 | Parameter Sets: (All) 104 | Aliases: 105 | 106 | Required: False 107 | Position: 9 108 | Default value: None 109 | Accept pipeline input: False 110 | Accept wildcard characters: False 111 | ``` 112 | 113 | ### -IPAddress 114 | Enter the IP address of the Steam based server. 115 | 116 | ```yaml 117 | Type: IPAddress 118 | Parameter Sets: (All) 119 | Aliases: 120 | 121 | Required: True 122 | Position: 3 123 | Default value: None 124 | Accept pipeline input: True (ByPropertyName) 125 | Accept wildcard characters: False 126 | ``` 127 | 128 | ### -LogPath 129 | Specify the directory of the log files. 130 | 131 | ```yaml 132 | Type: String 133 | Parameter Sets: (All) 134 | Aliases: LogLocation 135 | 136 | Required: False 137 | Position: 8 138 | Default value: C:\DedicatedServers\Logs 139 | Accept pipeline input: False 140 | Accept wildcard characters: False 141 | ``` 142 | 143 | ### -Path 144 | Install location of the game server. 145 | 146 | ```yaml 147 | Type: String 148 | Parameter Sets: (All) 149 | Aliases: ApplicationPath 150 | 151 | Required: False 152 | Position: 5 153 | Default value: "C:\DedicatedServers\$ServiceName" 154 | Accept pipeline input: False 155 | Accept wildcard characters: False 156 | ``` 157 | 158 | ### -Port 159 | Enter the port number of the Steam based server. 160 | 161 | ```yaml 162 | Type: Int32 163 | Parameter Sets: (All) 164 | Aliases: 165 | 166 | Required: True 167 | Position: 4 168 | Default value: 0 169 | Accept pipeline input: True (ByPropertyName) 170 | Accept wildcard characters: False 171 | ``` 172 | 173 | ### -ProgressAction 174 | {{ Fill ProgressAction Description }} 175 | 176 | ```yaml 177 | Type: ActionPreference 178 | Parameter Sets: (All) 179 | Aliases: proga 180 | 181 | Required: False 182 | Position: Named 183 | Default value: None 184 | Accept pipeline input: False 185 | Accept wildcard characters: False 186 | ``` 187 | 188 | ### -ServiceName 189 | Specify the Windows Service Name. 190 | You can get a list of services with Get-Service. 191 | 192 | ```yaml 193 | Type: String 194 | Parameter Sets: (All) 195 | Aliases: 196 | 197 | Required: True 198 | Position: 2 199 | Default value: None 200 | Accept pipeline input: False 201 | Accept wildcard characters: False 202 | ``` 203 | 204 | ### -TimeoutLimit 205 | Number of times the cmdlet checks if the server is online or offline. 206 | When 207 | the limit is reached an error is thrown. 208 | 209 | ```yaml 210 | Type: Int32 211 | Parameter Sets: (All) 212 | Aliases: 213 | 214 | Required: False 215 | Position: 11 216 | Default value: 10 217 | Accept pipeline input: False 218 | Accept wildcard characters: False 219 | ``` 220 | 221 | ### -Confirm 222 | Prompts you for confirmation before running the cmdlet. 223 | 224 | ```yaml 225 | Type: SwitchParameter 226 | Parameter Sets: (All) 227 | Aliases: cf 228 | 229 | Required: False 230 | Position: Named 231 | Default value: None 232 | Accept pipeline input: False 233 | Accept wildcard characters: False 234 | ``` 235 | 236 | ### -WhatIf 237 | Shows what would happen if the cmdlet runs. 238 | The cmdlet is not run. 239 | 240 | ```yaml 241 | Type: SwitchParameter 242 | Parameter Sets: (All) 243 | Aliases: wi 244 | 245 | Required: False 246 | Position: Named 247 | Default value: None 248 | Accept pipeline input: False 249 | Accept wildcard characters: False 250 | ``` 251 | 252 | ### CommonParameters 253 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 254 | 255 | ## INPUTS 256 | 257 | ## OUTPUTS 258 | 259 | ## NOTES 260 | Author: Frederik Hjorslev Nylander 261 | 262 | ## RELATED LINKS 263 | 264 | [https://hjorslev.github.io/SteamPS/Update-SteamServer.html](https://hjorslev.github.io/SteamPS/Update-SteamServer.html) 265 | 266 | -------------------------------------------------------------------------------- /docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/) 6 | and this project adheres to [Semantic Versioning](https://semver.org/). 7 | 8 | ## [3.2.1] - 04/04-2021 9 | 10 | - Get-PacketString 11 | - Fixes an issue in `Get-SteamServerInfo` that caused the cmdlet to display an 12 | error when querying a Valheim server ([#41](https://github.com/hjorslev/SteamPS/issues/41)). 13 | Thanks [ThePoShWolf](https://github.com/ThePoShWolf)! 14 | 15 | ## [3.2.0] - 13/09-2020 16 | 17 | ### Added 18 | 19 | - New cmdlets that can interact with the Steam Web API 20 | - Connect-SteamAPI 21 | - Get-SteamFriendList 22 | - Get-SteamNews 23 | - Get-SteamPlayerBan 24 | - Get-SteamPlayerSummary 25 | - Resolve-VanityURL 26 | 27 | ### Changed 28 | 29 | - Logging is now handled using *PSFramework* rather than the module *Logging*. Output 30 | of log files are stored in CSV format with more information about the system etc. 31 | - Get-SteamServerInfo 32 | - Write the error, if the server cannot be reached, instead of throwing it. This 33 | is implemented because if the server could not be reached after using Update-SteamServer, 34 | the workflow would be terminated, the first time the server could not be reached, 35 | instead of attempting to test it again. 36 | 37 | ### Fixed 38 | 39 | - Update-SteamServer 40 | - Fixed issue regarding the log file not being created due to a missing 41 | sub directory preventing any logging until the directory is created ([#29](https://github.com/hjorslev/SteamPS/issues/29)). 42 | - Fixed issue with the update workflow being corrupted if the server were offline 43 | at the beginning of the update ([#30](https://github.com/hjorslev/SteamPS/issues/30)). 44 | - Update-SteamApp 45 | - Remove the validate parameter when calling SteamCMD. Validation will overwrite 46 | any files that have been changed. This may cause issues with customized 47 | servers ([#33](https://github.com/hjorslev/SteamPS/issues/33)). 48 | 49 | ## [3.1.1] - 12/07-2020 50 | 51 | ### Fixed 52 | 53 | - Fix issue with error being thrown when adding SteamCMD location to PATH ([#24](https://github.com/hjorslev/SteamPS/issues/24)). 54 | - Find-SteamAppID 55 | - Fix changed API url. 56 | 57 | ## [3.1.0] - 07/07-2020 58 | 59 | ### Added 60 | 61 | - Update-SteamServer 62 | - Added `-Credential` parameter so apps that requires authentication can be 63 | updated ([#16](https://github.com/hjorslev/SteamPS/issues/16)). 64 | - Update-SteamApp 65 | - Output ExitCode from SteamCMD if it has another value than 0 (success). 66 | 67 | ### Changed 68 | 69 | - Improving structure / format of the code. 70 | - Remove sub-expressions where they are not needed. 71 | - Dependencies are now handled in the module manifest instead of using custom 72 | cmdlet `Use-Module`. 73 | - Update-SteamServer 74 | - Fix minor issue with TimeoutLimit being hardcoded when writing to the log 75 | instead of using the value defined in the parameter `$TimeoutLimit`. 76 | - Update tests to Pester 5. Thanks [Joel Sallow](https://github.com/vexx32/)! 77 | - ModuleValidation - general tests of the module. 78 | - Help - tests that each cmdlet uses Comment Based Help. 79 | 80 | ### Removed 81 | 82 | - Remove private cmdlet Use-Module. 83 | 84 | ## [3.0.0] - 19/05-2020 85 | 86 | ### Fixed 87 | 88 | - Place external help inside module folder instead of the project folder. 89 | 90 | ### Changed 91 | 92 | - Update-SteamServer 93 | - Change parameter ApplicationPath to Path. Set old parameter as an alias. 94 | - Change parameter LogLocation to LogPath. Set old parameter as an alias. 95 | - Get-SteamServerInfo 96 | - The cmdlet now uses Steam server queries to fetch data about the server. Added 97 | new parameters `-IPAddress`, `-Port` and `-Timeout`. Removed parameter `-ServerID` 98 | since the cmdlet is no longer dependent on Rust Server Info. 99 | 100 | ## [2.0.3] - 05/01-2020 101 | 102 | ### Added 103 | 104 | - Update-SteamServer 105 | - Add `Arguments` parameter. 106 | 107 | ## [2.0.2] - 22/12-2019 108 | 109 | ### Changed 110 | 111 | - New workflow with [InvokeBuild](https://github.com/nightroman/Invoke-Build). 112 | - Update-SteamServer 113 | - Changed default to only send Discord notification on errors. Introduce new 114 | parameter `AlwaysNotify` to always send notifications (fix [#3](https://github.com/hjorslev/SteamPS/issues/3)). 115 | 116 | ### Added 117 | 118 | - Update-SteamServer 119 | - Add new parameter `TimeoutLimit` to allow the customization of the timeout. 120 | Default is 10 loops before an error is thrown. 121 | 122 | ## [2.0.1] - 02/09-2019 123 | 124 | ### Fixed 125 | 126 | - Update-SteamApp 127 | - Validate that parameter *Path* does not contain a trailing slash as it breaks 128 | SteamCMD. 129 | 130 | ## [2.0.0] - 05/08-2019 131 | 132 | ### Added 133 | 134 | - Module [Logging](https://www.powershellgallery.com/packages/Logging) is listed 135 | as dependency. 136 | - New cmdlet: Update-SteamServer 137 | - Cmdlet that presents a workflow to keep a Steam based game server up to date. 138 | 139 | ### Changed 140 | 141 | - New workflow with AppVeyor. 142 | - Move `#Requires -RunAsAdministrator` statement from module file to the cmdlets 143 | that requires administrator priviliges (Install-SteamCMD, Update-SteamApp, 144 | Update-SteamServer) allowing some cmdlets to be executed without administrator 145 | priviliges (Find-SteamAppID, Get-SteamServerInfo). 146 | - Use `$env:Path` instead of registry database to handle the install location of 147 | SteamCMD. 148 | 149 | ## [1.2.1] - 17/07-2019 150 | 151 | ### Added 152 | 153 | - Add link to online help for all cmdlets. 154 | - New cmdlet: Get-SteamServerInfo 155 | - Get server information about game servers from [Rust Server Info (RSI)](https://rust-servers.info). 156 | - New-cmdlet: Find-SteamAppID 157 | - Moved functionality from Update-SteamApp into its own cmdlet allowing the 158 | user to use it as a standalone cmdlet as well. 159 | 160 | ### Changed 161 | 162 | - Update-SteamApp 163 | - Change parameter *GameName* to *ApplicationName*. Add *GameName* as an alias 164 | to *ApplicationName*. 165 | 166 | ## [1.2.0] - 02/07-2019 167 | 168 | ### Changed 169 | 170 | - Install-SteamCMD 171 | - Set predefined install path to Program Files in system drive. 172 | - Allow users to choose a custom install path of SteamCMD. 173 | 174 | ## [1.1.3] - 01/03-2019 175 | 176 | ### Fixed 177 | 178 | - Install-SteamCMD 179 | - Fix Undefined Variable 180 | 181 | ## [1.1.0] - 27/01-2019 182 | 183 | ### Changed 184 | 185 | - Split Update-SteamApp into Install-SteamCMD. 186 | 187 | ### Removed 188 | 189 | - Remove temp file with SteamApp IDs. Instead, the newest list is always downloaded. 190 | 191 | ## [1.0.3] - 27/01-2019 192 | 193 | ### Added 194 | 195 | - Add -UseBasicParsing to Invoke-WebRequest in order to support Windows Server Core. 196 | 197 | ## [1.0.2] - 08/01-2019 198 | 199 | ### Removed 200 | 201 | - Remove templates files. 202 | 203 | ### Changed 204 | 205 | - Update documentation. 206 | - Update module description. 207 | 208 | ## [1.0.1] - 01/01-2019 209 | 210 | ### Removed 211 | 212 | - Update-SteamApp 213 | - Remove check for version as it is done in SteamPS.psd1 214 | 215 | ## [1.0.0] - 01/01-2019 216 | 217 | ### Added 218 | 219 | - Initial version 220 | -------------------------------------------------------------------------------- /SteamPS/Public/API/Get-SteamPlayerSummary.ps1: -------------------------------------------------------------------------------- 1 | function Get-SteamPlayerSummary { 2 | <# 3 | .SYNOPSIS 4 | Fetches basic profile information for a list of 64-bit Steam IDs. 5 | 6 | .DESCRIPTION 7 | Fetches basic profile information from the Steam Community. 8 | 9 | .PARAMETER SteamID64 10 | Specifies a comma-separated list of 64-bit Steam IDs to fetch profile information for. Up to 100 Steam IDs can be requested. 11 | 12 | .EXAMPLE 13 | Get-SteamPlayerSummary -SteamID64 76561197960435530, 76561197960434622 14 | 15 | This example fetches profile information for the players with the specified Steam IDs. 16 | 17 | .INPUTS 18 | int64[]: Specifies an array of 64-bit integers representing Steam IDs. 19 | 20 | .OUTPUTS 21 | Returns a custom object with the properties listed below. 22 | 23 | Some data associated with a Steam account may be hidden if the user has their profile visibility set to "Friends Only" or "Private". In that case, only public data will be returned. 24 | 25 | Public Data 26 | - steamid: 64-bit SteamID of the user. 27 | - personaname: The player's persona name (display name). 28 | - profileurl: The full URL of the player's Steam Community profile. 29 | - avatar: The full URL of the player's 32x32px avatar. If the user hasn't configured an avatar, this will be the default ? avatar. 30 | - avatarmedium: The full URL of the player's 64x64px avatar. If the user hasn't configured an avatar, this will be the default ? avatar. 31 | - avatarfull: The full URL of the player's 184x184px avatar. If the user hasn't configured an avatar, this will be the default ? avatar. 32 | - personastate: The user's current status. 0 - Offline, 1 - Online, 2 - Busy, 3 - Away, 4 - Snooze, 5 - looking to trade, 6 - looking to play. If the player's profile is private, this will always be "0", except if the user has set their status to looking to trade or looking to play, because a bug makes those status appear even if the profile is private. 33 | - communityvisibilitystate: This represents whether the profile is visible or not, and if it is visible, why you are allowed to see it. Note that because this WebAPI does not use authentication, there are only two possible values returned: 1 - the profile is not visible to you (Private, Friends Only, etc), 3 - the profile is "Public", and the data is visible. Mike Blaszczak's post on Steam forums says, "The community visibility state this API returns is different than the privacy state. It's the effective visibility state from the account making the request to the account being viewed given the requesting account's relationship to the viewed account." 34 | - profilestate: If set, indicates the user has a community profile configured (will be set to '1') 35 | - lastlogoff: The last time the user was online, in unix time. Only available when you are friends with the requested user (since Feb, 4). 36 | - commentpermission: If set, indicates the profile allows public comments. 37 | 38 | Private Data 39 | - realname: The player's "Real Name", if they have set it. 40 | - primaryclanid: The player's primary group, as configured in their Steam Community profile. 41 | - timecreated: The time the player's account was created. 42 | - gameid: If the user is currently in-game, this value will be returned and set to the gameid of that game. 43 | - gameserverip: The ip and port of the game server the user is currently playing on, if they are playing on-line in a game using Steam matchmaking. Otherwise will be set to "0.0.0.0:0". 44 | - gameextrainfo: If the user is currently in-game, this will be the name of the game they are playing. This may be the name of a non-Steam game shortcut. 45 | - cityid: This value will be removed in a future update (see loccityid) 46 | - loccountrycode: If set on the user's Steam Community profile, The user's country of residence, 2-character ISO country code 47 | - locstatecode: If set on the user's Steam Community profile, The user's state of residence 48 | - loccityid: An internal code indicating the user's city of residence. A future update will provide this data in a more useful way. steam_location gem/package makes player location data readable for output. 49 | 50 | .NOTES 51 | Author: Frederik Hjorslev Nylander 52 | 53 | .LINK 54 | https://hjorslev.github.io/SteamPS/Get-SteamPlayerSummary.html 55 | #> 56 | 57 | [CmdletBinding()] 58 | param ( 59 | [Parameter(Mandatory = $true, 60 | HelpMessage = '64 bit Steam ID to return player summary for.', 61 | ValueFromPipelineByPropertyName = $true)] 62 | [int64[]]$SteamID64 63 | ) 64 | 65 | begin { 66 | Write-Verbose -Message "[BEGIN ] Starting: $($MyInvocation.MyCommand)" 67 | } 68 | 69 | process { 70 | $Request = Invoke-RestMethod -Uri 'https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2' -UseBasicParsing -Body @{ 71 | key = Get-SteamAPIKey 72 | steamids = ($SteamID64 -join ',') 73 | } 74 | 75 | if ($Request.response.players) { 76 | foreach ($Item in $Request.response.players) { 77 | [PSCustomObject]@{ 78 | SteamID64 = $Item.steamid 79 | PersonaName = $Item.personaname 80 | ProfileUrl = $Item.profileurl 81 | Avatar = $Item.avatar 82 | AvatarMedium = $Item.avatarmedium 83 | AvatarFull = $Item.avatarfull 84 | AvatarHash = $Item.avatarhash 85 | PersonaState = [PersonaState]$Item.personastate 86 | CommunityVisibilityState = [CommunityVisibilityState]$Item.communityvisibilitystate 87 | ProfileState = $Item.profilestate 88 | LastLogOff = ((Get-Date "01.01.1970") + ([System.TimeSpan]::FromSeconds($Item.lastlogoff))).ToString("yyyy-MM-dd HH:mm:ss") 89 | CommentPermission = $Item.commentpermission 90 | RealName = $Item.realname 91 | PrimaryClanID = $Item.primaryclanid 92 | TimeCreated = ((Get-Date "01.01.1970") + ([System.TimeSpan]::FromSeconds($Item.timecreated))).ToString("yyyy-MM-dd HH:mm:ss") 93 | AppID = $Item.gameid 94 | GameServerIP = [ipaddress]$Item.gameserverip 95 | GameExtraInfo = $Item.gameextrainfo 96 | PersonaStateFlags = $Item.personastateflags 97 | LocCountryCode = $Item.loccountrycode 98 | LocStateCode = $Item.locstatecode 99 | LocCityID = $Item.loccityid 100 | } 101 | } 102 | } elseif ($Request.response.players.Length -eq 0) { 103 | $Exception = [Exception]::new("SteamID $SteamID64 couldn't be found.") 104 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 105 | $Exception, 106 | 'NoPlayerFound', 107 | [System.Management.Automation.ErrorCategory]::ObjectNotFound, 108 | $Request 109 | ) 110 | $PSCmdlet.WriteError($ErrorRecord) 111 | } 112 | } # Process 113 | 114 | end { 115 | Write-Verbose -Message "[END ] Ending: $($MyInvocation.MyCommand)" 116 | } 117 | } -------------------------------------------------------------------------------- /SteamPS.build.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [ValidateSet('Debug', 'Release')] 4 | [string] $Configuration = 'Debug' 5 | ) 6 | 7 | $script:SteamPSModulePath = [IO.Path]::Combine($PSScriptRoot, 'SteamPS') 8 | $manifestItem = Get-Item ([IO.Path]::Combine($SteamPSModulePath, '*.psd1')) 9 | $ModuleName = $manifestItem.BaseName 10 | $psm1 = Join-Path $SteamPSModulePath -ChildPath ($ModuleName + '.psm1') 11 | 12 | $testModuleManifestSplat = @{ 13 | Path = $manifestItem.FullName 14 | ErrorAction = 'Ignore' 15 | WarningAction = 'Ignore' 16 | } 17 | 18 | $Manifest = Test-ModuleManifest @testModuleManifestSplat 19 | $ReleaseVersion = $env:GITHUB_REF -replace '^refs/tags/v(\d+\.\d+\.\d+)', '$1' 20 | 21 | if ($Configuration -eq 'Release') { 22 | $Version = $ReleaseVersion 23 | } else { 24 | $Version = $Manifest.Version 25 | } 26 | 27 | $BuildPath = [IO.Path]::Combine($PSScriptRoot, 'output') 28 | $CSharpPath = [IO.Path]::Combine($PSScriptRoot, 'src', $ModuleName) 29 | $isBinaryModule = Test-Path $CSharpPath 30 | $ReleasePath = [IO.Path]::Combine($BuildPath, $ModuleName, $Version) 31 | $UseNativeArguments = $PSVersionTable.PSVersion -gt '7.0' 32 | 33 | task Clean { 34 | if (Test-Path $ReleasePath) { 35 | Remove-Item $ReleasePath -Recurse -Force 36 | } 37 | 38 | New-Item -ItemType Directory $ReleasePath | Out-Null 39 | } 40 | 41 | task BuildDocs { 42 | $helpParams = @{ 43 | Path = [IO.Path]::Combine($PSScriptRoot, 'docs', 'en-US') 44 | OutputPath = [IO.Path]::Combine($ReleasePath, 'en-US') 45 | } 46 | New-ExternalHelp @helpParams | Out-Null 47 | } 48 | 49 | task BuildPowerShell { 50 | $buildModuleSplat = @{ 51 | SourcePath = $SteamPSModulePath 52 | OutputDirectory = $ReleasePath 53 | Encoding = 'UTF8Bom' 54 | IgnoreAlias = $true 55 | } 56 | 57 | if ($Configuration -eq 'Release') { 58 | $buildModuleSplat['SemVer'] = $ReleaseVersion 59 | } 60 | 61 | if (Test-Path $psm1) { 62 | $buildModuleSplat['Suffix'] = Get-Content $psm1 -Raw 63 | } 64 | 65 | Build-Module @buildModuleSplat 66 | } 67 | 68 | task BuildManaged { 69 | if (-not $isBinaryModule) { 70 | Write-Host 'No C# source path found. Skipping BuildManaged...' 71 | return 72 | } 73 | 74 | $arguments = @( 75 | 'publish' 76 | '--configuration', $Configuration 77 | '--verbosity', 'q' 78 | '-nologo' 79 | "-p:Version=$Version" 80 | ) 81 | 82 | Push-Location -LiteralPath $CSharpPath 83 | try { 84 | foreach ($framework in $TargetFrameworks) { 85 | Write-Host "Compiling for $framework" 86 | dotnet @arguments --framework $framework 87 | 88 | if ($LASTEXITCODE) { 89 | throw "Failed to compiled code for $framework" 90 | } 91 | } 92 | } finally { 93 | Pop-Location 94 | } 95 | } 96 | 97 | task CopyToRelease { 98 | foreach ($framework in $TargetFrameworks) { 99 | $buildFolder = [IO.Path]::Combine($CSharpPath, 'bin', $Configuration, $framework, 'publish') 100 | $binFolder = [IO.Path]::Combine($ReleasePath, 'bin', $framework, $_.Name) 101 | if (-not (Test-Path -LiteralPath $binFolder)) { 102 | New-Item -Path $binFolder -ItemType Directory | Out-Null 103 | } 104 | Copy-Item ([IO.Path]::Combine($buildFolder, '*')) -Destination $binFolder -Recurse 105 | } 106 | } 107 | 108 | task Package { 109 | $nupkgPath = [IO.Path]::Combine($BuildPath, "$ModuleName.$Version*.nupkg") 110 | if (Test-Path $nupkgPath) { 111 | Remove-Item $nupkgPath -Force 112 | } 113 | 114 | $repoParams = @{ 115 | Name = 'LocalRepo' 116 | SourceLocation = $BuildPath 117 | PublishLocation = $BuildPath 118 | InstallationPolicy = 'Trusted' 119 | } 120 | 121 | if (Get-PSRepository -Name $repoParams.Name -ErrorAction SilentlyContinue) { 122 | Unregister-PSRepository -Name $repoParams.Name 123 | } 124 | 125 | Register-PSRepository @repoParams 126 | 127 | try { 128 | Publish-Module -Path $ReleasePath -Repository $repoParams.Name 129 | } finally { 130 | Unregister-PSRepository -Name $repoParams.Name 131 | } 132 | } 133 | 134 | task Analyze { 135 | $analyzerPath = [IO.Path]::Combine($PSScriptRoot, 'PSScriptAnalyzerSettings.psd1') 136 | if (-not (Test-Path $analyzerPath)) { 137 | Write-Host 'No analyzer rules found, skipping...' 138 | return 139 | } 140 | 141 | $pssaSplat = @{ 142 | Path = $ReleasePath 143 | Settings = [IO.Path]::Combine($PSScriptRoot, 'PSScriptAnalyzerSettings.psd1') 144 | Recurse = $true 145 | ErrorAction = 'SilentlyContinue' 146 | } 147 | $results = Invoke-ScriptAnalyzer @pssaSplat 148 | 149 | if ($null -ne $results) { 150 | $results | Out-String 151 | throw 'Failed PsScriptAnalyzer tests, build failed' 152 | } 153 | } 154 | 155 | task DoUnitTest { 156 | $testsPath = [IO.Path]::Combine($PSScriptRoot, 'Tests', 'units') 157 | if (-not (Test-Path -LiteralPath $testsPath)) { 158 | Write-Host 'No unit tests found, skipping...' 159 | return 160 | } 161 | 162 | $resultsPath = [IO.Path]::Combine($BuildPath, 'TestResults') 163 | if (-not (Test-Path -LiteralPath $resultsPath)) { 164 | New-Item $resultsPath -ItemType Directory -ErrorAction Stop | Out-Null 165 | } 166 | 167 | $tempResultsPath = [IO.Path]::Combine($resultsPath, 'TempUnit') 168 | if (Test-Path -LiteralPath $tempResultsPath) { 169 | Remove-Item -LiteralPath $tempResultsPath -Force -Recurse 170 | } 171 | New-Item -Path $tempResultsPath -ItemType Directory | Out-Null 172 | 173 | try { 174 | $runSettingsPrefix = 'DataCollectionRunSettings.DataCollectors.DataCollector.Configuration' 175 | $arguments = @( 176 | 'test' 177 | $testsPath 178 | '--results-directory', $tempResultsPath 179 | if ($Configuration -eq 'Debug') { 180 | '--collect:"XPlat Code Coverage"' 181 | '--' 182 | "$runSettingsPrefix.Format=json" 183 | if ($UseNativeArguments) { 184 | "$runSettingsPrefix.IncludeDirectory=`"$CSharpPath`"" 185 | } else { 186 | "$runSettingsPrefix.IncludeDirectory=\`"$CSharpPath\`"" 187 | } 188 | } 189 | ) 190 | 191 | Write-Host 'Running unit tests' 192 | dotnet @arguments 193 | 194 | if ($LASTEXITCODE) { 195 | throw 'Unit tests failed' 196 | } 197 | 198 | if ($Configuration -eq 'Debug') { 199 | Move-Item -Path $tempResultsPath/*/*.json -Destination $resultsPath/UnitCoverage.json -Force 200 | } 201 | } finally { 202 | Remove-Item -LiteralPath $tempResultsPath -Force -Recurse 203 | } 204 | } 205 | 206 | task DoTest { 207 | $testsPath = [IO.Path]::Combine($PSScriptRoot, 'Tests') 208 | if (-not (Test-Path $testsPath)) { 209 | Write-Host 'No Pester tests found, skipping...' 210 | return 211 | } 212 | 213 | $resultsPath = [IO.Path]::Combine($BuildPath, 'TestResults') 214 | if (-not (Test-Path $resultsPath)) { 215 | New-Item $resultsPath -ItemType Directory -ErrorAction Stop | Out-Null 216 | } 217 | 218 | Get-ChildItem -LiteralPath $resultsPath | 219 | Remove-Item -ErrorAction Stop -Force 220 | 221 | $pesterScript = [IO.Path]::Combine($PSScriptRoot, 'tools', 'PesterTest.ps1') 222 | 223 | $testArgs = @{ 224 | TestPath = $testsPath 225 | ResultPath = $resultsPath 226 | SourceRoot = $SteamPSModulePath 227 | ReleasePath = $ReleasePath 228 | } 229 | 230 | & $pesterScript @testArgs 231 | } 232 | 233 | task Build -Jobs Clean, BuildManaged, BuildPowerShell, CopyToRelease, BuildDocs, Package 234 | task Test -Jobs BuildManaged, Analyze, DoUnitTest, DoTest 235 | task . Build 236 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/) 6 | and this project adheres to [Semantic Versioning](https://semver.org/). 7 | 8 | ## [3.2.3] - 14/05-2022 9 | 10 | ### Fixed 11 | 12 | - Get-SteamServerInfo 13 | - Fixes name property in output when no challenge is sent. Thanks [ThePoShWolf](https://github.com/ThePoShWolf)! 14 | 15 | ## [3.2.2] - 13/05-2022 16 | 17 | Please note there were a minor error in Get-SteamServerInfo in this version. 18 | Therefore, 3.2.2 has been hidden in the PowerShell Gallery. 19 | 20 | ### Fixed 21 | 22 | - Get-SteamServerInfo 23 | - Support the server challenge request (Linux based servers) ([#47](https://github.com/hjorslev/SteamPS/issues/47)). 24 | Thanks [ThePoShWolf](https://github.com/ThePoShWolf)! 25 | - Update-SteamApp 26 | - Fix a warning SteamCMD displays about the force_install_dir parameter needs to 27 | be called prior to the login parameter. 28 | 29 | ## [3.2.1] - 04/04-2021 30 | 31 | ### Fixe3 32 | 33 | - Get-PacketString 34 | - Fixes an issue in `Get-SteamServerInfo` that caused the cmdlet to display an 35 | error when querying a Valheim server ([#41](https://github.com/hjorslev/SteamPS/issues/41)). 36 | Thanks [ThePoShWolf](https://github.com/ThePoShWolf)! 37 | 38 | ## [3.2.0] - 13/09-2020 39 | 40 | ### Added 41 | 42 | - New cmdlets that can interact with the Steam Web API 43 | - Connect-SteamAPI 44 | - Get-SteamFriendList 45 | - Get-SteamNews 46 | - Get-SteamPlayerBan 47 | - Get-SteamPlayerSummary 48 | - Resolve-VanityURL 49 | 50 | ### Changed 51 | 52 | - Logging is now handled using *PSFramework* rather than the module *Logging*. Output 53 | of log files are stored in CSV format with more information about the system etc. 54 | - Get-SteamServerInfo 55 | - Write the error, if the server cannot be reached, instead of throwing it. This 56 | is implemented because if the server could not be reached after using Update-SteamServer, 57 | the workflow would be terminated, the first time the server could not be reached, 58 | instead of attempting to test it again. 59 | 60 | ### Fixed 61 | 62 | - Update-SteamServer 63 | - Fixed issue regarding the log file not being created due to a missing 64 | sub directory preventing any logging until the directory is created ([#29](https://github.com/hjorslev/SteamPS/issues/29)). 65 | - Fixed issue with the update workflow being corrupted if the server were offline 66 | at the beginning of the update ([#30](https://github.com/hjorslev/SteamPS/issues/30)). 67 | - Update-SteamApp 68 | - Remove the validate parameter when calling SteamCMD. Validation will overwrite 69 | any files that have been changed. This may cause issues with customized 70 | servers ([#33](https://github.com/hjorslev/SteamPS/issues/33)). 71 | 72 | ## [3.1.1] - 12/07-2020 73 | 74 | ### Fixed 75 | 76 | - Fix issue with error being thrown when adding SteamCMD location to PATH ([#24](https://github.com/hjorslev/SteamPS/issues/24)). 77 | - Find-SteamAppID 78 | - Fix changed API url. 79 | 80 | ## [3.1.0] - 07/07-2020 81 | 82 | ### Added 83 | 84 | - Update-SteamServer 85 | - Added `-Credential` parameter so apps that requires authentication can be 86 | updated ([#16](https://github.com/hjorslev/SteamPS/issues/16)). 87 | - Update-SteamApp 88 | - Output ExitCode from SteamCMD if it has another value than 0 (success). 89 | 90 | ### Changed 91 | 92 | - Improving structure / format of the code. 93 | - Remove sub-expressions where they are not needed. 94 | - Dependencies are now handled in the module manifest instead of using custom 95 | cmdlet `Use-Module`. 96 | - Update-SteamServer 97 | - Fix minor issue with TimeoutLimit being hardcoded when writing to the log 98 | instead of using the value defined in the parameter `$TimeoutLimit`. 99 | - Update tests to Pester 5. Thanks [Joel Sallow](https://github.com/vexx32/)! 100 | - ModuleValidation - general tests of the module. 101 | - Help - tests that each cmdlet uses Comment Based Help. 102 | 103 | ### Removed 104 | 105 | - Remove private cmdlet Use-Module. 106 | 107 | ## [3.0.0] - 19/05-2020 108 | 109 | ### Fixed 110 | 111 | - Place external help inside module folder instead of the project folder. 112 | 113 | ### Changed 114 | 115 | - Update-SteamServer 116 | - Change parameter ApplicationPath to Path. Set old parameter as an alias. 117 | - Change parameter LogLocation to LogPath. Set old parameter as an alias. 118 | - Get-SteamServerInfo 119 | - The cmdlet now uses Steam server queries to fetch data about the server. Added 120 | new parameters `-IPAddress`, `-Port` and `-Timeout`. Removed parameter `-ServerID` 121 | since the cmdlet is no longer dependent on Rust Server Info. 122 | 123 | ## [2.0.3] - 05/01-2020 124 | 125 | ### Added 126 | 127 | - Update-SteamServer 128 | - Add `Arguments` parameter. 129 | 130 | ## [2.0.2] - 22/12-2019 131 | 132 | ### Changed 133 | 134 | - New workflow with [InvokeBuild](https://github.com/nightroman/Invoke-Build). 135 | - Update-SteamServer 136 | - Changed default to only send Discord notification on errors. Introduce new 137 | parameter `AlwaysNotify` to always send notifications (fix [#3](https://github.com/hjorslev/SteamPS/issues/3)). 138 | 139 | ### Added 140 | 141 | - Update-SteamServer 142 | - Add new parameter `TimeoutLimit` to allow the customization of the timeout. 143 | Default is 10 loops before an error is thrown. 144 | 145 | ## [2.0.1] - 02/09-2019 146 | 147 | ### Fixed 148 | 149 | - Update-SteamApp 150 | - Validate that parameter *Path* does not contain a trailing slash as it breaks 151 | SteamCMD. 152 | 153 | ## [2.0.0] - 05/08-2019 154 | 155 | ### Added 156 | 157 | - Module [Logging](https://www.powershellgallery.com/packages/Logging) is listed 158 | as dependency. 159 | - New cmdlet: Update-SteamServer 160 | - Cmdlet that presents a workflow to keep a Steam based game server up to date. 161 | 162 | ### Changed 163 | 164 | - New workflow with AppVeyor. 165 | - Move `#Requires -RunAsAdministrator` statement from module file to the cmdlets 166 | that requires administrator privileges (Install-SteamCMD, Update-SteamApp, 167 | Update-SteamServer) allowing some cmdlets to be executed without administrator 168 | privileges (Find-SteamAppID, Get-SteamServerInfo). 169 | - Use `$env:Path` instead of registry database to handle the install location of 170 | SteamCMD. 171 | 172 | ## [1.2.1] - 17/07-2019 173 | 174 | ### Added 175 | 176 | - Add link to online help for all cmdlets. 177 | - New cmdlet: Get-SteamServerInfo 178 | - Get server information about game servers from [Rust Server Info (RSI)](https://rust-servers.info). 179 | - New-cmdlet: Find-SteamAppID 180 | - Moved functionality from Update-SteamApp into its own cmdlet allowing the 181 | user to use it as a standalone cmdlet as well. 182 | 183 | ### Changed 184 | 185 | - Update-SteamApp 186 | - Change parameter *GameName* to *ApplicationName*. Add *GameName* as an alias 187 | to *ApplicationName*. 188 | 189 | ## [1.2.0] - 02/07-2019 190 | 191 | ### Changed 192 | 193 | - Install-SteamCMD 194 | - Set predefined install path to Program Files in system drive. 195 | - Allow users to choose a custom install path of SteamCMD. 196 | 197 | ## [1.1.3] - 01/03-2019 198 | 199 | ### Fixed 200 | 201 | - Install-SteamCMD 202 | - Fix Undefined Variable 203 | 204 | ## [1.1.0] - 27/01-2019 205 | 206 | ### Changed 207 | 208 | - Split Update-SteamApp into Install-SteamCMD. 209 | 210 | ### Removed 211 | 212 | - Remove temp file with SteamApp IDs. Instead, the newest list is always downloaded. 213 | 214 | ## [1.0.3] - 27/01-2019 215 | 216 | ### Added 217 | 218 | - Add -UseBasicParsing to Invoke-WebRequest in order to support Windows Server Core. 219 | 220 | ## [1.0.2] - 08/01-2019 221 | 222 | ### Removed 223 | 224 | - Remove templates files. 225 | 226 | ### Changed 227 | 228 | - Update documentation. 229 | - Update module description. 230 | 231 | ## [1.0.1] - 01/01-2019 232 | 233 | ### Removed 234 | 235 | - Update-SteamApp 236 | - Remove check for version as it is done in SteamPS.psd1 237 | 238 | ## [1.0.0] - 01/01-2019 239 | 240 | ### Added 241 | 242 | - Initial version 243 | -------------------------------------------------------------------------------- /SteamPS/Public/Server/Update-SteamApp.ps1: -------------------------------------------------------------------------------- 1 | function Update-SteamApp { 2 | <# 3 | .SYNOPSIS 4 | Install or update a Steam application using SteamCMD. 5 | 6 | .DESCRIPTION 7 | Install or update a Steam application using SteamCMD. If SteamCMD is missing, it will be installed first. 8 | You can either search for the application by name or enter the specific Application ID. 9 | 10 | .PARAMETER ApplicationName 11 | Enter the name of the app to make a wildcard search for the application. 12 | 13 | .PARAMETER ApplicationID 14 | Enter the application ID you wish to install. 15 | 16 | .PARAMETER Credential 17 | If the app requires login to install or update, enter your Steam username and password. 18 | 19 | .PARAMETER Path 20 | Path to installation folder. 21 | 22 | .PARAMETER Arguments 23 | Enter any additional arguments here. 24 | 25 | Beware, the following arguments are already used: 26 | 27 | If you use Steam login to install/upload the app the following arguments are already used: "+force_install_dir $Path +login $SteamUserName $SteamPassword +app_update $SteamAppID $Arguments +quit" 28 | 29 | If you use anonymous login to install/upload the app the following arguments are already used: "+force_install_dir $Path +login anonymous +app_update $SteamAppID $Arguments +quit" 30 | 31 | .PARAMETER Force 32 | The Force parameter allows the user to skip the "Should Continue" box. 33 | 34 | .EXAMPLE 35 | Update-SteamApp -ApplicationName 'Arma 3' -Credential 'Toby' -Path 'C:\DedicatedServers\Arma3' 36 | 37 | Because there are multiple hits when searching for Arma 3, the user will be promted to select the right application. 38 | 39 | .EXAMPLE 40 | Update-SteamApp -AppID 376030 -Path 'C:\DedicatedServers\ARK-SurvivalEvolved' 41 | 42 | Here we use anonymous login because the particular application (ARK: Survival Evolved Dedicated Server) doesn't require login. 43 | 44 | .NOTES 45 | Author: Frederik Hjorslev Nylander 46 | 47 | SteamCMD CLI parameters: https://developer.valvesoftware.com/wiki/Command_Line_Options#Command-line_parameters_4 48 | 49 | .LINK 50 | https://hjorslev.github.io/SteamPS/Update-SteamApp.html 51 | #> 52 | 53 | [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '', Justification='Is implemented but not accepted by PSSA.')] 54 | [CmdletBinding(SupportsShouldProcess = $true, 55 | ConfirmImpact = 'Medium' 56 | )] 57 | param ( 58 | [Parameter(Position = 0, 59 | Mandatory = $true, 60 | ValueFromPipelineByPropertyName = $true, 61 | ParameterSetName = 'ApplicationName' 62 | )] 63 | [Alias('GameName')] 64 | [string]$ApplicationName, 65 | 66 | [Parameter(Position = 0, 67 | Mandatory = $true, 68 | ValueFromPipelineByPropertyName = $true, 69 | ParameterSetName = 'ApplicationID' 70 | )] 71 | [ValidateScript({ 72 | if ($null -eq (Get-SteamApp -ApplicationID $_)) { 73 | Write-Verbose -Message "ApplicationID $_ couldn't be found using the Steam Web API. Continuing anyway as the application might exist." 74 | } 75 | $true 76 | })] 77 | [Alias('AppID')] 78 | [int]$ApplicationID, 79 | 80 | [Parameter(Mandatory = $true)] 81 | [ValidateScript( { 82 | if ($_.Substring(($_.Length -1)) -eq '\') { 83 | throw "Path may not end with a trailing slash." 84 | } 85 | $true 86 | })] 87 | [string]$Path, 88 | 89 | [Parameter(Mandatory = $false)] 90 | [ValidateNotNull()] 91 | [System.Management.Automation.PSCredential] 92 | [System.Management.Automation.Credential()] 93 | $Credential = [System.Management.Automation.PSCredential]::Empty, 94 | 95 | [Parameter(Mandatory = $false)] 96 | [string]$Arguments, 97 | 98 | [Parameter(Mandatory = $false)] 99 | [switch]$Force 100 | ) 101 | 102 | begin { 103 | if ($null -eq (Get-SteamPath)) { 104 | throw 'SteamCMD could not be found in the env:Path. Have you executed Install-SteamCMD?' 105 | } 106 | 107 | # Install SteamCMD if it is missing. 108 | if (-not (Test-Path -Path (Get-SteamPath).Executable)) { 109 | Start-Process powershell -ArgumentList '-NoExit -Command "Install-SteamCMD; exit"' -Verb RunAs 110 | Write-Verbose -Message 'Installing SteamCMD in another window. Please wait and try again.' 111 | throw "SteamCMD is missing and is being installed in another window. Please wait until the other window closes, restart your console, and try again." 112 | } 113 | } # Begin 114 | 115 | process { 116 | function Use-SteamCMD ($SteamAppID) { 117 | # If Steam username and Steam password are not empty we use them for logging in. 118 | if ($null -ne $Credential.UserName) { 119 | Write-Verbose -Message "Logging into Steam as $($Credential | Select-Object -ExpandProperty UserName)." 120 | $SteamCMDProcess = Start-Process -FilePath (Get-SteamPath).Executable -NoNewWindow -ArgumentList "+force_install_dir `"$Path`" +login $($Credential.UserName) $($Credential.GetNetworkCredential().Password) +app_update $SteamAppID $Arguments +quit" -Wait -PassThru 121 | if ($SteamCMDProcess.ExitCode -ne 0) { 122 | Write-Error -Message ("SteamCMD closed with ExitCode {0}" -f $SteamCMDProcess.ExitCode) -Category CloseError 123 | } 124 | } 125 | # If Steam username and Steam password are empty we use anonymous login. 126 | elseif ($null -eq $Credential.UserName) { 127 | Write-Verbose -Message 'Using SteamCMD as anonymous.' 128 | $SteamCMDProcess = Start-Process -FilePath (Get-SteamPath).Executable -NoNewWindow -ArgumentList "+force_install_dir `"$Path`" +login anonymous +app_update $SteamAppID $Arguments +quit" -Wait -PassThru 129 | if ($SteamCMDProcess.ExitCode -ne 0) { 130 | Write-Error -Message ("SteamCMD closed with ExitCode {0}" -f $SteamCMDProcess.ExitCode) -Category CloseError 131 | } 132 | } 133 | } 134 | 135 | # If game is found by searching for game name. 136 | if ($PSCmdlet.ParameterSetName -eq 'ApplicationName') { 137 | try { 138 | $SteamApp = Get-SteamApp -ApplicationName $ApplicationName 139 | # Install selected Steam application if a SteamAppID has been selected. 140 | if (-not ($null -eq $SteamApp)) { 141 | if ($Force -or $PSCmdlet.ShouldContinue("Do you want to install or update $($SteamApp.ApplicationName)?", "Update SteamApp $($SteamApp.ApplicationName)?")) { 142 | Write-Verbose -Message "The application $($SteamApp.ApplicationName) is being updated. Please wait for SteamCMD to finish." 143 | Use-SteamCMD -SteamAppID $SteamApp.ApplicationID 144 | } # Should Continue 145 | } 146 | } catch { 147 | Throw "$ApplicationName couldn't be updated." 148 | } 149 | } # ParameterSet ApplicationName 150 | 151 | # If game is found by using a unique ApplicationID. 152 | if ($PSCmdlet.ParameterSetName -eq 'ApplicationID') { 153 | try { 154 | $SteamAppID = $ApplicationID 155 | # Install selected Steam application. 156 | if ($Force -or $PSCmdlet.ShouldContinue("Do you want to install or update $($SteamAppID)?", "Update SteamApp $($SteamAppID)?")) { 157 | Write-Verbose -Message "The application with AppID $SteamAppID is being updated. Please wait for SteamCMD to finish." 158 | Use-SteamCMD -SteamAppID $SteamAppID 159 | } # Should Continue 160 | } catch { 161 | Throw "$SteamAppID couldn't be updated." 162 | } 163 | } # ParameterSet AppID 164 | } # Process 165 | } # Cmdlet -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SteamPS 2 | 3 | <img align="right" width="150" src="assets/images/SteamPS-icon.svg"> 4 | 5 | | GH Actions | Codecov | PS Gallery | 6 | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | 7 | | [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/hjorslev/SteamPS/CI.yml?logo=GitHub&label=CI%2FCD)](https://github.com/hjorslev/SteamPS/actions/workflows/CI.yml) | [![Codecov (with branch)](https://img.shields.io/codecov/c/github/hjorslev/SteamPS/master)](https://app.codecov.io/gh/hjorslev/SteamPS) | [![PowerShell Gallery](https://img.shields.io/powershellgallery/dt/SteamPS?style=flat&logo=PowerShell)](https://www.powershellgallery.com/packages/SteamPS) | 8 | 9 | - [SteamPS](#steamps) 10 | - [Introduction](#introduction) 11 | - [Command Reference](#command-reference) 12 | - [Prerequisites](#prerequisites) 13 | - [Getting Started](#getting-started) 14 | - [Install from PowerShell Gallery](#install-from-powershell-gallery) 15 | - [Usage](#usage) 16 | - [Update single app / game server](#update-single-app--game-server) 17 | - [Install / Update using ApplicationName](#install--update-using-applicationname) 18 | - [Install / Update using AppID](#install--update-using-appid) 19 | - [Authenticating](#authenticating) 20 | - [Update Steam server automatically](#update-steam-server-automatically) 21 | 22 | ## Introduction 23 | 24 | SteamPS is a [PowerShell module](https://github.com/PowerShell/PowerShell/) that utilizes PowerShell as a wrapper for [SteamCMD](https://developer.valvesoftware.com/wiki/SteamCMD) and interacts with various [Steam APIs](https://steamcommunity.com/dev). 25 | 26 | SteamPS is aimed at server administrators maintaining one or more servers. It can 27 | be used to install SteamCMD, update game servers, query Steam based game servers 28 | for server information and more. 29 | 30 | ## Command Reference 31 | 32 | | Cmdlet | Description | 33 | | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | 34 | | [Connect-SteamAPI](docs/Connect-SteamAPI.md) | Create or update the Steam Web API config file. | 35 | | [Disconnect-SteamAPI](docs/Disconnect-SteamAPI.md) | Disconnects from the Steam API by removing the stored API key. | 36 | | [Get-SteamApp](docs/Get-SteamApp.md) | Retrieves the name and ID of a Steam application by searching the name or ID of the application. | 37 | | [Get-SteamFriendList](docs/Get-SteamFriendList.md) | Returns the friend list of any Steam user. | 38 | | [Get-SteamNews](docs/Get-SteamNews.md) | Returns the latest news of a game. | 39 | | [Get-SteamPlayerBan](docs/Get-SteamPlayerBan.md) | Returns Community, VAC, and Economy ban statuses for any given players. | 40 | | [Get-SteamPlayerSummary](docs/Get-SteamPlayerSummary.md) | Returns basic profile information for a list of 64-bit Steam IDs. | 41 | | [Get-SteamServerInfo](docs/Get-SteamServerInfo.md) | Query a running Steam based game server. | 42 | | [Install-SteamCMD](docs/Install-SteamCMD.md) | Downloads and installs SteamCMD. | 43 | | [Resolve-VanityURL](docs/Resolve-VanityURL.md) | Resolve a vanity URL (also named custom URL). | 44 | | [Update-SteamApp](docs/Update-SteamApp.md) | Install or update a Steam application using SteamCMD. | 45 | | [Update-SteamServer](docs/Update-SteamServer.md) | Update a Steam based game server through a workflow. | 46 | 47 | ## Prerequisites 48 | 49 | - Windows based OS 50 | - Windows PowerShell 5.1 / PowerShell 7. 51 | 52 | You can find your version of PowerShell by using: 53 | 54 | ```powershell 55 | $PSVersionTable.PSVersion 56 | ``` 57 | 58 | ## Getting Started 59 | 60 | ### Install from PowerShell Gallery 61 | 62 | The module is published in the [PowerShell Gallery](https://www.powershellgallery.com/packages/SteamPS). 63 | 64 | Run the following in an elevated prompt to install the module globally for all 65 | users on the server: 66 | 67 | ```powershell 68 | Install-Module -Name SteamPS 69 | ``` 70 | 71 | The module can also be installed in the current user's scope by adding 72 | `-Scope CurrentUser` to the above mentioned command. If multiple people are administrating 73 | the server, it can be easier to maintain the module by having SteamPS installed in 74 | just one location. 75 | 76 | Furthermore, if you plan to have cmdlets from the module running unattended 77 | you will need to make sure that the module is available to the user running it. This 78 | can be achieved by ensuring the module is installed for the user running it, or just 79 | have it installed globally for all users as exemplified above. 80 | 81 | When SteamPS is installed you will need to use the cmdlet `Install-SteamCMD` from 82 | the module to install SteamCMD. This is done by calling `Install-SteamCMD` from an 83 | elevated prompt: 84 | 85 | ```powershell 86 | Install-SteamCMD 87 | ``` 88 | 89 | <img src="assets/images/install-steamcmd.gif" alt="Select application" width="700px"/> 90 | 91 | By using the parameter `-InstallPath` you can specify an install location of SteamCMD. 92 | The default installation path is C:\Program Files\SteamCMD. The install path, 93 | default or custom, is added to the [PATH](<https://en.wikipedia.org/wiki/PATH_(variable)>). 94 | 95 | ### Usage 96 | 97 | #### Update single app / game server 98 | 99 | The cmdlet `Update-SteamApp` is used to both install and/or update an application. 100 | You can either specify the name of the application or the application ID. 101 | 102 | #### Install / Update using ApplicationName 103 | 104 | If you enter e.g. _Ground Branch_ as an application name you will see 105 | both the game itself as well as the dedicated server. You will have to select the 106 | correct application from the popup box. 107 | 108 | ```powershell 109 | Update-SteamApp -ApplicationName 'Ground Branch' -Path 'C:\DedicatedServers\GB' 110 | ``` 111 | 112 | <img src="assets/images/select-application.png" alt="Select application" width="700px"/> 113 | 114 | You can narrow down the search by typing an application name that is more specific 115 | than simply _Ground Branch_ e.g. _Ground Branch Dedi_ or type it out 116 | in its entirety as _Ground Branch Dedicated Server_. This will only give one result 117 | and not display a popup. 118 | 119 | ```powershell 120 | Update-SteamApp -ApplicationName 'Ground Branch Dedicated Server' -Path 'C:\DedicatedServers\GB' 121 | ``` 122 | 123 | <img src="assets/images/update-steamapp.gif" alt="Select application" width="700px"/> 124 | 125 | #### Install / Update using AppID 126 | 127 | In this example we install _ARK: SurvivalEvolved Dedicated Server_ by using its 128 | AppID. The AppID can be found by using a database such as 129 | [Steam Database](https://steamdb.info/) or by searching for the AppID with the cmdlet 130 | `Get-SteamApp` e.g. `Get-SteamApp -ApplicationName 'Counter-Strike'`. 131 | 132 | ```powershell 133 | Update-SteamApp -AppID 376030 -Path 'C:\DedicatedServers\ARK-SurvivalEvolved' 134 | ``` 135 | 136 | #### Authenticating 137 | 138 | The two previous examples do not require authentication to install. However, some 139 | applications might require a Steam account. If that is the case, you will need to 140 | use the parameter `-Credential` to authenticate: 141 | 142 | ```powershell 143 | Update-SteamApp -ApplicationName 'Ground Branch Dedicated Server' -Path 'C:\DedicatedServers\GB' -Credential SAS_Admin 144 | ``` 145 | 146 | This will present you with an option to type in your password. 147 | 148 | In case you need to authenticate and want to run the script unattended, avoid writing 149 | the password in plaintext in the script. See how this can be achieved: 150 | [Store Credentials in PowerShell Script](https://pscustomobject.github.io/powershell/howto/Store-Credentials-in-PowerShell-Script/#store-encrypted-password-in-an-external-file). 151 | 152 | ## Update Steam server automatically 153 | 154 | The cmdlet `Update-SteamServer` is, at least for my own use case, applied to automatically 155 | keep a server up to date. It will check if the server is empty before updating 156 | it. The script is configured as a [Windows Task](https://o365reports.com/2019/08/02/schedule-powershell-script-task-scheduler/) 157 | and runs very night. 158 | 159 | Please see the wiki for further information: [Update Steam server automatically](https://github.com/hjorslev/SteamPS/wiki/Update-Steam-server-automatically). 160 | 161 | ## Acknowledgements 162 | 163 | Joystick icon by Delapouite. Available at [game-icons.net](https://game-icons.net/1x1/delapouite/joystick.html). 164 | -------------------------------------------------------------------------------- /SteamPS/Public/Server/Update-SteamServer.ps1: -------------------------------------------------------------------------------- 1 | function Update-SteamServer { 2 | <# 3 | .SYNOPSIS 4 | Update a Steam based game server. 5 | 6 | .DESCRIPTION 7 | This cmdlet presents a workflow to keep a steam based game server up to date. 8 | The server is expecting the game server to be running as a Windows Service. 9 | 10 | .PARAMETER AppID 11 | Enter the application ID you wish to install. 12 | 13 | .PARAMETER ServiceName 14 | Specify the Windows Service Name. You can get a list of services with Get-Service. 15 | 16 | .PARAMETER IPAddress 17 | Enter the IP address of the Steam based server. 18 | 19 | .PARAMETER Port 20 | Enter the port number of the Steam based server. 21 | 22 | .PARAMETER Path 23 | Install location of the game server. 24 | 25 | .PARAMETER Credential 26 | If the app requires login to install or update, enter your Steam username and password. 27 | 28 | .PARAMETER Arguments 29 | Enter any additional arguments here. 30 | 31 | .PARAMETER LogPath 32 | Specify the directory of the log files. 33 | 34 | .PARAMETER DiscordWebhookUri 35 | Enter a Discord Webhook Uri if you wish to get notifications about the server 36 | update. 37 | 38 | .PARAMETER AlwaysNotify 39 | Always receive a notification when a server has been updated. Default is 40 | only to send on errors. 41 | 42 | .PARAMETER TimeoutLimit 43 | Number of times the cmdlet checks if the server is online or offline. When 44 | the limit is reached an error is thrown. 45 | 46 | .EXAMPLE 47 | Update-SteamServer -AppID 476400 -ServiceName GB-PG10 -IPAddress '185.15.73.207' -Port 27015 48 | 49 | .NOTES 50 | Author: Frederik Hjorslev Nylander 51 | 52 | .LINK 53 | https://hjorslev.github.io/SteamPS/Update-SteamServer.html 54 | #> 55 | 56 | # TODO: Implement support for ShouldContinue. Due to compatibility we wait with this. 57 | [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] 58 | [CmdletBinding(SupportsShouldProcess = $true, 59 | ConfirmImpact = 'High')] 60 | 61 | param ( 62 | [Parameter(Mandatory = $true)] 63 | [int]$AppID, 64 | 65 | [Parameter(Mandatory = $true)] 66 | [ValidateScript( { Get-Service -Name $_ })] 67 | [string]$ServiceName, 68 | 69 | [Parameter(Mandatory = $true, 70 | ValueFromPipelineByPropertyName = $true)] 71 | [System.Net.IPAddress]$IPAddress, 72 | 73 | [Parameter(Mandatory = $true, 74 | ValueFromPipelineByPropertyName = $true)] 75 | [int]$Port, 76 | 77 | [Parameter(Mandatory = $false)] 78 | [Alias('ApplicationPath')] 79 | [string]$Path = "C:\DedicatedServers\$ServiceName", 80 | 81 | [Parameter(Mandatory = $false)] 82 | [ValidateNotNull()] 83 | [System.Management.Automation.PSCredential] 84 | [System.Management.Automation.Credential()] 85 | $Credential = [System.Management.Automation.PSCredential]::Empty, 86 | 87 | [Parameter(Mandatory = $false)] 88 | [string]$Arguments, 89 | 90 | [Parameter(Mandatory = $false)] 91 | [Alias('LogLocation')] 92 | [string]$LogPath = 'C:\DedicatedServers\Logs', 93 | 94 | [Parameter(Mandatory = $false)] 95 | [string]$DiscordWebhookUri, 96 | 97 | [Parameter(Mandatory = $false)] 98 | [string]$AlwaysNotify, 99 | 100 | [Parameter(Mandatory = $false)] 101 | [int]$TimeoutLimit = 10 102 | ) 103 | 104 | begin { 105 | if ($null -eq (Get-SteamPath)) { 106 | $Exception = [Exception]::new('SteamCMD could not be found in the env:Path. Have you executed Install-SteamCMD?') 107 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 108 | $Exception, 109 | 'SteamCMDNotInstalled', 110 | [System.Management.Automation.ErrorCategory]::NotInstalled, 111 | (Test-Admin) 112 | ) 113 | $PSCmdlet.ThrowTerminatingError($ErrorRecord) 114 | } 115 | 116 | if ((Test-Admin) -eq $false) { 117 | $Exception = [Exception]::new('The current PowerShell session is not running as Administrator. Start PowerShell by using the Run as Administrator option, and then try running the script again.') 118 | $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( 119 | $Exception, 120 | 'MissingUserPermissions', 121 | [System.Management.Automation.ErrorCategory]::PermissionDenied, 122 | (Test-Admin) 123 | ) 124 | $PSCmdlet.ThrowTerminatingError($ErrorRecord) 125 | } 126 | 127 | # Log settings 128 | $PSFLoggingProvider = @{ 129 | Name = 'logfile' 130 | InstanceName = "Update game server $ServiceName" 131 | FilePath = "$LogPath\$ServiceName\$ServiceName-%Date%.csv" 132 | Enabled = $true 133 | LogRotatePath = "$LogPath\$ServiceName\$ServiceName-*.csv" 134 | } 135 | Set-PSFLoggingProvider @PSFLoggingProvider 136 | 137 | # Variable that stores how many times the cmdlet has checked whether the 138 | # server is offline or online. 139 | $TimeoutCounter = 0 140 | } 141 | 142 | process { 143 | # Get server status and output it. 144 | $ServerStatus = Get-SteamServerInfo -IPAddress $IPAddress -Port $Port -ErrorAction SilentlyContinue 145 | 146 | # If server is alive we check it is empty before updating it. 147 | if ($ServerStatus) { 148 | Write-PSFMessage -Level Host -Message $ServerStatus -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" 149 | 150 | # Waiting to server is empty. Checking every 60 seconds. 151 | while ($ServerStatus.Players -ne 0) { 152 | Write-PSFMessage -Level Host -Message 'Awaiting that the server is empty before updating.' -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" 153 | $ServerStatus = Get-SteamServerInfo -IPAddress $IPAddress -Port $Port -ErrorAction SilentlyContinue 154 | Write-PSFMessage -Level Host -Message $($ServerStatus | Select-Object -Property ServerName, Port, Players) -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" 155 | Start-Sleep -Seconds 60 156 | } 157 | # Server is now empty and we stop, update and start the server. 158 | Write-PSFMessage -Level Host -Message "Stopping $ServiceName..." -Tag 'ServerUpdate' -ModuleName 'SteamPS' -Target $ServiceName 159 | Stop-Service -Name $ServiceName 160 | Write-PSFMessage -Level Host -Message "$($ServiceName): $((Get-Service -Name $ServiceName).Status)." -Tag 'ServerUpdate' -ModuleName 'SteamPS' -Target $ServiceName 161 | } else { 162 | Write-PSFMessage -Level Host -Message 'Server could not be reached.' -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" 163 | Write-PSFMessage -Level Host -Message 'Continuing with updating server.' -Tag 'ServerUpdate' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" 164 | } 165 | 166 | Write-PSFMessage -Level Host -Message "Updating $ServiceName..." -Tag 'ServerUpdate' -ModuleName 'SteamPS' -Target $ServiceName 167 | if ($null -ne $Credential) { 168 | Update-SteamApp -AppID $AppID -Path $Path -Credential $Credential -Arguments "$Arguments" -Force 169 | } else { 170 | Update-SteamApp -AppID $AppID -Path $Path -Arguments "$Arguments" -Force 171 | } 172 | 173 | Write-PSFMessage -Level Host -Message "Starting $ServiceName" -Tag 'ServerUpdate' -ModuleName 'SteamPS' -Target $ServiceName 174 | Start-Service -Name $ServiceName 175 | Write-PSFMessage -Level Host -Message "$($ServiceName): $((Get-Service -Name $ServiceName).Status)." -Tag 'ServerUpdate' -ModuleName 'SteamPS' -Target $ServiceName 176 | 177 | do { 178 | $TimeoutCounter++ # Add +1 for every loop. 179 | Write-PSFMessage -Level Host -Message 'Waiting for server to come online again.' -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" 180 | Start-Sleep -Seconds 60 181 | # Getting new server information. 182 | $ServerStatus = Get-SteamServerInfo -IPAddress $IPAddress -Port $Port -ErrorAction SilentlyContinue | Select-Object -Property ServerName, Port, Players 183 | Write-PSFMessage -Level Host -Message $ServerStatus -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" 184 | Write-PSFMessage -Level Host -Message "No response from $($IPAddress):$($Port)." -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" 185 | Write-PSFMessage -Level Host -Message "TimeoutCounter: $TimeoutCounter/$TimeoutLimit" -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" 186 | if ($TimeoutCounter -ge $TimeoutLimit) { 187 | break 188 | } 189 | } until ($null -ne $ServerStatus.ServerName) 190 | 191 | if ($null -ne $ServerStatus.ServerName) { 192 | Write-PSFMessage -Level Host -Message "$($ServerStatus.ServerName) is now ONLINE." -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" 193 | $ServerState = 'ONLINE' 194 | $Color = 'Green' 195 | } else { 196 | Write-PSFMessage -Level Critical -Message "Server seems to be OFFLINE after the update..." -Tag 'ServerStatus' -ModuleName 'SteamPS' -Target "$($IPAddress):$($Port)" 197 | $ServerState = 'OFFLINE' 198 | $Color = 'Red' 199 | } 200 | } # Process 201 | 202 | end { 203 | if ($null -ne $DiscordWebhookUri -and ($ServerState -eq 'OFFLINE' -or $AlwaysNotify -eq $true)) { 204 | # Send Message to Discord about the update. 205 | $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) 206 | $ServerStateFact = New-DiscordFact -Name 'Server State' -Value $(Write-Output -InputObject "Server is $ServerState!") 207 | $LogFact = New-DiscordFact -Name 'Log Location' -Value "$LogPath\$ServiceName\$ServiceName-%Date%.csv" 208 | $Section = New-DiscordSection -Title "$ServiceName - Update Script Executed" -Facts $ServerStateFact, $ServerFact, $LogFact -Color $Color 209 | Send-DiscordMessage -WebHookUrl $DiscordWebhookUri -Sections $Section 210 | } 211 | } # End 212 | } # Cmdlet --------------------------------------------------------------------------------