作者非常喜歡這個遊戲,他本人是一個「純粹為了朋友」的小伺服器的管理員。 正如業餘愛好者中常見的那樣,伺服器上的所有內容都經過修改,這會導致不穩定,從而導致崩潰。 由於 Powershell 的作者比他所在街道上商店的位置更了解,因此他決定製作“啟動 Minecraft 2020 的最佳腳本」 相同的腳本作為模板的基礎
我們需要的命令
替代日誌記錄
有一天,在安裝了幾個模組後,我發現伺服器顯然在沒有宣戰的情況下崩潰了。 伺服器沒有在latest.log或debug中寫入錯誤,理論上應該寫入此錯誤並停止的控制台被關閉。
如果他不想寫,他就不需要寫。 我們有 cmdlet 的 Powershell T卹對象,它獲取一個物件並將其同時輸出到文件和控制台。
.handler.ps1 | Tee-Object .StandardOutput.txt -Append
這樣,Powershell 將獲取標準輸出並將其寫入檔案。 不要嘗試使用 啟動進程因為它會回傳System.ComponentModel.Component而不是StandardOutput,而-RedirectStandardOutput將導致無法進入控制台,這是我們想要避免的。
啟動參數
安裝同一對模組後,作者註意到伺服器也沒有足夠的 RAM。 這需要更改啟動參數。 不必每次都在每個人都使用的 start.bat 中更改它們,只需使用此腳本即可。
由於 Tee-Object 僅在呼叫「Just Like This」執行檔時讀取 StandardOutput,因此您必須建立另一個腳本。 該腳本將由 Minecraft 本身啟動。 讓我們從論點開始。
為了在未來沉迷於終極懶惰,腳本必須即時收集啟動參數。 為此,我們首先搜尋最新版本 偽造.
$forge = ((Get-ChildItem | Where-Object Name -Like "forge*").Name | Sort-Object -Descending) | Select-Object -last 1
使用 sort-object,我們將始終取得編號最大的對象,無論您放了多少個物件。 終極的懶惰。
現在您需要為伺服器分配記憶體。 為此,請取得系統記憶體量並將其寫入字串。
$ram = ((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb)
$xmx = "-Xms" + $ram + "G"
正確自動重啟
作者看過其他人的.bat文件,但沒有考慮到伺服器停止的原因。 這樣很不方便,如果你只需要更改mod檔或刪除一些東西怎麼辦?
現在讓我們正確重啟。 作者之前遇到過奇怪的腳本,無論伺服器為何關閉,都會重新啟動伺服器。 我們將使用退出代碼。 Java 使用 0 作為成功,所以我們從這裡開始跳舞。
首先,讓我們建立一個在伺服器失敗時重新啟動伺服器的函數。
function Get-MinecraftExitCode {
do {
if ($global:Process.ExitCode -ne 0) {
Write-Log
Restart-Minecraft
}
else {
Write-Log
}
} until ($global:Process.ExitCode -eq 0)
}
該腳本將保留在循環中,直到伺服器使用 /stop 命令從其自己的控制台正常關閉。
如果我們決定將所有事情自動化,那麼最好收集開始日期、完成日期以及完成原因。
為此,我們將 Start-Process 的結果寫入變數中。 在腳本中它看起來像這樣:
$global:Process = Start-Process -FilePath "C:Program Files (x86)common filesOracleJavajavapath_target_*java.exe" -ArgumentList "$xmx -server -jar $forge nogui" -Wait -NoNewWindow -PassThru
然後我們將結果寫入文件。 這是變數中傳回給我們的內容:
$global:Process.StartTime
$global:Process.ExitCode
$global:Process.ExitTime
所有這些都可以使用新增內容新增到文件中。 稍微梳理了一下,我們得到了這個腳本,我們稱之為 handler.ps1。
Add-Content -Value "Start time:" -Path $Logfile
$global:Process.StartTime
Add-Content -Value "Exit code:" -Path $Logfile
$global:Process.ExitCode | Add-Content $Logfile
Add-Content -Value "Exit time:" -Path $Logfile
$global:Process.ExitTime | Add-Content $Logfile
現在讓我們建立一個啟動處理程序的腳本。
正確啟動
作者希望從一個模組中的任意路徑運行不同版本的 Minecraft,並且還能夠將日誌儲存在特定資料夾中。
問題是該進程必須由登入系統的使用者啟動。 這可以透過桌面或 WinRm 完成。 如果您以系統使用者甚至管理員身份運行伺服器,但沒有登錄,那麼 Server.jar 甚至無法讀取 eula.txt 並啟動。
我們可以透過向註冊表添加三個條目來啟用自動登入。
New-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name DefaultUserName -Value $Username -ErrorAction SilentlyContinue
New-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name DefaultPassword -Value $Password -ErrorAction SilentlyContinue
New-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name AutoAdminLogon -Value 1 -ErrorAction SilentlyContinue
這是不安全的。 此處以明文形式指示登入名稱和密碼,因此要啟動伺服器,您需要建立具有使用者等級或更窄群組存取權限的單獨使用者。 嚴格不建議為此使用標準管理員。
我們解決了自動登入問題。 現在您需要為伺服器註冊一個新任務。 我們將從 Powershell 執行該命令,因此它將如下所示:
$Trigger = New-ScheduledTaskTrigger -AtLogOn
$User = "ServerAdmin"
$PS = New-ScheduledTaskAction -Execute 'PowerShell.exe" -Argument "Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"'
Register-ScheduledTask -TaskName "StartSSMS" -Trigger $Trigger -User $User -Action $PS -RunLevel Highest
組裝模組
現在讓我們將所有內容放入稍後可以使用的模組中。 現成腳本的所有程式碼都在這裡,導入即可使用。
如果您不想使用模組,則可以單獨使用上述所有內容。
開始-我的世界
首先,讓我們建立一個模組,它只會執行一個監聽和記錄標準輸出的腳本。
在參數區塊中,他詢問從哪個資料夾啟動 Minecraft 以及將日誌放在哪裡。
Set-Location (Split-Path $MyInvocation.MyCommand.Path)
function Start-Minecraft {
[CmdletBinding()]
param (
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]
$LogFile,
[Parameter(Mandatory)]
[ValidateSet('Vanilla', 'Forge')]
[ValidateNotNullOrEmpty()]
[string]
$Type,
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string[]]
$MinecraftPath
)
powershell.exe -file .handler.ps1 -type $type -MinecraftPath $MinecraftPath | Tee-Object $LogFile -Append
}
Export-ModuleMember -Function Start-Minecraft
你需要像這樣啟動 Minecraft:
Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"
現在讓我們繼續討論現成的 Handler.ps1
為了讓我們的腳本在呼叫時接受參數,我們還需要指定一個參數區塊。 請注意,它運行 Oracle Java,如果您使用不同的發行版,則需要更改可執行檔的路徑。
param (
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$type,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$MinecraftPath,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$StandardOutput
)
Set-Location $MinecraftPath
function Restart-Minecraft {
Write-host "=============== Starting godlike game server ============"
$forge = ((Get-ChildItem | Where-Object Name -Like "forge*").Name | Sort-Object -Descending) | Select-Object -first 1
$ram = ((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb)
$xmx = "-Xms" + $ram + "G"
$global:Process = Start-Process -FilePath "C:Program Files (x86)common filesOracleJavajavapath_target_*java.exe" -ArgumentList "$xmx -server -jar $forge nogui" -Wait -NoNewWindow -PassThru
}
function Write-Log {
Write-host "Start time:" $global:Process.StartTime
Write-host "Exit code:" $global:Process.ExitCode
Write-host "Exit time:" $global:Process.ExitTime
Write-host "=============== Stopped godlike game server ============="
}
function Get-MinecraftExitCode {
do {
if ($global:Process.ExitCode -ne 0) {
Restart-Minecraft
Write-Log
}
else {
Write-Log
}
} until ($global:Process.ExitCode -eq 0)
}
Get-MinecraftExitCode
註冊-我的世界
該腳本實際上與 Start-Minecraft 相同,只是它只註冊一個新任務。 接受相同的論點。 如果未指定使用者名,則採用目前使用者名稱。
function Register-Minecraft {
[CmdletBinding()]
param (
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]
$LogFile,
[Parameter(Mandatory)]
[ValidateSet('Vanilla', 'Forge')]
[ValidateNotNullOrEmpty()]
[string]$Type,
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$MinecraftPath,
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$User,
[Parameter(Mandatory)]
[string]$TaskName = $env:USERNAME
)
$Trigger = New-ScheduledTaskTrigger -AtLogOn
$arguments = "Start-Minecraft -Type $Type -LogFile $LogFile -MinecraftPath $MinecraftPath"
$PS = New-ScheduledTaskAction -Execute "PowerShell" -Argument "-noexit -command $arguments"
Register-ScheduledTask -TaskName $TaskName -Trigger $Trigger -User $User -Action $PS -RunLevel Highest
}
Export-ModuleMember -Function Register-Minecraft
註冊-自動登入
在參數區塊中,腳本接受使用者名稱和密碼參數。 如果未指定使用者名,則使用目前使用者的名稱。
function Set-Autologon {
param (
[Parameter(
HelpMessage="Username for autologon")]
$Username = $env:USERNAME,
[Parameter(Mandatory=$true,
HelpMessage="User password")]
[ValidateNotNullOrEmpty()]
$Password
)
$i = Get-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon"
if ($null -eq $i) {
New-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name DefaultUserName -Value $Username
New-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name DefaultPassword -Value $Password
New-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name AutoAdminLogon -Value 1
Write-Verbose "Set-Autologon will enable user auto logon."
}
else {
Set-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name DefaultUserName -Value $Username
Set-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name DefaultPassword -Value $Password
Set-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name AutoAdminLogon -Value 1
}
Write-Verbose "Autologon was set successfully."
}
運行這個腳本看起來像這樣:
Set-Autologon -Password "PlaintextPassword"
如何使用
現在讓我們看看作者本人是如何使用這一切的。 如何在 Windows 上正確部署公用 Minecraft 伺服器。 讓我們從頭開始。
1.創建用戶
$pass = Get-Credential
New-LocalUser -Name "MinecraftServer" -Password $pass.Password -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword
2.註冊任務運行腳本
您可以使用如下模組進行註冊:
Register-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft" -User "MInecraftServer" -TaskName "MinecraftStarter"
或使用標準工具:
$Trigger = New-ScheduledTaskTrigger -AtLogOn
$User = "ServerAdmin"
$PS = New-ScheduledTaskAction -Execute 'PowerShell.exe" -Argument "Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"'
Register-ScheduledTask -TaskName "StartSSMS" -Trigger $Trigger -User $User -Action $PS -RunLevel Highest
3.啟用自動登入並重新啟動機器
Set-Autologon -Username "MinecraftServer" -Password "Qw3"
完成
作者製作了劇本,包括為他自己製作,因此,他很樂意聽取您改進劇本的建議。 作者希望所有這些程式碼至少對您有用,並且這篇文章很有趣。
來源: www.habr.com