diff --git a/src/PSProxmoxVE/Cmdlets/Containers/CopyPveContainerCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Containers/CopyPveContainerCmdlet.cs
new file mode 100644
index 0000000..f505adb
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Containers/CopyPveContainerCmdlet.cs
@@ -0,0 +1,98 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Containers
+{
+ ///
+ /// Clones (copies) an LXC container on a Proxmox VE node.
+ ///
+ /// Creates a clone of an existing LXC container. By default, a linked clone is created
+ /// when the source is a template. Use -Full to create a full independent copy. Optionally
+ /// specify a target node to create the clone on a different cluster node.
+ /// Use -Wait to block until the clone task completes.
+ ///
+ ///
+ [Cmdlet(VerbsCommon.Copy, "PveContainer", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class CopyPveContainerCmdlet : PveCmdletBase
+ {
+ ///
+ /// The node on which the source container resides.
+ ///
+ [Parameter(Mandatory = true)]
+ public string SourceNode { get; set; } = string.Empty;
+
+ ///
+ /// The ID of the source container to clone. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ ///
+ /// The container ID to assign to the new clone. When omitted, the next available ID is used.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? NewVmId { get; set; }
+
+ ///
+ /// The hostname for the new clone.
+ ///
+ [Parameter(Mandatory = false)]
+ public string? NewName { get; set; }
+
+ ///
+ /// The target node for the clone. Defaults to the source node.
+ ///
+ [Parameter(Mandatory = false)]
+ public string? TargetNode { get; set; }
+
+ ///
+ ///
+ /// When specified, creates a full independent clone instead of a linked clone.
+ /// A full clone is required when the source container is not a template.
+ ///
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Full { get; set; }
+
+ ///
+ /// Target storage pool for the full clone root filesystem.
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Storage { get; set; }
+
+ ///
+ /// When specified, waits for the clone task to complete before returning.
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Wait { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ var target = TargetNode ?? SourceNode;
+ if (!ShouldProcess($"Container {VmId} on node '{SourceNode}' to new container on node '{target}'", "Copy-PveContainer"))
+ return;
+
+ var session = GetSession();
+ var containerService = new ContainerService();
+
+ var task = containerService.CloneContainer(
+ session,
+ SourceNode,
+ VmId,
+ NewVmId ?? 0,
+ NewName,
+ TargetNode,
+ Full.IsPresent);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node ?? SourceNode, task.Upid!, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Containers/GetPveContainerCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Containers/GetPveContainerCmdlet.cs
new file mode 100644
index 0000000..9709284
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Containers/GetPveContainerCmdlet.cs
@@ -0,0 +1,78 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Containers;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Containers
+{
+ ///
+ /// Gets one or more LXC containers from a Proxmox VE server.
+ ///
+ /// Retrieves container objects from the Proxmox VE API. Results can be filtered by
+ /// node, container ID, name, status, or tag.
+ ///
+ ///
+ [Cmdlet(VerbsCommon.Get, "PveContainer")]
+ [OutputType(typeof(PveContainer))]
+ public sealed class GetPveContainerCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The name of the node to query. Accepts pipeline input from a PveNode object's Name property.
+ /// When omitted, containers from all nodes are returned.
+ ///
+ ///
+ [Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true)]
+ public string? Node { get; set; }
+
+ ///
+ /// Filter results to the container with this ID.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? VmId { get; set; }
+
+ ///
+ /// Filter results to containers whose name matches this value (case-insensitive, contains match).
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Name { get; set; }
+
+ ///
+ /// Filter results to containers in the specified status (e.g., "running", "stopped").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Status { get; set; }
+
+ ///
+ /// Filter results to containers that have the specified tag (substring match against the semicolon-separated tags field).
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Tag { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ var session = GetSession();
+ var service = new ContainerService();
+
+ IEnumerable containers = service.GetContainers(session, Node);
+
+ if (VmId.HasValue)
+ containers = containers.Where(c => c.VmId == VmId.Value);
+
+ if (!string.IsNullOrEmpty(Name))
+ containers = containers.Where(c => c.Name != null &&
+ c.Name.IndexOf(Name, System.StringComparison.OrdinalIgnoreCase) >= 0);
+
+ if (!string.IsNullOrEmpty(Status))
+ containers = containers.Where(c => string.Equals(c.Status, Status, System.StringComparison.OrdinalIgnoreCase));
+
+ if (!string.IsNullOrEmpty(Tag))
+ containers = containers.Where(c => c.Tags != null &&
+ c.Tags.IndexOf(Tag, System.StringComparison.OrdinalIgnoreCase) >= 0);
+
+ foreach (var container in containers)
+ WriteObject(container);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Containers/GetPveContainerConfigCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Containers/GetPveContainerConfigCmdlet.cs
new file mode 100644
index 0000000..5cafd67
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Containers/GetPveContainerConfigCmdlet.cs
@@ -0,0 +1,41 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Containers;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Containers
+{
+ ///
+ /// Gets the configuration of an LXC container.
+ ///
+ /// Retrieves the full configuration of the specified LXC container from the Proxmox VE API,
+ /// including CPU, memory, storage, network, and metadata settings.
+ ///
+ ///
+ [Cmdlet(VerbsCommon.Get, "PveContainerConfig")]
+ [OutputType(typeof(PveContainerConfig))]
+ public sealed class GetPveContainerConfigCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the container resides. Accepts pipeline input from a PveNode object's Name property.
+ ///
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public string Node { get; set; } = string.Empty;
+
+ ///
+ /// The ID of the container whose configuration to retrieve. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ var session = GetSession();
+ var containerService = new ContainerService();
+
+ var config = containerService.GetContainerConfig(session, Node, VmId);
+ WriteObject(config);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Containers/NewPveContainerCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Containers/NewPveContainerCmdlet.cs
new file mode 100644
index 0000000..6d87b8d
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Containers/NewPveContainerCmdlet.cs
@@ -0,0 +1,192 @@
+using System.Collections.Generic;
+using System.Management.Automation;
+using System.Net;
+using System.Runtime.InteropServices;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Containers
+{
+ ///
+ /// Creates a new LXC container on a Proxmox VE node.
+ ///
+ /// Creates a new Linux container using the Proxmox VE API. An OS template is required.
+ /// The container runs in unprivileged mode by default. Use -Wait to block until the
+ /// creation task completes.
+ ///
+ ///
+ [Cmdlet(VerbsCommon.New, "PveContainer", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class NewPveContainerCmdlet : PveCmdletBase
+ {
+ ///
+ /// The node on which to create the container.
+ ///
+ [Parameter(Mandatory = true, Position = 0)]
+ public string Node { get; set; } = string.Empty;
+
+ ///
+ /// The container ID to assign. When omitted, the next available ID is used.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? VmId { get; set; }
+
+ ///
+ /// The hostname to assign to the container.
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Hostname { get; set; }
+
+ ///
+ /// Memory limit in MiB.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? Memory { get; set; }
+
+ ///
+ /// Swap size in MiB.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? Swap { get; set; }
+
+ ///
+ /// Number of CPU cores to allocate to the container.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? Cores { get; set; }
+
+ ///
+ /// Size of the root filesystem (e.g., "8G").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? RootFsSize { get; set; }
+
+ ///
+ /// Storage pool for the root filesystem (e.g., "local-lvm").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? RootFsStorage { get; set; }
+
+ ///
+ ///
+ /// The OS template to use (e.g., "local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst").
+ ///
+ ///
+ [Parameter(Mandatory = false)]
+ public string? OsTemplate { get; set; }
+
+ ///
+ /// Root password for the container.
+ ///
+ [Parameter(Mandatory = false)]
+ public System.Security.SecureString? Password { get; set; }
+
+ ///
+ /// SSH public keys to inject for the root user (newline-separated).
+ ///
+ [Parameter(Mandatory = false)]
+ public string? SshPublicKeys { get; set; }
+
+ ///
+ ///
+ /// When specified (the default), the container runs in unprivileged mode.
+ /// To create a privileged container, explicitly set this to $false.
+ ///
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Unprivileged { get; set; } = new SwitchParameter(true);
+
+ ///
+ /// Network interface model (e.g., "eth0").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Network { get; set; }
+
+ ///
+ /// Network bridge to attach to (e.g., "vmbr0").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Bridge { get; set; }
+
+ ///
+ /// When specified, starts the container after creation.
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Start { get; set; }
+
+ ///
+ /// When specified, waits for the creation task to complete before returning.
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Wait { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ if (!ShouldProcess($"Container on node '{Node}'", "New-PveContainer"))
+ return;
+
+ var session = GetSession();
+ var containerService = new ContainerService();
+
+ var config = new Dictionary();
+
+ if (VmId.HasValue)
+ config["vmid"] = VmId.Value.ToString();
+ if (!string.IsNullOrEmpty(Hostname))
+ config["hostname"] = Hostname!;
+ if (Memory.HasValue)
+ config["memory"] = Memory.Value.ToString();
+ if (Swap.HasValue)
+ config["swap"] = Swap.Value.ToString();
+ if (Cores.HasValue)
+ config["cores"] = Cores.Value.ToString();
+ if (!string.IsNullOrEmpty(OsTemplate))
+ config["ostemplate"] = OsTemplate!;
+
+ if (!string.IsNullOrEmpty(RootFsStorage))
+ {
+ var rootFsValue = RootFsStorage!;
+ if (!string.IsNullOrEmpty(RootFsSize))
+ rootFsValue += $":{RootFsSize}";
+ config["rootfs"] = rootFsValue;
+ }
+
+ if (Password != null)
+ {
+ var ptr = Marshal.SecureStringToGlobalAllocUnicode(Password);
+ try
+ {
+ config["password"] = Marshal.PtrToStringUni(ptr) ?? string.Empty;
+ }
+ finally
+ {
+ Marshal.ZeroFreeGlobalAllocUnicode(ptr);
+ }
+ }
+
+ if (!string.IsNullOrEmpty(SshPublicKeys))
+ config["ssh-public-keys"] = SshPublicKeys!;
+
+ config["unprivileged"] = Unprivileged.IsPresent ? "1" : "0";
+
+ if (!string.IsNullOrEmpty(Bridge))
+ {
+ var ifName = string.IsNullOrEmpty(Network) ? "eth0" : Network!;
+ config["net0"] = $"name={ifName},bridge={Bridge}";
+ }
+
+ if (Start.IsPresent)
+ config["start"] = "1";
+
+ var task = containerService.CreateContainer(session, Node, config);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node ?? Node, task.Upid!, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Containers/RemovePveContainerCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Containers/RemovePveContainerCmdlet.cs
new file mode 100644
index 0000000..f7b38a7
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Containers/RemovePveContainerCmdlet.cs
@@ -0,0 +1,75 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Containers
+{
+ ///
+ /// Removes an LXC container from a Proxmox VE node.
+ ///
+ /// Deletes an LXC container and, optionally, all associated storage.
+ /// This operation is destructive and requires confirmation unless -Force is specified.
+ ///
+ ///
+ [Cmdlet(VerbsCommon.Remove, "PveContainer",
+ SupportsShouldProcess = true,
+ ConfirmImpact = ConfirmImpact.High)]
+ [OutputType(typeof(PveTask))]
+ public sealed class RemovePveContainerCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the container resides. Accepts pipeline input from a PveNode object's Name property.
+ ///
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public string Node { get; set; } = string.Empty;
+
+ ///
+ /// The ID of the container to remove. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ ///
+ ///
+ /// When specified, also removes the container from HA resource configuration and replication jobs.
+ ///
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Purge { get; set; }
+
+ ///
+ ///
+ /// When specified, bypasses locks and forces removal even if a lock is set on the container.
+ ///
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Force { get; set; }
+
+ ///
+ /// When specified, waits for the removal task to complete before returning.
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Wait { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ if (!ShouldProcess($"Container {VmId} on node '{Node}'", "Remove-PveContainer"))
+ return;
+
+ var session = GetSession();
+ var containerService = new ContainerService();
+
+ var task = containerService.RemoveContainer(session, Node, VmId, Purge.IsPresent);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node ?? Node, task.Upid!, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Containers/RestartPveContainerCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Containers/RestartPveContainerCmdlet.cs
new file mode 100644
index 0000000..c7e3986
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Containers/RestartPveContainerCmdlet.cs
@@ -0,0 +1,71 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Containers
+{
+ ///
+ /// Gracefully restarts an LXC container on a Proxmox VE node.
+ ///
+ /// Performs a graceful shutdown of the container followed by a start via the Proxmox VE API.
+ /// A configurable timeout controls how long to wait for the container to shut down cleanly.
+ /// Use -Wait to block until both tasks complete.
+ ///
+ ///
+ [Cmdlet(VerbsLifecycle.Restart, "PveContainer", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class RestartPveContainerCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the container resides. Accepts pipeline input from a PveNode object's Name property.
+ ///
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public string Node { get; set; } = string.Empty;
+
+ ///
+ /// The ID of the container to restart. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ ///
+ ///
+ /// Timeout in seconds for the graceful shutdown phase. Defaults to 60 seconds.
+ ///
+ ///
+ [Parameter(Mandatory = false)]
+ public int Timeout { get; set; } = 60;
+
+ ///
+ /// When specified, waits for both shutdown and start tasks to complete before returning.
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Wait { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ if (!ShouldProcess($"Container {VmId} on node '{Node}'", "Restart-PveContainer"))
+ return;
+
+ var session = GetSession();
+ var containerService = new ContainerService();
+ var taskService = new TaskService();
+
+ // Graceful shutdown
+ var shutdownTask = containerService.ShutdownContainer(session, Node, VmId, Timeout);
+
+ if (Wait.IsPresent)
+ taskService.WaitForTask(session, shutdownTask.Node ?? Node, shutdownTask.Upid!, null, null, null);
+
+ // Start
+ var startTask = containerService.StartContainer(session, Node, VmId);
+
+ if (Wait.IsPresent)
+ startTask = taskService.WaitForTask(session, startTask.Node ?? Node, startTask.Upid!, null, null, null);
+
+ WriteObject(startTask);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Containers/SetPveContainerConfigCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Containers/SetPveContainerConfigCmdlet.cs
new file mode 100644
index 0000000..bb1fc2a
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Containers/SetPveContainerConfigCmdlet.cs
@@ -0,0 +1,110 @@
+using System.Collections.Generic;
+using System.Management.Automation;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Containers
+{
+ ///
+ /// Updates the configuration of an LXC container.
+ ///
+ /// Modifies one or more configuration settings of the specified LXC container via the
+ /// Proxmox VE API. Only the parameters explicitly provided are changed; all other settings
+ /// are left untouched.
+ ///
+ ///
+ [Cmdlet(VerbsCommon.Set, "PveContainerConfig", SupportsShouldProcess = true)]
+ public sealed class SetPveContainerConfigCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the container resides. Accepts pipeline input from a PveNode object's Name property.
+ ///
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public string Node { get; set; } = string.Empty;
+
+ ///
+ /// The ID of the container to configure. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ ///
+ /// The hostname to assign to the container.
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Hostname { get; set; }
+
+ ///
+ /// Number of CPU cores to allocate to the container.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? Cores { get; set; }
+
+ ///
+ /// Memory limit in MiB.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? Memory { get; set; }
+
+ ///
+ /// Swap size in MiB.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? Swap { get; set; }
+
+ ///
+ /// Human-readable description / notes for the container.
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Description { get; set; }
+
+ ///
+ /// Semicolon-separated list of tags to assign to the container.
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Tags { get; set; }
+
+ ///
+ /// DNS nameservers (space-separated).
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Nameserver { get; set; }
+
+ ///
+ /// DNS search domain.
+ ///
+ [Parameter(Mandatory = false)]
+ public string? SearchDomain { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ if (!ShouldProcess($"Container {VmId} on node '{Node}'", "Set-PveContainerConfig"))
+ return;
+
+ var session = GetSession();
+ var containerService = new ContainerService();
+
+ var config = new Dictionary();
+
+ if (!string.IsNullOrEmpty(Hostname))
+ config["hostname"] = Hostname!;
+ if (Cores.HasValue)
+ config["cores"] = Cores.Value.ToString();
+ if (Memory.HasValue)
+ config["memory"] = Memory.Value.ToString();
+ if (Swap.HasValue)
+ config["swap"] = Swap.Value.ToString();
+ if (!string.IsNullOrEmpty(Description))
+ config["description"] = Description!;
+ if (!string.IsNullOrEmpty(Tags))
+ config["tags"] = Tags!;
+ if (!string.IsNullOrEmpty(Nameserver))
+ config["nameserver"] = Nameserver!;
+ if (!string.IsNullOrEmpty(SearchDomain))
+ config["searchdomain"] = SearchDomain!;
+
+ containerService.SetContainerConfig(session, Node, VmId, config);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Containers/StartPveContainerCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Containers/StartPveContainerCmdlet.cs
new file mode 100644
index 0000000..6cceea7
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Containers/StartPveContainerCmdlet.cs
@@ -0,0 +1,57 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Containers
+{
+ ///
+ /// Starts an LXC container on a Proxmox VE node.
+ ///
+ /// Sends a start command to the specified LXC container via the Proxmox VE API.
+ /// Use -Wait to block until the start task completes.
+ ///
+ ///
+ [Cmdlet(VerbsLifecycle.Start, "PveContainer", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class StartPveContainerCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the container resides. Accepts pipeline input from a PveNode object's Name property.
+ ///
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public string Node { get; set; } = string.Empty;
+
+ ///
+ /// The ID of the container to start. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ ///
+ /// When specified, waits for the start task to complete before returning.
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Wait { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ if (!ShouldProcess($"Container {VmId} on node '{Node}'", "Start-PveContainer"))
+ return;
+
+ var session = GetSession();
+ var containerService = new ContainerService();
+
+ var task = containerService.StartContainer(session, Node, VmId);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node ?? Node, task.Upid!, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Containers/StopPveContainerCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Containers/StopPveContainerCmdlet.cs
new file mode 100644
index 0000000..70c2129
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Containers/StopPveContainerCmdlet.cs
@@ -0,0 +1,59 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Containers
+{
+ ///
+ /// Stops (powers off) an LXC container on a Proxmox VE node.
+ ///
+ /// Sends a stop command to the specified LXC container via the Proxmox VE API.
+ /// This immediately terminates the container without a graceful shutdown.
+ /// Use Restart-PveContainer or a guest-initiated shutdown for graceful stops.
+ /// Use -Wait to block until the stop task completes.
+ ///
+ ///
+ [Cmdlet(VerbsLifecycle.Stop, "PveContainer", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class StopPveContainerCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the container resides. Accepts pipeline input from a PveNode object's Name property.
+ ///
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public string Node { get; set; } = string.Empty;
+
+ ///
+ /// The ID of the container to stop. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ ///
+ /// When specified, waits for the stop task to complete before returning.
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Wait { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ if (!ShouldProcess($"Container {VmId} on node '{Node}'", "Stop-PveContainer"))
+ return;
+
+ var session = GetSession();
+ var containerService = new ContainerService();
+
+ var task = containerService.StopContainer(session, Node, VmId);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node ?? Node, task.Upid!, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}