Added assembly name and root namespace to project file; updated session and vlan classes with new properties; modified module manifest to reference DLL and updated exported cmdlets; corrected property name in address class.

This commit is contained in:
2026-01-19 14:45:31 +03:00
parent 010cce0fd8
commit 114267b1d5
26 changed files with 2512 additions and 8 deletions

View File

@@ -0,0 +1,43 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet("Assign", "Tag")]
public class AssignTagCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0)]
[ValidateNotNullOrEmpty]
public Address? AddressObject { get; set; }
[Parameter(
Mandatory = true,
Position = 1)]
[ValidateNotNullOrEmpty]
public Tag? Tag { get; set; }
protected override void ProcessRecord()
{
try
{
var identifiers = new List<string> { AddressObject!.Id.ToString() };
var body = new Dictionary<string, object>
{
{ "tag", Tag!.Id }
};
RequestHelper.InvokeRequest("PATCH", controllers.addresses, null, null, body, identifiers.ToArray())
.GetAwaiter().GetResult();
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "AssignTagError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,21 @@
namespace PS.IPAM.Cmdlets;
using System.Management.Automation;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Close, "Session")]
public class CloseSessionCmdlet : PSCmdlet
{
protected override void ProcessRecord()
{
try
{
RequestHelper.InvokeRequest("DELETE", controllers.user, null, null, null, null)
.GetAwaiter().GetResult();
SessionManager.CloseSession();
}
catch (System.Exception ex)
{
WriteError(new ErrorRecord(ex, "CloseSessionError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,162 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Net;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Get, "Address", DefaultParameterSetName = "ByID")]
[OutputType(typeof(Address))]
public class GetAddressCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
[ValidateNotNullOrEmpty]
public int Id { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByIP")]
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 1,
ParameterSetName = "BySubnetId")]
[ValidateNotNullOrEmpty]
public IPAddress? IP { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByHostName")]
[ValidateNotNullOrEmpty]
public string? HostName { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByHostBase")]
[ValidateNotNullOrEmpty]
public string? HostBase { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByTag")]
[ValidateNotNullOrEmpty]
public int? TagId { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetId")]
[ValidateNotNullOrEmpty]
public int? SubnetId { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetCIDR")]
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
[ValidateNotNullOrEmpty]
public string? SubnetCIDR { get; set; }
protected override void ProcessRecord()
{
try
{
var controller = controllers.addresses;
var identifiers = new List<string>();
switch (ParameterSetName)
{
case "ByID":
identifiers.Add(Id.ToString());
break;
case "ByIP":
identifiers.Add("search");
identifiers.Add(IP!.ToString());
break;
case "ByHostName":
identifiers.Add("search_hostname");
identifiers.Add(HostName!);
break;
case "ByHostBase":
identifiers.Add("search_hostbase");
identifiers.Add(HostBase!);
break;
case "ByTag":
identifiers.Add("tags");
identifiers.Add(TagId!.Value.ToString());
identifiers.Add("addresses");
break;
case "BySubnetId":
if (IP != null)
{
identifiers.Add(IP.ToString());
identifiers.Add(SubnetId!.Value.ToString());
}
else
{
controller = controllers.subnets;
identifiers.Add(SubnetId!.Value.ToString());
identifiers.Add("addresses");
}
break;
case "BySubnetCIDR":
controller = controllers.subnets;
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "cidr", SubnetCIDR! })
.GetAwaiter().GetResult();
if (subnet == null)
{
throw new Exception("Cannot find subnet!");
}
var subnetObj = subnet as Subnetwork;
identifiers.Add(subnetObj!.Id.ToString());
identifiers.Add("addresses");
break;
}
var result = RequestHelper.InvokeRequest("GET", controller, types.Address, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetAddressError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,79 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Net;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Get, "FirstFreeIP", DefaultParameterSetName = "ByID")]
public class GetFirstFreeIPCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByCIDR")]
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
[ValidateNotNullOrEmpty]
public string? CIDR { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetObject")]
[ValidateNotNullOrEmpty]
public Subnetwork? SubnetObject { get; set; }
protected override void ProcessRecord()
{
try
{
int subnetId;
if (ParameterSetName == "ByCIDR")
{
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "cidr", CIDR! })
.GetAwaiter().GetResult();
if (subnet == null)
{
throw new Exception("Cannot find subnet!");
}
var subnetObj = subnet as Subnetwork;
subnetId = subnetObj!.Id;
}
else if (ParameterSetName == "BySubnetObject")
{
subnetId = SubnetObject!.Id;
}
else
{
subnetId = Id!.Value;
}
var identifiers = new List<string> { subnetId.ToString(), "first_free" };
var result = RequestHelper.InvokeRequest("GET", controllers.subnets, null, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
if (result != null)
{
WriteObject(new { Ip = result.ToString() });
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetFirstFreeIPError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,54 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Get, "L2Domain", DefaultParameterSetName = "ByID")]
[OutputType(typeof(Domain))]
public class GetL2DomainCmdlet : PSCmdlet
{
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
protected override void ProcessRecord()
{
try
{
var identifiers = new List<string>();
if (Id.HasValue)
{
identifiers.Add(Id.Value.ToString());
}
var result = RequestHelper.InvokeRequest("GET", controllers.l2domains, types.Domain, null, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
.GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetL2DomainError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,54 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Get, "Nameserver", DefaultParameterSetName = "NoParams")]
[OutputType(typeof(Nameserver))]
public class GetNameserverCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
protected override void ProcessRecord()
{
try
{
var identifiers = new List<string>();
if (Id.HasValue)
{
identifiers.Add(Id.Value.ToString());
}
var result = RequestHelper.InvokeRequest("GET", controllers.tools, types.Nameserver, subcontrollers.nameservers, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
.GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetNameserverError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,148 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Net;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Get, "Permissions")]
public class GetPermissionsCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
[ValidateNotNullOrEmpty]
public string? Id { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByIP")]
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 1,
ParameterSetName = "BySubnetId")]
[ValidateNotNullOrEmpty]
public IPAddress? IP { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByHostName")]
[ValidateNotNullOrEmpty]
public string? HostName { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByTag")]
[ValidateNotNullOrEmpty]
public string? TagId { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetId")]
[ValidateNotNullOrEmpty]
public string? SubnetId { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetCIDR")]
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
[ValidateNotNullOrEmpty]
public string? SubnetCIDR { get; set; }
protected override void ProcessRecord()
{
try
{
var controller = controllers.addresses;
var identifiers = new List<string>();
switch (ParameterSetName)
{
case "ByID":
identifiers.Add(Id!);
break;
case "ByIP":
identifiers.Add("search");
identifiers.Add(IP!.ToString());
break;
case "ByHostName":
identifiers.Add("search_hostname");
identifiers.Add(HostName!);
break;
case "ByTag":
identifiers.Add("tags");
identifiers.Add(TagId!);
identifiers.Add("addresses");
break;
case "BySubnetId":
if (IP != null)
{
identifiers.Add(IP.ToString());
identifiers.Add(SubnetId!);
}
else
{
controller = controllers.subnets;
identifiers.Add(SubnetId!);
identifiers.Add("addresses");
}
break;
case "BySubnetCIDR":
controller = controllers.subnets;
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "cidr", SubnetCIDR! })
.GetAwaiter().GetResult();
if (subnet == null)
{
throw new Exception("Cannot find subnet!");
}
var subnetObj = subnet as Subnetwork;
identifiers.Add(subnetObj!.Id.ToString());
identifiers.Add("addresses");
break;
}
var result = RequestHelper.InvokeRequest("GET", controller, null, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetPermissionsError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,65 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Get, "Section", DefaultParameterSetName = "NoParams")]
[OutputType(typeof(Section))]
public class GetSectionCmdlet : PSCmdlet
{
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
Position = 0,
ParameterSetName = "ByID")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
Position = 0,
ParameterSetName = "ByName")]
[ValidateNotNullOrEmpty]
public string? Name { get; set; }
protected override void ProcessRecord()
{
try
{
var identifiers = new List<string>();
if (ParameterSetName == "ByID" && Id.HasValue)
{
identifiers.Add(Id.Value.ToString());
}
else if (ParameterSetName == "ByName")
{
identifiers.Add(Name!);
}
var result = RequestHelper.InvokeRequest("GET", controllers.sections, types.Section, null, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
.GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetSectionError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,261 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Net;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Get, "Subnet", DefaultParameterSetName = "NoParams")]
[OutputType(typeof(Subnetwork))]
public class GetSubnetCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByCIDR")]
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
[ValidateNotNullOrEmpty]
public string? CIDR { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySectionId")]
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 2,
ParameterSetName = "ByVlanNumber")]
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 1,
ParameterSetName = "ByVlanId")]
[ValidateNotNullOrEmpty]
public int? SectionId { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySectionName")]
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 3,
ParameterSetName = "ByVlanNumber")]
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 2,
ParameterSetName = "ByVlanId")]
[ValidateNotNullOrEmpty]
public string? SectionName { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByVrfId")]
[ValidateNotNullOrEmpty]
public int? VrfId { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByVlanId")]
[ValidateNotNullOrEmpty]
public int? VlanId { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByVlanNumber")]
[ValidateNotNullOrEmpty]
public int? VlanNumber { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 1,
ParameterSetName = "ByID")]
public SwitchParameter Slaves { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 2,
ParameterSetName = "ByID")]
public SwitchParameter Recurse { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 1,
ParameterSetName = "ByVlanNumber")]
[ValidateNotNullOrEmpty]
public int? VlanDomainId { get; set; }
protected override void ProcessRecord()
{
try
{
var controller = controllers.subnets;
var identifiers = new List<string>();
switch (ParameterSetName)
{
case "ByCIDR":
identifiers.Add("cidr");
identifiers.Add(CIDR!);
break;
case "ByID":
identifiers.Add(Id!.Value.ToString());
if (Slaves.IsPresent)
{
identifiers.Add(Recurse.IsPresent ? "slaves_recursive" : "slaves");
}
break;
case "BySectionId":
controller = controllers.sections;
identifiers.Add(SectionId!.Value.ToString());
identifiers.Add("subnets");
break;
case "BySectionName":
controller = controllers.sections;
var section = RequestHelper.InvokeRequest("GET", controllers.sections, types.Section, null, null, new[] { SectionName! })
.GetAwaiter().GetResult();
if (section == null)
{
throw new Exception("Cannot find section!");
}
var sectionObj = section as Section;
identifiers.Add(sectionObj!.Id.ToString());
identifiers.Add("subnets");
break;
case "ByVrfId":
controller = controllers.vrf;
identifiers.Add(VrfId!.Value.ToString());
identifiers.Add("subnets");
break;
case "ByVlanId":
controller = controllers.vlan;
identifiers.Add(VlanId!.Value.ToString());
identifiers.Add("subnets");
if (SectionId.HasValue)
{
identifiers.Add(SectionId.Value.ToString());
}
else if (!string.IsNullOrEmpty(SectionName))
{
var section2 = RequestHelper.InvokeRequest("GET", controllers.sections, types.Section, null, null, new[] { SectionName })
.GetAwaiter().GetResult();
if (section2 != null)
{
var sectionObj2 = section2 as Section;
identifiers.Add(sectionObj2!.Id.ToString());
}
}
break;
case "ByVlanNumber":
controller = controllers.vlan;
var vlans = RequestHelper.InvokeRequest("GET", controllers.vlan, types.Vlan, null, null, new[] { "search", VlanNumber!.Value.ToString() })
.GetAwaiter().GetResult();
if (vlans == null)
{
throw new Exception("Cannot find Vlan!");
}
var vlanList = vlans as System.Collections.IEnumerable;
Vlan? foundVlan = null;
if (vlanList != null)
{
foreach (var v in vlanList)
{
if (v is Vlan vlan)
{
if (VlanDomainId.HasValue && vlan.DomainId != VlanDomainId.Value)
continue;
if (foundVlan != null)
{
throw new Exception($"More than one vLan with {VlanNumber} number is present!");
}
foundVlan = vlan;
}
}
}
if (foundVlan == null)
{
throw new Exception("Cannot find Vlan!");
}
identifiers.Add(foundVlan.Id.ToString());
identifiers.Add("subnets");
if (SectionId.HasValue)
{
identifiers.Add(SectionId.Value.ToString());
}
else if (!string.IsNullOrEmpty(SectionName))
{
var section3 = RequestHelper.InvokeRequest("GET", controllers.sections, types.Section, null, null, new[] { SectionName })
.GetAwaiter().GetResult();
if (section3 != null)
{
var sectionObj3 = section3 as Section;
identifiers.Add(sectionObj3!.Id.ToString());
}
}
break;
}
var result = RequestHelper.InvokeRequest("GET", controller, types.Subnetwork, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetSubnetError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,66 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Net;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Get, "SubnetUsage", DefaultParameterSetName = "ByID")]
public class GetSubnetUsageCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByCIDR")]
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
[ValidateNotNullOrEmpty]
public string? CIDR { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
protected override void ProcessRecord()
{
try
{
int subnetId;
if (ParameterSetName == "ByCIDR")
{
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "cidr", CIDR! })
.GetAwaiter().GetResult();
if (subnet == null)
{
throw new Exception("Cannot find subnet!");
}
var subnetObj = subnet as Subnetwork;
subnetId = subnetObj!.Id;
}
else
{
subnetId = Id!.Value;
}
var identifiers = new List<string> { subnetId.ToString(), "usage" };
var result = RequestHelper.InvokeRequest("GET", controllers.subnets, null, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
if (result != null)
{
WriteObject(result);
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetSubnetUsageError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,98 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Get, "Tag", DefaultParameterSetName = "NoParams")]
[OutputType(typeof(Tag))]
public class GetTagCmdlet : PSCmdlet
{
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByAddressObject")]
[ValidateNotNullOrEmpty]
public Address? AddressObject { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetObject")]
[ValidateNotNullOrEmpty]
public Subnetwork? SubnetObject { get; set; }
protected override void ProcessRecord()
{
try
{
var identifiers = new List<string> { "tags" };
switch (ParameterSetName)
{
case "ByID":
if (Id.HasValue)
{
identifiers.Add(Id.Value.ToString());
}
break;
case "ByAddressObject":
if (AddressObject?.TagId > 0)
{
identifiers.Add(AddressObject.TagId.ToString());
}
else
{
return;
}
break;
case "BySubnetObject":
if (SubnetObject?.TagId > 0)
{
identifiers.Add(SubnetObject.TagId.ToString());
}
else
{
return;
}
break;
}
var result = RequestHelper.InvokeRequest("GET", controllers.addresses, types.Tag, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetTagError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,134 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Get, "Vlan", DefaultParameterSetName = "NoParams")]
[OutputType(typeof(Vlan))]
public class GetVlanCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByNumber")]
[ValidateNotNullOrEmpty]
public int? Number { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByL2Domain")]
[ValidateNotNullOrEmpty]
public int? L2DomainId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetObject")]
[ValidateNotNullOrEmpty]
public Subnetwork? SubnetObject { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByDomainObject")]
[ValidateNotNullOrEmpty]
public Domain? DomainObject { get; set; }
protected override void ProcessRecord()
{
try
{
var controller = controllers.vlan;
var identifiers = new List<string>();
switch (ParameterSetName)
{
case "ByID":
identifiers.Add(Id!.Value.ToString());
break;
case "ByNumber":
identifiers.Add("search");
identifiers.Add(Number!.Value.ToString());
break;
case "ByL2Domain":
controller = controllers.l2domains;
identifiers.Add(L2DomainId!.Value.ToString());
identifiers.Add(subcontrollers.vlans.ToString());
break;
case "BySubnetObject":
if (SubnetObject != null && SubnetObject.VlanId > 0)
{
identifiers.Add(SubnetObject.VlanId.ToString());
}
else
{
return;
}
break;
case "ByDomainObject":
if (DomainObject != null)
{
var result = RequestHelper.InvokeRequest("GET", controllers.l2domains, types.Vlan, subcontrollers.vlans, null, new[] { DomainObject.Id.ToString() })
.GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
}
return;
}
var vlanResult = RequestHelper.InvokeRequest("GET", controller, types.Vlan, null, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
.GetAwaiter().GetResult();
if (vlanResult != null)
{
if (vlanResult is System.Collections.IEnumerable enumerable && !(vlanResult is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(vlanResult);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetVlanError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,54 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Get, "Vrf", DefaultParameterSetName = "NoParams")]
[OutputType(typeof(Vrf))]
public class GetVrfCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
protected override void ProcessRecord()
{
try
{
var identifiers = new List<string>();
if (Id.HasValue)
{
identifiers.Add(Id.Value.ToString());
}
var result = RequestHelper.InvokeRequest("GET", controllers.vrf, types.Vrf, null, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
.GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetVrfError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,219 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Net;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.New, "Address", DefaultParameterSetName = "BySubnetId")]
[OutputType(typeof(Address))]
public class NewAddressCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetId")]
[ValidateNotNullOrEmpty]
public int? SubnetId { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetObject")]
[ValidateNotNullOrEmpty]
public Subnetwork? SubnetObject { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 1)]
[ValidateNotNullOrEmpty]
public string IP { get; set; } = string.Empty;
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 2)]
public SwitchParameter Gateway { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 3)]
public string? Description { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 4)]
public string? Hostname { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 5)]
public string? MAC { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 6)]
public string? Owner { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 7)]
public int? TagId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 8)]
public SwitchParameter PTRIgnore { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 7)]
public int? PTRId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 10)]
public string? Note { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 11)]
public SwitchParameter ExcludePing { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 12)]
public int? DeviceId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 13)]
public string? Port { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 14)]
public object? CustomFields { get; set; }
protected override void ProcessRecord()
{
try
{
int actualSubnetId;
if (ParameterSetName == "BySubnetObject")
{
actualSubnetId = SubnetObject!.Id;
}
else
{
actualSubnetId = SubnetId!.Value;
}
var body = new Dictionary<string, object>
{
{ "subnetId", actualSubnetId },
{ "ip", IP }
};
if (Gateway.IsPresent)
body["is_gateway"] = "1";
if (!string.IsNullOrEmpty(Description))
body["description"] = Description;
if (!string.IsNullOrEmpty(Hostname))
body["hostname"] = Hostname;
if (!string.IsNullOrEmpty(MAC))
body["mac"] = MAC;
if (!string.IsNullOrEmpty(Owner))
body["owner"] = Owner;
if (TagId.HasValue)
body["tag"] = TagId.Value;
if (PTRIgnore.IsPresent)
body["PTRignore"] = "1";
if (PTRId.HasValue)
body["PTR"] = PTRId.Value;
if (!string.IsNullOrEmpty(Note))
body["note"] = Note;
if (ExcludePing.IsPresent)
body["excludePing"] = "1";
if (DeviceId.HasValue)
body["deviceId"] = DeviceId.Value;
if (!string.IsNullOrEmpty(Port))
body["port"] = Port;
if (CustomFields != null)
{
var customDict = ConvertCustomFields(CustomFields);
foreach (var kvp in customDict)
{
body[kvp.Key] = kvp.Value;
}
}
var result = RequestHelper.InvokeRequest("POST", controllers.addresses, null, null, body, null)
.GetAwaiter().GetResult();
if (result != null)
{
var address = RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "search", IP })
.GetAwaiter().GetResult();
if (address != null)
{
WriteObject(address);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewAddressError", ErrorCategory.InvalidOperation, null));
}
}
private Dictionary<string, object> ConvertCustomFields(object customFields)
{
var dict = new Dictionary<string, object>();
if (customFields is PSObject psobj)
{
foreach (var prop in psobj.Properties)
{
dict[prop.Name] = prop.Value ?? new object();
}
}
else if (customFields is Dictionary<string, object> dictObj)
{
return dictObj;
}
return dict;
}
}

View File

@@ -0,0 +1,190 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.New, "FirstFreeIP")]
[OutputType(typeof(Address))]
public class NewFirstFreeIPCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0)]
[ValidateNotNullOrEmpty]
public string SubnetId { get; set; } = string.Empty;
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 2)]
public SwitchParameter Gateway { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 3)]
public string? Description { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 4)]
public string? Hostname { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 5)]
public string? MAC { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 6)]
public string? Owner { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 7)]
public string? TagId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 8)]
public SwitchParameter PTRIgnore { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 9)]
public string? PTRId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 10)]
public string? Note { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 11)]
public SwitchParameter ExcludePing { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 12)]
public string? DeviceId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 13)]
public string? Port { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true)]
public object? CustomFields { get; set; }
protected override void ProcessRecord()
{
try
{
var identifiers = new List<string> { "first_free" };
var body = new Dictionary<string, object>
{
{ "subnetId", SubnetId }
};
if (Gateway.IsPresent)
body["is_gateway"] = "1";
if (!string.IsNullOrEmpty(Description))
body["description"] = Description;
if (!string.IsNullOrEmpty(Hostname))
body["hostname"] = Hostname;
if (!string.IsNullOrEmpty(MAC))
body["mac"] = MAC;
if (!string.IsNullOrEmpty(Owner))
body["owner"] = Owner;
if (!string.IsNullOrEmpty(TagId))
body["tag"] = TagId;
if (PTRIgnore.IsPresent)
body["PTRignore"] = "1";
if (!string.IsNullOrEmpty(PTRId))
body["PTR"] = PTRId;
if (!string.IsNullOrEmpty(Note))
body["note"] = Note;
if (ExcludePing.IsPresent)
body["excludePing"] = "1";
if (!string.IsNullOrEmpty(DeviceId))
body["deviceId"] = DeviceId;
if (!string.IsNullOrEmpty(Port))
body["port"] = Port;
if (CustomFields != null)
{
var customDict = ConvertCustomFields(CustomFields);
foreach (var kvp in customDict)
{
body[kvp.Key] = kvp.Value;
}
}
var result = RequestHelper.InvokeRequest("POST", controllers.addresses, null, null, body, identifiers.ToArray())
.GetAwaiter().GetResult();
if (result != null)
{
var ip = result.ToString();
var address = RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "search", ip })
.GetAwaiter().GetResult();
if (address != null)
{
WriteObject(address);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewFirstFreeIPError", ErrorCategory.InvalidOperation, null));
}
}
private Dictionary<string, object> ConvertCustomFields(object customFields)
{
var dict = new Dictionary<string, object>();
if (customFields is PSObject psobj)
{
foreach (var prop in psobj.Properties)
{
dict[prop.Name] = prop.Value ?? new object();
}
}
else if (customFields is Dictionary<string, object> dictObj)
{
return dictObj;
}
return dict;
}
}

View File

@@ -0,0 +1,81 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.New, "Session", DefaultParameterSetName = "Credentials")]
public class NewSessionCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0)]
[ValidateNotNullOrEmpty]
[ValidatePattern("^https?://")]
public string URL { get; set; } = string.Empty;
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 1)]
[ValidateNotNullOrEmpty]
public string AppID { get; set; } = string.Empty;
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 2,
ParameterSetName = "Credentials")]
[ValidateNotNullOrEmpty]
public PSCredential? Credentials { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 2,
ParameterSetName = "Token")]
[ValidateNotNullOrEmpty]
public string? Token { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 3)]
public SwitchParameter IgnoreSSL { get; set; }
protected override void ProcessRecord()
{
try
{
Session session;
if (ParameterSetName == "Credentials" && Credentials != null)
{
session = SessionManager.CreateSessionWithCredentials(
URL,
AppID,
Credentials,
IgnoreSSL.IsPresent
).GetAwaiter().GetResult();
}
else if (ParameterSetName == "Token" && Token != null)
{
session = SessionManager.CreateSessionWithToken(URL, AppID, Token);
}
else
{
throw new ArgumentException("Invalid parameter set");
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewSessionError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,231 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Net;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.New, "Subnet")]
[OutputType(typeof(Subnetwork))]
public class NewSubnetCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0)]
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
[ValidateNotNullOrEmpty]
public string CIDR { get; set; } = string.Empty;
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 1)]
[ValidateNotNullOrEmpty]
public int SectionId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 2)]
public string? Description { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 3)]
public int? VlanId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 4)]
public int? VrfId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 5)]
public int? MasterSubnetId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 6)]
public int? NameserverId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 7)]
public SwitchParameter ShowName { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 8)]
public SwitchParameter DNSRecursive { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 9)]
public SwitchParameter DNSRecords { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 10)]
public SwitchParameter AllowRequests { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 11)]
public int? ScanAgentId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 12)]
public SwitchParameter DiscoverSubnet { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 12)]
public SwitchParameter IsFull { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 12)]
public int? TagId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 13)]
[ValidateRange(1, 100)]
public int? Threshold { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 14)]
public int? LocationId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 15)]
public object? CustomFields { get; set; }
protected override void ProcessRecord()
{
try
{
var parts = CIDR.Split('/');
var body = new Dictionary<string, object>
{
{ "subnet", parts[0] },
{ "mask", parts[1] },
{ "sectionId", SectionId }
};
if (!string.IsNullOrEmpty(Description))
body["description"] = Description;
if (VlanId.HasValue)
body["vlanId"] = VlanId.Value;
if (VrfId.HasValue)
body["vrfId"] = VrfId.Value;
if (MasterSubnetId.HasValue)
body["masterSubnetId"] = MasterSubnetId.Value;
if (NameserverId.HasValue)
body["nameserverId"] = NameserverId.Value;
if (ShowName.IsPresent)
body["showName"] = "1";
if (DNSRecursive.IsPresent)
body["DNSrecursive"] = "1";
if (DNSRecords.IsPresent)
body["DNSrecords"] = "1";
if (AllowRequests.IsPresent)
body["allowRequests"] = "1";
if (ScanAgentId.HasValue)
body["scanAgent"] = ScanAgentId.Value;
if (DiscoverSubnet.IsPresent)
body["discoverSubnet"] = "1";
if (IsFull.IsPresent)
body["isFull"] = "1";
if (TagId.HasValue)
body["state"] = TagId.Value;
if (Threshold.HasValue)
body["threshold"] = Threshold.Value;
if (LocationId.HasValue)
body["location"] = LocationId.Value;
if (CustomFields != null)
{
var customDict = ConvertCustomFields(CustomFields);
foreach (var kvp in customDict)
{
body[kvp.Key] = kvp.Value;
}
}
var result = RequestHelper.InvokeRequest("POST", controllers.subnets, null, null, body, null)
.GetAwaiter().GetResult();
if (result != null)
{
// Get the created subnet
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "cidr", CIDR })
.GetAwaiter().GetResult();
if (subnet != null)
{
WriteObject(subnet);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewSubnetError", ErrorCategory.InvalidOperation, null));
}
}
private Dictionary<string, object> ConvertCustomFields(object customFields)
{
var dict = new Dictionary<string, object>();
if (customFields is PSObject psobj)
{
foreach (var prop in psobj.Properties)
{
dict[prop.Name] = prop.Value ?? new object();
}
}
else if (customFields is Dictionary<string, object> dictObj)
{
return dictObj;
}
return dict;
}
}

View File

@@ -0,0 +1,51 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Remove, "Address", DefaultParameterSetName = "ByID")]
public class RemoveAddressCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
Position = 0,
ParameterSetName = "ByID")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByAddressObject")]
[ValidateNotNullOrEmpty]
public Address? AddressObject { get; set; }
protected override void ProcessRecord()
{
try
{
int addressId;
if (ParameterSetName == "ByID")
{
addressId = Id!.Value;
}
else
{
addressId = AddressObject!.Id;
}
var identifiers = new List<string> { addressId.ToString() };
RequestHelper.InvokeRequest("DELETE", controllers.addresses, null, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "RemoveAddressError", ErrorCategory.InvalidOperation, null));
}
}
}

View File

@@ -0,0 +1,186 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Set, "Address", DefaultParameterSetName = "ById")]
[OutputType(typeof(Address))]
public class SetAddressCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ById")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByAddressObject")]
[ValidateNotNullOrEmpty]
public Address? AddressObject { get; set; }
[Parameter(
Position = 1,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "ById")]
public bool? Gateway { get; set; }
[Parameter(
Position = 2,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "ById")]
public string? Description { get; set; }
[Parameter(
Mandatory = false,
Position = 3)]
public string? Hostname { get; set; }
[Parameter(
Mandatory = false,
Position = 4)]
public string? MAC { get; set; }
[Parameter(
Mandatory = false,
Position = 5)]
public string? Owner { get; set; }
[Parameter(
Mandatory = false,
Position = 6)]
public int? TagId { get; set; }
[Parameter(
Mandatory = false,
Position = 7)]
public bool? PTRIgnore { get; set; }
[Parameter(
Mandatory = false,
Position = 8)]
public int? PTRId { get; set; }
[Parameter(
Mandatory = false,
Position = 9)]
public string? Note { get; set; }
[Parameter(
Mandatory = false,
Position = 10)]
public bool? ExcludePing { get; set; }
[Parameter(
Mandatory = false,
Position = 11)]
public int? DeviceId { get; set; }
[Parameter(
Mandatory = false,
Position = 12)]
public string? Port { get; set; }
[Parameter(
Mandatory = false)]
public object? CustomFields { get; set; }
protected override void ProcessRecord()
{
try
{
int addressId;
if (ParameterSetName == "ById")
{
addressId = Id!.Value;
}
else
{
addressId = AddressObject!.Id;
}
var identifiers = new List<string> { addressId.ToString() };
var body = new Dictionary<string, object>();
if (Gateway.HasValue)
body["is_gateway"] = Gateway.Value;
if (!string.IsNullOrEmpty(Description))
body["description"] = Description;
if (!string.IsNullOrEmpty(Hostname))
body["hostname"] = Hostname;
if (!string.IsNullOrEmpty(MAC))
body["mac"] = MAC;
if (!string.IsNullOrEmpty(Owner))
body["owner"] = Owner;
if (TagId.HasValue)
body["tag"] = TagId.Value;
if (PTRIgnore.HasValue)
body["PTRignore"] = PTRIgnore.Value;
if (PTRId.HasValue)
body["PTR"] = PTRId.Value;
if (!string.IsNullOrEmpty(Note))
body["note"] = Note;
if (ExcludePing.HasValue)
body["excludePing"] = ExcludePing.Value;
if (DeviceId.HasValue)
body["deviceId"] = DeviceId.Value;
if (!string.IsNullOrEmpty(Port))
body["port"] = Port;
if (CustomFields != null)
{
var customDict = ConvertCustomFields(CustomFields);
foreach (var kvp in customDict)
{
body[kvp.Key] = kvp.Value;
}
}
try
{
RequestHelper.InvokeRequest("PATCH", controllers.addresses, null, null, body, identifiers.ToArray())
.GetAwaiter().GetResult();
}
finally
{
var address = RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
if (address != null)
{
WriteObject(address);
}
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "SetAddressError", ErrorCategory.InvalidOperation, null));
}
}
private Dictionary<string, object> ConvertCustomFields(object customFields)
{
var dict = new Dictionary<string, object>();
if (customFields is PSObject psobj)
{
foreach (var prop in psobj.Properties)
{
dict[prop.Name] = prop.Value ?? new object();
}
}
else if (customFields is Dictionary<string, object> dictObj)
{
return dictObj;
}
return dict;
}
}

View File

@@ -0,0 +1,164 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Set, "Subnet")]
[OutputType(typeof(Subnetwork))]
public class SetSubnetCmdlet : PSCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0)]
[ValidateNotNullOrEmpty]
public int Id { get; set; }
[Parameter(
Mandatory = false)]
public string? Description { get; set; }
[Parameter(
Mandatory = false)]
public int? VlanId { get; set; }
[Parameter(
Mandatory = false)]
public int? VrfId { get; set; }
[Parameter(
Mandatory = false)]
public int? MasterSubnetId { get; set; }
[Parameter(
Mandatory = false)]
public int? NameserverId { get; set; }
[Parameter(
Mandatory = false)]
public SwitchParameter ShowName { get; set; }
[Parameter(
Mandatory = false)]
public SwitchParameter DNSRecursive { get; set; }
[Parameter(
Mandatory = false)]
public SwitchParameter DNSRecords { get; set; }
[Parameter(
Mandatory = false)]
public SwitchParameter AllowRequests { get; set; }
[Parameter(
Mandatory = false)]
public int? ScanAgentId { get; set; }
[Parameter(
Mandatory = false)]
public SwitchParameter DiscoverSubnet { get; set; }
[Parameter(
Mandatory = false)]
public SwitchParameter IsFull { get; set; }
[Parameter(
Mandatory = false)]
public int? TagId { get; set; }
[Parameter(
Mandatory = false)]
[ValidateRange(1, 100)]
public int? Threshold { get; set; }
[Parameter(
Mandatory = false)]
public int? LocationId { get; set; }
[Parameter(
Mandatory = false)]
public object? CustomFields { get; set; }
protected override void ProcessRecord()
{
try
{
var identifiers = new List<string> { Id.ToString() };
var body = new Dictionary<string, object>();
if (!string.IsNullOrEmpty(Description))
body["description"] = Description;
if (VlanId.HasValue)
body["vlanId"] = VlanId.Value;
if (VrfId.HasValue)
body["vrfId"] = VrfId.Value;
if (MasterSubnetId.HasValue)
body["masterSubnetId"] = MasterSubnetId.Value;
if (NameserverId.HasValue)
body["nameserverId"] = NameserverId.Value;
if (ShowName.IsPresent)
body["showName"] = "1";
if (DNSRecursive.IsPresent)
body["DNSrecursive"] = "1";
if (DNSRecords.IsPresent)
body["DNSrecords"] = "1";
if (AllowRequests.IsPresent)
body["allowRequests"] = "1";
if (ScanAgentId.HasValue)
body["scanAgent"] = ScanAgentId.Value;
if (DiscoverSubnet.IsPresent)
body["discoverSubnet"] = "1";
if (IsFull.IsPresent)
body["isFull"] = "1";
if (TagId.HasValue)
body["state"] = TagId.Value;
if (Threshold.HasValue)
body["threshold"] = Threshold.Value;
if (LocationId.HasValue)
body["location"] = LocationId.Value;
if (CustomFields != null)
{
var customDict = ConvertCustomFields(CustomFields);
foreach (var kvp in customDict)
{
body[kvp.Key] = kvp.Value;
}
}
RequestHelper.InvokeRequest("PATCH", controllers.subnets, null, null, body, identifiers.ToArray())
.GetAwaiter().GetResult();
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
if (subnet != null)
{
WriteObject(subnet);
}
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "SetSubnetError", ErrorCategory.InvalidOperation, null));
}
}
private Dictionary<string, object> ConvertCustomFields(object customFields)
{
var dict = new Dictionary<string, object>();
if (customFields is PSObject psobj)
{
foreach (var prop in psobj.Properties)
{
dict[prop.Name] = prop.Value ?? new object();
}
}
else if (customFields is Dictionary<string, object> dictObj)
{
return dictObj;
}
return dict;
}
}

View File

@@ -0,0 +1,131 @@
namespace PS.IPAM.Helpers;
using System;
using System.Management.Automation;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using PS.IPAM;
public static class SessionManager
{
private static Session? _currentSession;
public static Session? CurrentSession
{
get => _currentSession;
set => _currentSession = value;
}
public static string TestSession()
{
if (_currentSession == null)
{
return "NoToken";
}
if (_currentSession.Expires == null)
{
return "Valid";
}
if (_currentSession.Expires < DateTime.Now)
{
return "Expired";
}
return "Valid";
}
public static async Task<Session> CreateSessionWithCredentials(
string url,
string appId,
PSCredential credentials,
bool ignoreSsl = false)
{
var uri = $"{url}/api/{appId}/user";
var auth = Convert.ToBase64String(
Encoding.UTF8.GetBytes($"{credentials.UserName}:{GetPassword(credentials)}"));
using var client = CreateHttpClient(ignoreSsl);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth);
var response = await client.PostAsync(uri, null);
var content = await response.Content.ReadAsStringAsync();
var jsonResponse = JsonConvert.DeserializeObject<dynamic>(content);
if (jsonResponse?.success != true)
{
throw new Exception(jsonResponse?.error?.ToString() ?? "Failed to create session");
}
var token = jsonResponse.data.token.ToString();
var expires = DateTime.Parse(jsonResponse.data.expires.ToString());
_currentSession = new Session(
AuthType.credentials,
token,
appId,
url,
expires,
credentials
);
return _currentSession;
}
public static Session CreateSessionWithToken(
string url,
string appId,
string token)
{
_currentSession = new Session(
AuthType.token,
token,
appId,
url,
null,
null
);
return _currentSession;
}
public static void CloseSession()
{
_currentSession = null;
}
private static string GetPassword(PSCredential credential)
{
var ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(credential.Password);
try
{
return System.Runtime.InteropServices.Marshal.PtrToStringBSTR(ptr);
}
finally
{
System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(ptr);
}
}
public static HttpClient CreateHttpClient(bool ignoreSsl = false, HttpMessageHandler? handler = null)
{
if (handler != null)
{
return new HttpClient(handler);
}
if (ignoreSsl)
{
var sslHandler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
};
return new HttpClient(sslHandler);
}
return new HttpClient();
}
}

View File

@@ -61,7 +61,7 @@ public class Address {
this.Location = location;
this.Port = port;
this.Note = note;
this.EditDate = lastSeen;
this.LastSeen = lastSeen;
this.ExcludePing = excludePing;
this.PTRignore = PTRignore;
this.PTR = PTR;

View File

@@ -1,21 +1,22 @@
namespace PS.IPAM;
using System;
using System.Management.Automation;
[Serializable]
public class Session {
public AuthType AuthType { get; }
public string Token { get; }
public string Token { get; set; }
public string AppID { get; }
public string URL { get; }
public DateTime? Expires { get; }
public Object? Credentials { get; }
public DateTime? Expires { get; set; }
public object? Credentials { get; }
public Session(
AuthType authType,
string token,
string appId,
string url,
DateTime? expires,
Object? credentials
object? credentials
) {
AuthType = authType;
Token = token;

View File

@@ -5,6 +5,7 @@ using System.Dynamic;
[Serializable]
public class Vlan : DynamicObject {
public int Id { get; }
public int VlanId { get; }
public int DomainId { get; }
public string Name { get; }
public int Number { get; }
@@ -23,6 +24,7 @@ public class Vlan : DynamicObject {
Object? custom_fields
) {
this.Id = vlanId;
this.VlanId = vlanId;
this.DomainId = domainId;
this.Name = name;
this.Number = number;

View File

@@ -5,6 +5,14 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<AssemblyName>ps.ipam</AssemblyName>
<RootNamespace>PS.IPAM</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PowerShellStandard.Library" Version="5.1.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
</ItemGroup>
</Project>

View File

@@ -6,7 +6,7 @@
#
@{
RootModule = 'ps.ipam.psm1'
RootModule = 'ps.ipam.dll'
ModuleVersion = '2.0'
GUID = 'cd573493-4245-4073-a238-fab2251d78d0'
Author = 'Nikolay Tatarinov'
@@ -15,14 +15,14 @@
PowerShellVersion = '5.1'
RequiredAssemblies = @(
'classlib\bin\Release\netstandard2.1\publish\classlib.dll'
'ps.ipam.dll'
)
TypesToProcess = @(
'types\types.ps1xml'
)
FunctionsToExport = @(
CmdletsToExport = @(
'Assign-Tag',
'Close-Session',
'New-Session',
@@ -41,6 +41,7 @@
'New-Address',
'New-FirstFreeIP',
'Set-Address',
'Set-Subnet',
'Remove-Address'
)
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.