diff --git a/src/PSProxmoxVE.Core/Utilities/ApiValueHelper.cs b/src/PSProxmoxVE.Core/Utilities/ApiValueHelper.cs
new file mode 100644
index 0000000..8296cae
--- /dev/null
+++ b/src/PSProxmoxVE.Core/Utilities/ApiValueHelper.cs
@@ -0,0 +1,38 @@
+using System;
+
+namespace PSProxmoxVE.Core.Utilities
+{
+ ///
+ /// Helper methods for normalizing and checking values received from the Proxmox VE API.
+ /// The API may return the same logical value in different formats (e.g., boolean true, integer 1, or string "1").
+ ///
+ public static class ApiValueHelper
+ {
+ ///
+ /// Determines if a value represents a true/exited state.
+ /// Accepts boolean true, integer 1 (as Int64 or Int32), and string "1" as true.
+ /// All other values (false, 0, "0", null, etc.) are false.
+ ///
+ /// The value to check, typically from API response data.
+ /// True if the value represents an exited/true state, false otherwise.
+ public static bool IsExited(object? value)
+ {
+ if (value == null)
+ return false;
+
+ if (value is bool b)
+ return b;
+
+ if (value is long l)
+ return l == 1L;
+
+ if (value is int i)
+ return i == 1;
+
+ if (value is string s)
+ return s == "1";
+
+ return false;
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Vms/InvokePveVmGuestExecCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/InvokePveVmGuestExecCmdlet.cs
index b61ba1e..1c1d523 100644
--- a/src/PSProxmoxVE/Cmdlets/Vms/InvokePveVmGuestExecCmdlet.cs
+++ b/src/PSProxmoxVE/Cmdlets/Vms/InvokePveVmGuestExecCmdlet.cs
@@ -2,6 +2,7 @@ using System;
using System.Diagnostics;
using System.Management.Automation;
using PSProxmoxVE.Core.Services;
+using PSProxmoxVE.Core.Utilities;
namespace PSProxmoxVE.Cmdlets.Vms
{
@@ -60,7 +61,7 @@ namespace PSProxmoxVE.Cmdlets.Vms
if (sw.Elapsed >= deadline)
throw new TimeoutException($"Guest command did not complete within {Timeout} seconds.");
result = service.GetGuestExecStatus(session, Node, VmId, pid);
- } while (!result.TryGetValue("exited", out var exited) || !Equals(exited, 1L));
+ } while (!result.TryGetValue("exited", out var exited) || !ApiValueHelper.IsExited(exited));
var output = new PSObject();
output.Properties.Add(new PSNoteProperty("ExitCode", result.TryGetValue("exitcode", out var ec) && ec is long ecl ? (int)ecl : -1));
diff --git a/tests/PSProxmoxVE.Core.Tests/Utilities/ApiValueHelperTests.cs b/tests/PSProxmoxVE.Core.Tests/Utilities/ApiValueHelperTests.cs
new file mode 100644
index 0000000..1d69253
--- /dev/null
+++ b/tests/PSProxmoxVE.Core.Tests/Utilities/ApiValueHelperTests.cs
@@ -0,0 +1,52 @@
+using Newtonsoft.Json.Linq;
+using PSProxmoxVE.Core.Utilities;
+using Xunit;
+
+namespace PSProxmoxVE.Core.Tests.Utilities
+{
+ public class ApiValueHelperTests
+ {
+ [Theory]
+ [InlineData(true)]
+ [InlineData(1L)]
+ [InlineData(1)]
+ [InlineData("1")]
+ public void IsExited_TrueValues_ReturnsTrue(object value)
+ {
+ Assert.True(ApiValueHelper.IsExited(value));
+ }
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(0L)]
+ [InlineData(0)]
+ [InlineData("0")]
+ [InlineData(null)]
+ [InlineData("")]
+ [InlineData("true")]
+ [InlineData(2L)]
+ [InlineData(42)]
+ public void IsExited_FalseValues_ReturnsFalse(object? value)
+ {
+ Assert.False(ApiValueHelper.IsExited(value));
+ }
+
+ [Theory]
+ [InlineData("{\"data\":{\"exited\":true}}", true)]
+ [InlineData("{\"data\":{\"exited\":false}}", false)]
+ [InlineData("{\"data\":{\"exited\":1}}", true)]
+ [InlineData("{\"data\":{\"exited\":0}}", false)]
+ [InlineData("{\"data\":{\"exited\":\"1\"}}", true)]
+ [InlineData("{\"data\":{\"exited\":\"0\"}}", false)]
+ [InlineData("{\"data\":{\"exited\":null}}", false)]
+ [InlineData("{\"data\":{}}", false)]
+ public void IsExited_ApiJsonValues_ReturnExpectedCompletionState(string json, bool expected)
+ {
+ var data = (JObject)JObject.Parse(json)["data"]!;
+ var status = JsonHelper.ToDictionary(data);
+ var completed = status.TryGetValue("exited", out var exited) && ApiValueHelper.IsExited(exited);
+
+ Assert.Equal(expected, completed);
+ }
+ }
+}