diff --git a/src/PSProxmoxVE/Cmdlets/Vms/CopyPveVmCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/CopyPveVmCmdlet.cs
new file mode 100644
index 0000000..4ebc5a2
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Vms/CopyPveVmCmdlet.cs
@@ -0,0 +1,92 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Vms
+{
+ ///
+ /// Clones (copies) a QEMU/KVM virtual machine on a Proxmox VE node.
+ ///
+ /// Creates a clone of an existing VM. 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, "PveVm", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class CopyPveVmCmdlet : PveCmdletBase
+ {
+ ///
+ /// The node on which the source VM resides.
+ ///
+ [Parameter(Mandatory = true)]
+ public string SourceNode { get; set; } = string.Empty;
+
+ ///
+ /// The ID of the source VM to clone. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ ///
+ /// The VM ID to assign to the new clone. When omitted, the next available ID is used.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? NewVmId { get; set; }
+
+ ///
+ /// The display name 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 VM is not a template.
+ ///
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Full { get; set; }
+
+ ///
+ /// Target storage pool for the full clone disks.
+ ///
+ [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($"VM {VmId} on node '{SourceNode}' to new VM on node '{target}'", "Copy-PveVm"))
+ return;
+
+ var session = GetSession();
+ var vmService = new VmService();
+
+ var newid = NewVmId ?? 0;
+ var task = vmService.CloneVm(session, SourceNode, VmId, newid, NewName, TargetNode, Full.IsPresent);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node, task.Upid, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Vms/GetPveVmCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/GetPveVmCmdlet.cs
new file mode 100644
index 0000000..a3532c0
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Vms/GetPveVmCmdlet.cs
@@ -0,0 +1,87 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Vms
+{
+ ///
+ /// Gets one or more QEMU/KVM virtual machines from a Proxmox VE server.
+ ///
+ /// Retrieves virtual machine objects from the Proxmox VE API. Results can be filtered by
+ /// node, VM ID, name, status, tag, or limited to template VMs only.
+ ///
+ ///
+ [Cmdlet(VerbsCommon.Get, "PveVm")]
+ [OutputType(typeof(PveVm))]
+ public sealed class GetPveVmCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The name of the node to query. Accepts pipeline input from a PveNode object's Name property.
+ /// When omitted, VMs from all nodes are returned.
+ ///
+ ///
+ [Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true)]
+ public string? Node { get; set; }
+
+ ///
+ /// Filter results to the VM with this ID.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? VmId { get; set; }
+
+ ///
+ /// Filter results to VMs whose name matches this value (case-insensitive, contains match).
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Name { get; set; }
+
+ ///
+ /// Filter results to VMs in the specified status (e.g., "running", "stopped").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Status { get; set; }
+
+ ///
+ /// Filter results to VMs that have the specified tag (substring match against the semicolon-separated tags field).
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Tag { get; set; }
+
+ ///
+ /// When specified, returns only VMs that are marked as templates.
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter TemplatesOnly { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ var session = GetSession();
+ var service = new VmService();
+
+ IEnumerable vms = service.GetVms(session, Node);
+
+ if (VmId.HasValue)
+ vms = vms.Where(v => v.VmId == VmId.Value);
+
+ if (!string.IsNullOrEmpty(Name))
+ vms = vms.Where(v => v.Name != null &&
+ v.Name.IndexOf(Name, System.StringComparison.OrdinalIgnoreCase) >= 0);
+
+ if (!string.IsNullOrEmpty(Status))
+ vms = vms.Where(v => string.Equals(v.Status, Status, System.StringComparison.OrdinalIgnoreCase));
+
+ if (!string.IsNullOrEmpty(Tag))
+ vms = vms.Where(v => v.Tags != null &&
+ v.Tags.IndexOf(Tag, System.StringComparison.OrdinalIgnoreCase) >= 0);
+
+ if (TemplatesOnly.IsPresent)
+ vms = vms.Where(v => v.Template == 1);
+
+ foreach (var vm in vms)
+ WriteObject(vm);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Vms/GetPveVmConfigCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/GetPveVmConfigCmdlet.cs
new file mode 100644
index 0000000..f4b8696
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Vms/GetPveVmConfigCmdlet.cs
@@ -0,0 +1,41 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Vms
+{
+ ///
+ /// Gets the configuration of a QEMU/KVM virtual machine.
+ ///
+ /// Retrieves the full hardware and metadata configuration of the specified virtual machine
+ /// from the Proxmox VE API, including CPU, memory, disk, network, and cloud-init settings.
+ ///
+ ///
+ [Cmdlet(VerbsCommon.Get, "PveVmConfig")]
+ [OutputType(typeof(PveVmConfig))]
+ public sealed class GetPveVmConfigCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the VM 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 VM 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 vmService = new VmService();
+
+ var config = vmService.GetVmConfig(session, Node, VmId);
+ WriteObject(config);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Vms/MovePveVmCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/MovePveVmCmdlet.cs
new file mode 100644
index 0000000..38539f4
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Vms/MovePveVmCmdlet.cs
@@ -0,0 +1,73 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Vms
+{
+ ///
+ /// Migrates a QEMU/KVM virtual machine to a different Proxmox VE node.
+ ///
+ /// Performs a live or offline migration of the specified virtual machine to the target node.
+ /// Use -Online for live migration (VM remains running). Use -Wait to block until the
+ /// migration task completes.
+ ///
+ ///
+ [Cmdlet(VerbsCommon.Move, "PveVm", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class MovePveVmCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the VM currently 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 VM to migrate. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ ///
+ /// The destination node to migrate the VM to.
+ ///
+ [Parameter(Mandatory = true)]
+ public string TargetNode { get; set; } = string.Empty;
+
+ ///
+ ///
+ /// When specified, performs a live migration so the VM remains running during migration.
+ /// Requires shared storage between the source and target nodes.
+ ///
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Online { get; set; }
+
+ ///
+ /// When specified, waits for the migration task to complete before returning.
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Wait { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ if (!ShouldProcess($"VM {VmId} from node '{Node}' to node '{TargetNode}'", "Move-PveVm"))
+ return;
+
+ var session = GetSession();
+ var vmService = new VmService();
+
+ var task = vmService.MigrateVm(session, Node, VmId, TargetNode, Online.IsPresent);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node, task.Upid, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Vms/NewPveVmCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/NewPveVmCmdlet.cs
new file mode 100644
index 0000000..eed3d2a
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Vms/NewPveVmCmdlet.cs
@@ -0,0 +1,178 @@
+using System.Collections.Generic;
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Vms
+{
+ ///
+ /// Creates a new QEMU/KVM virtual machine on a Proxmox VE node.
+ ///
+ /// Creates a new virtual machine using the Proxmox VE API. Supports common hardware
+ /// configuration options. Use -Wait to block until the creation task completes.
+ ///
+ ///
+ [Cmdlet(VerbsCommon.New, "PveVm", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class NewPveVmCmdlet : PveCmdletBase
+ {
+ ///
+ /// The node on which to create the VM.
+ ///
+ [Parameter(Mandatory = true, Position = 0)]
+ public string Node { get; set; } = string.Empty;
+
+ ///
+ /// The VM ID to assign. When omitted, the next available ID is used.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? VmId { get; set; }
+
+ ///
+ /// The display name of the VM.
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Name { get; set; }
+
+ ///
+ /// Memory size in MiB.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? Memory { get; set; }
+
+ ///
+ /// Number of CPU cores per socket.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? Cores { get; set; }
+
+ ///
+ /// Number of CPU sockets.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? Sockets { get; set; }
+
+ ///
+ /// Emulated CPU type (e.g., "host", "x86-64-v2-AES").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? CpuType { get; set; }
+
+ ///
+ /// BIOS type: "seabios" (default) or "ovmf" (UEFI).
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Bios { get; set; }
+
+ ///
+ /// Emulated machine type (e.g., "q35", "i440fx").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Machine { get; set; }
+
+ ///
+ /// Size of the primary disk (e.g., "32G").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? DiskSize { get; set; }
+
+ ///
+ /// Storage pool for the primary disk (e.g., "local-lvm").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? DiskStorage { get; set; }
+
+ ///
+ /// Disk format (e.g., "raw", "qcow2").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? DiskFormat { get; set; }
+
+ ///
+ /// Network interface model (e.g., "virtio", "e1000").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Network { get; set; }
+
+ ///
+ /// Network bridge to attach to (e.g., "vmbr0").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Bridge { get; set; }
+
+ ///
+ /// Guest OS type hint (e.g., "l26" for Linux 2.6+, "win10").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? OsType { get; set; }
+
+ ///
+ /// When specified, starts the VM 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($"VM on node '{Node}'", "New-PveVm"))
+ return;
+
+ var session = GetSession();
+ var vmService = new VmService();
+
+ var config = new Dictionary();
+
+ if (VmId.HasValue)
+ config["vmid"] = VmId.Value;
+ if (!string.IsNullOrEmpty(Name))
+ config["name"] = Name!;
+ if (Memory.HasValue)
+ config["memory"] = Memory.Value;
+ if (Cores.HasValue)
+ config["cores"] = Cores.Value;
+ if (Sockets.HasValue)
+ config["sockets"] = Sockets.Value;
+ if (!string.IsNullOrEmpty(CpuType))
+ config["cpu"] = CpuType!;
+ if (!string.IsNullOrEmpty(Bios))
+ config["bios"] = Bios!;
+ if (!string.IsNullOrEmpty(Machine))
+ config["machine"] = Machine!;
+ if (!string.IsNullOrEmpty(OsType))
+ config["ostype"] = OsType!;
+
+ if (!string.IsNullOrEmpty(DiskStorage) && !string.IsNullOrEmpty(DiskSize))
+ {
+ var diskValue = $"{DiskStorage}:{DiskSize}";
+ if (!string.IsNullOrEmpty(DiskFormat))
+ diskValue += $",format={DiskFormat}";
+ config["virtio0"] = diskValue;
+ }
+
+ if (!string.IsNullOrEmpty(Bridge))
+ {
+ var netModel = string.IsNullOrEmpty(Network) ? "virtio" : Network!;
+ config["net0"] = $"{netModel},bridge={Bridge}";
+ }
+
+ if (Start.IsPresent)
+ config["start"] = "1";
+
+ var task = vmService.CreateVm(session, Node, config);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node, task.Upid, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Vms/RemovePveVmCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/RemovePveVmCmdlet.cs
new file mode 100644
index 0000000..bd3813d
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Vms/RemovePveVmCmdlet.cs
@@ -0,0 +1,75 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Vms
+{
+ ///
+ /// Removes a QEMU/KVM virtual machine from a Proxmox VE node.
+ ///
+ /// Deletes a virtual machine and, optionally, all associated disk images.
+ /// This operation is destructive and requires confirmation unless -Force is specified.
+ ///
+ ///
+ [Cmdlet(VerbsCommon.Remove, "PveVm",
+ SupportsShouldProcess = true,
+ ConfirmImpact = ConfirmImpact.High)]
+ [OutputType(typeof(PveTask))]
+ public sealed class RemovePveVmCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the VM 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 VM to remove. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ ///
+ ///
+ /// When specified, also removes the VM 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 VM.
+ ///
+ ///
+ [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($"VM {VmId} on node '{Node}'", "Remove-PveVm"))
+ return;
+
+ var session = GetSession();
+ var vmService = new VmService();
+
+ var task = vmService.RemoveVm(session, Node, VmId, Purge.IsPresent);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node, task.Upid, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Vms/ResetPveVmCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/ResetPveVmCmdlet.cs
new file mode 100644
index 0000000..0d9e44e
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Vms/ResetPveVmCmdlet.cs
@@ -0,0 +1,59 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Vms
+{
+ ///
+ /// Resets (hard-resets) a QEMU/KVM virtual machine on a Proxmox VE node.
+ ///
+ /// Sends a hard-reset signal to the specified virtual machine via the Proxmox VE API.
+ /// This is equivalent to pressing the physical reset button on a machine — no graceful
+ /// shutdown occurs. Use Restart-PveVm for a graceful reboot.
+ /// Use -Wait to block until the reset task completes.
+ ///
+ ///
+ [Cmdlet("Reset", "PveVm", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class ResetPveVmCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the VM 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 VM to reset. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ ///
+ /// When specified, waits for the reset task to complete before returning.
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Wait { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ if (!ShouldProcess($"VM {VmId} on node '{Node}'", "Reset-PveVm"))
+ return;
+
+ var session = GetSession();
+ var vmService = new VmService();
+
+ var task = vmService.ResetVm(session, Node, VmId);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node, task.Upid, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Vms/ResizePveVmDiskCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/ResizePveVmDiskCmdlet.cs
new file mode 100644
index 0000000..abaec99
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Vms/ResizePveVmDiskCmdlet.cs
@@ -0,0 +1,77 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Vms
+{
+ ///
+ /// Resizes a disk attached to a QEMU/KVM virtual machine.
+ ///
+ /// Resizes the specified disk on a virtual machine via the Proxmox VE API.
+ /// Use an absolute size (e.g., "50G") to set a fixed size, or a relative size
+ /// prefixed with "+" (e.g., "+10G") to grow the disk by that amount.
+ /// Disk shrinking is not supported by Proxmox VE.
+ /// Use -Wait to block until the resize task completes.
+ ///
+ ///
+ [Cmdlet(VerbsCommon.Resize, "PveVmDisk", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class ResizePveVmDiskCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the VM 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 VM whose disk should be resized. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ ///
+ ///
+ /// The disk slot to resize (e.g., "virtio0", "scsi0", "ide0", "sata0").
+ ///
+ ///
+ [Parameter(Mandatory = true)]
+ public string Disk { get; set; } = string.Empty;
+
+ ///
+ ///
+ /// The new size for the disk. Use an absolute value (e.g., "50G") to set a specific size,
+ /// or a "+" prefix (e.g., "+10G") to grow the disk by the specified amount.
+ ///
+ ///
+ [Parameter(Mandatory = true)]
+ public string Size { get; set; } = string.Empty;
+
+ ///
+ /// When specified, waits for the resize task to complete before returning.
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Wait { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ if (!ShouldProcess($"Disk '{Disk}' on VM {VmId} (node '{Node}') to size '{Size}'", "Resize-PveVmDisk"))
+ return;
+
+ var session = GetSession();
+ var vmService = new VmService();
+
+ var task = vmService.ResizeDisk(session, Node, VmId, Disk, Size);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node, task.Upid, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Vms/RestartPveVmCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/RestartPveVmCmdlet.cs
new file mode 100644
index 0000000..ca33251
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Vms/RestartPveVmCmdlet.cs
@@ -0,0 +1,71 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Vms
+{
+ ///
+ /// Gracefully restarts a QEMU/KVM virtual machine on a Proxmox VE node.
+ ///
+ /// Performs a graceful shutdown of the VM followed by a start, via the Proxmox VE API.
+ /// A configurable timeout controls how long to wait for the guest to shut down cleanly
+ /// before the operation is considered failed. Use -Wait to block until both tasks complete.
+ ///
+ ///
+ [Cmdlet(VerbsLifecycle.Restart, "PveVm", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class RestartPveVmCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the VM 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 VM 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($"VM {VmId} on node '{Node}'", "Restart-PveVm"))
+ return;
+
+ var session = GetSession();
+ var vmService = new VmService();
+ var taskService = new TaskService();
+
+ // Graceful shutdown
+ var shutdownTask = vmService.ShutdownVm(session, Node, VmId, Timeout);
+
+ if (Wait.IsPresent)
+ taskService.WaitForTask(session, shutdownTask.Node, shutdownTask.Upid, null, null, null);
+
+ // Start
+ var startTask = vmService.StartVm(session, Node, VmId);
+
+ if (Wait.IsPresent)
+ startTask = taskService.WaitForTask(session, startTask.Node, startTask.Upid, null, null, null);
+
+ WriteObject(startTask);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Vms/ResumePveVmCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/ResumePveVmCmdlet.cs
new file mode 100644
index 0000000..54ba77c
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Vms/ResumePveVmCmdlet.cs
@@ -0,0 +1,57 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Vms
+{
+ ///
+ /// Resumes a suspended QEMU/KVM virtual machine on a Proxmox VE node.
+ ///
+ /// Resumes execution of a previously suspended virtual machine via the Proxmox VE API.
+ /// Use -Wait to block until the resume task completes.
+ ///
+ ///
+ [Cmdlet(VerbsLifecycle.Resume, "PveVm", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class ResumePveVmCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the VM 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 VM to resume. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ ///
+ /// When specified, waits for the resume task to complete before returning.
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Wait { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ if (!ShouldProcess($"VM {VmId} on node '{Node}'", "Resume-PveVm"))
+ return;
+
+ var session = GetSession();
+ var vmService = new VmService();
+
+ var task = vmService.ResumeVm(session, Node, VmId);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node, task.Upid, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Vms/SetPveVmConfigCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/SetPveVmConfigCmdlet.cs
new file mode 100644
index 0000000..1a16aa5
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Vms/SetPveVmConfigCmdlet.cs
@@ -0,0 +1,118 @@
+using System.Collections.Generic;
+using System.Management.Automation;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Vms
+{
+ ///
+ /// Updates the configuration of a QEMU/KVM virtual machine.
+ ///
+ /// Modifies one or more configuration settings of the specified virtual machine via the
+ /// Proxmox VE API. Only the parameters explicitly provided are changed; all other settings
+ /// are left untouched. The operation is synchronous and produces no output.
+ ///
+ ///
+ [Cmdlet(VerbsCommon.Set, "PveVmConfig", SupportsShouldProcess = true)]
+ public sealed class SetPveVmConfigCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the VM 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 VM to configure. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ ///
+ /// Number of CPU cores per socket.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? Cores { get; set; }
+
+ ///
+ /// Number of CPU sockets.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? Sockets { get; set; }
+
+ ///
+ /// Memory size in MiB.
+ ///
+ [Parameter(Mandatory = false)]
+ public int? Memory { get; set; }
+
+ ///
+ /// Emulated CPU type (e.g., "host", "x86-64-v2-AES").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? CpuType { get; set; }
+
+ ///
+ /// Human-readable description / notes for the VM.
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Description { get; set; }
+
+ ///
+ /// Semicolon-separated list of tags to assign to the VM.
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Tags { get; set; }
+
+ ///
+ /// BIOS type: "seabios" or "ovmf".
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Bios { get; set; }
+
+ ///
+ /// Emulated machine type (e.g., "q35", "i440fx").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? Machine { get; set; }
+
+ ///
+ /// Guest OS type hint (e.g., "l26", "win10").
+ ///
+ [Parameter(Mandatory = false)]
+ public string? OsType { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ if (!ShouldProcess($"VM {VmId} on node '{Node}'", "Set-PveVmConfig"))
+ return;
+
+ var session = GetSession();
+ var vmService = new VmService();
+
+ var config = new Dictionary();
+
+ if (Cores.HasValue)
+ config["cores"] = Cores.Value;
+ if (Sockets.HasValue)
+ config["sockets"] = Sockets.Value;
+ if (Memory.HasValue)
+ config["memory"] = Memory.Value;
+ if (!string.IsNullOrEmpty(CpuType))
+ config["cpu"] = CpuType!;
+ if (!string.IsNullOrEmpty(Description))
+ config["description"] = Description!;
+ if (!string.IsNullOrEmpty(Tags))
+ config["tags"] = Tags!;
+ if (!string.IsNullOrEmpty(Bios))
+ config["bios"] = Bios!;
+ if (!string.IsNullOrEmpty(Machine))
+ config["machine"] = Machine!;
+ if (!string.IsNullOrEmpty(OsType))
+ config["ostype"] = OsType!;
+
+ vmService.SetVmConfig(session, Node, VmId, config);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Vms/StartPveVmCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/StartPveVmCmdlet.cs
new file mode 100644
index 0000000..9dd632c
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Vms/StartPveVmCmdlet.cs
@@ -0,0 +1,57 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Vms
+{
+ ///
+ /// Starts a QEMU/KVM virtual machine on a Proxmox VE node.
+ ///
+ /// Sends a start command to the specified virtual machine via the Proxmox VE API.
+ /// Use -Wait to block until the start task completes.
+ ///
+ ///
+ [Cmdlet(VerbsLifecycle.Start, "PveVm", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class StartPveVmCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the VM 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 VM 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($"VM {VmId} on node '{Node}'", "Start-PveVm"))
+ return;
+
+ var session = GetSession();
+ var vmService = new VmService();
+
+ var task = vmService.StartVm(session, Node, VmId);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node, task.Upid, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Vms/StopPveVmCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/StopPveVmCmdlet.cs
new file mode 100644
index 0000000..f897a97
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Vms/StopPveVmCmdlet.cs
@@ -0,0 +1,59 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Vms
+{
+ ///
+ /// Stops (powers off) a QEMU/KVM virtual machine on a Proxmox VE node.
+ ///
+ /// Sends a stop command to the specified virtual machine via the Proxmox VE API.
+ /// This is equivalent to pulling the power plug — the VM is stopped immediately without
+ /// a graceful shutdown. Use Restart-PveVm or a guest-initiated shutdown for graceful stops.
+ /// Use -Wait to block until the stop task completes.
+ ///
+ ///
+ [Cmdlet(VerbsLifecycle.Stop, "PveVm", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class StopPveVmCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the VM 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 VM 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($"VM {VmId} on node '{Node}'", "Stop-PveVm"))
+ return;
+
+ var session = GetSession();
+ var vmService = new VmService();
+
+ var task = vmService.StopVm(session, Node, VmId);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node, task.Upid, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}
diff --git a/src/PSProxmoxVE/Cmdlets/Vms/SuspendPveVmCmdlet.cs b/src/PSProxmoxVE/Cmdlets/Vms/SuspendPveVmCmdlet.cs
new file mode 100644
index 0000000..d89c010
--- /dev/null
+++ b/src/PSProxmoxVE/Cmdlets/Vms/SuspendPveVmCmdlet.cs
@@ -0,0 +1,58 @@
+using System.Management.Automation;
+using PSProxmoxVE.Core.Models.Vms;
+using PSProxmoxVE.Core.Services;
+
+namespace PSProxmoxVE.Cmdlets.Vms
+{
+ ///
+ /// Suspends a QEMU/KVM virtual machine on a Proxmox VE node.
+ ///
+ /// Suspends (pauses) the specified virtual machine via the Proxmox VE API.
+ /// The VM state is preserved in memory. Use Resume-PveVm to resume execution.
+ /// Use -Wait to block until the suspend task completes.
+ ///
+ ///
+ [Cmdlet(VerbsLifecycle.Suspend, "PveVm", SupportsShouldProcess = true)]
+ [OutputType(typeof(PveTask))]
+ public sealed class SuspendPveVmCmdlet : PveCmdletBase
+ {
+ ///
+ ///
+ /// The node on which the VM 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 VM to suspend. Accepts pipeline input.
+ ///
+ [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
+ public int VmId { get; set; }
+
+ ///
+ /// When specified, waits for the suspend task to complete before returning.
+ ///
+ [Parameter(Mandatory = false)]
+ public SwitchParameter Wait { get; set; }
+
+ protected override void ProcessRecord()
+ {
+ if (!ShouldProcess($"VM {VmId} on node '{Node}'", "Suspend-PveVm"))
+ return;
+
+ var session = GetSession();
+ var vmService = new VmService();
+
+ var task = vmService.SuspendVm(session, Node, VmId);
+
+ if (Wait.IsPresent)
+ {
+ var taskService = new TaskService();
+ task = taskService.WaitForTask(session, task.Node, task.Upid, null, null, null);
+ }
+
+ WriteObject(task);
+ }
+ }
+}