如何修复PowerShell脚本使Palworld服务器监控持续运行?
修复Palworld服务器监控脚本的自动循环问题
问题根源
你的脚本在while循环中每次都会调用Commands函数,而该函数内的Read-Host是阻塞式的——它会暂停整个脚本的执行,直到用户输入内容并按下回车。这就导致监控检查(崩溃重启、内存检测)只执行一次后就卡在等待输入的状态,无法自动重复运行。
解决方案
要实现监控循环自动执行,同时保留用户输入命令的功能,需要将用户输入的处理改为非阻塞式。可以通过检测控制台是否有输入可用,避免脚本被Read-Host卡住。
修改后的完整脚本
# SteamCMD Pfad $SteamPfad = '...\steamcmd.exe' # Palworld $PalworldPfad = '...\PalServer.exe' $PalworldLaunchOptions = "-publiclobby -log" # ARRCON $ARRCONHost = '...' $ARRCONPort = '...' $ARRCONPassword = '...' # Discord $DiscordWebhook = '...' # PowerShell Variablen $ramThreshold = 2 * 1024 * 1024 * 1024 # 2GB for testing, normally 16GB max function Start-Server { Write-Host "PalShell v.1.0 by Gerrxt" Write-Host "-------------------" Write-Host "Server Startet..." Start-Process -FilePath $PalworldPfad -ArgumentList $PalworldLaunchOptions $DiscordPayload = @{ content = "Der Palworld Server wurde gestartet!" username = "Palshell" avatar_url = "..." } $DiscordJsonPayload = $DiscordPayload | ConvertTo-Json Invoke-RestMethod -Uri $DiscordWebhook -Method Post -Body $DiscordJsonPayload -ContentType "application/json" } function Stop-Server { Write-Host "Server Stoppt..." C:\Users\Administrator\Desktop\PalShell\ARRCON.exe -H $ARRCONHost -P $ARRCONPort -p $ARRCONPassword "save" C:\Users\Administrator\Desktop\PalShell\ARRCON.exe -H $ARRCONHost -P $ARRCONPort -p $ARRCONPassword "shutdown 10 Der Server stoppt in 10 Sekunden!" $DiscordPayload = @{ content = "Der Palworld Server wird herruntergefahren!" username = "Palshell" avatar_url = "..." } $DiscordJsonPayload = $DiscordPayload | ConvertTo-Json Invoke-RestMethod -Uri $DiscordWebhook -Method Post -Body $DiscordJsonPayload -ContentType "application/json" } function Update-Server { Write-Host "Nach Updates wird gesucht..." $updateOutput = Start-Process -FilePath $SteamPfad -ArgumentList "+force_install_dir C:\...\Palworld +login anonymous +app_update 2394010 validate +quit" -NoNewWindow -Wait -PassThru if ($updateOutput.ExitCode -eq 0) { Write-Host "Es gibt kein neues Update." } else { Write-Host "Ein Update wurde gefunden und installiert. Der Server startet." $DiscordPayload = @{ content = "Der Palworld Server wurde aktualisiert!" username = "Palshell" avatar_url = "..." } $DiscordJsonPayload = $DiscordPayload | ConvertTo-Json Invoke-RestMethod -Uri $DiscordWebhook -Method Post -Body $DiscordJsonPayload -ContentType "application/json" } } function Check-ProcessRAMUsage { param ( [string]$processName, [long]$ramThreshold ) $process = Get-Process -Name $processName -ErrorAction SilentlyContinue Write-Host "DEBUG: Internal RAM Check..." if ($process) { $ramUsage = $process.WorkingSet64 if ($ramUsage -gt $ramThreshold) { Write-Host "Warnung: Der Server verwendet mehr als 16GB RAM!" $DiscordPayload = @{ content = "Warnung: Der Palworld Server verwendet mehr als 16GB RAM!" username = "Palshell" avatar_url = "..." } $DiscordJsonPayload = $DiscordPayload | ConvertTo-Json Invoke-RestMethod -Uri $DiscordWebhook -Method Post -Body $DiscordJsonPayload -ContentType "application/json" Write-Host "Der Server wird neugestartet..." Stop-Server Start-Sleep -Seconds 15 Start-Server } } else { Write-Host "Process $processName not found." } } function Process-UserCommand { param ( [ref]$stopRequested ) $user_input = Read-Host "Nutze einen der PalShell Befehle (Hilfe: help)" switch ($user_input) { "stop" { Stop-Server Write-Output "Der Server wird heruntergefahren. Die Powershell schliesst automatisch." Start-Sleep -Seconds 5 $stopRequested.Value = $true } "help" { Write-Output "" Write-Output "Befehle:" Write-Output "help (Zeige die Befehle an.)" Write-Output "stop (Palworld Server stoppt.)" Write-Output "neustart (Der Server wird neugestartet.)" Write-Output "" } "neustart" { Write-Output "Der Server wird neugestartet..." Stop-Server Start-Sleep -Seconds 15 Start-Server } default { Write-Output "Diesen Befehl gibt es nicht. Nutze help um die Befehle anzuzeigen." } } } #Update-Server #Excluded for testing, but its working Start-Server $stopRequested = $false $processName = "PalServer-Win64-Shipping-Cmd" $checkInterval = 5 # 调整监控检查的间隔时间(秒) while (-not $stopRequested) { Write-Host "DEBUG: Server Status Check..." $serverProcess = Get-Process -Name $processName -ErrorAction SilentlyContinue if (-not $serverProcess) { Write-Host "Server gecrasht. Starte Neu..." $DiscordPayload = @{ content = "Der Palworld Server ist gecrashed." username = "Palshell" avatar_url = "..." } $DiscordJsonPayload = $DiscordPayload | ConvertTo-Json Invoke-RestMethod -Uri $DiscordWebhook -Method Post -Body $DiscordJsonPayload -ContentType "application/json" Start-Server } Write-Host "DEBUG: Server RAM Check..." Check-ProcessRAMUsage -processName $processName -ramThreshold $ramThreshold # 非阻塞式检测用户输入 if ([Console]::KeyAvailable) { Write-Host "`nDEBUG: 检测到用户输入,处理命令..." Process-UserCommand -stopRequested ([ref]$stopRequested) } Start-Sleep -Seconds $checkInterval }
关键修改点
- 重命名函数:将原
Commands函数改为Process-UserCommand,语义更清晰。 - 非阻塞输入检测:在循环中使用
[Console]::KeyAvailable判断是否有用户输入,只有当用户按下按键时才调用命令处理函数,避免脚本被阻塞。 - 调整监控间隔:新增
$checkInterval变量,让你可以灵活设置监控检查的时间间隔(默认5秒,可根据需求调整)。
说明
修改后的脚本会持续循环执行崩溃检测和内存监控,同时在后台监听用户输入。当你需要执行命令时,直接输入对应的指令并回车即可,脚本会立即处理命令,之后继续恢复自动监控。
内容的提问来源于stack exchange,提问作者Gerrxt
相关产品推荐
相关产品推荐

