Der Autor liebt das Spiel sehr und ist außerdem Administrator eines kleinen Servers „nur für Freunde“. Wie es unter Liebhabern üblich ist, ist der Server modifiziert, was zu Instabilität führt und somit Abstürze zur Folge hat. Da der Autor Powershell besser kennt als die Lage der Geschäfte in seiner Straße, entschied er sich, "Das beste Skript zum Starten von Minecraft 2020" zu erstellen. Dieses Skript diente auch als Grundlage für eine Vorlage im . Aber alle Quellcodes sind bereits im Artikel vorhanden. Jetzt der Reihe nach, wie das alles umgesetzt wurde.
Die benötigten Befehle
Alternatives Logging
Eine weitere Modifikation auf dem Server führte dazu, dass er, anscheinend, ohne Vorwarnung abstürzt. Der Server schrieb keine Fehler in latest.log oder in debug, und die Konsole, die diesen Fehler melden und anhalten sollte, war geschlossen.
Will er nichts schreiben – dann ist das auch nicht erforderlich. Wir haben Powershell mit dem Cmdlet Tee-Object, das ein Objekt nimmt und es gleichzeitig in eine Datei und in die Konsole ausgibt.
.handler.ps1 | Tee-Object .StandardOutput.txt -AppendAuf diese Weise wird Powershell den StandardOutput sammeln und in die Datei schreiben. Versuchen Sie nicht, Start-Process, zu verwenden, da es System.ComponentModel.Component zurückgibt und nicht den StandardOutput. Außerdem würde -RedirectStandardOutput die Eingabe in die Konsole unmöglich machen, was wir vermeiden wollen.
Startargumente
Nachdem der Autor die besagte Modifikation installiert hatte, stellte er fest, dass dem Server auch Arbeitsspeicher fehlt. Daher müssen die Startargumente geändert werden. Anstatt sie jedes Mal in start.bat zu ändern, die alle verwenden, verwenden Sie einfach dieses Skript.
Da Tee-Object den StandardOutput nur liest, wenn die ausführbare Datei "so direkt" aufgerufen wird, muss ein weiteres Skript erstellt werden. Dieses Skript wird Minecraft selbst starten. Beginnen wir mit den Argumenten.
Um in Zukunft in ultimativer Faulheit zu schwelgen, sollte das Skript die Startargumente dynamisch sammeln. Dazu beginnen wir mit der Suche nach der neuesten Version von forge.
$forge = ((Get-ChildItem | Where-Object Name -Like "forge*").Name | Sort-Object -Descending) | Select-Object -last 1Mit sort-object werden wir immer das Objekt mit der höchsten Zahl verwenden, wie viele auch immer Sie dort platziert haben. Ultimative Faulheit.
Jetzt muss dem Server Arbeitsspeicher zugewiesen werden. Dazu nehmen wir die Menge an Systemarbeitsspeicher und speichern dessen Summe in einer Zeichenkette.
$ram = ((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb)
$xmx = "-Xms" + $ram + "G"Richtiger automatischer Neustart
Der Autor hat .bat-Dateien von anderen Personen gesehen, aber sie berücksichtigten nicht den Grund, warum der Server gestoppt wurde. Es ist unpraktisch, wenn man einfach die Mod-Datei wechseln oder etwas löschen muss.
Jetzt machen wir einen richtigen Neustart. Der Autor ist früher auf seltsame Skripte gestoßen, die den Server neu starteten, unabhängig davon, warum der Server beendet wurde. Wir werden jedoch den Exitcode verwenden. Java nutzt 0 als erfolgreiche Beendigung, darauf werden wir aufsetzen.
Zuerst erstellen wir eine Funktion, die den Server bei einem fehlerhaften Abschluss neu startet.
function Get-MinecraftExitCode {
do {
if ($global:Process.ExitCode -ne 0) {
Write-Log
Restart-Minecraft
}
else {
Write-Log
}
} until ($global:Process.ExitCode -eq 0)
}
Das Skript bleibt in einer Schleife, bis der Server von seiner eigenen Konsole ordnungsgemäß mit dem Befehl /stop beendet wird.
Wenn wir alles automatisieren wollen, wäre es gut, auch den Startzeitpunkt, die Beendigungszeit sowie den Grund für die Beendigung zu erfassen.
Dafür speichern wir das Ergebnis von Start-Process in einer Variablen. Im Skript sieht das so aus:
$global:Process = Start-Process -FilePath "C:Program Files (x86)common filesOracleJavajavapath_target_*java.exe" -ArgumentList "$xmx -server -jar $forge nogui" -Wait -NoNewWindow -PassThruAls nächstes speichern wir die Ergebnisse in einer Datei. Das sind die Werte, die wir in die Variable zurückbekommen:
$global:Process.StartTime
$global:Process.ExitCode
$global:Process.ExitTimeAll dies kann mit Add-Content in die Datei hinzugefügt werden. Ein wenig aufbereitet, erhalten wir so ein Skript, das wir handler.ps1 nennen.
Add-Content -Value "Startzeit:" -Path $Logfile
$global:Process.StartTime
Add-Content -Value "Exit-Code:" -Path $Logfile
$global:Process.ExitCode | Add-Content $Logfile
Add-Content -Value "Beendigungszeit:" -Path $Logfile
$global:Process.ExitTime | Add-Content $Logfile
Jetzt lassen Sie uns das Skript zum Starten des Handlers gestalten.
Richtige Autostart
Der Autor möchte Minecraft verschiedener Versionen aus beliebigen Verzeichnissen mit einem Modul starten und zudem die Möglichkeit haben, Protokolle in einem bestimmten Ordner zu speichern.
Das Problem besteht darin, dass der Prozess von einem Benutzer gestartet werden muss, der im System angemeldet ist. Dies kann über den Desktop oder WinRm erfolgen. Wenn der Server im Namen des Systems oder sogar des Administrators ohne Benutzeranmeldung gestartet wird, kann Server.jar nicht einmal die eula.txt lesen und starten.
Den automatischen Login erreichen wir durch Hinzufügen von drei Einträgen in die Registrierung.
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 SilentlyContinueEs ist unsicher. Der Benutzername und das Passwort werden hier im Klartext angegeben, weshalb für den Serverstart ein separater Benutzer eingerichtet werden sollte, der Zugriff auf Benutzerebene oder in einer noch engeren Gruppe hat. Die Verwendung des Standardadministrators für diesen Zweck wird kategorisch nicht empfohlen.
Mit dem Autologin haben wir uns befasst. Jetzt müssen wir eine neue Aufgabe für den Server registrieren. Wir werden den Befehl aus Powershell ausführen, daher wird es so aussehen:
$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 HighestWir erstellen ein Modul
Lass uns jetzt alles in Module packen, die wir später verwenden können. Der gesamte Code der fertigen Skripte ist hier, importiere und benutze ihn.
Alles, was oben beschrieben wurde, kannst du separat verwenden, wenn du dich nicht mit Modulen befassen möchtest.
Start-Minecraft
Zuerst erstellen wir ein Modul, das nur das Skript ausführen wird, das die standardausgabe überwacht und aufzeichnet.
Im Parameterblock wird nach dem Ordner gefragt, aus dem Minecraft gestartet werden soll, und wo das Protokoll gespeichert werden soll.
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-MinecraftUnd so muss Minecraft gestartet werden:
Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"Jetzt kommen wir zu dem einsatzbereiten Handler.ps1
Damit unser Skript Parameter bei der Aufruf annehmen kann, muss auch ein Parameterblock angegeben werden. Beachte, dass er Oracle Java startet; wenn du eine andere Distribution verwendest, muss der Pfad zur ausführbaren Datei geändert werden.
param (
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$type,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$MinecraftPath,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$StandardOutput
)
Set-Location $MinecraftPath
function Restart-Minecraft {
Write-host "=============== Starte den göttlichen Spieleserver ============"
$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 "Startzeit:" $global:Process.StartTime
Write-host "Exit-Code:" $global:Process.ExitCode
Write-host "Endzeit:" $global:Process.ExitTime
Write-host "=============== Gestoppter göttlicher Spieleserver ============="
}
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
Register-Minecraft
Das Skript wiederholt praktisch Start-Minecraft, mit der Ausnahme, dass es nur eine neue Aufgabe registriert. Es nimmt die gleichen Argumente. Der Benutzername, wenn nicht angegeben, wird auf den aktuellen gesetzt.
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-MinecraftRegister-Autologon
Im Parameterblock des Skripts wird der Parameter Benutzername und Passwort akzeptiert. Wenn der Benutzername nicht angegeben ist, wird der aktuelle Benutzername verwendet.
function Set-Autologon {
param (
[Parameter(
HelpMessage="Benutzername für den Autologon")]
$Username = $env:USERNAME,
[Parameter(Mandatory=$true,
HelpMessage="Benutzerpasswort")]
[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 wird die Benutzeranmeldung aktivieren."
}
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 wurde erfolgreich eingerichtet."
}
So sieht der Start dieses Skripts aus:
Set-Autologon -Password "PlaintextPassword"Wie man es benutzt
Jetzt schauen wir uns an, wie der Autor all dies selbst nutzt. Wie man richtig einen öffentlichen Minecraft-Server unter Windows einrichtet. Beginnen wir von ganz vorne.
1. Benutzer erstellen
$pass = Get-Credential
New-LocalUser -Name "MinecraftServer" -Password $pass.Password -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword2. Aufgabe zum Starten des Skripts registrieren
Sie können dies mit einem Modul so registrieren:
Register-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft" -User "MInecraftServer" -TaskName "MinecraftStarter"Oder Sie verwenden die Standardmittel:
$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 Highest3. Autologon aktivieren und das System neu starten
Set-Autologon -Username "MinecraftServer" -Password "Qw3"Abschluss
Der Autor hat das Skript auch für sich selbst erstellt und freut sich daher über Ihre Vorschläge zur Verbesserung des Skripts. Der Autor hofft, dass dieser gesamte Code für Sie zumindest minimal nützlich war und der Artikel interessant ist.
Quelle: habr.com
