diff --git a/README.md b/README.md index 1c2bf86..8e92412 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,175 @@ -# ps.ipam + + + + + + + + +
+
+ + Logo + + +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) +![Powershell](https://img.shields.io/badge/powershell-v5.1+-blue.svg) + +

PS.IPAM

+ +

+ Powershell module for phpIPAM +
+ Explore the docs » +
+
+ Report Bug + · + Request Feature +

+
+ + + + +
+ Table of Contents +
    +
  1. + About The Project +
  2. +
  3. + Getting Started + +
  4. +
  5. Usage
  6. +
  7. Roadmap
  8. +
  9. Contributing
  10. +
  11. License
  12. +
  13. Contact
  14. +
  15. Links
  16. +
+
+ + + + +## About The Project +PS.IPAM is Powershell module that wraps phpIPAM RESTful APi into cmdlets +Use the `README.md` to get started. + +

(back to top)

+ + + + +## Getting Started + +### Installation +* **PSGallery** + ```sh + Install-Module -Name ps.ipam + ``` +* **Offline** + 1. Unblock the Internet-downloaded NuGet package (`.nupkg`) file, for example using `Unblock-File -Path C:\Downloads\module.nupkg` cmdlet. + 2. Extract the contents of the NuGet package to a local folder. + 3. Delete the NuGet-specific elements from the folder. + 4. Rename the folder. The default folder name is usually `.`. The version can include `-prerelease` if the module is tagged as a prerelease version. Rename the folder to just the module name. For example, `azurerm.storage.5.0.4-preview` becomes `azurerm.storage`. + 5. Copy the folder to one of the folders in the `$env:PSModulePath value`. `$env:PSModulePath` is a semicolon-delimited set of paths in which PowerShell should look for modules. + +

(back to top)

+ + + + +## Usage + +At first you have to create new session: +```sh +New-PSIPAMSession -URL -AppID -Credentials +``` + +_For more examples, please refer to the [Documentation](https://git.arnike.ru/Arnike/ps.ipam/wiki)_ + +

(back to top)

+ + + + +## Roadmap + +- [ ] Implement all **Set** functions + +See the [open issues](https://git.arnike.ru/Arnike/ps.ipam/issues) for a full list of proposed features (and known issues). + +

(back to top)

+ + + + +## Contributing + +Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. + +If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". +Don't forget to give the project a star! Thanks again! + +1. Fork the Project +2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) +3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) +4. Push to the Branch (`git push origin feature/AmazingFeature`) +5. Open a Pull Request + +

(back to top)

+ + + + +## License + +Distributed under the GNU GPL 2.0 or later License. See `LICENSE` for more information. + +

(back to top)

+ + + + +## Contact + +Nikolay Tatarinov - arnikes@gmail.com + +Project Link: [https://git.arnike.ru/Arnike/ps.ipam](https://git.arnike.ru/Arnike/ps.ipam) + +

(back to top)

+ + + + +## Links + +* [phpIPAM API Documentation](https://phpipam.net/api/api_documentation/) +* [PSGallery](https://www.powershellgallery.com/packages/ps.ipam/1.0) + +

(back to top)

+ + + + + +[logo]: images/logo.png diff --git a/functions/private/Invoke-PSIPAMRequest.ps1 b/functions/private/Invoke-PSIPAMRequest.ps1 new file mode 100644 index 0000000..00040bf --- /dev/null +++ b/functions/private/Invoke-PSIPAMRequest.ps1 @@ -0,0 +1,64 @@ +function Invoke-PSIPAMRequest { + [CmdletBinding()] + param ( + [parameter(Mandatory=$true)] + [ValidateSet("POST","GET","PATCH","DELETE")] + [string] + $Method, + [parameter(Mandatory=$true)] + [ValidateSet("user","vlan","subnets","addresses","sections","vrf","l2domains","tools")] + [string] + $Controller, + [parameter(Mandatory=$false)] + [ValidateSet("nameservers")] + [string] + $SubController, + [Parameter(Mandatory=$false)] + [ValidateScript({ $_ -is [Hashtable] -or $_ -is [PSCustomObject] })] + $Params, + [Parameter(Mandatory=$false)] + [array] + $Identifiers + ) + $_tokenStatus = Test-PSIPAMSession + + if ($_tokenStatus -eq "NoToken") { throw "No session available!" } + if ($_tokenStatus -eq "Expired") { Update-PSIPAMSession } + + $Controller = $Controller.ToLower() + + $_uri = "$($script:ipamURL)/api/$($script:ipamAppID)/$Controller" + if ($SubController) { $_uri += "/$SubController" } + if ($Identifiers) { $_uri += "/$($Identifiers -join '/')/" } + + $_headers = @{ + "Accept" = "application/json" + "Content-Type" = "application/json" + "token" = $script:ipamToken + } + + $_arguments = @{ + Method = $Method + Uri = $_uri + Headers = $_headers + } + + if ($Method -match "POST|PATCH") { + if ($Params -is [PSCustomObject]) { + $_params = @{}; + $Params | Get-Member -MemberType *Property | Where-Object { + $_params.($_.name) = $Params.($_.name) + } + } else { $_params = $Params } + + $_arguments.Add("Body",($_params | ConvertTo-Json)) + } + + $_response = Invoke-RestMethod @_arguments + + if ($_response.code -match "20\d") { + return $_response.data + } else { + throw ("Error - $($_response.code)") + } +} \ No newline at end of file diff --git a/functions/private/Test-PSIPAMSession.ps1 b/functions/private/Test-PSIPAMSession.ps1 new file mode 100644 index 0000000..4c4cf77 --- /dev/null +++ b/functions/private/Test-PSIPAMSession.ps1 @@ -0,0 +1,15 @@ +function Test-PSIPAMSession { + [CmdletBinding()] + param ( + + ) + if ($script:ipamToken) { + if ($script:ipamExpires -lt (Get-Date)) { + return "Expired" + } else { + return "Valid" + } + } else { + return "NoToken" + } +} \ No newline at end of file diff --git a/functions/private/Update-PSIPAMSession.ps1 b/functions/private/Update-PSIPAMSession.ps1 new file mode 100644 index 0000000..d8ade10 --- /dev/null +++ b/functions/private/Update-PSIPAMSession.ps1 @@ -0,0 +1,18 @@ +function Update-PSIPAMSession { + [CmdletBinding()] + param ( + [switch] + $Force + ) + $_tokenStatus = Test-PSIPAMSession + if ($_tokenStatus -eq "NoToken") { + throw "No session available!" + } + if ($_tokenStatus -eq "Valid") { + return (Invoke-PSIPAMRequest -Method PATCH -Controller user).expires + } + if ($_tokenStatus -eq "Expired" -or $Force) { + New-PSIPAMSession -URL $script:ipamURL -AppID $script:ipamAppID -Credentials $script:ipamCredentials + return $script:ipamExpires + } +} \ No newline at end of file diff --git a/functions/public/Get-PSIPAMAddress.ps1 b/functions/public/Get-PSIPAMAddress.ps1 new file mode 100644 index 0000000..252536c --- /dev/null +++ b/functions/public/Get-PSIPAMAddress.ps1 @@ -0,0 +1,70 @@ +function Get-PSIPAMAddress { + [CmdletBinding(DefaultParameterSetName="ByID")] + param ( + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByID")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $Id, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByIP")] + [parameter(Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=1,ParameterSetName="BySubnetId")] + [ValidateScript({[ipaddress] $_})] + [ValidateNotNullOrEmpty()] + [string] + $IP, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByHostName")] + [ValidateNotNullOrEmpty()] + [string] + $HostName, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByTag")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $TagId, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="BySubnetId")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $SubnetId, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="BySubnetCIDR")] + [ValidateScript({[ipaddress] $_.Split("/")[0] -and $_.Split("/")[1] -match "\d{1,2}"})] + [ValidateNotNullOrEmpty()] + [string] + $SubnetCIDR + ) + process { + [string[]]$visiblePropertiesList = @('Id','Ip','Hostname','Description') + $visibleProperties = [System.Management.Automation.PSPropertySet]::new('DefaultDisplayPropertySet',$visiblePropertiesList) + + $_params = @{ + Controller = "addresses" + Method = "GET" + } + switch ($PSCmdlet.ParameterSetName) { + "ByID" { $_identifiers = @($id) } + "ByIP" { $_identifiers = ("search",$IP) } + "ByHostName" { $_identifiers = ("search_hostname",$HostName) } + "ByTag" { $_identifiers = ("tags",$TagId,"addresses") } + "BySubnetId" { + if ($IP) { + $_identifiers = ($IP,$SubnetId) + } else { + $_params.Item("Controller") = "subnets" + $_identifiers = ($SubnetId,"addresses") + } + } + "BySubnetCIDR" { + $_params.Item("Controller") = "subnets" + $_subnetId = (Get-PSIPAMSubnet -CIDR $SubnetCIDR).id + if (!$_subnetId) { throw "Cannot find subnet!" } + + $_identifiers = ($_subnetId,"addresses") + } + } + $_params.Add("Identifiers",$_identifiers) + + Invoke-PSIPAMRequest @_params | ` + Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $visibleProperties -PassThru + } +} +Export-ModuleMember -Function Get-PSIPAMAddress \ No newline at end of file diff --git a/functions/public/Get-PSIPAMFirstFreeIP.ps1 b/functions/public/Get-PSIPAMFirstFreeIP.ps1 new file mode 100644 index 0000000..47215d2 --- /dev/null +++ b/functions/public/Get-PSIPAMFirstFreeIP.ps1 @@ -0,0 +1,33 @@ +function Get-PSIPAMFirstFreeIP { + [CmdletBinding(DefaultParameterSetName="ByID")] + param ( + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByCIDR")] + [ValidateScript({[ipaddress] $_.Split("/")[0] -and $_.Split("/")[1] -match "\d{1,2}"})] + [ValidateNotNullOrEmpty()] + [string] + $CIDR, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByID")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $Id + ) + process { + $_params = @{ + Controller = "subnets" + Method = "GET" + } + switch ($PSCmdlet.ParameterSetName) { + "ByID" { $_subnetId = $Id } + "ByCIDR" { + $_subnetId = (Get-PSIPAMSubnet -CIDR $CIDR).id + if (!$_subnetId) { throw "Cannot find subnet!" } + } + } + $_identifiers = @($_subnetId,"first_free") + $_params.Add("Identifiers",$_identifiers) + + return Invoke-PSIPAMRequest @_params | Select-Object @{n="Ip";e={$_}} + } +} +Export-ModuleMember -Function Get-PSIPAMFirstFreeIP \ No newline at end of file diff --git a/functions/public/Get-PSIPAML2Domain.ps1 b/functions/public/Get-PSIPAML2Domain.ps1 new file mode 100644 index 0000000..2a20537 --- /dev/null +++ b/functions/public/Get-PSIPAML2Domain.ps1 @@ -0,0 +1,26 @@ +function Get-PSIPAML2Domain { + [CmdletBinding(DefaultParameterSetName="ByID")] + param ( + [parameter(Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $Id + ) + process { + [string[]]$visiblePropertiesList = @('Id','Name','Description') + $visibleProperties = [System.Management.Automation.PSPropertySet]::new('DefaultDisplayPropertySet',$visiblePropertiesList) + + $_params = @{ + Controller = "l2domains" + Method = "GET" + } + $_identifiers = @($Id) + + $_params.Add("Identifiers",$_identifiers) + + Invoke-PSIPAMRequest @_params | ` + Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $visibleProperties -PassThru + } +} +Export-ModuleMember -Function Get-PSIPAML2Domain \ No newline at end of file diff --git a/functions/public/Get-PSIPAMNameserver.ps1 b/functions/public/Get-PSIPAMNameserver.ps1 new file mode 100644 index 0000000..8c6fa3b --- /dev/null +++ b/functions/public/Get-PSIPAMNameserver.ps1 @@ -0,0 +1,29 @@ +function Get-PSIPAMNameserver { + [CmdletBinding(DefaultParameterSetName="ByID")] + param ( + [parameter(Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByID")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $Id + ) + process { + [string[]]$visiblePropertiesList = @('Id','Name','Address','Description') + $visibleProperties = [System.Management.Automation.PSPropertySet]::new('DefaultDisplayPropertySet',$visiblePropertiesList) + + $_params = @{ + Controller = "tools" + SubController = "nameservers" + Method = "GET" + } + switch ($PSCmdlet.ParameterSetName) { + "ByID" { $_nameserverId = $Id } + } + $_identifiers = @($_nameserverId) + $_params.Add("Identifiers",$_identifiers) + + Invoke-PSIPAMRequest @_params | Select-Object @{n="address";e={$_.namesrv1}},* | Select-Object -ExcludeProperty namesrv1 | ` + Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $visibleProperties -PassThru + } +} +Export-ModuleMember -Function Get-PSIPAMNameserver \ No newline at end of file diff --git a/functions/public/Get-PSIPAMSection.ps1 b/functions/public/Get-PSIPAMSection.ps1 new file mode 100644 index 0000000..0894b1d --- /dev/null +++ b/functions/public/Get-PSIPAMSection.ps1 @@ -0,0 +1,32 @@ +function Get-PSIPAMSection { + [CmdletBinding(DefaultParameterSetName="ByID")] + param ( + [parameter(Mandatory=$false,ValueFromPipeline=$true,Position=0,ParameterSetName="ByID")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $Id, + [parameter(Mandatory=$true,ValueFromPipeline=$true,Position=0,ParameterSetName="ByName")] + [ValidateNotNullOrEmpty()] + [string] + $Name + ) + process { + [string[]]$visiblePropertiesList = @('Id','Name','Description') + $visibleProperties = [System.Management.Automation.PSPropertySet]::new('DefaultDisplayPropertySet',$visiblePropertiesList) + + $_params = @{ + Controller = "sections" + Method = "GET" + } + switch ($PSCmdlet.ParameterSetName) { + "ByID" { $_identifiers = @($Id) } + "ByName" { $_identifiers = @($Name) } + } + $_params.Add("Identifiers",$_identifiers) + + Invoke-PSIPAMRequest @_params | ` + Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $visibleProperties -PassThru + } +} +Export-ModuleMember Get-PSIPAMSection \ No newline at end of file diff --git a/functions/public/Get-PSIPAMSubnet.ps1 b/functions/public/Get-PSIPAMSubnet.ps1 new file mode 100644 index 0000000..0d22635 --- /dev/null +++ b/functions/public/Get-PSIPAMSubnet.ps1 @@ -0,0 +1,129 @@ +function Get-PSIPAMSubnet { + [CmdletBinding(DefaultParameterSetName="ByID")] + param ( + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByCIDR")] + [ValidateScript({[ipaddress] $_.Split("/")[0] -and $_.Split("/")[1] -match "\d{1,2}"})] + [ValidateNotNullOrEmpty()] + [string] + $CIDR, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByID")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $Id, + [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")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $SectionId, + [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()] + [string] + $SectionName, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByVrfId")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $VrfId, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByVlanId")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $VlanId, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByVlanNumber")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $VlanNumber, + [parameter(Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=1,ParameterSetName="ByVlanNumber")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $VlanDomain, + [parameter(Mandatory=$false,ParameterSetName="ByID")] + [switch] + $Slaves, + [parameter(Mandatory=$false,ParameterSetName="ByID")] + [switch] + $Recurse + ) + process { + [string[]]$visiblePropertiesList = @('Id','Subnet','Mask','Description') + $visibleProperties = [System.Management.Automation.PSPropertySet]::new('DefaultDisplayPropertySet',$visiblePropertiesList) + + $_params = @{ + Controller = "subnets" + Method = "GET" + } + switch ($PSCmdlet.ParameterSetName) { + "ByCIDR" { + $_identifiers = @("cidr",$CIDR) + } + "ByID" { + $_identifiers = @($Id) + + if ($Slaves) { + if ($Recurse) { + $_identifiers += "slaves_recursive" + } else { + $_identifiers += "slaves" + } + } + } + "BySectionId" { + $_params.Item("Controller") = "sections" + $_sectionId = $SectionId + + $_identifiers = @($_sectionId,"subnets") + } + "BySectionName" { + $_params.Item("Controller") = "sections" + $_sectionId = (Get-PSIPAMSection -Name $SectionName).id + if (!$_sectionId) { throw "Cannot find section!" } + + $_identifiers = @($_sectionId,"subnets") + } + "ByVrfId" { + $_params.Item("Controller") = "vrf" + $_vrfId = $VrfId + + $_identifiers = @($_vrfId,"subnets") + } + "ByVlanId" { + $_params.Item("Controller") = "vlan" + $_vlanId = $VlanId + if ($SectionId) { $_sectionId = $SectionId } + if ($SectionName){ $_sectionId = (Get-PSIPAMSection -Name $SectionName).id } + + $_identifiers = @($_vlanId,"subnets") + + if ($_sectionId) { $_identifiers += $_sectionId } + } + "ByVlanNumber" { + $_params.Item("Controller") = "vlan" + $_vlans = Get-PSIPAMVlan -Number $VlanNumber + if ($VlanDomain) { $_vlans = $_vlans | Where-Object {$_.domainId -eq $VlanDomain} } + if ($SectionId) { $_sectionId = $SectionId } + if ($SectionName){ $_sectionId = (Get-PSIPAMSection -Name $SectionName).id } + + $_vlanId = $_vlans.vlanId + + if ($_vlanid -is [System.Array]) { throw "More than one vLan with $VlanNumber number is present!" } + if (!$_vlanId) { throw "Cannot find Vlan!"} + + $_identifiers = @($_vlanId,"subnets") + + if ($_sectionId) { $_identifiers += $_sectionId } + } + } + $_params.Add("Identifiers",$_identifiers) + + Invoke-PSIPAMRequest @_params | ` + Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $visibleProperties -PassThru + } +} +Export-ModuleMember Get-PSIPAMSubnet \ No newline at end of file diff --git a/functions/public/Get-PSIPAMSubnetUsage.ps1 b/functions/public/Get-PSIPAMSubnetUsage.ps1 new file mode 100644 index 0000000..7b8b550 --- /dev/null +++ b/functions/public/Get-PSIPAMSubnetUsage.ps1 @@ -0,0 +1,33 @@ +function Get-PSIPAMSubnetUsage { + [CmdletBinding(DefaultParameterSetName="ByID")] + param ( + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByCIDR")] + [ValidateScript({[ipaddress] $_.Split("/")[0] -and $_.Split("/")[1] -match "\d{1,2}"})] + [ValidateNotNullOrEmpty()] + [string] + $CIDR, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByID")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $Id + ) + process { + $_params = @{ + Controller = "subnets" + Method = "GET" + } + switch ($PSCmdlet.ParameterSetName) { + "ByCIDR" { + $_subnetId = (Get-PSIPAMSubnet -CIDR $CIDR).id + if (!$_subnetId) { throw "Cannot find subnet!" } + } + "ByID" { $_subnetId = $Id } + } + $_identifiers = @($_subnetId,"usage") + $_params.Add("Identifiers",$_identifiers) + + return Invoke-PSIPAMRequest @_params + } +} +Export-ModuleMember -Function Get-PSIPAMSubnetUsage \ No newline at end of file diff --git a/functions/public/Get-PSIPAMTags.ps1 b/functions/public/Get-PSIPAMTags.ps1 new file mode 100644 index 0000000..cd8f0ec --- /dev/null +++ b/functions/public/Get-PSIPAMTags.ps1 @@ -0,0 +1,26 @@ +function Get-PSIPAMTags { + [CmdletBinding()] + param ( + [parameter(Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $Id + ) + process { + [string[]]$visiblePropertiesList = @('Id','Name') + $visibleProperties = [System.Management.Automation.PSPropertySet]::new('DefaultDisplayPropertySet',$visiblePropertiesList) + + $_params = @{ + Controller = "addresses" + Method = "GET" + } + $_identifiers = @("tags") + if ($Id) { $_identifiers += $Id } + $_params.Add("Identifiers",$_identifiers) + + Invoke-PSIPAMRequest @_params | ` + Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $visibleProperties -PassThru + } +} +Export-ModuleMember -Function Get-PSIPAMTags \ No newline at end of file diff --git a/functions/public/Get-PSIPAMVlan.ps1 b/functions/public/Get-PSIPAMVlan.ps1 new file mode 100644 index 0000000..60634b2 --- /dev/null +++ b/functions/public/Get-PSIPAMVlan.ps1 @@ -0,0 +1,45 @@ +function Get-PSIPAMVlan { + [CmdletBinding(DefaultParameterSetName="ByID")] + param ( + [parameter(Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByID")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $Id, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByNumber")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $Number, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByL2Domain")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $L2DomainId + ) + process { + [string[]]$visiblePropertiesList = @('Id','Name','Description') + $visibleProperties = [System.Management.Automation.PSPropertySet]::new('DefaultDisplayPropertySet',$visiblePropertiesList) + + $_params = @{ + Controller = "vlan" + Method = "GET" + } + switch ($PSCmdlet.ParameterSetName) { + "ByID" { $_identifiers = @($Id) } + "ByNumber" { $_identifiers = @("search",$Number) } + "ByL2Domain"{ + $_params.Item("Controller") = "l2domains" + + $_l2domainId = $L2DomainId + + $_identifiers = @($_l2domainId,"vlans") + } + } + $_params.Add("Identifiers",$_identifiers) + + Invoke-PSIPAMRequest @_params | Select-Object @{n="id";e={$_.vlanId}},* | Select-Object -ExcludeProperty vlanId | ` + Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $visibleProperties -PassThru + } +} +Export-ModuleMember -Function Get-PSIPAMVlan \ No newline at end of file diff --git a/functions/public/Get-PSIPAMVrf.ps1 b/functions/public/Get-PSIPAMVrf.ps1 new file mode 100644 index 0000000..6846a4c --- /dev/null +++ b/functions/public/Get-PSIPAMVrf.ps1 @@ -0,0 +1,26 @@ +function Get-PSIPAMVrf { + [CmdletBinding(DefaultParameterSetName="ByID")] + param ( + [parameter(Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0,ParameterSetName="ByID")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $Id + ) + process { + [string[]]$visiblePropertiesList = @('Id','Name','Description') + $visibleProperties = [System.Management.Automation.PSPropertySet]::new('DefaultDisplayPropertySet',$visiblePropertiesList) + + $_params = @{ + Controller = "vrf" + Method = "GET" + } + if ($Id) { $_identifiers = @($Id) } + + $_params.Add("Identifiers",$_identifiers) + + Invoke-PSIPAMRequest @_params | Select-Object @{n="id";e={$_.vrfId}},* | Select-Object -ExcludeProperty vrfId | ` + Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $visibleProperties -PassThru + } +} +Export-ModuleMember -Function Get-PSIPAMVrf \ No newline at end of file diff --git a/functions/public/New-PSIPAMAddress.ps1 b/functions/public/New-PSIPAMAddress.ps1 new file mode 100644 index 0000000..0a70bfa --- /dev/null +++ b/functions/public/New-PSIPAMAddress.ps1 @@ -0,0 +1,182 @@ +function New-PSIPAMAddress { + [CmdletBinding()] + param ( + [parameter( + Mandatory=$true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Id of subnet address belongs to", + Position=0)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $SubnetId, + [parameter( + Mandatory=$true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="IP address", + Position=1)] + [ValidateScript({[ipaddress] $_ })] + [ValidateNotNullOrEmpty()] + [string] + $Ip, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Defines if address is presented as gateway", + Position=2)] + [switch] + $Gateway, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Address description", + Position=3)] + [ValidateNotNullOrEmpty()] + [string] + $Description, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Address hostname", + Position=4)] + [ValidateNotNullOrEmpty()] + [string] + $Hostname, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Mac address", + Position=5)] + [ValidateScript({ $_.Replace(":","") -match "^$('([A-F0-9]{2})' * 6)$" })] + [ValidateNotNullOrEmpty()] + [string] + $MAC, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Address owner", + Position=6)] + [ValidateNotNullOrEmpty()] + [string] + $Owner, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Id of subnet address belongs to", + Position=7)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $TagId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Controls if PTR should not be created", + Position=8)] + [switch] + $PTRIgnore, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Id of PowerDNS PTR record", + Position=7)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $PTRId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Note", + Position=10)] + [ValidateNotNullOrEmpty()] + [string] + $Note, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Exclude this address from status update scans (ping)", + Position=11)] + [switch] + $ExcludePing, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Id of device address belongs to", + Position=12)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $DeviceId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Port", + Position=13)] + [ValidateNotNullOrEmpty()] + [string] + $Port, + + [parameter(Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] + [ValidateScript({ $_ -is [Hashtable] -or $_ -is [PSCustomObject] })] + $CustomFields + ) + process { + $_params = @{ + Controller = "addresses" + Method = "POST" + } + + $_body = @{ + subnetId = $SubnetId + ip = $Ip + } + if ($Gateway) { $_body.Add("is_gateway", "1") } + if ($Description) { $_body.Add("description", $Description) } + if ($Hostname) { $_body.Add("hostname", $Hostname) } + if ($MAC) { $_body.Add("mac", $MAC) } + if ($Owner) { $_body.Add("owner", $Owner) } + if ($TagId) { $_body.Add("tag", $TagId) } + if ($PTRIgnore) { $_body.Add("PTRignore", "1") } + if ($PTRId) { $_body.add("PTR", $PTRId)} + if ($Note) { $_body.Add("note", $Note) } + if ($ExcludePing) { $_body.Add("excludePing", "1") } + if ($DeviceId) { $_body.Add("deviceId", $DeviceId) } + if ($Port) { $_body.Add("port", $Port) } + + if ($CustomFields) { + if ($CustomFields -is [PSCustomObject]) { + $_customFields = @{}; + $CustomFields | Get-Member -MemberType *Property | Where-Object { + $_customFields.($_.name) = $CustomFields.($_.name) + } + } else { $_customFields = $CustomFields } + + $_body = $_body + $_customFields + } + + $_params.Add("Params",$_body) + + try { + Invoke-PSIPAMRequest @_params + } + finally { + Get-PSIPAMAddress -SubnetId $SubnetId -Ip $Ip + } + } +} +Export-ModuleMember -Function New-PSIPAMAddress \ No newline at end of file diff --git a/functions/public/New-PSIPAMFirstFreeIP.ps1 b/functions/public/New-PSIPAMFirstFreeIP.ps1 new file mode 100644 index 0000000..fe377dc --- /dev/null +++ b/functions/public/New-PSIPAMFirstFreeIP.ps1 @@ -0,0 +1,172 @@ +function New-PSIPAMFirstFreeIP { + [CmdletBinding()] + param ( + [parameter( + Mandatory=$true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Id of subnet address belongs to", + Position=0)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $SubnetId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Defines if address is presented as gateway", + Position=2)] + [switch] + $Gateway, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Address description", + Position=3)] + [ValidateNotNullOrEmpty()] + [string] + $Description, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Address hostname", + Position=4)] + [ValidateNotNullOrEmpty()] + [string] + $Hostname, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Mac address", + Position=5)] + [ValidateScript({ $_.Replace(":","") -match "^$('([A-F0-9]{2})' * 6)$" })] + [ValidateNotNullOrEmpty()] + [string] + $MAC, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Address owner", + Position=6)] + [ValidateNotNullOrEmpty()] + [string] + $Owner, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Id of subnet address belongs to", + Position=7)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $TagId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Controls if PTR should not be created", + Position=8)] + [switch] + $PTRIgnore, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Id of PowerDNS PTR record", + Position=9)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $PTRId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Note", + Position=10)] + [ValidateNotNullOrEmpty()] + [string] + $Note, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Exclude this address from status update scans (ping)", + Position=11)] + [switch] + $ExcludePing, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Id of device address belongs to", + Position=12)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $DeviceId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Port", + Position=13)] + [ValidateNotNullOrEmpty()] + [string] + $Port, + + [parameter(Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] + [ValidateScript({ $_ -is [Hashtable] -or $_ -is [PSCustomObject] })] + $CustomFields + ) + process { + $_params = @{ + Controller = "addresses" + Method = "POST" + } + $_identifiers = @('first_free') + + $_params.Add("Identifiers",$_identifiers) + + $_body = @{ + subnetId = $SubnetId + } + if ($Gateway) { $_body.Add("is_gateway", "1") } + if ($Description) { $_body.Add("description", $Description) } + if ($Hostname) { $_body.Add("hostname", $Hostname) } + if ($MAC) { $_body.Add("mac", $MAC) } + if ($Owner) { $_body.Add("owner", $Owner) } + if ($TagId) { $_body.Add("tag", $TagId) } + if ($PTRIgnore) { $_body.Add("PTRignore", "1") } + if ($PTRId) { $_body.add("PTR", $PTRId)} + if ($Note) { $_body.Add("note", $Note) } + if ($ExcludePing) { $_body.Add("excludePing", "1") } + if ($DeviceId) { $_body.Add("deviceId", $DeviceId) } + if ($Port) { $_body.Add("port", $Port) } + + if ($CustomFields) { + if ($CustomFields -is [PSCustomObject]) { + $_customFields = @{}; + $CustomFields | Get-Member -MemberType *Property | Where-Object { + $_customFields.($_.name) = $CustomFields.($_.name) + } + } else { $_customFields = $CustomFields } + + $_body = $_body + $_customFields + } + + $_params.Add("Params",$_body) + + $_result = Invoke-PSIPAMRequest @_params + if ($_result) { + Get-PSIPAMAddress -SubnetId $SubnetId -IP $_result + } + } +} +Export-ModuleMember -Function New-PSIPAMFirstFreeIP \ No newline at end of file diff --git a/functions/public/New-PSIPAMSession.ps1 b/functions/public/New-PSIPAMSession.ps1 new file mode 100644 index 0000000..119a59e --- /dev/null +++ b/functions/public/New-PSIPAMSession.ps1 @@ -0,0 +1,37 @@ +function New-PSIPAMSession { + [CmdletBinding()] + param ( + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0)] + [ValidateNotNullOrEmpty()] + [string]$URL, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=1)] + [ValidateNotNullOrEmpty()] + [string]$AppID, + [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=2)] + [ValidateNotNullOrEmpty()] + [pscredential]$Credentials + ) + $_bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credentials.Password) + $_password = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($_bstr) + $_uri = "$URL/api/$AppID/user" + $_auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$($Credentials.UserName):$_password")) + $_headers = @{ + "Accept" = "application/json" + "Content-Type" = "application/json" + "Authorization" = "Basic $_auth" + } + + $_response = Invoke-RestMethod -Method Post -Uri $_uri -Headers $_headers -ErrorAction SilentlyContinue + + if ($_response.success -eq $true) { + $script:ipamAuth = $true + $script:ipamToken = $_response.data.token + $script:ipamAppID = $AppID + $script:ipamURL = $URL + $script:ipamCredentials = $Credentials + $script:ipamExpires = Get-Date $_response.data.expires + } else { + $_response.error + } +} +Export-ModuleMember -Function New-PSIPAMSession \ No newline at end of file diff --git a/functions/public/New-PSIPAMSubnet.ps1 b/functions/public/New-PSIPAMSubnet.ps1 new file mode 100644 index 0000000..d655d34 --- /dev/null +++ b/functions/public/New-PSIPAMSubnet.ps1 @@ -0,0 +1,202 @@ +function New-PSIPAMSubnet { + [CmdletBinding()] + param ( + [parameter( + Mandatory=$true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="CIDR of subnet in dotted format (e.g 10.10.10.0/24)", + Position=0)] + [ValidateScript({[ipaddress] $_.Split("/")[0] -and $_.Split("/")[1] -match "\d{1,2}"})] + [ValidateNotNullOrEmpty()] + [string] + $CIDR, + [parameter( + Mandatory=$true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Section identifier", + Position=1)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $SectionId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Subnet description", + Position=2)] + [string] + $Description, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Assigns subnet to VLAN", + Position=3)] + [ValidateScript({ $_ -match "^\d+$" })] + [string] + $VlanId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Assigns subnet to VRF", + Position=4)] + [ValidateScript({ $_ -match "^\d+$" })] + [string] + $VrfId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Master subnet id for nested subnet", + Position=5)] + [ValidateScript({ $_ -match "^\d+$" })] + [string] + $MasterSubnetId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Id of nameserver to attach to subnet", + Position=6)] + [ValidateScript({ $_ -match "^\d+$" })] + [string] + $NameserverId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Controls weather subnet is displayed as IP address or Name in subnets menu", + Position=7)] + [switch] + $ShowName, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Controls if PTR records should be created for subnet", + Position=8)] + [switch] + $DNSRecursive, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Controls weather hostname DNS records are displayed", + Position=9)] + [switch] + $DNSRecords, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Controls if IP requests are allowed for subnet", + Position=10)] + [switch] + $AllowRequests, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Controls which scanagent to use for subnet (default id 1)", + Position=11)] + [ValidateScript({ $_ -match "^\d+$" })] + [string] + $ScanAgentId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Controls if new hosts should be discovered for new host scans", + Position=12)] + [switch] + $DiscoverSubnet, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Marks subnet as used", + Position=12)] + [switch] + $IsFull, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Assignes state (tag) to subnet (default: 1 Used)", + Position=12)] + [ValidateScript({ $_ -match "^\d+$" })] + [string] + $TagId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Subnet threshold", + Position=13)] + [ValidateScript({ $_ -match "^\d+$" -and $_ -le 100 -and $_ -ge 1 })] + $Threshold, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Location index", + Position=14)] + [ValidateScript({ $_ -match "^\d+$" })] + [string] + $LocationId, + + [parameter(Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] + [ValidateScript({ $_ -is [Hashtable] -or $_ -is [PSCustomObject] })] + $CustomFields + ) + process { + $_params = @{ + Controller = "subnets" + Method = "POST" + } + + $_body = @{ + subnet = $CIDR.Split('/')[0] + mask = $CIDR.Split('/')[1] + sectionId = $SectionId + } + if ($Description) { $_body.Add("description", $Description) } + if ($VlanId) { $_body.Add("vlanId", $VlanId) } + if ($VrfId) { $_body.Add("vrfId", $VrfId) } + if ($MasterSubnetId) { $_body.Add("masterSubnetId", $MasterSubnetId) } + if ($NameserverId) { $_body.Add("nameserverId", $NameserverId) } + if ($ShowName) { $_body.Add("showName", "1") } + if ($DNSRecursive) { $_body.Add("DNSrecursive", "1") } + if ($DNSRecords) { $_body.Add("DNSrecords", "1") } + if ($AllowRequests) { $_body.Add("allowRequests", "1") } + if ($ScanAgentId) { $_body.Add("scanAgent", $ScanAgentId) } + if ($DiscoverSubnet) { $_body.Add("discoverSubnet", "1") } + if ($IsFull) { $_body.Add("isFull", "1") } + if ($TagId) { $_body.Add("state", $TagId) } + if ($Threshold) { $_body.Add("threshold", $Threshold) } + if ($Location) { $_body.Add("location", $Location) } + + if ($CustomFields) { + if ($CustomFields -is [PSCustomObject]) { + $_customFields = @{}; + $CustomFields | Get-Member -MemberType *Property | Where-Object { + $_customFields.($_.name) = $CustomFields.($_.name) + } + } else { $_customFields = $CustomFields } + + $_body = $_body + $_customFields + } + + $_params.Add("Params",$_body) + + $_result = Invoke-PSIPAMRequest @_params + if ($_result) { + return Get-PSIPAMSubnet -CIDR $_result + } + } +} +Export-ModuleMember -Function New-PSIPAMSubnet \ No newline at end of file diff --git a/functions/public/Remove-PSIPAMAddress.ps1 b/functions/public/Remove-PSIPAMAddress.ps1 new file mode 100644 index 0000000..49d31b0 --- /dev/null +++ b/functions/public/Remove-PSIPAMAddress.ps1 @@ -0,0 +1,35 @@ +function Remove-PSIPAMAddress { + [CmdletBinding(DefaultParameterSetName="ByID")] + param ( + [parameter(Mandatory=$true,ValueFromPipeline=$true,Position=0,ParameterSetName="ByID")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $Id, + [parameter(Mandatory=$true,ValueFromPipeline=$true,Position=0,ParameterSetName="ByIP")] + [ValidateScript({[ipaddress] $_ })] + [ValidateNotNullOrEmpty()] + [string] + $IP, + [parameter(Mandatory=$true,ValueFromPipeline=$true,Position=1,ParameterSetName="ByIP")] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $SubnetId + ) + process { + $_params = @{ + Controller = "addresses" + Method = "DELETE" + } + + switch ($PSCmdlet.ParameterSetName) { + "ByID" { $_identifiers = @($Id) } + "ByIP" { $_identifiers = @($IP,$SubnetId) } + } + $_params.Add("Identifiers",$_identifiers) + + Invoke-PSIPAMRequest @_params + } +} +Export-ModuleMember Remove-PSIPAMAddress \ No newline at end of file diff --git a/functions/public/Set-PSIPAMAddress.ps1 b/functions/public/Set-PSIPAMAddress.ps1 new file mode 100644 index 0000000..df04f00 --- /dev/null +++ b/functions/public/Set-PSIPAMAddress.ps1 @@ -0,0 +1,172 @@ +function Set-PSIPAMAddress { + [CmdletBinding()] + param ( + [parameter( + Mandatory=$true, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Id of subnet address belongs to", + Position=0)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $Id, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Defines if address is presented as gateway", + Position=1)] + [bool] + $Gateway, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Address description", + Position=2)] + [ValidateNotNullOrEmpty()] + [string] + $Description, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Address hostname", + Position=3)] + [ValidateNotNullOrEmpty()] + [string] + $Hostname, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Mac address", + Position=4)] + [ValidateScript({ $_.Replace(":","") -match "^$('([A-F0-9]{2})' * 6)$" })] + [ValidateNotNullOrEmpty()] + [string] + $MAC, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Address owner", + Position=5)] + [ValidateNotNullOrEmpty()] + [string] + $Owner, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Id of subnet address belongs to", + Position=6)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $TagId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Controls if PTR should not be created", + Position=7)] + [bool] + $PTRIgnore, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Id of PowerDNS PTR record", + Position=8)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $PTRId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Note", + Position=9)] + [ValidateNotNullOrEmpty()] + [string] + $Note, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Exclude this address from status update scans (ping)", + Position=10)] + [bool] + $ExcludePing, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Id of device address belongs to", + Position=11)] + [ValidateScript({ $_ -match "^\d+$" })] + [ValidateNotNullOrEmpty()] + [string] + $DeviceId, + [parameter( + Mandatory=$false, + ValueFromPipeline=$true, + ValueFromPipelineByPropertyName=$true, + HelpMessage="Port", + Position=12)] + [ValidateNotNullOrEmpty()] + [string] + $Port, + + [parameter(Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] + [ValidateScript({ $_ -is [Hashtable] -or $_ -is [PSCustomObject] })] + $CustomFields + ) + process { + $_params = @{ + Controller = "addresses" + Method = "PATCH" + } + $_identifiers = @($Id) + + $_params.Add("Identifiers",$_identifiers) + + $_body = @{ } + if ($Gateway) { $_body.Add("is_gateway", [int]$Gateway) } + if ($Description) { $_body.Add("description", $Description) } + if ($Hostname) { $_body.Add("hostname", $Hostname) } + if ($MAC) { $_body.Add("mac", $MAC) } + if ($Owner) { $_body.Add("owner", $Owner) } + if ($TagId) { $_body.Add("tag", $TagId) } + if ($PTRIgnore) { $_body.Add("PTRignore", [int]$PTRIgnore) } + if ($PTRId) { $_body.add("PTR", $PTRId)} + if ($Note) { $_body.Add("note", $Note) } + if ($ExcludePing) { $_body.Add("excludePing", [int]$ExcludePing) } + if ($DeviceId) { $_body.Add("deviceId", $DeviceId) } + if ($Port) { $_body.Add("port", $Port) } + + if ($CustomFields) { + if ($CustomFields -is [PSCustomObject]) { + $_customFields = @{}; + $CustomFields | Get-Member -MemberType *Property | Where-Object { + $_customFields.($_.name) = $CustomFields.($_.name) + } + } else { $_customFields = $CustomFields } + + $_body = $_body + $_customFields + } + + $_params.Add("Params",$_body) + + try { + Invoke-PSIPAMRequest @_params + } + finally { + Get-PSIPAMAddress -Id $Id + } + } +} +Export-ModuleMember -Function Set-PSIPAMAddress \ No newline at end of file diff --git a/functions/public/Set-PSIPAMSubnet.ps1 b/functions/public/Set-PSIPAMSubnet.ps1 new file mode 100644 index 0000000..e69de29 diff --git a/images/logo.png b/images/logo.png new file mode 100644 index 0000000..d770944 Binary files /dev/null and b/images/logo.png differ diff --git a/ps.ipam.code-workspace b/ps.ipam.code-workspace new file mode 100644 index 0000000..876a149 --- /dev/null +++ b/ps.ipam.code-workspace @@ -0,0 +1,8 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": {} +} \ No newline at end of file diff --git a/ps.ipam.psd1 b/ps.ipam.psd1 new file mode 100644 index 0000000..24b4119 Binary files /dev/null and b/ps.ipam.psd1 differ diff --git a/ps.ipam.psm1 b/ps.ipam.psm1 new file mode 100644 index 0000000..89aad14 --- /dev/null +++ b/ps.ipam.psm1 @@ -0,0 +1,6 @@ +Get-ChildItem "$(Split-Path $script:MyInvocation.MyCommand.Path)\functions" -Filter "*.ps1" -Recurse | ForEach-Object { + . $_.FullName +} +Get-ChildItem "$(Split-Path $script:MyInvocation.MyCommand.Path)\classes" -Filter "*.ps1" -Recurse | ForEach-Object { + . $_.FullName +}