Files
IT-Nexus/agent-cs/Services/CommandExecutor.cs
Simon Grüssing e2521f405d Fix: Agent-Rollout downloadete immer globale AGENT_VERSION statt Gruppen-Ziel (v2.5.0)
- downloadSetup() nutzte process.env.AGENT_VERSION statt der Patch-Gruppen-
  Zielversion → Staged Rollout (Test/Pilot/Produktion) hatte nie funktioniert,
  jeder Agent bekam beim Auto-Update immer dieselbe globale Version
- Fix: downloadSetup() löst jetzt per ?hostname=X die Gruppen-Zielversion auf,
  exakt wie checkin() es bereits tat
- ApiService.DownloadSetupAsync() schickt jetzt den Hostnamen mit
- Version: 2.4.0 → 2.5.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 09:35:01 +02:00

152 lines
5.5 KiB
C#

using ITNexusAgent.Models;
using System.Diagnostics;
using System.Management;
using System.Net.Http;
namespace ITNexusAgent.Services;
public class CommandExecutor(ApiService api, string hostname, string dataDir, string exePath)
{
private readonly ApiService _api = api;
private readonly string _hostname = hostname;
private readonly string _dataDir = dataDir;
private readonly string _exePath = exePath;
private static void RunSchtasks(string args) =>
Process.Start(new ProcessStartInfo("schtasks.exe", args) { CreateNoWindow = true })?.WaitForExit();
public async Task ExecuteAsync(PatchCommand cmd)
{
string result;
try
{
result = cmd.Command switch
{
"check_updates" => await CheckUpdates(),
"install_updates" => await InstallUpdates(),
"reboot" => await Reboot(cmd.Id),
"upgrade_win11" => await UpgradeWin11(),
"update_agent" => await UpdateAgent(),
"shell_exec" => await ShellExec(cmd.Params ?? ""),
_ => $"Unbekannter Command: {cmd.Command}"
};
}
catch (Exception ex)
{
result = $"Fehler: {ex.Message}";
}
if (cmd.Command != "reboot")
{
await _api.ReportCommandResultAsync(new CommandResult
{
CommandId = cmd.Id,
Status = "done",
Result = result
});
}
}
private Task<string> CheckUpdates()
{
Process.Start(new ProcessStartInfo("UsoClient.exe", "StartScan") { CreateNoWindow = true });
Thread.Sleep(5000);
return Task.FromResult("Update-Scan gestartet");
}
private Task<string> InstallUpdates()
{
Process.Start(new ProcessStartInfo("UsoClient.exe", "StartDownload") { CreateNoWindow = true });
Thread.Sleep(3000);
Process.Start(new ProcessStartInfo("UsoClient.exe", "StartInstall") { CreateNoWindow = true });
return Task.FromResult("Update-Installation gestartet");
}
private async Task<string> Reboot(int cmdId)
{
await _api.ReportCommandResultAsync(new CommandResult
{
CommandId = cmdId,
Status = "done",
Result = "Neustart wird in 60 Sekunden durchgeführt"
});
Process.Start("shutdown.exe", "/r /t 60 /c \"IT Nexus Patch Management - Geplanter Neustart\"");
return "";
}
private Task<string> UpgradeWin11()
{
var exePath = Path.Combine(_dataDir, "Win11Upgrade.exe");
using var client = new HttpClient();
var bytes = client.GetByteArrayAsync("https://go.microsoft.com/fwlink/?linkid=2171764").Result;
if (bytes.Length < 1024 * 1024) return Task.FromResult("Download fehlgeschlagen");
File.WriteAllBytes(exePath, bytes);
var fullUser = NotificationService.GetLoggedOnUser();
if (!string.IsNullOrEmpty(fullUser))
{
RunSchtasks("/delete /tn \"IT Nexus Win11 Upgrade\" /f");
RunSchtasks($"/create /tn \"IT Nexus Win11 Upgrade\" /tr \"\\\"{exePath}\\\" /skipeula /auto upgrade\" /sc ONCE /st {DateTime.Now.AddSeconds(20):HH:mm} /ru \"{fullUser}\" /it /rl HIGHEST /f");
}
else
{
Process.Start(new ProcessStartInfo(exePath, "/quietinstall /skipeula /auto upgrade")
{ CreateNoWindow = true });
}
return Task.FromResult("running");
}
private Task<string> ShellExec(string command)
{
if (string.IsNullOrWhiteSpace(command)) return Task.FromResult("Kein Befehl angegeben");
try
{
var psi = new ProcessStartInfo("powershell.exe",
$"-NonInteractive -NoProfile -ExecutionPolicy Bypass -Command \"{command.Replace("\"", "\\\"")}\"")
{
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
var p = Process.Start(psi)!;
var stdout = p.StandardOutput.ReadToEnd();
var stderr = p.StandardError.ReadToEnd();
p.WaitForExit(30000);
var output = stdout;
if (!string.IsNullOrEmpty(stderr)) output += "\n[STDERR] " + stderr;
return Task.FromResult(string.IsNullOrEmpty(output) ? "(kein Output)" : output.Trim());
}
catch (Exception ex)
{
return Task.FromResult($"Fehler: {ex.Message}");
}
}
private async Task<string> UpdateAgent()
{
var bytes = await _api.DownloadSetupAsync(_hostname);
if (bytes.Length < 512 * 1024) return "Download fehlgeschlagen - Installer zu klein";
var setupPath = Path.Combine(_dataDir, "IT-Nexus-Agent-Setup-Update.exe");
var batchPath = Path.Combine(_dataDir, "update.cmd");
await File.WriteAllBytesAsync(setupPath, bytes);
// Batch: wartet kurz, führt Installer silent aus, löscht sich selbst
var batch = $"""
@echo off
timeout /t 5 /nobreak > nul
"{setupPath}" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART
del "{setupPath}" > nul
del "%~f0"
""";
await File.WriteAllTextAsync(batchPath, batch, System.Text.Encoding.ASCII);
Process.Start(new ProcessStartInfo("cmd.exe", $"/c \"{batchPath}\"")
{ CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden });
return "Update-Installer gestartet";
}
}