Initial commit of PSProxmox module

This commit is contained in:
Alphaeus Mote
2025-04-28 14:11:32 -04:00
commit 2385442c83
80 changed files with 9481 additions and 0 deletions
+67
View File
@@ -0,0 +1,67 @@
using System;
using System.Management.Automation;
using PSProxmox.IPAM;
using PSProxmox.Models;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Clears an IP address pool.</para>
/// <para type="description">The Clear-ProxmoxIPPool cmdlet clears all used IP addresses from an IP pool and returns them to the available pool.</para>
/// <example>
/// <para>Clear a specific IP pool</para>
/// <code>Clear-ProxmoxIPPool -Name "Production"</code>
/// </example>
/// <example>
/// <para>Clear all IP pools</para>
/// <code>Clear-ProxmoxIPPool -All</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Clear, "ProxmoxIPPool")]
[OutputType(typeof(ProxmoxIPPool))]
public class ClearProxmoxIPPoolCmdlet : PSCmdlet
{
private static readonly IPAMManager _ipamManager = new IPAMManager();
/// <summary>
/// <para type="description">The name of the IP pool to clear.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0, ParameterSetName = "ByName")]
public string Name { get; set; }
/// <summary>
/// <para type="description">Whether to clear all IP pools.</para>
/// </summary>
[Parameter(Mandatory = true, ParameterSetName = "All")]
public SwitchParameter All { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
if (ParameterSetName == "ByName")
{
// Clear a specific pool
var pool = _ipamManager.GetPool(Name);
pool.Clear();
WriteObject(ProxmoxIPPool.FromIPPool(pool));
}
else
{
// Clear all pools
foreach (var pool in _ipamManager.GetPools())
{
pool.Clear();
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "ClearProxmoxIPPoolError", ErrorCategory.InvalidOperation, Name));
}
}
}
}
+120
View File
@@ -0,0 +1,120 @@
using System;
using System.Management.Automation;
using System.Security;
using PSProxmox.Models;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Connects to a Proxmox VE server.</para>
/// <para type="description">The Connect-ProxmoxServer cmdlet establishes a connection to a Proxmox VE server and returns a connection object that can be used with other cmdlets.</para>
/// <example>
/// <para>Connect to a Proxmox VE server using a credential object</para>
/// <code>$credential = Get-Credential
/// $connection = Connect-ProxmoxServer -Server "proxmox.example.com" -Credential $credential</code>
/// </example>
/// <example>
/// <para>Connect to a Proxmox VE server with explicit username and password</para>
/// <code>$securePassword = ConvertTo-SecureString "password" -AsPlainText -Force
/// $connection = Connect-ProxmoxServer -Server "proxmox.example.com" -Username "root" -Password $securePassword -Realm "pam"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommunications.Connect, "ProxmoxServer")]
[OutputType(typeof(ProxmoxConnectionInfo))]
public class ConnectProxmoxServerCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The server hostname or IP address.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public string Server { get; set; }
/// <summary>
/// <para type="description">The port number.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int Port { get; set; } = 8006;
/// <summary>
/// <para type="description">Whether to use HTTPS.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter UseSSL { get; set; } = true;
/// <summary>
/// <para type="description">Whether to skip SSL certificate validation.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter SkipCertificateValidation { get; set; }
/// <summary>
/// <para type="description">The credential object containing username and password.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Credential")]
public PSCredential Credential { get; set; }
/// <summary>
/// <para type="description">The username for authentication.</para>
/// </summary>
[Parameter(Mandatory = true, ParameterSetName = "UsernamePassword")]
public string Username { get; set; }
/// <summary>
/// <para type="description">The password for authentication.</para>
/// </summary>
[Parameter(Mandatory = true, ParameterSetName = "UsernamePassword")]
public SecureString Password { get; set; }
/// <summary>
/// <para type="description">The realm for authentication.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Realm { get; set; } = "pam";
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
string username;
SecureString password;
if (ParameterSetName == "Credential")
{
if (Credential == null)
{
throw new PSArgumentNullException(nameof(Credential));
}
username = Credential.UserName;
password = Credential.Password;
}
else
{
username = Username;
password = Password;
}
var connection = ProxmoxSession.Login(
Server,
Port,
UseSSL.IsPresent,
SkipCertificateValidation.IsPresent,
username,
password,
Realm,
this);
WriteObject(ProxmoxConnectionInfo.FromConnection(connection));
SessionState.PSVariable.Set(new PSVariable("ProxmoxConnection", connection, ScopedItemOptions.Private));
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "ConnectProxmoxServerError", ErrorCategory.ConnectionError, Server));
}
}
}
}
+45
View File
@@ -0,0 +1,45 @@
using System;
using System.Management.Automation;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Disconnects from a Proxmox VE server.</para>
/// <para type="description">The Disconnect-ProxmoxServer cmdlet terminates a connection to a Proxmox VE server.</para>
/// <example>
/// <para>Disconnect from a Proxmox VE server</para>
/// <code>Disconnect-ProxmoxServer -Connection $connection</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommunications.Disconnect, "ProxmoxServer")]
public class DisconnectProxmoxServerCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to disconnect from.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
if (Connection == null)
{
throw new PSArgumentNullException(nameof(Connection));
}
ProxmoxSession.Logout(Connection, this);
WriteVerbose($"Disconnected from {Connection.Server}");
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "DisconnectProxmoxServerError", ErrorCategory.ConnectionError, Connection));
}
}
}
}
+98
View File
@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets cluster backups from Proxmox VE.</para>
/// <para type="description">The Get-ProxmoxClusterBackup cmdlet retrieves cluster backups from Proxmox VE.</para>
/// <example>
/// <para>Get all cluster backups</para>
/// <code>$backups = Get-ProxmoxClusterBackup -Connection $connection</code>
/// </example>
/// <example>
/// <para>Get a specific cluster backup by ID</para>
/// <code>$backup = Get-ProxmoxClusterBackup -Connection $connection -BackupID "vzdump-cluster-2023_04_28-12_00_00.vma.lzo"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "ProxmoxClusterBackup")]
[OutputType(typeof(ProxmoxClusterBackup), typeof(string))]
public class GetProxmoxClusterBackupCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The ID of the backup to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string BackupID { get; set; }
/// <summary>
/// <para type="description">Whether to return the raw JSON response.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter RawJson { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
string response;
response = client.Get("cluster/backup");
var backupsData = JsonUtility.DeserializeResponse<JArray>(response);
var backups = new List<ProxmoxClusterBackup>();
foreach (var backupObj in backupsData)
{
var backup = backupObj.ToObject<ProxmoxClusterBackup>();
if (string.IsNullOrEmpty(BackupID) || backup.BackupID == BackupID)
{
backups.Add(backup);
}
}
if (RawJson.IsPresent)
{
WriteObject(response);
}
else if (string.IsNullOrEmpty(BackupID))
{
WriteObject(backups, true);
}
else if (backups.Count > 0)
{
WriteObject(backups[0]);
}
else
{
WriteError(new ErrorRecord(
new Exception($"Backup with ID {BackupID} not found"),
"BackupNotFound",
ErrorCategory.ObjectNotFound,
BackupID));
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetProxmoxClusterBackupError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+97
View File
@@ -0,0 +1,97 @@
using System;
using System.Management.Automation;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets cluster information from Proxmox VE.</para>
/// <para type="description">The Get-ProxmoxCluster cmdlet retrieves cluster information from Proxmox VE.</para>
/// <example>
/// <para>Get cluster information</para>
/// <code>$cluster = Get-ProxmoxCluster -Connection $connection</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "ProxmoxCluster")]
[OutputType(typeof(ProxmoxCluster), typeof(string))]
public class GetProxmoxClusterCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">Whether to return the raw JSON response.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter RawJson { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Get cluster status
string statusResponse = client.Get("cluster/status");
var statusData = JsonUtility.DeserializeResponse<JArray>(statusResponse);
// Get cluster config
string configResponse = client.Get("cluster/config");
var configData = JsonUtility.DeserializeResponse<JObject>(configResponse);
// Create the cluster object
var cluster = new ProxmoxCluster();
// Parse the cluster name and ID from the config
if (configData["cluster"] != null)
{
cluster.Name = configData["cluster"]["name"]?.ToString();
cluster.ID = configData["cluster"]["clusterId"]?.ToString();
}
// Parse the cluster version
if (statusData != null)
{
foreach (var item in statusData)
{
if (item["type"]?.ToString() == "cluster")
{
cluster.Version = item["version"]?.ToString();
cluster.ConfigVersion = item["config_version"]?.ToObject<int>() ?? 0;
break;
}
}
}
if (RawJson.IsPresent)
{
var combinedResponse = new JObject
{
["status"] = statusData,
["config"] = configData
};
WriteObject(combinedResponse.ToString());
}
else
{
WriteObject(cluster);
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetProxmoxClusterError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+63
View File
@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PSProxmox.IPAM;
using PSProxmox.Models;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets IP address pools.</para>
/// <para type="description">The Get-ProxmoxIPPool cmdlet retrieves IP address pools used with Proxmox VE virtual machines.</para>
/// <example>
/// <para>Get all IP pools</para>
/// <code>$pools = Get-ProxmoxIPPool</code>
/// </example>
/// <example>
/// <para>Get a specific IP pool by name</para>
/// <code>$pool = Get-ProxmoxIPPool -Name "Production"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "ProxmoxIPPool")]
[OutputType(typeof(ProxmoxIPPool))]
public class GetProxmoxIPPoolCmdlet : PSCmdlet
{
private static readonly IPAMManager _ipamManager = new IPAMManager();
/// <summary>
/// <para type="description">The name of the IP pool to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false, Position = 0)]
public string Name { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
if (string.IsNullOrEmpty(Name))
{
// Get all pools
var pools = new List<ProxmoxIPPool>();
foreach (var pool in _ipamManager.GetPools())
{
pools.Add(ProxmoxIPPool.FromIPPool(pool));
}
WriteObject(pools, true);
}
else
{
// Get a specific pool
var pool = _ipamManager.GetPool(Name);
WriteObject(ProxmoxIPPool.FromIPPool(pool));
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetProxmoxIPPoolError", ErrorCategory.InvalidOperation, Name));
}
}
}
}
+110
View File
@@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets network interfaces from Proxmox VE.</para>
/// <para type="description">The Get-ProxmoxNetwork cmdlet retrieves network interfaces from Proxmox VE.</para>
/// <example>
/// <para>Get all network interfaces</para>
/// <code>$networks = Get-ProxmoxNetwork -Connection $connection -Node "pve1"</code>
/// </example>
/// <example>
/// <para>Get a specific network interface by name</para>
/// <code>$network = Get-ProxmoxNetwork -Connection $connection -Node "pve1" -Interface "vmbr0"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "ProxmoxNetwork")]
[OutputType(typeof(ProxmoxNetwork), typeof(string))]
public class GetProxmoxNetworkCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The node to retrieve network interfaces from.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string Node { get; set; }
/// <summary>
/// <para type="description">The name of the interface to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Interface { get; set; }
/// <summary>
/// <para type="description">Whether to return the raw JSON response.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter RawJson { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
string response;
if (string.IsNullOrEmpty(Interface))
{
// Get all network interfaces
response = client.Get($"nodes/{Node}/network");
var networksData = JsonUtility.DeserializeResponse<JArray>(response);
var networks = new List<ProxmoxNetwork>();
foreach (var networkObj in networksData)
{
var network = networkObj.ToObject<ProxmoxNetwork>();
network.Node = Node;
networks.Add(network);
}
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(networks, true);
}
}
else
{
// Get a specific network interface
response = client.Get($"nodes/{Node}/network/{Interface}");
var networkData = JsonUtility.DeserializeResponse<JObject>(response);
var network = networkData.ToObject<ProxmoxNetwork>();
network.Node = Node;
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(network);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetProxmoxNetworkError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+103
View File
@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets nodes from a Proxmox VE cluster.</para>
/// <para type="description">The Get-ProxmoxNode cmdlet retrieves nodes from a Proxmox VE cluster.</para>
/// <example>
/// <para>Get all nodes</para>
/// <code>$nodes = Get-ProxmoxNode -Connection $connection</code>
/// </example>
/// <example>
/// <para>Get a specific node by name</para>
/// <code>$node = Get-ProxmoxNode -Connection $connection -Name "pve1"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "ProxmoxNode")]
[OutputType(typeof(ProxmoxNode), typeof(string))]
public class GetProxmoxNodeCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The name of the node to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Name { get; set; }
/// <summary>
/// <para type="description">Whether to return the raw JSON response.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter RawJson { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
string response;
if (string.IsNullOrEmpty(Name))
{
// Get all nodes
response = client.Get("nodes");
var nodesData = JsonUtility.DeserializeResponse<JArray>(response);
var nodes = new List<ProxmoxNode>();
foreach (var nodeObj in nodesData)
{
var node = nodeObj.ToObject<ProxmoxNode>();
nodes.Add(node);
}
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(nodes, true);
}
}
else
{
// Get a specific node
response = client.Get($"nodes/{Name}/status");
var nodeData = JsonUtility.DeserializeResponse<JObject>(response);
var node = nodeData.ToObject<ProxmoxNode>();
node.Name = Name;
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(node);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetProxmoxNodeError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+102
View File
@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets roles from Proxmox VE.</para>
/// <para type="description">The Get-ProxmoxRole cmdlet retrieves roles from Proxmox VE.</para>
/// <example>
/// <para>Get all roles</para>
/// <code>$roles = Get-ProxmoxRole -Connection $connection</code>
/// </example>
/// <example>
/// <para>Get a specific role by ID</para>
/// <code>$role = Get-ProxmoxRole -Connection $connection -RoleID "Administrator"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "ProxmoxRole")]
[OutputType(typeof(ProxmoxRole), typeof(string))]
public class GetProxmoxRoleCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The ID of the role to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string RoleID { get; set; }
/// <summary>
/// <para type="description">Whether to return the raw JSON response.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter RawJson { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
string response;
if (string.IsNullOrEmpty(RoleID))
{
// Get all roles
response = client.Get("access/roles");
var rolesData = JsonUtility.DeserializeResponse<JArray>(response);
var roles = new List<ProxmoxRole>();
foreach (var roleObj in rolesData)
{
var role = roleObj.ToObject<ProxmoxRole>();
roles.Add(role);
}
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(roles, true);
}
}
else
{
// Get a specific role
response = client.Get($"access/roles/{Uri.EscapeDataString(RoleID)}");
var roleData = JsonUtility.DeserializeResponse<JObject>(response);
var role = roleData.ToObject<ProxmoxRole>();
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(role);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetProxmoxRoleError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+114
View File
@@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets SDN VNets from Proxmox VE.</para>
/// <para type="description">The Get-ProxmoxSDNVnet cmdlet retrieves SDN VNets from Proxmox VE.</para>
/// <example>
/// <para>Get all SDN VNets</para>
/// <code>$vnets = Get-ProxmoxSDNVnet -Connection $connection</code>
/// </example>
/// <example>
/// <para>Get a specific SDN VNet by name</para>
/// <code>$vnet = Get-ProxmoxSDNVnet -Connection $connection -VNet "vnet1"</code>
/// </example>
/// <example>
/// <para>Get all SDN VNets in a specific zone</para>
/// <code>$vnets = Get-ProxmoxSDNVnet -Connection $connection -Zone "zone1"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "ProxmoxSDNVnet")]
[OutputType(typeof(ProxmoxSDNVnet), typeof(string))]
public class GetProxmoxSDNVnetCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The name of the VNet to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string VNet { get; set; }
/// <summary>
/// <para type="description">The name of the zone to retrieve VNets from.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Zone { get; set; }
/// <summary>
/// <para type="description">Whether to return the raw JSON response.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter RawJson { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
string response;
if (string.IsNullOrEmpty(VNet))
{
// Get all VNets or VNets in a specific zone
string endpoint = string.IsNullOrEmpty(Zone) ? "sdn/vnets" : $"sdn/zones/{Zone}/vnets";
response = client.Get(endpoint);
var vnetsData = JsonUtility.DeserializeResponse<JArray>(response);
var vnets = new List<ProxmoxSDNVnet>();
foreach (var vnetObj in vnetsData)
{
var vnet = vnetObj.ToObject<ProxmoxSDNVnet>();
vnets.Add(vnet);
}
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(vnets, true);
}
}
else
{
// Get a specific VNet
string endpoint = string.IsNullOrEmpty(Zone) ? $"sdn/vnets/{VNet}" : $"sdn/zones/{Zone}/vnets/{VNet}";
response = client.Get(endpoint);
var vnetData = JsonUtility.DeserializeResponse<JObject>(response);
var vnet = vnetData.ToObject<ProxmoxSDNVnet>();
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(vnet);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetProxmoxSDNVnetError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+102
View File
@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets SDN zones from Proxmox VE.</para>
/// <para type="description">The Get-ProxmoxSDNZone cmdlet retrieves SDN zones from Proxmox VE.</para>
/// <example>
/// <para>Get all SDN zones</para>
/// <code>$zones = Get-ProxmoxSDNZone -Connection $connection</code>
/// </example>
/// <example>
/// <para>Get a specific SDN zone by name</para>
/// <code>$zone = Get-ProxmoxSDNZone -Connection $connection -Zone "zone1"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "ProxmoxSDNZone")]
[OutputType(typeof(ProxmoxSDNZone), typeof(string))]
public class GetProxmoxSDNZoneCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The name of the zone to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Zone { get; set; }
/// <summary>
/// <para type="description">Whether to return the raw JSON response.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter RawJson { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
string response;
if (string.IsNullOrEmpty(Zone))
{
// Get all zones
response = client.Get("sdn/zones");
var zonesData = JsonUtility.DeserializeResponse<JArray>(response);
var zones = new List<ProxmoxSDNZone>();
foreach (var zoneObj in zonesData)
{
var zone = zoneObj.ToObject<ProxmoxSDNZone>();
zones.Add(zone);
}
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(zones, true);
}
}
else
{
// Get a specific zone
response = client.Get($"sdn/zones/{Zone}");
var zoneData = JsonUtility.DeserializeResponse<JObject>(response);
var zone = zoneData.ToObject<ProxmoxSDNZone>();
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(zone);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetProxmoxSDNZoneError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+158
View File
@@ -0,0 +1,158 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets storage from a Proxmox VE server.</para>
/// <para type="description">The Get-ProxmoxStorage cmdlet retrieves storage from a Proxmox VE server.</para>
/// <example>
/// <para>Get all storage</para>
/// <code>$storage = Get-ProxmoxStorage -Connection $connection</code>
/// </example>
/// <example>
/// <para>Get a specific storage by name</para>
/// <code>$storage = Get-ProxmoxStorage -Connection $connection -Name "local"</code>
/// </example>
/// <example>
/// <para>Get storage on a specific node</para>
/// <code>$storage = Get-ProxmoxStorage -Connection $connection -Node "pve1"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "ProxmoxStorage")]
[OutputType(typeof(ProxmoxStorage), typeof(string))]
public class GetProxmoxStorageCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The name of the storage to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Name { get; set; }
/// <summary>
/// <para type="description">The node to retrieve storage from.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Node { get; set; }
/// <summary>
/// <para type="description">Whether to return the raw JSON response.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter RawJson { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
string response;
if (string.IsNullOrEmpty(Node))
{
// Get storage from all nodes
if (string.IsNullOrEmpty(Name))
{
// Get all storage
response = client.Get("storage");
var storageData = JsonUtility.DeserializeResponse<JArray>(response);
var allStorage = new List<ProxmoxStorage>();
foreach (var storageObj in storageData)
{
var storage = storageObj.ToObject<ProxmoxStorage>();
allStorage.Add(storage);
}
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(allStorage, true);
}
}
else
{
// Get a specific storage
response = client.Get($"storage/{Name}");
var storage = JsonUtility.DeserializeResponse<ProxmoxStorage>(response);
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(storage);
}
}
}
else
{
// Get storage from a specific node
if (string.IsNullOrEmpty(Name))
{
// Get all storage on the node
response = client.Get($"nodes/{Node}/storage");
var storageData = JsonUtility.DeserializeResponse<JArray>(response);
var nodeStorage = new List<ProxmoxStorage>();
foreach (var storageObj in storageData)
{
var storage = storageObj.ToObject<ProxmoxStorage>();
storage.Node = Node;
nodeStorage.Add(storage);
}
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(nodeStorage, true);
}
}
else
{
// Get a specific storage on the node
response = client.Get($"nodes/{Node}/storage/{Name}");
var storage = JsonUtility.DeserializeResponse<ProxmoxStorage>(response);
storage.Node = Node;
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(storage);
}
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetProxmoxStorageError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+102
View File
@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets users from Proxmox VE.</para>
/// <para type="description">The Get-ProxmoxUser cmdlet retrieves users from Proxmox VE.</para>
/// <example>
/// <para>Get all users</para>
/// <code>$users = Get-ProxmoxUser -Connection $connection</code>
/// </example>
/// <example>
/// <para>Get a specific user by ID</para>
/// <code>$user = Get-ProxmoxUser -Connection $connection -UserID "root@pam"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "ProxmoxUser")]
[OutputType(typeof(ProxmoxUser), typeof(string))]
public class GetProxmoxUserCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The ID of the user to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string UserID { get; set; }
/// <summary>
/// <para type="description">Whether to return the raw JSON response.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter RawJson { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
string response;
if (string.IsNullOrEmpty(UserID))
{
// Get all users
response = client.Get("access/users");
var usersData = JsonUtility.DeserializeResponse<JArray>(response);
var users = new List<ProxmoxUser>();
foreach (var userObj in usersData)
{
var user = userObj.ToObject<ProxmoxUser>();
users.Add(user);
}
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(users, true);
}
}
else
{
// Get a specific user
response = client.Get($"access/users/{Uri.EscapeDataString(UserID)}");
var userData = JsonUtility.DeserializeResponse<JObject>(response);
var user = userData.ToObject<ProxmoxUser>();
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(user);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetProxmoxUserError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+200
View File
@@ -0,0 +1,200 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets virtual machines from a Proxmox VE server.</para>
/// <para type="description">The Get-ProxmoxVM cmdlet retrieves virtual machines from a Proxmox VE server.</para>
/// <example>
/// <para>Get all virtual machines</para>
/// <code>$vms = Get-ProxmoxVM -Connection $connection</code>
/// </example>
/// <example>
/// <para>Get a specific virtual machine by ID</para>
/// <code>$vm = Get-ProxmoxVM -Connection $connection -VMID 100</code>
/// </example>
/// <example>
/// <para>Get virtual machines on a specific node</para>
/// <code>$vms = Get-ProxmoxVM -Connection $connection -Node "pve1"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "ProxmoxVM")]
[OutputType(typeof(ProxmoxVM), typeof(string))]
public class GetProxmoxVMCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The ID of the virtual machine to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int? VMID { get; set; }
/// <summary>
/// <para type="description">The node to retrieve virtual machines from.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Node { get; set; }
/// <summary>
/// <para type="description">Whether to return the raw JSON response.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter RawJson { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
string response;
if (VMID.HasValue)
{
// Get a specific VM
if (string.IsNullOrEmpty(Node))
{
// First, get the list of nodes
string nodesResponse = client.Get("nodes");
var nodesData = JsonUtility.DeserializeResponse<JArray>(nodesResponse);
// Search for the VM on each node
foreach (var nodeObj in nodesData)
{
string nodeName = nodeObj["node"].ToString();
try
{
response = client.Get($"nodes/{nodeName}/qemu/{VMID.Value}/status/current");
var vm = JsonUtility.DeserializeResponse<ProxmoxVM>(response);
vm.Node = nodeName;
vm.VMID = VMID.Value;
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(vm);
}
return;
}
catch
{
// VM not found on this node, continue to the next one
}
}
WriteError(new ErrorRecord(
new Exception($"VM with ID {VMID.Value} not found on any node"),
"VMNotFound",
ErrorCategory.ObjectNotFound,
VMID.Value));
}
else
{
// Get the VM from the specified node
response = client.Get($"nodes/{Node}/qemu/{VMID.Value}/status/current");
var vm = JsonUtility.DeserializeResponse<ProxmoxVM>(response);
vm.Node = Node;
vm.VMID = VMID.Value;
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(vm);
}
}
}
else
{
// Get all VMs
if (string.IsNullOrEmpty(Node))
{
// First, get the list of nodes
string nodesResponse = client.Get("nodes");
var nodesData = JsonUtility.DeserializeResponse<JArray>(nodesResponse);
var allVMs = new List<ProxmoxVM>();
// Get VMs from each node
foreach (var nodeObj in nodesData)
{
string nodeName = nodeObj["node"].ToString();
try
{
response = client.Get($"nodes/{nodeName}/qemu");
var vms = JsonUtility.DeserializeResponse<JArray>(response);
foreach (var vmObj in vms)
{
var vm = vmObj.ToObject<ProxmoxVM>();
vm.Node = nodeName;
allVMs.Add(vm);
}
}
catch
{
// Error getting VMs from this node, continue to the next one
WriteWarning($"Failed to get VMs from node {nodeName}");
}
}
if (RawJson.IsPresent)
{
WriteObject(JsonConvert.SerializeObject(allVMs));
}
else
{
WriteObject(allVMs, true);
}
}
else
{
// Get VMs from the specified node
response = client.Get($"nodes/{Node}/qemu");
var vms = JsonUtility.DeserializeResponse<JArray>(response);
var nodeVMs = new List<ProxmoxVM>();
foreach (var vmObj in vms)
{
var vm = vmObj.ToObject<ProxmoxVM>();
vm.Node = Node;
nodeVMs.Add(vm);
}
if (RawJson.IsPresent)
{
WriteObject(response);
}
else
{
WriteObject(nodeVMs, true);
}
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetProxmoxVMError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+61
View File
@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PSProxmox.Models;
using PSProxmox.Templates;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Gets virtual machine templates.</para>
/// <para type="description">The Get-ProxmoxVMTemplate cmdlet retrieves virtual machine templates.</para>
/// <example>
/// <para>Get all templates</para>
/// <code>$templates = Get-ProxmoxVMTemplate</code>
/// </example>
/// <example>
/// <para>Get a specific template by name</para>
/// <code>$template = Get-ProxmoxVMTemplate -Name "Ubuntu-Template"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Get, "ProxmoxVMTemplate")]
[OutputType(typeof(ProxmoxVMTemplate))]
public class GetProxmoxVMTemplateCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The name of the template to retrieve.</para>
/// </summary>
[Parameter(Mandatory = false, Position = 0)]
public string Name { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
if (string.IsNullOrEmpty(Name))
{
// Get all templates
var templates = new List<ProxmoxVMTemplate>();
foreach (var template in TemplateManager.GetTemplates())
{
templates.Add(template);
}
WriteObject(templates, true);
}
else
{
// Get a specific template
var template = TemplateManager.GetTemplate(Name);
WriteObject(template);
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetProxmoxVMTemplateError", ErrorCategory.InvalidOperation, Name));
}
}
}
}
+92
View File
@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Security;
using PSProxmox.Client;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Joins a node to a Proxmox VE cluster.</para>
/// <para type="description">The Join-ProxmoxCluster cmdlet joins a node to a Proxmox VE cluster.</para>
/// <example>
/// <para>Join a node to a cluster</para>
/// <code>Join-ProxmoxCluster -Connection $connection -ClusterName "cluster1" -HostName "pve2" -Password $securePassword</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Join, "ProxmoxCluster", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
public class JoinProxmoxClusterCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The name of the cluster to join.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string ClusterName { get; set; }
/// <summary>
/// <para type="description">The hostname or IP address of an existing cluster member.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string HostName { get; set; }
/// <summary>
/// <para type="description">The password for the root@pam user on the existing cluster member.</para>
/// </summary>
[Parameter(Mandatory = true)]
public SecureString Password { get; set; }
/// <summary>
/// <para type="description">Whether to force joining the cluster.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Force { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Confirm joining the cluster
if (!ShouldProcess($"Node {Connection.Server}", $"Join cluster {ClusterName}"))
{
return;
}
// Convert SecureString to plain text (only for sending to API)
string plainPassword = new System.Net.NetworkCredential(string.Empty, Password).Password;
// Join the cluster
var parameters = new Dictionary<string, string>
{
["hostname"] = HostName,
["password"] = plainPassword
};
if (Force.IsPresent)
{
parameters["force"] = "1";
}
WriteVerbose($"Joining cluster {ClusterName} via host {HostName}");
client.Post("cluster/join", parameters);
WriteVerbose($"Node {Connection.Server} joined cluster {ClusterName}");
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "JoinProxmoxClusterError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+66
View File
@@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Removes a node from a Proxmox VE cluster.</para>
/// <para type="description">The Leave-ProxmoxCluster cmdlet removes a node from a Proxmox VE cluster.</para>
/// <example>
/// <para>Remove a node from a cluster</para>
/// <code>Leave-ProxmoxCluster -Connection $connection -Force</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Leave, "ProxmoxCluster", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
public class LeaveProxmoxClusterCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">Whether to force leaving the cluster.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Force { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Confirm leaving the cluster
if (!ShouldProcess($"Node {Connection.Server}", "Leave cluster"))
{
return;
}
// Leave the cluster
var parameters = new Dictionary<string, string>();
if (Force.IsPresent)
{
parameters["force"] = "1";
}
WriteVerbose($"Removing node {Connection.Server} from cluster");
client.Delete("cluster/leave", parameters);
WriteVerbose($"Node {Connection.Server} removed from cluster");
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "LeaveProxmoxClusterError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+135
View File
@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Creates a new cluster backup in Proxmox VE.</para>
/// <para type="description">The New-ProxmoxClusterBackup cmdlet creates a new cluster backup in Proxmox VE.</para>
/// <example>
/// <para>Create a new cluster backup</para>
/// <code>$backup = New-ProxmoxClusterBackup -Connection $connection -Compress</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.New, "ProxmoxClusterBackup")]
[OutputType(typeof(ProxmoxClusterBackup))]
public class NewProxmoxClusterBackupCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">Whether to compress the backup.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Compress { get; set; }
/// <summary>
/// <para type="description">Whether to wait for the backup to complete.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Wait { get; set; }
/// <summary>
/// <para type="description">The timeout in seconds to wait for the backup to complete.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int Timeout { get; set; } = 300;
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Create the backup
var parameters = new Dictionary<string, string>();
if (Compress.IsPresent)
{
parameters["compress"] = "1";
}
WriteVerbose("Creating cluster backup");
string response = client.Post("cluster/backup", parameters);
var taskData = JsonUtility.DeserializeResponse<dynamic>(response);
string taskId = taskData.data;
if (Wait.IsPresent && !string.IsNullOrEmpty(taskId))
{
WriteVerbose($"Waiting for backup task {taskId} to complete");
int attempts = 0;
int maxAttempts = Timeout / 5;
bool completed = false;
while (attempts < maxAttempts)
{
string taskResponse = client.Get($"nodes/{Connection.Server}/tasks/{taskId}/status");
var taskStatus = JsonUtility.DeserializeResponse<dynamic>(taskResponse);
string status = taskStatus.data.status;
if (status == "stopped")
{
completed = true;
break;
}
System.Threading.Thread.Sleep(5000);
attempts++;
}
if (!completed)
{
WriteWarning($"Timeout waiting for backup task {taskId} to complete");
}
else
{
WriteVerbose($"Backup task {taskId} completed successfully");
}
}
// Get the latest backup
string backupsResponse = client.Get("cluster/backup");
var backupsData = JsonUtility.DeserializeResponse<dynamic>(backupsResponse);
var backups = backupsData.data;
if (backups.Count > 0)
{
var latestBackup = backups[0];
var backup = new ProxmoxClusterBackup
{
BackupID = latestBackup["backup-id"],
Time = latestBackup["time"],
Type = latestBackup["type"],
Version = latestBackup["version"],
Size = latestBackup["size"],
Compression = latestBackup["compression"],
Node = latestBackup["node"],
Path = latestBackup["path"]
};
WriteObject(backup);
}
else
{
WriteWarning("No backups found after creating backup");
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewProxmoxClusterBackupError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+56
View File
@@ -0,0 +1,56 @@
using System;
using System.Management.Automation;
using PSProxmox.IPAM;
using PSProxmox.Models;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Creates a new IP address pool.</para>
/// <para type="description">The New-ProxmoxIPPool cmdlet creates a new IP address pool for use with Proxmox VE virtual machines.</para>
/// <example>
/// <para>Create a new IP pool</para>
/// <code>$pool = New-ProxmoxIPPool -Name "Production" -CIDR "192.168.1.0/24" -ExcludeIPs "192.168.1.1", "192.168.1.254"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.New, "ProxmoxIPPool")]
[OutputType(typeof(ProxmoxIPPool))]
public class NewProxmoxIPPoolCmdlet : PSCmdlet
{
private static readonly IPAMManager _ipamManager = new IPAMManager();
/// <summary>
/// <para type="description">The name of the IP pool.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public string Name { get; set; }
/// <summary>
/// <para type="description">The CIDR notation of the IP pool (e.g., 192.168.1.0/24).</para>
/// </summary>
[Parameter(Mandatory = true, Position = 1)]
public string CIDR { get; set; }
/// <summary>
/// <para type="description">IP addresses to exclude from the pool.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string[] ExcludeIPs { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var pool = _ipamManager.CreatePool(Name, CIDR, ExcludeIPs);
WriteObject(ProxmoxIPPool.FromIPPool(pool));
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewProxmoxIPPoolError", ErrorCategory.InvalidOperation, Name));
}
}
}
}
+225
View File
@@ -0,0 +1,225 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Creates a new network interface in Proxmox VE.</para>
/// <para type="description">The New-ProxmoxNetwork cmdlet creates a new network interface in Proxmox VE.</para>
/// <example>
/// <para>Create a new bridge interface</para>
/// <code>$network = New-ProxmoxNetwork -Connection $connection -Node "pve1" -Interface "vmbr1" -Type "bridge" -BridgePorts "eth1" -Method "static" -Address "192.168.2.1" -Netmask "255.255.255.0" -Autostart</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.New, "ProxmoxNetwork")]
[OutputType(typeof(ProxmoxNetwork))]
public class NewProxmoxNetworkCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The node to create the network interface on.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string Node { get; set; }
/// <summary>
/// <para type="description">The name of the interface.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string Interface { get; set; }
/// <summary>
/// <para type="description">The type of the interface.</para>
/// </summary>
[Parameter(Mandatory = true)]
[ValidateSet("bridge", "bond", "eth", "vlan")]
public string Type { get; set; }
/// <summary>
/// <para type="description">The method of the interface.</para>
/// </summary>
[Parameter(Mandatory = false)]
[ValidateSet("static", "dhcp", "manual")]
public string Method { get; set; } = "static";
/// <summary>
/// <para type="description">The IP address of the interface.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Address { get; set; }
/// <summary>
/// <para type="description">The netmask of the interface.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Netmask { get; set; }
/// <summary>
/// <para type="description">The gateway of the interface.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Gateway { get; set; }
/// <summary>
/// <para type="description">The bridge ports of the interface.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string BridgePorts { get; set; }
/// <summary>
/// <para type="description">The bridge STP of the interface.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter BridgeSTP { get; set; }
/// <summary>
/// <para type="description">The bridge FD of the interface.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int? BridgeFD { get; set; }
/// <summary>
/// <para type="description">The bond slaves of the interface.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string BondSlaves { get; set; }
/// <summary>
/// <para type="description">The bond mode of the interface.</para>
/// </summary>
[Parameter(Mandatory = false)]
[ValidateSet("balance-rr", "active-backup", "balance-xor", "broadcast", "802.3ad", "balance-tlb", "balance-alb")]
public string BondMode { get; set; }
/// <summary>
/// <para type="description">The VLAN ID of the interface.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int? VlanID { get; set; }
/// <summary>
/// <para type="description">The VLAN raw device of the interface.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string VlanRawDevice { get; set; }
/// <summary>
/// <para type="description">Whether the interface should autostart.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Autostart { get; set; }
/// <summary>
/// <para type="description">The comments of the interface.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Comments { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Create the network interface
var parameters = new Dictionary<string, string>
{
["iface"] = Interface,
["type"] = Type
};
if (!string.IsNullOrEmpty(Method))
{
parameters["method"] = Method;
}
if (!string.IsNullOrEmpty(Address))
{
parameters["address"] = Address;
}
if (!string.IsNullOrEmpty(Netmask))
{
parameters["netmask"] = Netmask;
}
if (!string.IsNullOrEmpty(Gateway))
{
parameters["gateway"] = Gateway;
}
if (!string.IsNullOrEmpty(BridgePorts))
{
parameters["bridge_ports"] = BridgePorts;
}
if (BridgeSTP.IsPresent)
{
parameters["bridge_stp"] = "on";
}
if (BridgeFD.HasValue)
{
parameters["bridge_fd"] = BridgeFD.Value.ToString();
}
if (!string.IsNullOrEmpty(BondSlaves))
{
parameters["bond_slaves"] = BondSlaves;
}
if (!string.IsNullOrEmpty(BondMode))
{
parameters["bond_mode"] = BondMode;
}
if (VlanID.HasValue)
{
parameters["vlan-id"] = VlanID.Value.ToString();
}
if (!string.IsNullOrEmpty(VlanRawDevice))
{
parameters["vlan-raw-device"] = VlanRawDevice;
}
parameters["autostart"] = Autostart.IsPresent ? "1" : "0";
if (!string.IsNullOrEmpty(Comments))
{
parameters["comments"] = Comments;
}
// Create the network interface
client.Post($"nodes/{Node}/network", parameters);
// Apply the network configuration
client.Put($"nodes/{Node}/network", new Dictionary<string, string>());
// Get the created network interface
string networkResponse = client.Get($"nodes/{Node}/network/{Interface}");
var network = JsonUtility.DeserializeResponse<ProxmoxNetwork>(networkResponse);
network.Node = Node;
WriteObject(network);
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewProxmoxNetworkError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+72
View File
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Creates a new role in Proxmox VE.</para>
/// <para type="description">The New-ProxmoxRole cmdlet creates a new role in Proxmox VE.</para>
/// <example>
/// <para>Create a new role</para>
/// <code>$role = New-ProxmoxRole -Connection $connection -RoleID "Developer" -Privileges "VM.Allocate", "VM.Config.Disk", "VM.Config.CPU", "VM.PowerMgmt"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.New, "ProxmoxRole")]
[OutputType(typeof(ProxmoxRole))]
public class NewProxmoxRoleCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The role ID.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string RoleID { get; set; }
/// <summary>
/// <para type="description">The role's privileges.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string[] Privileges { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Create the role
var parameters = new Dictionary<string, string>
{
["roleid"] = RoleID,
["privs"] = string.Join(",", Privileges)
};
// Create the role
client.Post("access/roles", parameters);
// Get the created role
string roleResponse = client.Get($"access/roles/{Uri.EscapeDataString(RoleID)}");
var role = JsonUtility.DeserializeResponse<ProxmoxRole>(roleResponse);
WriteObject(role);
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewProxmoxRoleError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+212
View File
@@ -0,0 +1,212 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Creates a new SDN VNet in Proxmox VE.</para>
/// <para type="description">The New-ProxmoxSDNVnet cmdlet creates a new SDN VNet in Proxmox VE.</para>
/// <example>
/// <para>Create a new SDN VNet</para>
/// <code>$vnet = New-ProxmoxSDNVnet -Connection $connection -VNet "vnet1" -Zone "zone1" -IPv4 "192.168.1.0/24" -Gateway "192.168.1.1"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.New, "ProxmoxSDNVnet")]
[OutputType(typeof(ProxmoxSDNVnet))]
public class NewProxmoxSDNVnetCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The name of the VNet.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string VNet { get; set; }
/// <summary>
/// <para type="description">The zone of the VNet.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string Zone { get; set; }
/// <summary>
/// <para type="description">The alias of the VNet.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Alias { get; set; }
/// <summary>
/// <para type="description">The VLAN ID of the VNet.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int? VlanID { get; set; }
/// <summary>
/// <para type="description">The tag of the VNet.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int? Tag { get; set; }
/// <summary>
/// <para type="description">The IPv4 subnet of the VNet.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string IPv4 { get; set; }
/// <summary>
/// <para type="description">The IPv6 subnet of the VNet.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string IPv6 { get; set; }
/// <summary>
/// <para type="description">The MAC address of the VNet.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string MAC { get; set; }
/// <summary>
/// <para type="description">The gateway of the VNet.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Gateway { get; set; }
/// <summary>
/// <para type="description">The IPv6 gateway of the VNet.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Gateway6 { get; set; }
/// <summary>
/// <para type="description">The MTU of the VNet.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int? MTU { get; set; }
/// <summary>
/// <para type="description">Whether DHCP is enabled for the VNet.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter DHCP { get; set; }
/// <summary>
/// <para type="description">The DNS servers of the VNet.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string DNS { get; set; }
/// <summary>
/// <para type="description">The DNS search domain of the VNet.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string DNSSearchDomain { get; set; }
/// <summary>
/// <para type="description">The reverse DNS of the VNet.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string ReverseDNS { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Create the VNet
var parameters = new Dictionary<string, string>
{
["vnet"] = VNet,
["zone"] = Zone
};
if (!string.IsNullOrEmpty(Alias))
{
parameters["alias"] = Alias;
}
if (VlanID.HasValue)
{
parameters["vlanid"] = VlanID.Value.ToString();
}
if (Tag.HasValue)
{
parameters["tag"] = Tag.Value.ToString();
}
if (!string.IsNullOrEmpty(IPv4))
{
parameters["ipv4"] = IPv4;
}
if (!string.IsNullOrEmpty(IPv6))
{
parameters["ipv6"] = IPv6;
}
if (!string.IsNullOrEmpty(MAC))
{
parameters["mac"] = MAC;
}
if (!string.IsNullOrEmpty(Gateway))
{
parameters["gateway"] = Gateway;
}
if (!string.IsNullOrEmpty(Gateway6))
{
parameters["gateway6"] = Gateway6;
}
if (MTU.HasValue)
{
parameters["mtu"] = MTU.Value.ToString();
}
parameters["dhcp"] = DHCP.IsPresent ? "1" : "0";
if (!string.IsNullOrEmpty(DNS))
{
parameters["dns"] = DNS;
}
if (!string.IsNullOrEmpty(DNSSearchDomain))
{
parameters["dnssearchdomain"] = DNSSearchDomain;
}
if (!string.IsNullOrEmpty(ReverseDNS))
{
parameters["reversedns"] = ReverseDNS;
}
// Create the VNet
client.Post("sdn/vnets", parameters);
// Get the created VNet
string vnetResponse = client.Get($"sdn/vnets/{VNet}");
var vnet = JsonUtility.DeserializeResponse<ProxmoxSDNVnet>(vnetResponse);
WriteObject(vnet);
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewProxmoxSDNVnetError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+191
View File
@@ -0,0 +1,191 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Creates a new SDN zone in Proxmox VE.</para>
/// <para type="description">The New-ProxmoxSDNZone cmdlet creates a new SDN zone in Proxmox VE.</para>
/// <example>
/// <para>Create a new SDN zone</para>
/// <code>$zone = New-ProxmoxSDNZone -Connection $connection -Zone "zone1" -Type "vlan" -Bridge "vmbr0"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.New, "ProxmoxSDNZone")]
[OutputType(typeof(ProxmoxSDNZone))]
public class NewProxmoxSDNZoneCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The name of the zone.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string Zone { get; set; }
/// <summary>
/// <para type="description">The type of the zone.</para>
/// </summary>
[Parameter(Mandatory = true)]
[ValidateSet("vlan", "vxlan", "qinq", "simple")]
public string Type { get; set; }
/// <summary>
/// <para type="description">The bridge of the zone.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Bridge { get; set; }
/// <summary>
/// <para type="description">The DNS servers of the zone.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string DNS { get; set; }
/// <summary>
/// <para type="description">The DNS search domains of the zone.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string DNSZone { get; set; }
/// <summary>
/// <para type="description">The DHCP server of the zone.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string DHCP { get; set; }
/// <summary>
/// <para type="description">The reverse DNS of the zone.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string ReverseDNS { get; set; }
/// <summary>
/// <para type="description">The IPv6 of the zone.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string IPv6 { get; set; }
/// <summary>
/// <para type="description">The MTU of the zone.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int? MTU { get; set; }
/// <summary>
/// <para type="description">Whether the zone is VLAN aware.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter VLANAware { get; set; }
/// <summary>
/// <para type="description">The controller of the zone.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Controller { get; set; }
/// <summary>
/// <para type="description">The gateway of the zone.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Gateway { get; set; }
/// <summary>
/// <para type="description">The MAC prefix of the zone.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string MACPrefix { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Create the zone
var parameters = new Dictionary<string, string>
{
["zone"] = Zone,
["type"] = Type
};
if (!string.IsNullOrEmpty(Bridge))
{
parameters["bridge"] = Bridge;
}
if (!string.IsNullOrEmpty(DNS))
{
parameters["dns"] = DNS;
}
if (!string.IsNullOrEmpty(DNSZone))
{
parameters["dnszone"] = DNSZone;
}
if (!string.IsNullOrEmpty(DHCP))
{
parameters["dhcp"] = DHCP;
}
if (!string.IsNullOrEmpty(ReverseDNS))
{
parameters["reversedns"] = ReverseDNS;
}
if (!string.IsNullOrEmpty(IPv6))
{
parameters["ipv6"] = IPv6;
}
if (MTU.HasValue)
{
parameters["mtu"] = MTU.Value.ToString();
}
parameters["vlanaware"] = VLANAware.IsPresent ? "1" : "0";
if (!string.IsNullOrEmpty(Controller))
{
parameters["controller"] = Controller;
}
if (!string.IsNullOrEmpty(Gateway))
{
parameters["gateway"] = Gateway;
}
if (!string.IsNullOrEmpty(MACPrefix))
{
parameters["mac_prefix"] = MACPrefix;
}
// Create the zone
client.Post("sdn/zones", parameters);
// Get the created zone
string zoneResponse = client.Get($"sdn/zones/{Zone}");
var zone = JsonUtility.DeserializeResponse<ProxmoxSDNZone>(zoneResponse);
WriteObject(zone);
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewProxmoxSDNZoneError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+136
View File
@@ -0,0 +1,136 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Creates a new storage in Proxmox VE.</para>
/// <para type="description">The New-ProxmoxStorage cmdlet creates a new storage in Proxmox VE.</para>
/// <example>
/// <para>Create a new directory storage</para>
/// <code>$storage = New-ProxmoxStorage -Connection $connection -Name "backup" -Type "dir" -Path "/mnt/backup" -Content "backup,iso"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.New, "ProxmoxStorage")]
[OutputType(typeof(ProxmoxStorage))]
public class NewProxmoxStorageCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The name of the storage.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string Name { get; set; }
/// <summary>
/// <para type="description">The type of the storage.</para>
/// </summary>
[Parameter(Mandatory = true)]
[ValidateSet("dir", "nfs", "cifs", "lvm", "lvmthin", "zfs", "zfspool", "iscsi", "glusterfs", "cephfs", "rbd")]
public string Type { get; set; }
/// <summary>
/// <para type="description">The path of the storage.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Path { get; set; }
/// <summary>
/// <para type="description">The content types allowed on the storage.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Content { get; set; }
/// <summary>
/// <para type="description">The node to create the storage on.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Node { get; set; }
/// <summary>
/// <para type="description">Whether the storage is shared.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Shared { get; set; }
/// <summary>
/// <para type="description">Whether the storage is enabled.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Enabled { get; set; } = true;
/// <summary>
/// <para type="description">Additional parameters for the storage.</para>
/// </summary>
[Parameter(Mandatory = false)]
public Hashtable AdditionalParameters { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Create the storage
var parameters = new Dictionary<string, string>
{
["storage"] = Name,
["type"] = Type
};
if (!string.IsNullOrEmpty(Path))
{
parameters["path"] = Path;
}
if (!string.IsNullOrEmpty(Content))
{
parameters["content"] = Content;
}
if (!string.IsNullOrEmpty(Node))
{
parameters["nodes"] = Node;
}
parameters["shared"] = Shared.IsPresent ? "1" : "0";
parameters["disable"] = Enabled.IsPresent ? "0" : "1";
// Add additional parameters
if (AdditionalParameters != null)
{
foreach (var key in AdditionalParameters.Keys)
{
parameters[key.ToString()] = AdditionalParameters[key].ToString();
}
}
// Create the storage
string createResponse = client.Post("storage", parameters);
// Get the created storage
string storageResponse = client.Get($"storage/{Name}");
var storage = JsonUtility.DeserializeResponse<ProxmoxStorage>(storageResponse);
WriteObject(storage);
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewProxmoxStorageError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+156
View File
@@ -0,0 +1,156 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Security;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Creates a new user in Proxmox VE.</para>
/// <para type="description">The New-ProxmoxUser cmdlet creates a new user in Proxmox VE.</para>
/// <example>
/// <para>Create a new user</para>
/// <code>$user = New-ProxmoxUser -Connection $connection -Username "john" -Realm "pam" -Password $securePassword -FirstName "John" -LastName "Doe" -Email "john.doe@example.com"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.New, "ProxmoxUser")]
[OutputType(typeof(ProxmoxUser))]
public class NewProxmoxUserCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The username.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string Username { get; set; }
/// <summary>
/// <para type="description">The realm.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string Realm { get; set; }
/// <summary>
/// <para type="description">The password.</para>
/// </summary>
[Parameter(Mandatory = true)]
public SecureString Password { get; set; }
/// <summary>
/// <para type="description">The user's first name.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string FirstName { get; set; }
/// <summary>
/// <para type="description">The user's last name.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string LastName { get; set; }
/// <summary>
/// <para type="description">The user's email address.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Email { get; set; }
/// <summary>
/// <para type="description">The user's comment.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Comment { get; set; }
/// <summary>
/// <para type="description">The user's expiration date.</para>
/// </summary>
[Parameter(Mandatory = false)]
public DateTime? Expire { get; set; }
/// <summary>
/// <para type="description">The user's groups.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string[] Groups { get; set; }
/// <summary>
/// <para type="description">Whether the user is enabled.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Enabled { get; set; } = true;
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Create the user
var parameters = new Dictionary<string, string>
{
["userid"] = $"{Username}@{Realm}"
};
// Convert SecureString to plain text (only for sending to API)
string plainPassword = new System.Net.NetworkCredential(string.Empty, Password).Password;
parameters["password"] = plainPassword;
if (!string.IsNullOrEmpty(FirstName))
{
parameters["firstname"] = FirstName;
}
if (!string.IsNullOrEmpty(LastName))
{
parameters["lastname"] = LastName;
}
if (!string.IsNullOrEmpty(Email))
{
parameters["email"] = Email;
}
if (!string.IsNullOrEmpty(Comment))
{
parameters["comment"] = Comment;
}
if (Expire.HasValue)
{
parameters["expire"] = ((DateTimeOffset)Expire.Value).ToUnixTimeSeconds().ToString();
}
if (Groups != null && Groups.Length > 0)
{
parameters["groups"] = string.Join(",", Groups);
}
parameters["enable"] = Enabled.IsPresent ? "1" : "0";
// Create the user
client.Post("access/users", parameters);
// Get the created user
string userResponse = client.Get($"access/users/{Uri.EscapeDataString($"{Username}@{Realm}")}");
var user = JsonUtility.DeserializeResponse<ProxmoxUser>(userResponse);
WriteObject(user);
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewProxmoxUserError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+140
View File
@@ -0,0 +1,140 @@
using System;
using System.Management.Automation;
using PSProxmox.Models;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Creates a new virtual machine configuration builder for Proxmox VE.</para>
/// <para type="description">The New-ProxmoxVMBuilder cmdlet creates a new virtual machine configuration builder that can be used with New-ProxmoxVM.</para>
/// <example>
/// <para>Create a basic VM builder</para>
/// <code>$builder = New-ProxmoxVMBuilder -Name "web-server"</code>
/// </example>
/// <example>
/// <para>Create a VM builder with initial configuration</para>
/// <code>$builder = New-ProxmoxVMBuilder -Name "db-server" -Memory 4096 -Cores 2 -Node "pve1"</code>
/// </example>
/// <example>
/// <para>Create a VM builder and add configuration</para>
/// <code>$builder = New-ProxmoxVMBuilder -Name "app-server"
/// $builder.WithMemory(8192).WithCores(4).WithDisk(100, "local-lvm")
/// $builder.WithNetwork("virtio", "vmbr0").WithIPConfig("192.168.1.10/24", "192.168.1.1")</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.New, "ProxmoxVMBuilder")]
[OutputType(typeof(ProxmoxVMBuilder))]
public class NewProxmoxVMBuilderCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The name of the VM.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public string Name { get; set; }
/// <summary>
/// <para type="description">The VM ID. If not specified, the next available ID will be used.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int? VMID { get; set; }
/// <summary>
/// <para type="description">The node to create the VM on.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Node { get; set; }
/// <summary>
/// <para type="description">The description of the VM.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Description { get; set; }
/// <summary>
/// <para type="description">The tags for the VM.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string[] Tags { get; set; }
/// <summary>
/// <para type="description">The amount of memory in MB.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int Memory { get; set; } = 512;
/// <summary>
/// <para type="description">The number of CPU cores.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int Cores { get; set; } = 1;
/// <summary>
/// <para type="description">The CPU type.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string CPUType { get; set; } = "host";
/// <summary>
/// <para type="description">The operating system type.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string OSType { get; set; } = "l26"; // Linux 2.6+
/// <summary>
/// <para type="description">Whether to start the VM after creation.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Start { get; set; }
/// <summary>
/// <para type="description">The IP pool to use for assigning an IP address.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string IPPool { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var builder = new ProxmoxVMBuilder(Name)
{
Memory = Memory,
Cores = Cores,
CPUType = CPUType,
OSType = OSType,
Start = Start.IsPresent,
IPPool = IPPool
};
if (VMID.HasValue)
{
builder.WithVMID(VMID.Value);
}
if (!string.IsNullOrEmpty(Node))
{
builder.WithNode(Node);
}
if (!string.IsNullOrEmpty(Description))
{
builder.WithDescription(Description);
}
if (Tags != null && Tags.Length > 0)
{
builder.WithTags(Tags);
}
WriteObject(builder);
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewProxmoxVMBuilderError", ErrorCategory.InvalidOperation, Name));
}
}
}
}
+236
View File
@@ -0,0 +1,236 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using Newtonsoft.Json;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Creates a new virtual machine in Proxmox VE.</para>
/// <para type="description">The New-ProxmoxVM cmdlet creates a new virtual machine in Proxmox VE.</para>
/// <example>
/// <para>Create a new virtual machine using direct parameters</para>
/// <code>$vm = New-ProxmoxVM -Connection $connection -Node "pve1" -Name "test-vm" -Memory 2048 -Cores 2 -DiskSize 32</code>
/// </example>
/// <example>
/// <para>Create a new virtual machine using a builder</para>
/// <code>$builder = New-ProxmoxVMBuilder -Name "web-server"
/// $builder.WithMemory(4096).WithCores(2).WithDisk(50, "local-lvm")
/// $builder.WithNetwork("virtio", "vmbr0").WithIPConfig("192.168.1.10/24", "192.168.1.1")
/// $vm = New-ProxmoxVM -Connection $connection -Node "pve1" -Builder $builder</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.New, "ProxmoxVM")]
[OutputType(typeof(ProxmoxVM))]
public class NewProxmoxVMCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The node to create the VM on.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string Node { get; set; }
/// <summary>
/// <para type="description">The VM configuration builder.</para>
/// </summary>
[Parameter(Mandatory = true, ParameterSetName = "Builder")]
public ProxmoxVMBuilder Builder { get; set; }
/// <summary>
/// <para type="description">The name of the VM.</para>
/// </summary>
[Parameter(Mandatory = true, ParameterSetName = "Direct")]
public string Name { get; set; }
/// <summary>
/// <para type="description">The VM ID. If not specified, the next available ID will be used.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Direct")]
public int? VMID { get; set; }
/// <summary>
/// <para type="description">The amount of memory in MB.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Direct")]
public int Memory { get; set; } = 512;
/// <summary>
/// <para type="description">The number of CPU cores.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Direct")]
public int Cores { get; set; } = 1;
/// <summary>
/// <para type="description">The disk size in GB.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Direct")]
public int DiskSize { get; set; } = 8;
/// <summary>
/// <para type="description">The storage location for the disk.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Direct")]
public string Storage { get; set; } = "local";
/// <summary>
/// <para type="description">The operating system type.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Direct")]
public string OSType { get; set; } = "l26"; // Linux 2.6+
/// <summary>
/// <para type="description">The network interface model.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Direct")]
public string NetworkModel { get; set; } = "virtio";
/// <summary>
/// <para type="description">The network bridge.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Direct")]
public string NetworkBridge { get; set; } = "vmbr0";
/// <summary>
/// <para type="description">Whether to start the VM after creation.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Direct")]
public SwitchParameter Start { get; set; }
/// <summary>
/// <para type="description">The IP pool to use for assigning an IP address.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "Direct")]
public string IPPool { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
Dictionary<string, string> parameters;
int vmid;
string vmName;
string ipPool;
bool startVm;
// Process based on parameter set
if (ParameterSetName == "Builder")
{
// Use the builder to create parameters
if (Builder == null)
{
throw new PSArgumentNullException(nameof(Builder));
}
// Set the node if not already set in the builder
if (string.IsNullOrEmpty(Builder.Node))
{
Builder.WithNode(Node);
}
// Get the next available VMID if not specified
if (!Builder.VMID.HasValue)
{
string response = client.Get("cluster/nextid");
var nextId = JsonUtility.DeserializeResponse<string>(response);
Builder.WithVMID(int.Parse(nextId));
}
// Build the parameters
parameters = Builder.Build();
vmid = Builder.VMID.Value;
vmName = Builder.Name;
ipPool = Builder.IPPool;
startVm = Builder.Start;
}
else // Direct parameters
{
// Get the next available VMID if not specified
if (!VMID.HasValue)
{
string response = client.Get("cluster/nextid");
var nextId = JsonUtility.DeserializeResponse<string>(response);
VMID = int.Parse(nextId);
}
// Create the VM parameters
parameters = new Dictionary<string, string>
{
["vmid"] = VMID.Value.ToString(),
["name"] = Name,
["memory"] = Memory.ToString(),
["cores"] = Cores.ToString(),
["ostype"] = OSType,
["net0"] = $"{NetworkModel},bridge={NetworkBridge}"
};
// Add disk
parameters["ide0"] = $"{Storage}:{DiskSize}";
vmid = VMID.Value;
vmName = Name;
ipPool = IPPool;
startVm = Start.IsPresent;
}
// Create the VM
WriteVerbose($"Creating VM {vmName} on node {Node}");
client.Post($"nodes/{Node}/qemu", parameters);
// Get the created VM
string vmResponse = client.Get($"nodes/{Node}/qemu/{vmid}/status/current");
var vm = JsonUtility.DeserializeResponse<ProxmoxVM>(vmResponse);
vm.Node = Node;
vm.VMID = vmid;
// Assign IP if pool is specified
if (!string.IsNullOrEmpty(ipPool))
{
try
{
var ipamManager = new IPAM.IPAMManager();
var pool = ipamManager.GetPool(ipPool);
var ip = pool.GetNextIP();
WriteVerbose($"Assigned IP {ip} from pool {ipPool} to VM {vmName}");
}
catch (Exception ex)
{
WriteWarning($"Failed to assign IP from pool {ipPool}: {ex.Message}");
}
}
// Start the VM if requested
if (startVm)
{
WriteVerbose($"Starting VM {vmName}");
client.Post($"nodes/{Node}/qemu/{vmid}/status/start", null);
// Refresh VM status
vmResponse = client.Get($"nodes/{Node}/qemu/{vmid}/status/current");
vm = JsonUtility.DeserializeResponse<ProxmoxVM>(vmResponse);
vm.Node = Node;
vm.VMID = vmid;
}
WriteObject(vm);
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewProxmoxVMError", ErrorCategory.OperationStopped, Connection));
}
}
}
}
+276
View File
@@ -0,0 +1,276 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Templates;
using PSProxmox.Utilities;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Creates a new virtual machine from a template in Proxmox VE.</para>
/// <para type="description">The New-ProxmoxVMFromTemplate cmdlet creates a new virtual machine from a template in Proxmox VE.</para>
/// <example>
/// <para>Create a new VM from a template</para>
/// <code>$vm = New-ProxmoxVMFromTemplate -Connection $connection -Node "pve1" -TemplateName "Ubuntu-Template" -Name "web01" -Start</code>
/// </example>
/// <example>
/// <para>Create multiple VMs from a template with a prefix and counter</para>
/// <code>$vms = New-ProxmoxVMFromTemplate -Connection $connection -Node "pve1" -TemplateName "Ubuntu-Template" -Prefix "web" -Count 3 -Start</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.New, "ProxmoxVMFromTemplate")]
[OutputType(typeof(ProxmoxVM))]
public class NewProxmoxVMFromTemplateCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The node to create the VM on.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string Node { get; set; }
/// <summary>
/// <para type="description">The name of the template to use.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string TemplateName { get; set; }
/// <summary>
/// <para type="description">The name of the VM to create.</para>
/// </summary>
[Parameter(Mandatory = true, ParameterSetName = "SingleVM")]
public string Name { get; set; }
/// <summary>
/// <para type="description">The prefix for the VM names when creating multiple VMs.</para>
/// </summary>
[Parameter(Mandatory = true, ParameterSetName = "MultipleVMs")]
public string Prefix { get; set; }
/// <summary>
/// <para type="description">The number of VMs to create.</para>
/// </summary>
[Parameter(Mandatory = true, ParameterSetName = "MultipleVMs")]
public int Count { get; set; }
/// <summary>
/// <para type="description">The starting index for the VM names when creating multiple VMs.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "MultipleVMs")]
public int StartIndex { get; set; } = 1;
/// <summary>
/// <para type="description">The VM ID. If not specified, the next available ID will be used.</para>
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "SingleVM")]
public int? VMID { get; set; }
/// <summary>
/// <para type="description">Whether to start the VM after creation.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Start { get; set; }
/// <summary>
/// <para type="description">The IP pool to use for assigning an IP address.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string IPPool { get; set; }
/// <summary>
/// <para type="description">The amount of memory in MB. If specified, overrides the template value.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int? Memory { get; set; }
/// <summary>
/// <para type="description">The number of CPU cores. If specified, overrides the template value.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int? Cores { get; set; }
/// <summary>
/// <para type="description">The disk size in GB. If specified, overrides the template value.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int? DiskSize { get; set; }
/// <summary>
/// <para type="description">The storage location for the disk. If specified, overrides the template value.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Storage { get; set; }
/// <summary>
/// <para type="description">The network interface model. If specified, overrides the template value.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string NetworkModel { get; set; }
/// <summary>
/// <para type="description">The network bridge. If specified, overrides the template value.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string NetworkBridge { get; set; }
/// <summary>
/// <para type="description">The description of the VM. If specified, overrides the template value.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Description { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Get the template
ProxmoxVMTemplate template;
try
{
template = TemplateManager.GetTemplate(TemplateName);
}
catch (Exception ex)
{
WriteError(new ErrorRecord(
new Exception($"Template '{TemplateName}' not found: {ex.Message}"),
"TemplateNotFound",
ErrorCategory.ObjectNotFound,
TemplateName));
return;
}
// Create VMs
if (ParameterSetName == "SingleVM")
{
// Create a single VM
var vm = CreateVMFromTemplate(client, template, Name, VMID);
WriteObject(vm);
}
else
{
// Create multiple VMs
var vms = new List<ProxmoxVM>();
for (int i = 0; i < Count; i++)
{
string vmName = $"{Prefix}{StartIndex + i}";
var vm = CreateVMFromTemplate(client, template, vmName, null);
vms.Add(vm);
}
WriteObject(vms, true);
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewProxmoxVMFromTemplateError", ErrorCategory.OperationStopped, Connection));
}
}
private ProxmoxVM CreateVMFromTemplate(ProxmoxApiClient client, ProxmoxVMTemplate template, string vmName, int? vmId)
{
// Get the next available VMID if not specified
if (!vmId.HasValue)
{
string response = client.Get("cluster/nextid");
var nextId = JsonUtility.DeserializeResponse<string>(response);
vmId = int.Parse(nextId);
}
// Clone the template VM
var parameters = new Dictionary<string, string>
{
["newid"] = vmId.Value.ToString(),
["name"] = vmName
};
if (Memory.HasValue)
{
parameters["memory"] = Memory.Value.ToString();
}
if (Cores.HasValue)
{
parameters["cores"] = Cores.Value.ToString();
}
if (DiskSize.HasValue)
{
parameters["disksize"] = DiskSize.Value.ToString();
}
if (!string.IsNullOrEmpty(Storage))
{
parameters["storage"] = Storage;
}
if (!string.IsNullOrEmpty(Description))
{
parameters["description"] = Description;
}
// Clone the VM
WriteVerbose($"Creating VM {vmName} from template {template.Name}");
client.Post($"nodes/{template.Node}/qemu/{template.VMID}/clone", parameters);
// Get the created VM
string vmResponse = client.Get($"nodes/{Node}/qemu/{vmId.Value}/status/current");
var vm = JsonUtility.DeserializeResponse<ProxmoxVM>(vmResponse);
vm.Node = Node;
vm.VMID = vmId.Value;
// Update network settings if specified
if (!string.IsNullOrEmpty(NetworkModel) || !string.IsNullOrEmpty(NetworkBridge))
{
var networkParams = new Dictionary<string, string>();
string netModel = NetworkModel ?? "virtio";
string netBridge = NetworkBridge ?? "vmbr0";
networkParams["net0"] = $"{netModel},bridge={netBridge}";
client.Put($"nodes/{Node}/qemu/{vmId.Value}/config", networkParams);
}
// Assign IP if pool is specified
if (!string.IsNullOrEmpty(IPPool))
{
try
{
var ipamManager = new IPAM.IPAMManager();
var pool = ipamManager.GetPool(IPPool);
var ip = pool.GetNextIP();
WriteVerbose($"Assigned IP {ip} from pool {IPPool} to VM {vmName}");
}
catch (Exception ex)
{
WriteWarning($"Failed to assign IP from pool {IPPool}: {ex.Message}");
}
}
// Start the VM if requested
if (Start.IsPresent)
{
WriteVerbose($"Starting VM {vmName}");
client.Post($"nodes/{Node}/qemu/{vmId.Value}/status/start", null);
// Refresh VM status
vmResponse = client.Get($"nodes/{Node}/qemu/{vmId.Value}/status/current");
vm = JsonUtility.DeserializeResponse<ProxmoxVM>(vmResponse);
vm.Node = Node;
vm.VMID = vmId.Value;
}
return vm;
}
}
}
+146
View File
@@ -0,0 +1,146 @@
using System;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
using PSProxmox.Templates;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Creates a new virtual machine template in Proxmox VE.</para>
/// <para type="description">The New-ProxmoxVMTemplate cmdlet creates a new virtual machine template in Proxmox VE.</para>
/// <example>
/// <para>Create a new template from an existing VM</para>
/// <code>$template = New-ProxmoxVMTemplate -Connection $connection -VMID 100 -Name "Ubuntu-Template" -Description "Ubuntu 20.04 Template"</code>
/// </example>
/// <example>
/// <para>Create a new template from an existing VM using pipeline input</para>
/// <code>Get-ProxmoxVM -Connection $connection -VMID 100 | New-ProxmoxVMTemplate -Connection $connection -Name "Ubuntu-Template" -Description "Ubuntu 20.04 Template"</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.New, "ProxmoxVMTemplate")]
[OutputType(typeof(ProxmoxVMTemplate))]
public class NewProxmoxVMTemplateCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The ID of the VM to convert to a template.</para>
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "FromVM")]
public int VMID { get; set; }
/// <summary>
/// <para type="description">The node where the VM is located.</para>
/// </summary>
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, ParameterSetName = "FromVM")]
public string Node { get; set; }
/// <summary>
/// <para type="description">The name of the template.</para>
/// </summary>
[Parameter(Mandatory = true)]
public string Name { get; set; }
/// <summary>
/// <para type="description">The description of the template.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string Description { get; set; }
/// <summary>
/// <para type="description">Tags for the template.</para>
/// </summary>
[Parameter(Mandatory = false)]
public string[] Tags { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// If node is not specified, find the VM on any node
if (string.IsNullOrEmpty(Node))
{
string nodesResponse = client.Get("nodes");
var nodesData = Newtonsoft.Json.Linq.JObject.Parse(nodesResponse)["data"] as Newtonsoft.Json.Linq.JArray;
foreach (var nodeObj in nodesData)
{
string nodeName = nodeObj["node"].ToString();
try
{
// Check if the VM exists on this node
client.Get($"nodes/{nodeName}/qemu/{VMID}/status/current");
Node = nodeName;
break;
}
catch
{
// VM not found on this node, continue to the next one
}
}
if (string.IsNullOrEmpty(Node))
{
WriteError(new ErrorRecord(
new Exception($"VM with ID {VMID} not found on any node"),
"VMNotFound",
ErrorCategory.ObjectNotFound,
VMID));
return;
}
}
// Check if the VM is running
string vmResponse = client.Get($"nodes/{Node}/qemu/{VMID}/status/current");
var vmData = Newtonsoft.Json.Linq.JObject.Parse(vmResponse)["data"] as Newtonsoft.Json.Linq.JObject;
string status = vmData["status"].ToString();
if (status == "running")
{
WriteError(new ErrorRecord(
new Exception($"VM with ID {VMID} is running. Stop the VM before converting to a template."),
"VMRunning",
ErrorCategory.InvalidOperation,
VMID));
return;
}
// Convert the VM to a template
WriteVerbose($"Converting VM {VMID} to template on node {Node}");
client.Post($"nodes/{Node}/qemu/{VMID}/template", null);
// Get the VM details
vmResponse = client.Get($"nodes/{Node}/qemu/{VMID}/config");
var vm = PSProxmox.Utilities.JsonUtility.DeserializeResponse<ProxmoxVM>(vmResponse);
vm.Node = Node;
vm.VMID = VMID;
// Create the template object
var template = ProxmoxVMTemplate.FromVM(vm);
template.Name = Name;
template.Description = Description;
template.Tags = Tags != null ? string.Join(",", Tags) : null;
// Save the template
TemplateManager.CreateTemplate(template);
WriteObject(template);
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewProxmoxVMTemplateError", ErrorCategory.OperationStopped, VMID));
}
}
}
}
+72
View File
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Removes a network interface from Proxmox VE.</para>
/// <para type="description">The Remove-ProxmoxNetwork cmdlet removes a network interface from Proxmox VE.</para>
/// <example>
/// <para>Remove a network interface</para>
/// <code>Remove-ProxmoxNetwork -Connection $connection -Node "pve1" -Interface "vmbr1"</code>
/// </example>
/// <example>
/// <para>Remove a network interface using pipeline input</para>
/// <code>Get-ProxmoxNetwork -Connection $connection -Node "pve1" -Interface "vmbr1" | Remove-ProxmoxNetwork -Connection $connection</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Remove, "ProxmoxNetwork", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
public class RemoveProxmoxNetworkCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The node where the network interface is located.</para>
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
public string Node { get; set; }
/// <summary>
/// <para type="description">The name of the interface to remove.</para>
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
public string Interface { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Confirm removal
if (!ShouldProcess($"Network interface {Interface} on node {Node}", "Remove"))
{
return;
}
// Remove the network interface
WriteVerbose($"Removing network interface {Interface} on node {Node}");
client.Delete($"nodes/{Node}/network/{Interface}");
// Apply the network configuration
client.Put($"nodes/{Node}/network", new Dictionary<string, string>());
WriteVerbose($"Network interface {Interface} removed from node {Node}");
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "RemoveProxmoxNetworkError", ErrorCategory.OperationStopped, Interface));
}
}
}
}
+62
View File
@@ -0,0 +1,62 @@
using System;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Removes a role from Proxmox VE.</para>
/// <para type="description">The Remove-ProxmoxRole cmdlet removes a role from Proxmox VE.</para>
/// <example>
/// <para>Remove a role</para>
/// <code>Remove-ProxmoxRole -Connection $connection -RoleID "Developer"</code>
/// </example>
/// <example>
/// <para>Remove a role using pipeline input</para>
/// <code>Get-ProxmoxRole -Connection $connection -RoleID "Developer" | Remove-ProxmoxRole -Connection $connection</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Remove, "ProxmoxRole", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
public class RemoveProxmoxRoleCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The ID of the role to remove.</para>
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
public string RoleID { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Confirm removal
if (!ShouldProcess($"Role {RoleID}", "Remove"))
{
return;
}
// Remove the role
WriteVerbose($"Removing role {RoleID}");
client.Delete($"access/roles/{Uri.EscapeDataString(RoleID)}");
WriteVerbose($"Role {RoleID} removed");
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "RemoveProxmoxRoleError", ErrorCategory.OperationStopped, RoleID));
}
}
}
}
+62
View File
@@ -0,0 +1,62 @@
using System;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Removes an SDN VNet from Proxmox VE.</para>
/// <para type="description">The Remove-ProxmoxSDNVnet cmdlet removes an SDN VNet from Proxmox VE.</para>
/// <example>
/// <para>Remove an SDN VNet</para>
/// <code>Remove-ProxmoxSDNVnet -Connection $connection -VNet "vnet1"</code>
/// </example>
/// <example>
/// <para>Remove an SDN VNet using pipeline input</para>
/// <code>Get-ProxmoxSDNVnet -Connection $connection -VNet "vnet1" | Remove-ProxmoxSDNVnet -Connection $connection</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Remove, "ProxmoxSDNVnet", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
public class RemoveProxmoxSDNVnetCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The name of the VNet to remove.</para>
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
public string VNet { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Confirm removal
if (!ShouldProcess($"SDN VNet {VNet}", "Remove"))
{
return;
}
// Remove the VNet
WriteVerbose($"Removing SDN VNet {VNet}");
client.Delete($"sdn/vnets/{VNet}");
WriteVerbose($"SDN VNet {VNet} removed");
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "RemoveProxmoxSDNVnetError", ErrorCategory.OperationStopped, VNet));
}
}
}
}
+62
View File
@@ -0,0 +1,62 @@
using System;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Removes an SDN zone from Proxmox VE.</para>
/// <para type="description">The Remove-ProxmoxSDNZone cmdlet removes an SDN zone from Proxmox VE.</para>
/// <example>
/// <para>Remove an SDN zone</para>
/// <code>Remove-ProxmoxSDNZone -Connection $connection -Zone "zone1"</code>
/// </example>
/// <example>
/// <para>Remove an SDN zone using pipeline input</para>
/// <code>Get-ProxmoxSDNZone -Connection $connection -Zone "zone1" | Remove-ProxmoxSDNZone -Connection $connection</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Remove, "ProxmoxSDNZone", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
public class RemoveProxmoxSDNZoneCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The name of the zone to remove.</para>
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
public string Zone { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Confirm removal
if (!ShouldProcess($"SDN zone {Zone}", "Remove"))
{
return;
}
// Remove the zone
WriteVerbose($"Removing SDN zone {Zone}");
client.Delete($"sdn/zones/{Zone}");
WriteVerbose($"SDN zone {Zone} removed");
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "RemoveProxmoxSDNZoneError", ErrorCategory.OperationStopped, Zone));
}
}
}
}
+62
View File
@@ -0,0 +1,62 @@
using System;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Removes a storage from Proxmox VE.</para>
/// <para type="description">The Remove-ProxmoxStorage cmdlet removes a storage from Proxmox VE.</para>
/// <example>
/// <para>Remove a storage</para>
/// <code>Remove-ProxmoxStorage -Connection $connection -Name "backup"</code>
/// </example>
/// <example>
/// <para>Remove a storage using pipeline input</para>
/// <code>Get-ProxmoxStorage -Connection $connection -Name "backup" | Remove-ProxmoxStorage -Connection $connection</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Remove, "ProxmoxStorage", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
public class RemoveProxmoxStorageCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The name of the storage to remove.</para>
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
public string Name { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Confirm removal
if (!ShouldProcess($"Storage {Name}", "Remove"))
{
return;
}
// Remove the storage
WriteVerbose($"Removing storage {Name}");
client.Delete($"storage/{Name}");
WriteVerbose($"Storage {Name} removed");
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "RemoveProxmoxStorageError", ErrorCategory.OperationStopped, Name));
}
}
}
}
+62
View File
@@ -0,0 +1,62 @@
using System;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Removes a user from Proxmox VE.</para>
/// <para type="description">The Remove-ProxmoxUser cmdlet removes a user from Proxmox VE.</para>
/// <example>
/// <para>Remove a user</para>
/// <code>Remove-ProxmoxUser -Connection $connection -UserID "john@pam"</code>
/// </example>
/// <example>
/// <para>Remove a user using pipeline input</para>
/// <code>Get-ProxmoxUser -Connection $connection -UserID "john@pam" | Remove-ProxmoxUser -Connection $connection</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Remove, "ProxmoxUser", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
public class RemoveProxmoxUserCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The ID of the user to remove.</para>
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
public string UserID { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Confirm removal
if (!ShouldProcess($"User {UserID}", "Remove"))
{
return;
}
// Remove the user
WriteVerbose($"Removing user {UserID}");
client.Delete($"access/users/{Uri.EscapeDataString(UserID)}");
WriteVerbose($"User {UserID} removed");
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "RemoveProxmoxUserError", ErrorCategory.OperationStopped, UserID));
}
}
}
}
+163
View File
@@ -0,0 +1,163 @@
using System;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Removes a virtual machine from Proxmox VE.</para>
/// <para type="description">The Remove-ProxmoxVM cmdlet removes a virtual machine from Proxmox VE.</para>
/// <example>
/// <para>Remove a virtual machine</para>
/// <code>Remove-ProxmoxVM -Connection $connection -Node "pve1" -VMID 100</code>
/// </example>
/// <example>
/// <para>Remove a virtual machine using pipeline input</para>
/// <code>Get-ProxmoxVM -Connection $connection -VMID 100 | Remove-ProxmoxVM -Connection $connection</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Remove, "ProxmoxVM", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
public class RemoveProxmoxVMCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The node where the VM is located.</para>
/// </summary>
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true)]
public string Node { get; set; }
/// <summary>
/// <para type="description">The ID of the VM to remove.</para>
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
public int VMID { get; set; }
/// <summary>
/// <para type="description">Whether to force removal of the VM.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Force { get; set; }
/// <summary>
/// <para type="description">Whether to purge the VM's files.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Purge { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// If node is not specified, find the VM on any node
if (string.IsNullOrEmpty(Node))
{
string nodesResponse = client.Get("nodes");
var nodesData = Newtonsoft.Json.Linq.JObject.Parse(nodesResponse)["data"] as Newtonsoft.Json.Linq.JArray;
foreach (var nodeObj in nodesData)
{
string nodeName = nodeObj["node"].ToString();
try
{
// Check if the VM exists on this node
client.Get($"nodes/{nodeName}/qemu/{VMID}/status/current");
Node = nodeName;
break;
}
catch
{
// VM not found on this node, continue to the next one
}
}
if (string.IsNullOrEmpty(Node))
{
WriteError(new ErrorRecord(
new Exception($"VM with ID {VMID} not found on any node"),
"VMNotFound",
ErrorCategory.ObjectNotFound,
VMID));
return;
}
}
// Check if the VM is running
string vmResponse = client.Get($"nodes/{Node}/qemu/{VMID}/status/current");
var vmData = Newtonsoft.Json.Linq.JObject.Parse(vmResponse)["data"] as Newtonsoft.Json.Linq.JObject;
string status = vmData["status"].ToString();
if (status == "running" && !Force.IsPresent)
{
WriteError(new ErrorRecord(
new Exception($"VM with ID {VMID} is running. Use -Force to stop and remove it."),
"VMRunning",
ErrorCategory.InvalidOperation,
VMID));
return;
}
// Confirm removal
if (!ShouldProcess($"VM {VMID} on node {Node}", "Remove"))
{
return;
}
// Stop the VM if it's running
if (status == "running")
{
WriteVerbose($"Stopping VM {VMID} on node {Node}");
client.Post($"nodes/{Node}/qemu/{VMID}/status/stop", null);
// Wait for the VM to stop
int attempts = 0;
while (attempts < 10)
{
vmResponse = client.Get($"nodes/{Node}/qemu/{VMID}/status/current");
vmData = Newtonsoft.Json.Linq.JObject.Parse(vmResponse)["data"] as Newtonsoft.Json.Linq.JObject;
status = vmData["status"].ToString();
if (status != "running")
{
break;
}
System.Threading.Thread.Sleep(1000);
attempts++;
}
if (status == "running")
{
WriteWarning($"VM {VMID} did not stop gracefully. Forcing removal.");
}
}
// Remove the VM
WriteVerbose($"Removing VM {VMID} from node {Node}");
string deleteUrl = $"nodes/{Node}/qemu/{VMID}";
if (Purge.IsPresent)
{
deleteUrl += "?purge=1";
}
client.Delete(deleteUrl);
WriteVerbose($"VM {VMID} removed from node {Node}");
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "RemoveProxmoxVMError", ErrorCategory.OperationStopped, VMID));
}
}
}
}
+54
View File
@@ -0,0 +1,54 @@
using System;
using System.Management.Automation;
using PSProxmox.Models;
using PSProxmox.Templates;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Removes a virtual machine template.</para>
/// <para type="description">The Remove-ProxmoxVMTemplate cmdlet removes a virtual machine template.</para>
/// <example>
/// <para>Remove a template</para>
/// <code>Remove-ProxmoxVMTemplate -Name "Ubuntu-Template"</code>
/// </example>
/// <example>
/// <para>Remove a template using pipeline input</para>
/// <code>Get-ProxmoxVMTemplate -Name "Ubuntu-Template" | Remove-ProxmoxVMTemplate</code>
/// </example>
/// </summary>
[Cmdlet(VerbsCommon.Remove, "ProxmoxVMTemplate", SupportsShouldProcess = true)]
public class RemoveProxmoxVMTemplateCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The name of the template to remove.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)]
public string Name { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
// Confirm removal
if (!ShouldProcess($"Template {Name}", "Remove"))
{
return;
}
// Remove the template
WriteVerbose($"Removing template {Name}");
TemplateManager.RemoveTemplate(Name);
WriteVerbose($"Template {Name} removed");
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "RemoveProxmoxVMTemplateError", ErrorCategory.InvalidOperation, Name));
}
}
}
}
+216
View File
@@ -0,0 +1,216 @@
using System;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Restarts a virtual machine in Proxmox VE.</para>
/// <para type="description">The Restart-ProxmoxVM cmdlet restarts a virtual machine in Proxmox VE.</para>
/// <example>
/// <para>Restart a virtual machine</para>
/// <code>Restart-ProxmoxVM -Connection $connection -Node "pve1" -VMID 100</code>
/// </example>
/// <example>
/// <para>Restart a virtual machine using pipeline input</para>
/// <code>Get-ProxmoxVM -Connection $connection -VMID 100 | Restart-ProxmoxVM -Connection $connection</code>
/// </example>
/// </summary>
[Cmdlet(VerbsLifecycle.Restart, "ProxmoxVM", SupportsShouldProcess = true)]
[OutputType(typeof(ProxmoxVM))]
public class RestartProxmoxVMCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The node where the VM is located.</para>
/// </summary>
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true)]
public string Node { get; set; }
/// <summary>
/// <para type="description">The ID of the VM to restart.</para>
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
public int VMID { get; set; }
/// <summary>
/// <para type="description">Whether to wait for the VM to restart.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Wait { get; set; }
/// <summary>
/// <para type="description">The timeout in seconds to wait for the VM to restart.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int Timeout { get; set; } = 120;
/// <summary>
/// <para type="description">Whether to force restart the VM.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Force { get; set; }
/// <summary>
/// <para type="description">Whether to return the VM object after restarting.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter PassThru { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// If node is not specified, find the VM on any node
if (string.IsNullOrEmpty(Node))
{
string nodesResponse = client.Get("nodes");
var nodesData = Newtonsoft.Json.Linq.JObject.Parse(nodesResponse)["data"] as Newtonsoft.Json.Linq.JArray;
foreach (var nodeObj in nodesData)
{
string nodeName = nodeObj["node"].ToString();
try
{
// Check if the VM exists on this node
client.Get($"nodes/{nodeName}/qemu/{VMID}/status/current");
Node = nodeName;
break;
}
catch
{
// VM not found on this node, continue to the next one
}
}
if (string.IsNullOrEmpty(Node))
{
WriteError(new ErrorRecord(
new Exception($"VM with ID {VMID} not found on any node"),
"VMNotFound",
ErrorCategory.ObjectNotFound,
VMID));
return;
}
}
// Check if the VM is running
string vmResponse = client.Get($"nodes/{Node}/qemu/{VMID}/status/current");
var vmData = Newtonsoft.Json.Linq.JObject.Parse(vmResponse)["data"] as Newtonsoft.Json.Linq.JObject;
string status = vmData["status"].ToString();
if (status != "running" && !Force.IsPresent)
{
WriteError(new ErrorRecord(
new Exception($"VM with ID {VMID} is not running. Use -Force to start it."),
"VMNotRunning",
ErrorCategory.InvalidOperation,
VMID));
return;
}
// Confirm restart
if (!ShouldProcess($"VM {VMID} on node {Node}", "Restart"))
{
return;
}
if (status == "running")
{
// Restart the VM
WriteVerbose($"Restarting VM {VMID} on node {Node}");
string restartUrl = $"nodes/{Node}/qemu/{VMID}/status/";
restartUrl += Force.IsPresent ? "reset" : "reboot";
client.Post(restartUrl, null);
}
else if (Force.IsPresent)
{
// Start the VM
WriteVerbose($"Starting VM {VMID} on node {Node}");
client.Post($"nodes/{Node}/qemu/{VMID}/status/start", null);
}
// Wait for the VM to restart if requested
if (Wait.IsPresent)
{
WriteVerbose($"Waiting for VM {VMID} to restart");
int attempts = 0;
int maxAttempts = Timeout / 2;
bool restarted = false;
// First, wait for the VM to stop (if it was running)
if (status == "running")
{
while (attempts < maxAttempts / 2)
{
vmResponse = client.Get($"nodes/{Node}/qemu/{VMID}/status/current");
vmData = Newtonsoft.Json.Linq.JObject.Parse(vmResponse)["data"] as Newtonsoft.Json.Linq.JObject;
status = vmData["status"].ToString();
if (status != "running")
{
break;
}
System.Threading.Thread.Sleep(2000);
attempts++;
}
}
// Then, wait for the VM to start again
attempts = 0;
while (attempts < maxAttempts / 2)
{
vmResponse = client.Get($"nodes/{Node}/qemu/{VMID}/status/current");
vmData = Newtonsoft.Json.Linq.JObject.Parse(vmResponse)["data"] as Newtonsoft.Json.Linq.JObject;
status = vmData["status"].ToString();
if (status == "running")
{
restarted = true;
break;
}
System.Threading.Thread.Sleep(2000);
attempts++;
}
if (!restarted)
{
WriteWarning($"Timeout waiting for VM {VMID} to restart");
}
else
{
WriteVerbose($"VM {VMID} restarted successfully");
}
}
// Return the VM object if requested
if (PassThru.IsPresent)
{
vmResponse = client.Get($"nodes/{Node}/qemu/{VMID}/status/current");
var vm = PSProxmox.Utilities.JsonUtility.DeserializeResponse<ProxmoxVM>(vmResponse);
vm.Node = Node;
vm.VMID = VMID;
WriteObject(vm);
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "RestartProxmoxVMError", ErrorCategory.OperationStopped, VMID));
}
}
}
}
@@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Restores a cluster backup in Proxmox VE.</para>
/// <para type="description">The Restore-ProxmoxClusterBackup cmdlet restores a cluster backup in Proxmox VE.</para>
/// <example>
/// <para>Restore a cluster backup</para>
/// <code>Restore-ProxmoxClusterBackup -Connection $connection -BackupID "vzdump-cluster-2023_04_28-12_00_00.vma.lzo" -Force</code>
/// </example>
/// <example>
/// <para>Restore a cluster backup using pipeline input</para>
/// <code>Get-ProxmoxClusterBackup -Connection $connection | Select-Object -First 1 | Restore-ProxmoxClusterBackup -Connection $connection -Force</code>
/// </example>
/// </summary>
[Cmdlet(VerbsData.Restore, "ProxmoxClusterBackup", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
public class RestoreProxmoxClusterBackupCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The ID of the backup to restore.</para>
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
public string BackupID { get; set; }
/// <summary>
/// <para type="description">Whether to force the restore operation.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Force { get; set; }
/// <summary>
/// <para type="description">Whether to wait for the restore to complete.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Wait { get; set; }
/// <summary>
/// <para type="description">The timeout in seconds to wait for the restore to complete.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int Timeout { get; set; } = 600;
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// Confirm restore
if (!ShouldProcess($"Cluster backup {BackupID}", "Restore"))
{
return;
}
// Restore the backup
var parameters = new Dictionary<string, string>
{
["backup-id"] = BackupID
};
if (Force.IsPresent)
{
parameters["force"] = "1";
}
WriteVerbose($"Restoring cluster backup {BackupID}");
string response = client.Post("cluster/backup/restore", parameters);
var taskData = PSProxmox.Utilities.JsonUtility.DeserializeResponse<dynamic>(response);
string taskId = taskData.data;
if (Wait.IsPresent && !string.IsNullOrEmpty(taskId))
{
WriteVerbose($"Waiting for restore task {taskId} to complete");
int attempts = 0;
int maxAttempts = Timeout / 5;
bool completed = false;
while (attempts < maxAttempts)
{
string taskResponse = client.Get($"nodes/{Connection.Server}/tasks/{taskId}/status");
var taskStatus = PSProxmox.Utilities.JsonUtility.DeserializeResponse<dynamic>(taskResponse);
string status = taskStatus.data.status;
if (status == "stopped")
{
completed = true;
break;
}
System.Threading.Thread.Sleep(5000);
attempts++;
}
if (!completed)
{
WriteWarning($"Timeout waiting for restore task {taskId} to complete");
}
else
{
WriteVerbose($"Restore task {taskId} completed successfully");
}
}
WriteVerbose($"Cluster backup {BackupID} restored");
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "RestoreProxmoxClusterBackupError", ErrorCategory.OperationStopped, BackupID));
}
}
}
}
+175
View File
@@ -0,0 +1,175 @@
using System;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Starts a virtual machine in Proxmox VE.</para>
/// <para type="description">The Start-ProxmoxVM cmdlet starts a virtual machine in Proxmox VE.</para>
/// <example>
/// <para>Start a virtual machine</para>
/// <code>Start-ProxmoxVM -Connection $connection -Node "pve1" -VMID 100</code>
/// </example>
/// <example>
/// <para>Start a virtual machine using pipeline input</para>
/// <code>Get-ProxmoxVM -Connection $connection -VMID 100 | Start-ProxmoxVM -Connection $connection</code>
/// </example>
/// </summary>
[Cmdlet(VerbsLifecycle.Start, "ProxmoxVM")]
[OutputType(typeof(ProxmoxVM))]
public class StartProxmoxVMCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The node where the VM is located.</para>
/// </summary>
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true)]
public string Node { get; set; }
/// <summary>
/// <para type="description">The ID of the VM to start.</para>
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
public int VMID { get; set; }
/// <summary>
/// <para type="description">Whether to wait for the VM to start.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Wait { get; set; }
/// <summary>
/// <para type="description">The timeout in seconds to wait for the VM to start.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int Timeout { get; set; } = 60;
/// <summary>
/// <para type="description">Whether to return the VM object after starting.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter PassThru { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// If node is not specified, find the VM on any node
if (string.IsNullOrEmpty(Node))
{
string nodesResponse = client.Get("nodes");
var nodesData = Newtonsoft.Json.Linq.JObject.Parse(nodesResponse)["data"] as Newtonsoft.Json.Linq.JArray;
foreach (var nodeObj in nodesData)
{
string nodeName = nodeObj["node"].ToString();
try
{
// Check if the VM exists on this node
client.Get($"nodes/{nodeName}/qemu/{VMID}/status/current");
Node = nodeName;
break;
}
catch
{
// VM not found on this node, continue to the next one
}
}
if (string.IsNullOrEmpty(Node))
{
WriteError(new ErrorRecord(
new Exception($"VM with ID {VMID} not found on any node"),
"VMNotFound",
ErrorCategory.ObjectNotFound,
VMID));
return;
}
}
// Check if the VM is already running
string vmResponse = client.Get($"nodes/{Node}/qemu/{VMID}/status/current");
var vmData = Newtonsoft.Json.Linq.JObject.Parse(vmResponse)["data"] as Newtonsoft.Json.Linq.JObject;
string status = vmData["status"].ToString();
if (status == "running")
{
WriteVerbose($"VM {VMID} is already running on node {Node}");
if (PassThru.IsPresent)
{
var vm = PSProxmox.Utilities.JsonUtility.DeserializeResponse<ProxmoxVM>(vmResponse);
vm.Node = Node;
vm.VMID = VMID;
WriteObject(vm);
}
return;
}
// Start the VM
WriteVerbose($"Starting VM {VMID} on node {Node}");
client.Post($"nodes/{Node}/qemu/{VMID}/status/start", null);
// Wait for the VM to start if requested
if (Wait.IsPresent)
{
WriteVerbose($"Waiting for VM {VMID} to start");
int attempts = 0;
int maxAttempts = Timeout / 2;
bool started = false;
while (attempts < maxAttempts)
{
vmResponse = client.Get($"nodes/{Node}/qemu/{VMID}/status/current");
vmData = Newtonsoft.Json.Linq.JObject.Parse(vmResponse)["data"] as Newtonsoft.Json.Linq.JObject;
status = vmData["status"].ToString();
if (status == "running")
{
started = true;
break;
}
System.Threading.Thread.Sleep(2000);
attempts++;
}
if (!started)
{
WriteWarning($"Timeout waiting for VM {VMID} to start");
}
else
{
WriteVerbose($"VM {VMID} started successfully");
}
}
// Return the VM object if requested
if (PassThru.IsPresent)
{
vmResponse = client.Get($"nodes/{Node}/qemu/{VMID}/status/current");
var vm = PSProxmox.Utilities.JsonUtility.DeserializeResponse<ProxmoxVM>(vmResponse);
vm.Node = Node;
vm.VMID = VMID;
WriteObject(vm);
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "StartProxmoxVMError", ErrorCategory.OperationStopped, VMID));
}
}
}
}
+195
View File
@@ -0,0 +1,195 @@
using System;
using System.Management.Automation;
using PSProxmox.Client;
using PSProxmox.Models;
using PSProxmox.Session;
namespace PSProxmox.Cmdlets
{
/// <summary>
/// <para type="synopsis">Stops a virtual machine in Proxmox VE.</para>
/// <para type="description">The Stop-ProxmoxVM cmdlet stops a virtual machine in Proxmox VE.</para>
/// <example>
/// <para>Stop a virtual machine</para>
/// <code>Stop-ProxmoxVM -Connection $connection -Node "pve1" -VMID 100</code>
/// </example>
/// <example>
/// <para>Stop a virtual machine using pipeline input</para>
/// <code>Get-ProxmoxVM -Connection $connection -VMID 100 | Stop-ProxmoxVM -Connection $connection</code>
/// </example>
/// </summary>
[Cmdlet(VerbsLifecycle.Stop, "ProxmoxVM", SupportsShouldProcess = true)]
[OutputType(typeof(ProxmoxVM))]
public class StopProxmoxVMCmdlet : PSCmdlet
{
/// <summary>
/// <para type="description">The connection to the Proxmox VE server.</para>
/// </summary>
[Parameter(Mandatory = true, Position = 0)]
public ProxmoxConnection Connection { get; set; }
/// <summary>
/// <para type="description">The node where the VM is located.</para>
/// </summary>
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true)]
public string Node { get; set; }
/// <summary>
/// <para type="description">The ID of the VM to stop.</para>
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
public int VMID { get; set; }
/// <summary>
/// <para type="description">Whether to wait for the VM to stop.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Wait { get; set; }
/// <summary>
/// <para type="description">The timeout in seconds to wait for the VM to stop.</para>
/// </summary>
[Parameter(Mandatory = false)]
public int Timeout { get; set; } = 60;
/// <summary>
/// <para type="description">Whether to force stop the VM.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter Force { get; set; }
/// <summary>
/// <para type="description">Whether to return the VM object after stopping.</para>
/// </summary>
[Parameter(Mandatory = false)]
public SwitchParameter PassThru { get; set; }
/// <summary>
/// Processes the cmdlet.
/// </summary>
protected override void ProcessRecord()
{
try
{
var client = new ProxmoxApiClient(Connection, this);
// If node is not specified, find the VM on any node
if (string.IsNullOrEmpty(Node))
{
string nodesResponse = client.Get("nodes");
var nodesData = Newtonsoft.Json.Linq.JObject.Parse(nodesResponse)["data"] as Newtonsoft.Json.Linq.JArray;
foreach (var nodeObj in nodesData)
{
string nodeName = nodeObj["node"].ToString();
try
{
// Check if the VM exists on this node
client.Get($"nodes/{nodeName}/qemu/{VMID}/status/current");
Node = nodeName;
break;
}
catch
{
// VM not found on this node, continue to the next one
}
}
if (string.IsNullOrEmpty(Node))
{
WriteError(new ErrorRecord(
new Exception($"VM with ID {VMID} not found on any node"),
"VMNotFound",
ErrorCategory.ObjectNotFound,
VMID));
return;
}
}
// Check if the VM is running
string vmResponse = client.Get($"nodes/{Node}/qemu/{VMID}/status/current");
var vmData = Newtonsoft.Json.Linq.JObject.Parse(vmResponse)["data"] as Newtonsoft.Json.Linq.JObject;
string status = vmData["status"].ToString();
if (status != "running")
{
WriteVerbose($"VM {VMID} is not running on node {Node}");
if (PassThru.IsPresent)
{
var vm = PSProxmox.Utilities.JsonUtility.DeserializeResponse<ProxmoxVM>(vmResponse);
vm.Node = Node;
vm.VMID = VMID;
WriteObject(vm);
}
return;
}
// Confirm stop
if (!ShouldProcess($"VM {VMID} on node {Node}", "Stop"))
{
return;
}
// Stop the VM
WriteVerbose($"Stopping VM {VMID} on node {Node}");
string stopUrl = $"nodes/{Node}/qemu/{VMID}/status/";
stopUrl += Force.IsPresent ? "stop" : "shutdown";
client.Post(stopUrl, null);
// Wait for the VM to stop if requested
if (Wait.IsPresent)
{
WriteVerbose($"Waiting for VM {VMID} to stop");
int attempts = 0;
int maxAttempts = Timeout / 2;
bool stopped = false;
while (attempts < maxAttempts)
{
vmResponse = client.Get($"nodes/{Node}/qemu/{VMID}/status/current");
vmData = Newtonsoft.Json.Linq.JObject.Parse(vmResponse)["data"] as Newtonsoft.Json.Linq.JObject;
status = vmData["status"].ToString();
if (status != "running")
{
stopped = true;
break;
}
System.Threading.Thread.Sleep(2000);
attempts++;
}
if (!stopped)
{
WriteWarning($"Timeout waiting for VM {VMID} to stop");
if (Force.IsPresent)
{
WriteVerbose($"Forcing VM {VMID} to stop");
client.Post($"nodes/{Node}/qemu/{VMID}/status/stop", null);
System.Threading.Thread.Sleep(5000);
}
}
else
{
WriteVerbose($"VM {VMID} stopped successfully");
}
}
// Return the VM object if requested
if (PassThru.IsPresent)
{
vmResponse = client.Get($"nodes/{Node}/qemu/{VMID}/status/current");
var vm = PSProxmox.Utilities.JsonUtility.DeserializeResponse<ProxmoxVM>(vmResponse);
vm.Node = Node;
vm.VMID = VMID;
WriteObject(vm);
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "StopProxmoxVMError", ErrorCategory.OperationStopped, VMID));
}
}
}
}