Forfatteren elsker spillet meget, og han er selv administrator af en lille server "rent for venner". Som sædvanligt blandt amatører er alt på serveren modificeret, og det medfører ustabilitet i arbejdet og som følge heraf et fald. Da forfatteren kender Powershell bedre end placeringen af butikker på hans gade, besluttede han at gøre "Bedste script til at starte Minecraft 2020". Det samme script fungerede som grundlag for skabelonen i
De kommandoer, vi har brug for
Alternativ logning
Da jeg installerede et par mods mere, fandt jeg ud af, at serveren tilsyneladende styrtede ned uden at erklære krig. Serveren skrev ikke fejl til latest.log eller debug, og konsollen, som i teorien skulle skrive denne fejl og stoppe, blev lukket.
Hvis du ikke vil skrive, så lad være. Vi har Powershell med en cmdlet Tee-objekt, som tager et objekt og udsender det til en fil og til konsollen på samme tid.
.handler.ps1 | Tee-Object .StandardOutput.txt -Append
Så Powershell henter StandardOutput og skriver det til en fil. Forsøg ikke at bruge Start-proces, fordi det vil returnere en System.ComponentModel.Component, ikke en StandardOutput, og -RedirectStandardOutput vil gøre det umuligt at skrive ind i konsollen, hvilket er det vi gerne vil undgå.
Start Argumenter
Efter at have installeret det samme par mods, bemærkede forfatteren, at serveren heller ikke havde nok RAM. Og det er nødvendigt at ændre lanceringsargumenterne. I stedet for at ændre dem hver gang i start.bat, som alle bruger, skal du bare bruge dette script.
Da Tee-Object kun læser StandardOutput, når den eksekverbare kaldes "Bare sådan", skal der laves et script mere. Dette script vil køre minecraft selv. Lad os starte med argumenterne.
For at hengive sig til ultimativ dovenskab i fremtiden skal manuskriptet samle lanceringsargumenter på farten. For at gøre dette, lad os starte med at lede efter den nyeste version smede.
$forge = ((Get-ChildItem | Where-Object Name -Like "forge*").Name | Sort-Object -Descending) | Select-Object -last 1
Med sort-object vil vi altid tage objektet med det største antal, uanset hvor mange du lægger der. Ultimativ dovenskab.
Nu skal vi tildele hukommelse til serveren. For at gøre dette tager vi mængden af systemhukommelse og skriver dens mængde til streng.
$ram = ((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb)
$xmx = "-Xms" + $ram + "G"
Korrekt automatisk genstart
Forfatteren har set .bat-filer fra andre mennesker, men de tog ikke højde for årsagen til, at serveren blev stoppet. Det er ubelejligt, hvad nu hvis du bare skal ændre mod-filen eller slette noget?
Lad os nu lave en ordentlig genstart. Forfatteren stødte tidligere på mærkelige scripts, der genstartede serveren, uanset hvorfor serveren afsluttede. Vi vil bruge exitcode. Java bruger 0 som succes, så lad os danse derfra.
Lad os først oprette en funktion, der genstarter serveren, hvis den fejler.
function Get-MinecraftExitCode {
do {
if ($global:Process.ExitCode -ne 0) {
Write-Log
Restart-Minecraft
}
else {
Write-Log
}
} until ($global:Process.ExitCode -eq 0)
}
Scriptet forbliver i løkken, indtil serveren afslutter normalt fra sin egen konsol ved hjælp af /stop-kommandoen.
Hvis vi besluttede at automatisere alt, ville det være rart at indsamle datoen for lanceringen, slutningen og også årsagen til slutningen.
For at gøre dette skriver vi resultatet af Start-Process til en variabel. I et script ser det sådan ud:
$global:Process = Start-Process -FilePath "C:Program Files (x86)common filesOracleJavajavapath_target_*java.exe" -ArgumentList "$xmx -server -jar $forge nogui" -Wait -NoNewWindow -PassThru
Og skriv derefter resultaterne til en fil. Her er hvad der returneres til os i en variabel:
$global:Process.StartTime
$global:Process.ExitCode
$global:Process.ExitTime
Alt dette kan tilføjes til filen ved hjælp af Add-Content. Efter at have børstet lidt, får vi sådan et script, men vi kalder det 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
Lad os nu designe scriptet med lanceringen af handleren.
Korrekt autoload
Forfatteren ønsker at køre minecraft af forskellige versioner fra en hvilken som helst sti med ét modul og også være i stand til at lægge logfiler i en bestemt mappe.
Problemet er, at processen skal startes af en bruger, der er logget ind. Dette kan gøres via skrivebordet eller WinRm. Hvis du kører serveren som et system eller endda en administrator, men ikke logger på, så vil Server.jar ikke engang kunne læse eula.txt og starte.
Vi kan aktivere autologon ved at tilføje tre poster til registreringsdatabasen.
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
Det er ikke sikkert. Login og adgangskode er her angivet med klartekst, derfor skal du for at starte serveren oprette en separat bruger, som har adgang på brugerniveau eller i en endnu smallere gruppe. Det frarådes på det kraftigste at bruge standardadministratoren til dette.
Vi fandt ud af autologin. Nu skal du registrere en ny opgave til serveren. Vi kører kommandoen fra Powershell, så den ser sådan ud:
$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
Samling af modulet
Lad os nu arrangere alt i moduler, der kan bruges senere. Al kode af færdige scripts er her, importer og brug.
Du kan bruge alt beskrevet ovenfor separat, hvis du ikke vil bøvle med moduler.
start minecraft
Lad os først lave et modul, der ikke gør andet end at køre et script, der lytter og skriver til standardoutput.
I parameterblokken spørger han, fra hvilken mappe han skal starte minecraft, og hvor loggen skal placeres.
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
Og du skal køre minecraft sådan her:
Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"
Lad os nu gå videre til Handler.ps1, der er klar til brug
For at vores script skal acceptere parametre, når de kaldes, skal vi også angive en parameterblok. Bemærk venligst, at den kører Oracle Java, hvis du bruger en anden distribution, skal du ændre stien til den eksekverbare fil.
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
registrer minecraft
Scriptet er praktisk talt det samme som Start-Minecraft, bortset fra at det kun registrerer en ny opgave. Accepterer de samme argumenter. Brugernavnet, hvis det ikke er angivet, tager det nuværende.
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
Registrer-Autologon
I parameterblokken accepterer scriptet parametrene Brugernavn og Adgangskode. Hvis brugernavn ikke er angivet, bruges den aktuelle brugers navn.
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."
}
At køre dette script ser sådan ud:
Set-Autologon -Password "PlaintextPassword"
Sådan bruges
Overvej nu, hvordan forfatteren selv bruger alt dette. Sådan installeres en Minecraft offentlig server korrekt på Windows. Lad os starte helt fra begyndelsen.
1. Opret en bruger
$pass = Get-Credential
New-LocalUser -Name "MinecraftServer" -Password $pass.Password -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword
2. Registrer opgaven for at køre scriptet
Du kan tilmelde dig et modul som sådan:
Register-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft" -User "MInecraftServer" -TaskName "MinecraftStarter"
Eller brug standardværktøjerne:
$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. Slå autologin til, og genstart maskinen
Set-Autologon -Username "MinecraftServer" -Password "Qw3"
Afslutning
Forfatteren har lavet manuskriptet, også for sig selv, derfor vil han med glæde lytte til dine forslag til forbedring af manuskriptet. Forfatteren håber, at al denne kode i det mindste var minimalt nyttig for dig, og artiklen er interessant.
Kilde: www.habr.com