diff --git a/.github/workflows/pssa.yml b/.github/workflows/pssa.yml
new file mode 100644
index 0000000..446a549
--- /dev/null
+++ b/.github/workflows/pssa.yml
@@ -0,0 +1,16 @@
+name: CI
+on: [pull_request]
+jobs:
+ lint:
+ name: Run PSSA
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v1
+ - name: lint
+ uses: docker://devblackops/github-action-psscriptanalyzer:2.3.0
+ with:
+ settingsPath: .vscode/PSScriptAnalyzerSettings.psd1
+ sendComment: false
+ failOnInfos: true
+ failOnErrors: true
+ failOnWarnings: true
\ No newline at end of file
diff --git a/.vscode/PSScriptAnalyzerSettings.psd1 b/.vscode/PSScriptAnalyzerSettings.psd1
new file mode 100644
index 0000000..311a301
--- /dev/null
+++ b/.vscode/PSScriptAnalyzerSettings.psd1
@@ -0,0 +1,5 @@
+@{
+ ExcludeRules = @(
+ 'PSUseToExportFieldsInManifest'
+ )
+}
\ No newline at end of file
diff --git a/Functions/Helpers/InvokeNetboxRequest.ps1 b/Functions/Helpers/InvokeNetboxRequest.ps1
index ef5d31e..9696518 100644
--- a/Functions/Helpers/InvokeNetboxRequest.ps1
+++ b/Functions/Helpers/InvokeNetboxRequest.ps1
@@ -1,4 +1,4 @@
-<#
+<#
.NOTES
===========================================================================
Created with: SAPIEN Technologies, Inc., PowerShell Studio 2020 v5.7.172
@@ -18,44 +18,46 @@ function InvokeNetboxRequest {
(
[Parameter(Mandatory = $true)]
[System.UriBuilder]$URI,
-
+
[Hashtable]$Headers = @{
},
-
+
[pscustomobject]$Body = $null,
-
- [ValidateRange(0, 60)]
- [uint16]$Timeout = 5,
-
+
+ [ValidateRange(1, 65535)]
+ [uint16]$Timeout = (Get-NetboxTimeout),
+
[ValidateSet('GET', 'PATCH', 'PUT', 'POST', 'DELETE', 'OPTIONS', IgnoreCase = $true)]
[string]$Method = 'GET',
-
+
[switch]$Raw
)
-
+
$creds = Get-NetboxCredential
-
+
$Headers.Authorization = "Token {0}" -f $creds.GetNetworkCredential().Password
-
+
$splat = @{
- 'Method' = $Method
- 'Uri' = $URI.Uri.AbsoluteUri # This property auto generates the scheme, hostname, path, and query
- 'Headers' = $Headers
- 'TimeoutSec' = $Timeout
+ 'Method' = $Method
+ 'Uri' = $URI.Uri.AbsoluteUri # This property auto generates the scheme, hostname, path, and query
+ 'Headers' = $Headers
+ 'TimeoutSec' = $Timeout
'ContentType' = 'application/json'
'ErrorAction' = 'Stop'
- 'Verbose' = $VerbosePreference
+ 'Verbose' = $VerbosePreference
}
-
+
+ $splat += Get-NetboxInvokeParams
+
if ($Body) {
Write-Verbose "BODY: $($Body | ConvertTo-Json -Compress)"
$null = $splat.Add('Body', ($Body | ConvertTo-Json -Compress))
}
-
+
$result = Invoke-RestMethod @splat
-
+
#region TODO: Handle errors a little more gracefully...
-
+
<#
try {
Write-Verbose "Sending request..."
@@ -69,7 +71,7 @@ function InvokeNetboxRequest {
Write-Verbose "RAW provided...throwing raw exception"
throw $_
}
-
+
Write-Verbose "Converting response to object"
$myError = GetNetboxAPIErrorBody -Response $_.Exception.Response | ConvertFrom-Json
} else {
@@ -77,18 +79,18 @@ function InvokeNetboxRequest {
$myError = $_
}
}
-
+
Write-Verbose "MyError is $($myError.GetType().FullName)"
-
+
if ($myError -is [Exception]) {
throw $_
} elseif ($myError -is [pscustomobject]) {
throw $myError.detail
- }
+ }
#>
-
+
#endregion TODO: Handle errors a little more gracefully...
-
+
# If the user wants the raw value from the API... otherwise return only the actual result
if ($Raw) {
Write-Verbose "Returning raw result by choice"
diff --git a/Functions/Setup/Connect-NetboxAPI.ps1 b/Functions/Setup/Connect-NetboxAPI.ps1
index 1b27c12..b012a0f 100644
--- a/Functions/Setup/Connect-NetboxAPI.ps1
+++ b/Functions/Setup/Connect-NetboxAPI.ps1
@@ -2,56 +2,69 @@
<#
.SYNOPSIS
Connects to the Netbox API and ensures Credential work properly
-
+
.DESCRIPTION
Connects to the Netbox API and ensures Credential work properly
-
+
.PARAMETER Hostname
The hostname for the resource such as netbox.domain.com
-
+
.PARAMETER Credential
Credential object containing the API key in the password. Username is not applicable
-
+
.PARAMETER Scheme
Scheme for the URI such as HTTP or HTTPS. Defaults to HTTPS
-
+
.PARAMETER Port
Port for the resource. Value between 1-65535
-
+
.PARAMETER URI
The full URI for the resource such as "https://netbox.domain.com:8443"
-
+
+ .PARAMETER SkipCertificateCheck
+ A description of the SkipCertificateCheck parameter.
+
+ .PARAMETER TimeoutSeconds
+ The number of seconds before the HTTP call times out. Defaults to 30 seconds
+
.EXAMPLE
PS C:\> Connect-NetboxAPI -Hostname "netbox.domain.com"
-
+
This will prompt for Credential, then proceed to attempt a connection to Netbox
-
+
.NOTES
Additional information about the function.
#>
-
+
[CmdletBinding(DefaultParameterSetName = 'Manual')]
param
(
[Parameter(ParameterSetName = 'Manual',
Mandatory = $true)]
[string]$Hostname,
-
+
[Parameter(Mandatory = $false)]
[pscredential]$Credential,
-
+
[Parameter(ParameterSetName = 'Manual')]
[ValidateSet('https', 'http', IgnoreCase = $true)]
[string]$Scheme = 'https',
-
+
[Parameter(ParameterSetName = 'Manual')]
[uint16]$Port = 443,
-
+
[Parameter(ParameterSetName = 'URI',
Mandatory = $true)]
- [string]$URI
+ [string]$URI,
+
+ [Parameter(Mandatory = $false)]
+ [switch]$SkipCertificateCheck = $false,
+
+ [ValidateNotNullOrEmpty()]
+ [ValidateRange(1, 65535)]
+ [uint16]$TimeoutSeconds = 30
)
-
+
if (-not $Credential) {
try {
$Credential = Get-NetboxCredential -ErrorAction Stop
@@ -62,14 +75,29 @@
}
}
}
-
- $null = Set-NetboxCredential -Credential $Credential
-
+
+ $invokeParams = @{ SkipCertificateCheck = $SkipCertificateCheck; }
+
+ if ("Desktop" -eq $PSVersionTable.PsEdition) {
+ #Remove -SkipCertificateCheck from Invoke Parameter (not supported <= PS 5)
+ $invokeParams.remove("SkipCertificateCheck")
+ }
+
+ #for PowerShell (<=) 5 (Desktop), Enable TLS 1.1, 1.2 and Disable SSL chain trust
+ if ("Desktop" -eq $PSVersionTable.PsEdition) {
+ #Enable TLS 1.1 and 1.2
+ Set-NetboxCipherSSL
+ if ($SkipCertificateCheck) {
+ #Disable SSL chain trust...
+ Set-NetboxuntrustedSSL
+ }
+ }
+
switch ($PSCmdlet.ParameterSetName) {
'Manual' {
$uriBuilder = [System.UriBuilder]::new($Scheme, $Hostname, $Port)
}
-
+
'URI' {
$uriBuilder = [System.UriBuilder]::new($URI)
if ([string]::IsNullOrWhiteSpace($uriBuilder.Host)) {
@@ -77,11 +105,14 @@
}
}
}
-
+
$null = Set-NetboxHostName -Hostname $uriBuilder.Host
+ $null = Set-NetboxCredential -Credential $Credential
$null = Set-NetboxHostScheme -Scheme $uriBuilder.Scheme
$null = Set-NetboxHostPort -Port $uriBuilder.Port
-
+ $null = Set-NetboxInvokeParams -invokeParams $invokeParams
+ $null = Set-NetboxTimeout -TimeoutSeconds $TimeoutSeconds
+
try {
Write-Verbose "Verifying API connectivity..."
$null = VerifyAPIConnectivity
@@ -94,18 +125,27 @@
throw $_
}
}
-
- Write-Verbose "Caching API definition"
- $script:NetboxConfig.APIDefinition = Get-NetboxAPIDefinition
-
- if ([version]$script:NetboxConfig.APIDefinition.info.version -lt 2.8) {
+
+# Write-Verbose "Caching API definition"
+# $script:NetboxConfig.APIDefinition = Get-NetboxAPIDefinition
+#
+# if ([version]$script:NetboxConfig.APIDefinition.info.version -lt 2.8) {
+# $Script:NetboxConfig.Connected = $false
+# throw "Netbox version is incompatible with this PS module. Requires >=2.8.*, found version $($script:NetboxConfig.APIDefinition.info.version)"
+ # }
+
+ Write-Verbose "Checking Netbox version compatibility"
+ $script:NetboxConfig.NetboxVersion = Get-NetboxVersion
+ if ([version]$script:NetboxConfig.NetboxVersion.'netbox-version' -lt 2.8) {
$Script:NetboxConfig.Connected = $false
- throw "Netbox version is incompatible with this PS module. Requires >=2.8.*, found version $($script:NetboxConfig.APIDefinition.info.version)"
+ throw "Netbox version is incompatible with this PS module. Requires >=2.8.*, found version $($script:NetboxConfig.NetboxVersion.'netbox-version')"
+ } else {
+ Write-Verbose "Found compatible version [$($script:NetboxConfig.NetboxVersion.'netbox-version')]!"
}
-
+
$script:NetboxConfig.Connected = $true
Write-Verbose "Successfully connected!"
-
+
#Write-Verbose "Caching static choices"
#$script:NetboxConfig.Choices.Circuits = Get-NetboxCircuitsChoices
#$script:NetboxConfig.Choices.DCIM = Get-NetboxDCIMChoices # Not completed yet
@@ -114,6 +154,6 @@
##$script:NetboxConfig.Choices.Secrets = Get-NetboxSecretsChoices # Not completed yet
##$script:NetboxConfig.Choices.Tenancy = Get-NetboxTenancyChoices
#$script:NetboxConfig.Choices.Virtualization = Get-NetboxVirtualizationChoices
-
+
Write-Verbose "Connection process completed"
}
\ No newline at end of file
diff --git a/Functions/Setup/Get-NetboxCredential.ps1 b/Functions/Setup/Get-NetboxCredential.ps1
index 25f0eb9..a1235fb 100644
--- a/Functions/Setup/Get-NetboxCredential.ps1
+++ b/Functions/Setup/Get-NetboxCredential.ps1
@@ -2,10 +2,10 @@
[CmdletBinding()]
[OutputType([pscredential])]
param ()
-
+
if (-not $script:NetboxConfig.Credential) {
throw "Netbox Credentials not set! You may set with Set-NetboxCredential"
}
-
+
$script:NetboxConfig.Credential
}
\ No newline at end of file
diff --git a/Functions/Setup/Get-NetboxHostname.ps1 b/Functions/Setup/Get-NetboxHostname.ps1
index 0629541..63a8c3f 100644
--- a/Functions/Setup/Get-NetboxHostname.ps1
+++ b/Functions/Setup/Get-NetboxHostname.ps1
@@ -1,11 +1,11 @@
function Get-NetboxHostname {
[CmdletBinding()]
param ()
-
+
Write-Verbose "Getting Netbox hostname"
if ($null -eq $script:NetboxConfig.Hostname) {
throw "Netbox Hostname is not set! You may set it with Set-NetboxHostname -Hostname 'hostname.domain.tld'"
}
-
+
$script:NetboxConfig.Hostname
}
\ No newline at end of file
diff --git a/Functions/Setup/Get-NetboxInvokeParams.ps1 b/Functions/Setup/Get-NetboxInvokeParams.ps1
new file mode 100644
index 0000000..ec95d24
--- /dev/null
+++ b/Functions/Setup/Get-NetboxInvokeParams.ps1
@@ -0,0 +1,11 @@
+function Get-NetboxInvokeParams {
+ [CmdletBinding()]
+ param ()
+
+ Write-Verbose "Getting Netbox InvokeParams"
+ if ($null -eq $script:NetboxConfig.InvokeParams) {
+ throw "Netbox Invoke Params is not set! You may set it with Set-NetboxInvokeParams -InvokeParams ..."
+ }
+
+ $script:NetboxConfig.InvokeParams
+}
\ No newline at end of file
diff --git a/Functions/Setup/Get-NetboxTimeout.ps1 b/Functions/Setup/Get-NetboxTimeout.ps1
new file mode 100644
index 0000000..220e3f1
--- /dev/null
+++ b/Functions/Setup/Get-NetboxTimeout.ps1
@@ -0,0 +1,13 @@
+
+function Get-NetboxTimeout {
+ [CmdletBinding()]
+ [OutputType([uint16])]
+ param ()
+
+ Write-Verbose "Getting Netbox Timeout"
+ if ($null -eq $script:NetboxConfig.Timeout) {
+ throw "Netbox Timeout is not set! You may set it with Set-NetboxTimeout -TimeoutSeconds [uint16]"
+ }
+
+ $script:NetboxConfig.Timeout
+}
\ No newline at end of file
diff --git a/Functions/Setup/Get-NetboxVersion.ps1 b/Functions/Setup/Get-NetboxVersion.ps1
new file mode 100644
index 0000000..7dc8c03
--- /dev/null
+++ b/Functions/Setup/Get-NetboxVersion.ps1
@@ -0,0 +1,15 @@
+
+function Get-NetboxVersion {
+ [CmdletBinding()]
+ param ()
+
+ $Segments = [System.Collections.ArrayList]::new(@('status'))
+
+ $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary @{
+ 'format' = 'json'
+ }
+
+ $URI = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters -SkipConnectedCheck
+
+ InvokeNetboxRequest -URI $URI
+}
diff --git a/Functions/Setup/Set-NetboxCipherSSL.ps1 b/Functions/Setup/Set-NetboxCipherSSL.ps1
new file mode 100644
index 0000000..bad4402
--- /dev/null
+++ b/Functions/Setup/Set-NetboxCipherSSL.ps1
@@ -0,0 +1,8 @@
+Function Set-NetboxCipherSSL {
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessforStateChangingFunctions", "")]
+ Param( )
+ # Hack for allowing TLS 1.1 and TLS 1.2 (by default it is only SSL3 and TLS (1.0))
+ $AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
+ [System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
+
+}
\ No newline at end of file
diff --git a/Functions/Setup/Set-NetboxCredential.ps1 b/Functions/Setup/Set-NetboxCredential.ps1
index 448f272..dcbb24a 100644
--- a/Functions/Setup/Set-NetboxCredential.ps1
+++ b/Functions/Setup/Set-NetboxCredential.ps1
@@ -1,32 +1,32 @@
function Set-NetboxCredential {
[CmdletBinding(DefaultParameterSetName = 'CredsObject',
- ConfirmImpact = 'Low',
- SupportsShouldProcess = $true)]
+ ConfirmImpact = 'Low',
+ SupportsShouldProcess = $true)]
[OutputType([pscredential])]
param
(
[Parameter(ParameterSetName = 'CredsObject',
- Mandatory = $true)]
+ Mandatory = $true)]
[pscredential]$Credential,
-
+
[Parameter(ParameterSetName = 'UserPass',
- Mandatory = $true)]
+ Mandatory = $true)]
[securestring]$Token
)
-
+
if ($PSCmdlet.ShouldProcess('Netbox Credentials', 'Set')) {
switch ($PsCmdlet.ParameterSetName) {
'CredsObject' {
$script:NetboxConfig.Credential = $Credential
break
}
-
+
'UserPass' {
$script:NetboxConfig.Credential = [System.Management.Automation.PSCredential]::new('notapplicable', $Token)
break
}
}
-
+
$script:NetboxConfig.Credential
}
}
\ No newline at end of file
diff --git a/Functions/Setup/Set-NetboxHostName.ps1 b/Functions/Setup/Set-NetboxHostName.ps1
index 92b9dbe..a70c055 100644
--- a/Functions/Setup/Set-NetboxHostName.ps1
+++ b/Functions/Setup/Set-NetboxHostName.ps1
@@ -1,13 +1,13 @@
function Set-NetboxHostName {
[CmdletBinding(ConfirmImpact = 'Low',
- SupportsShouldProcess = $true)]
+ SupportsShouldProcess = $true)]
[OutputType([string])]
param
(
[Parameter(Mandatory = $true)]
[string]$Hostname
)
-
+
if ($PSCmdlet.ShouldProcess('Netbox Hostname', 'Set')) {
$script:NetboxConfig.Hostname = $Hostname.Trim()
$script:NetboxConfig.Hostname
diff --git a/Functions/Setup/Set-NetboxInvokeParams.ps1 b/Functions/Setup/Set-NetboxInvokeParams.ps1
new file mode 100644
index 0000000..b82ef6d
--- /dev/null
+++ b/Functions/Setup/Set-NetboxInvokeParams.ps1
@@ -0,0 +1,14 @@
+function Set-NetboxInvokeParams {
+ [CmdletBinding(ConfirmImpact = 'Low',
+ SupportsShouldProcess = $true)]
+ [OutputType([string])]
+ param(
+ [Parameter(Mandatory = $true)]
+ [array]$InvokeParams
+ )
+
+ if ($PSCmdlet.ShouldProcess('Netbox Invoke Params', 'Set')) {
+ $script:NetboxConfig.InvokeParams = $InvokeParams
+ $script:NetboxConfig.InvokeParams
+ }
+}
\ No newline at end of file
diff --git a/Functions/Setup/Set-NetboxTimeout.ps1 b/Functions/Setup/Set-NetboxTimeout.ps1
new file mode 100644
index 0000000..a738019
--- /dev/null
+++ b/Functions/Setup/Set-NetboxTimeout.ps1
@@ -0,0 +1,17 @@
+
+function Set-NetboxTimeout {
+ [CmdletBinding(ConfirmImpact = 'Low',
+ SupportsShouldProcess = $true)]
+ [OutputType([uint16])]
+ param
+ (
+ [Parameter(Mandatory = $false)]
+ [ValidateRange(1, 65535)]
+ [uint16]$TimeoutSeconds = 30
+ )
+
+ if ($PSCmdlet.ShouldProcess('Netbox Timeout', 'Set')) {
+ $script:NetboxConfig.Timeout = $TimeoutSeconds
+ $script:NetboxConfig.Timeout
+ }
+}
\ No newline at end of file
diff --git a/Functions/Setup/Set-NetboxUnstrustedSSL.ps1 b/Functions/Setup/Set-NetboxUnstrustedSSL.ps1
new file mode 100644
index 0000000..e118d1c
--- /dev/null
+++ b/Functions/Setup/Set-NetboxUnstrustedSSL.ps1
@@ -0,0 +1,19 @@
+Function Set-NetboxUntrustedSSL {
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessforStateChangingFunctions", "")]
+ Param( )
+ # Hack for allowing untrusted SSL certs with https connections
+ Add-Type -TypeDefinition @"
+ using System.Net;
+ using System.Security.Cryptography.X509Certificates;
+ public class TrustAllCertsPolicy : ICertificatePolicy {
+ public bool CheckValidationResult(
+ ServicePoint srvPoint, X509Certificate certificate,
+ WebRequest request, int certificateProblem) {
+ return true;
+ }
+ }
+"@
+
+ [System.Net.ServicePointManager]::CertificatePolicy = New-Object -TypeName TrustAllCertsPolicy
+
+}
\ No newline at end of file
diff --git a/Functions/Setup/Support/Get-NetboxAPIDefinition.ps1 b/Functions/Setup/Support/Get-NetboxAPIDefinition.ps1
index 3fb0215..4fcdf0c 100644
--- a/Functions/Setup/Support/Get-NetboxAPIDefinition.ps1
+++ b/Functions/Setup/Support/Get-NetboxAPIDefinition.ps1
@@ -1,14 +1,14 @@
-<#
- .NOTES
- ===========================================================================
- Created with: SAPIEN Technologies, Inc., PowerShell Studio 2020 v5.7.174
- Created on: 4/28/2020 11:57
- Created by: Claussen
- Organization: NEOnet
- Filename: Get-NetboxAPIDefinition.ps1
- ===========================================================================
- .DESCRIPTION
- A description of the file.
+<#
+ .NOTES
+ ===========================================================================
+ Created with: SAPIEN Technologies, Inc., PowerShell Studio 2020 v5.7.174
+ Created on: 4/28/2020 11:57
+ Created by: Claussen
+ Organization: NEOnet
+ Filename: Get-NetboxAPIDefinition.ps1
+ ===========================================================================
+ .DESCRIPTION
+ A description of the file.
#>
@@ -16,14 +16,14 @@
function Get-NetboxAPIDefinition {
[CmdletBinding()]
param ()
-
+
#$URI = "https://netbox.neonet.org/api/docs/?format=openapi"
-
+
$Segments = [System.Collections.ArrayList]::new(@('docs'))
-
- $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary @{'format' = 'openapi'}
-
+
+ $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary @{'format' = 'openapi' }
+
$URI = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters -SkipConnectedCheck
-
- InvokeNetboxRequest -URI $URI -Timeout 10
+
+ InvokeNetboxRequest -URI $URI
}
diff --git a/Functions/Setup/Support/SetupNetboxConfigVariable.ps1 b/Functions/Setup/Support/SetupNetboxConfigVariable.ps1
index 20d84a8..a8ac41f 100644
--- a/Functions/Setup/Support/SetupNetboxConfigVariable.ps1
+++ b/Functions/Setup/Support/SetupNetboxConfigVariable.ps1
@@ -4,17 +4,17 @@
(
[switch]$Overwrite
)
-
+
Write-Verbose "Checking for NetboxConfig hashtable"
if ((-not ($script:NetboxConfig)) -or $Overwrite) {
Write-Verbose "Creating NetboxConfig hashtable"
$script:NetboxConfig = @{
- 'Connected' = $false
- 'Choices' = @{
+ 'Connected' = $false
+ 'Choices' = @{
}
'APIDefinition' = $null
}
}
-
+
Write-Verbose "NetboxConfig hashtable already exists"
}
\ No newline at end of file
diff --git a/Functions/Setup/Support/VerifyAPIConnectivity.ps1 b/Functions/Setup/Support/VerifyAPIConnectivity.ps1
index b53760e..fb8d9d1 100644
--- a/Functions/Setup/Support/VerifyAPIConnectivity.ps1
+++ b/Functions/Setup/Support/VerifyAPIConnectivity.ps1
@@ -1,10 +1,10 @@
function VerifyAPIConnectivity {
[CmdletBinding()]
param ()
-
+
$uriSegments = [System.Collections.ArrayList]::new(@('extras'))
-
- $uri = BuildNewURI -Segments $uriSegments -Parameters @{'format' = 'json'} -SkipConnectedCheck
-
+
+ $uri = BuildNewURI -Segments $uriSegments -Parameters @{'format' = 'json' } -SkipConnectedCheck
+
InvokeNetboxRequest -URI $uri
}
\ No newline at end of file
diff --git a/NetboxPS.psd1 b/NetboxPS.psd1
index 5601780..ead3b18 100644
--- a/NetboxPS.psd1
+++ b/NetboxPS.psd1
@@ -3,7 +3,7 @@
#
# Generated by: Ben Claussen
#
-# Generated on: 2021-03-31
+# Generated on: 2021-07-22
#
@{
@@ -12,7 +12,7 @@
RootModule = 'NetboxPS.psm1'
# Version number of this module.
-ModuleVersion = '1.3.3'
+ModuleVersion = '1.4'
# Supported PSEditions
# CompatiblePSEditions = @()
diff --git a/NetboxPS.psproj b/NetboxPS.psproj
index 938d28b..b71197d 100644
--- a/NetboxPS.psproj
+++ b/NetboxPS.psproj
@@ -108,6 +108,13 @@
Functions\Setup\Get-NetboxHostScheme.ps1
Functions\Setup\Set-NetboxHostPort.ps1
Functions\Setup\Get-NetboxHostPort.ps1
+ Functions\Setup\Get-NetboxInvokeParams.ps1
+ Functions\Setup\Set-NetboxCipherSSL.ps1
+ Functions\Setup\Set-NetboxInvokeParams.ps1
+ Functions\Setup\Set-NetboxUnstrustedSSL.ps1
+ Functions\Setup\Set-NetboxTimeout.ps1
+ Functions\Setup\Get-NetboxTimeout.ps1
+ Functions\Setup\Get-NetboxVersion.ps1
R:\Netbox\NetboxPS\Test-Module.ps1
\ No newline at end of file
diff --git a/NetboxPS/NetboxPS.psd1 b/NetboxPS/NetboxPS.psd1
index 5601780..ead3b18 100644
--- a/NetboxPS/NetboxPS.psd1
+++ b/NetboxPS/NetboxPS.psd1
@@ -3,7 +3,7 @@
#
# Generated by: Ben Claussen
#
-# Generated on: 2021-03-31
+# Generated on: 2021-07-22
#
@{
@@ -12,7 +12,7 @@
RootModule = 'NetboxPS.psm1'
# Version number of this module.
-ModuleVersion = '1.3.3'
+ModuleVersion = '1.4'
# Supported PSEditions
# CompatiblePSEditions = @()
diff --git a/NetboxPS/NetboxPS.psm1 b/NetboxPS/NetboxPS.psm1
index f500181..61fa4b8 100644
--- a/NetboxPS/NetboxPS.psm1
+++ b/NetboxPS/NetboxPS.psm1
@@ -471,56 +471,69 @@ function Connect-NetboxAPI {
<#
.SYNOPSIS
Connects to the Netbox API and ensures Credential work properly
-
+
.DESCRIPTION
Connects to the Netbox API and ensures Credential work properly
-
+
.PARAMETER Hostname
The hostname for the resource such as netbox.domain.com
-
+
.PARAMETER Credential
Credential object containing the API key in the password. Username is not applicable
-
+
.PARAMETER Scheme
Scheme for the URI such as HTTP or HTTPS. Defaults to HTTPS
-
+
.PARAMETER Port
Port for the resource. Value between 1-65535
-
+
.PARAMETER URI
The full URI for the resource such as "https://netbox.domain.com:8443"
-
+
+ .PARAMETER SkipCertificateCheck
+ A description of the SkipCertificateCheck parameter.
+
+ .PARAMETER TimeoutSeconds
+ The number of seconds before the HTTP call times out. Defaults to 30 seconds
+
.EXAMPLE
PS C:\> Connect-NetboxAPI -Hostname "netbox.domain.com"
-
+
This will prompt for Credential, then proceed to attempt a connection to Netbox
-
+
.NOTES
Additional information about the function.
#>
-
+
[CmdletBinding(DefaultParameterSetName = 'Manual')]
param
(
[Parameter(ParameterSetName = 'Manual',
Mandatory = $true)]
[string]$Hostname,
-
+
[Parameter(Mandatory = $false)]
[pscredential]$Credential,
-
+
[Parameter(ParameterSetName = 'Manual')]
[ValidateSet('https', 'http', IgnoreCase = $true)]
[string]$Scheme = 'https',
-
+
[Parameter(ParameterSetName = 'Manual')]
[uint16]$Port = 443,
-
+
[Parameter(ParameterSetName = 'URI',
Mandatory = $true)]
- [string]$URI
+ [string]$URI,
+
+ [Parameter(Mandatory = $false)]
+ [switch]$SkipCertificateCheck = $false,
+
+ [ValidateNotNullOrEmpty()]
+ [ValidateRange(1, 65535)]
+ [uint16]$TimeoutSeconds = 30
)
-
+
if (-not $Credential) {
try {
$Credential = Get-NetboxCredential -ErrorAction Stop
@@ -531,14 +544,29 @@ function Connect-NetboxAPI {
}
}
}
-
- $null = Set-NetboxCredential -Credential $Credential
-
+
+ $invokeParams = @{ SkipCertificateCheck = $SkipCertificateCheck; }
+
+ if ("Desktop" -eq $PSVersionTable.PsEdition) {
+ #Remove -SkipCertificateCheck from Invoke Parameter (not supported <= PS 5)
+ $invokeParams.remove("SkipCertificateCheck")
+ }
+
+ #for PowerShell (<=) 5 (Desktop), Enable TLS 1.1, 1.2 and Disable SSL chain trust
+ if ("Desktop" -eq $PSVersionTable.PsEdition) {
+ #Enable TLS 1.1 and 1.2
+ Set-NetboxCipherSSL
+ if ($SkipCertificateCheck) {
+ #Disable SSL chain trust...
+ Set-NetboxuntrustedSSL
+ }
+ }
+
switch ($PSCmdlet.ParameterSetName) {
'Manual' {
$uriBuilder = [System.UriBuilder]::new($Scheme, $Hostname, $Port)
}
-
+
'URI' {
$uriBuilder = [System.UriBuilder]::new($URI)
if ([string]::IsNullOrWhiteSpace($uriBuilder.Host)) {
@@ -546,11 +574,14 @@ function Connect-NetboxAPI {
}
}
}
-
+
$null = Set-NetboxHostName -Hostname $uriBuilder.Host
+ $null = Set-NetboxCredential -Credential $Credential
$null = Set-NetboxHostScheme -Scheme $uriBuilder.Scheme
$null = Set-NetboxHostPort -Port $uriBuilder.Port
-
+ $null = Set-NetboxInvokeParams -invokeParams $invokeParams
+ $null = Set-NetboxTimeout -TimeoutSeconds $TimeoutSeconds
+
try {
Write-Verbose "Verifying API connectivity..."
$null = VerifyAPIConnectivity
@@ -563,18 +594,27 @@ function Connect-NetboxAPI {
throw $_
}
}
-
- Write-Verbose "Caching API definition"
- $script:NetboxConfig.APIDefinition = Get-NetboxAPIDefinition
-
- if ([version]$script:NetboxConfig.APIDefinition.info.version -lt 2.8) {
+
+# Write-Verbose "Caching API definition"
+# $script:NetboxConfig.APIDefinition = Get-NetboxAPIDefinition
+#
+# if ([version]$script:NetboxConfig.APIDefinition.info.version -lt 2.8) {
+# $Script:NetboxConfig.Connected = $false
+# throw "Netbox version is incompatible with this PS module. Requires >=2.8.*, found version $($script:NetboxConfig.APIDefinition.info.version)"
+ # }
+
+ Write-Verbose "Checking Netbox version compatibility"
+ $script:NetboxConfig.NetboxVersion = Get-NetboxVersion
+ if ([version]$script:NetboxConfig.NetboxVersion.'netbox-version' -lt 2.8) {
$Script:NetboxConfig.Connected = $false
- throw "Netbox version is incompatible with this PS module. Requires >=2.8.*, found version $($script:NetboxConfig.APIDefinition.info.version)"
+ throw "Netbox version is incompatible with this PS module. Requires >=2.8.*, found version $($script:NetboxConfig.NetboxVersion.'netbox-version')"
+ } else {
+ Write-Verbose "Found compatible version [$($script:NetboxConfig.NetboxVersion.'netbox-version')]!"
}
-
+
$script:NetboxConfig.Connected = $true
Write-Verbose "Successfully connected!"
-
+
#Write-Verbose "Caching static choices"
#$script:NetboxConfig.Choices.Circuits = Get-NetboxCircuitsChoices
#$script:NetboxConfig.Choices.DCIM = Get-NetboxDCIMChoices # Not completed yet
@@ -583,7 +623,7 @@ function Connect-NetboxAPI {
##$script:NetboxConfig.Choices.Secrets = Get-NetboxSecretsChoices # Not completed yet
##$script:NetboxConfig.Choices.Tenancy = Get-NetboxTenancyChoices
#$script:NetboxConfig.Choices.Virtualization = Get-NetboxVirtualizationChoices
-
+
Write-Verbose "Connection process completed"
}
@@ -706,17 +746,17 @@ function Get-ModelDefinition {
#region File Get-NetboxAPIDefinition.ps1
-<#
- .NOTES
- ===========================================================================
- Created with: SAPIEN Technologies, Inc., PowerShell Studio 2020 v5.7.174
- Created on: 4/28/2020 11:57
- Created by: Claussen
- Organization: NEOnet
- Filename: Get-NetboxAPIDefinition.ps1
- ===========================================================================
- .DESCRIPTION
- A description of the file.
+<#
+ .NOTES
+ ===========================================================================
+ Created with: SAPIEN Technologies, Inc., PowerShell Studio 2020 v5.7.174
+ Created on: 4/28/2020 11:57
+ Created by: Claussen
+ Organization: NEOnet
+ Filename: Get-NetboxAPIDefinition.ps1
+ ===========================================================================
+ .DESCRIPTION
+ A description of the file.
#>
@@ -724,16 +764,16 @@ function Get-ModelDefinition {
function Get-NetboxAPIDefinition {
[CmdletBinding()]
param ()
-
+
#$URI = "https://netbox.neonet.org/api/docs/?format=openapi"
-
+
$Segments = [System.Collections.ArrayList]::new(@('docs'))
-
- $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary @{'format' = 'openapi'}
-
+
+ $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary @{'format' = 'openapi' }
+
$URI = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters -SkipConnectedCheck
-
- InvokeNetboxRequest -URI $URI -Timeout 10
+
+ InvokeNetboxRequest -URI $URI
}
#endregion
@@ -1152,11 +1192,11 @@ function Get-NetboxCredential {
[CmdletBinding()]
[OutputType([pscredential])]
param ()
-
+
if (-not $script:NetboxConfig.Credential) {
throw "Netbox Credentials not set! You may set with Set-NetboxCredential"
}
-
+
$script:NetboxConfig.Credential
}
@@ -1702,12 +1742,12 @@ function Get-NetboxDCIMSite {
function Get-NetboxHostname {
[CmdletBinding()]
param ()
-
+
Write-Verbose "Getting Netbox hostname"
if ($null -eq $script:NetboxConfig.Hostname) {
throw "Netbox Hostname is not set! You may set it with Set-NetboxHostname -Hostname 'hostname.domain.tld'"
}
-
+
$script:NetboxConfig.Hostname
}
@@ -1745,6 +1785,22 @@ function Get-NetboxHostScheme {
#endregion
+#region File Get-NetboxInvokeParams.ps1
+
+function Get-NetboxInvokeParams {
+ [CmdletBinding()]
+ param ()
+
+ Write-Verbose "Getting Netbox InvokeParams"
+ if ($null -eq $script:NetboxConfig.InvokeParams) {
+ throw "Netbox Invoke Params is not set! You may set it with Set-NetboxInvokeParams -InvokeParams ..."
+ }
+
+ $script:NetboxConfig.InvokeParams
+}
+
+#endregion
+
#region File Get-NetboxIPAMAddress.ps1
function Get-NetboxIPAMAddress {
@@ -2553,6 +2609,44 @@ function Get-NetboxTenant {
#endregion
+#region File Get-NetboxTimeout.ps1
+
+
+function Get-NetboxTimeout {
+ [CmdletBinding()]
+ [OutputType([uint16])]
+ param ()
+
+ Write-Verbose "Getting Netbox Timeout"
+ if ($null -eq $script:NetboxConfig.Timeout) {
+ throw "Netbox Timeout is not set! You may set it with Set-NetboxTimeout -TimeoutSeconds [uint16]"
+ }
+
+ $script:NetboxConfig.Timeout
+}
+
+#endregion
+
+#region File Get-NetboxVersion.ps1
+
+
+function Get-NetboxVersion {
+ [CmdletBinding()]
+ param ()
+
+ $Segments = [System.Collections.ArrayList]::new(@('status'))
+
+ $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary @{
+ 'format' = 'json'
+ }
+
+ $URI = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters -SkipConnectedCheck
+
+ InvokeNetboxRequest -URI $URI
+}
+
+#endregion
+
#region File Get-NetboxVirtualizationCluster.ps1
<#
@@ -2969,7 +3063,7 @@ function Get-NetboxVirtualMachineInterface {
#region File InvokeNetboxRequest.ps1
-<#
+<#
.NOTES
===========================================================================
Created with: SAPIEN Technologies, Inc., PowerShell Studio 2020 v5.7.172
@@ -2989,44 +3083,46 @@ function InvokeNetboxRequest {
(
[Parameter(Mandatory = $true)]
[System.UriBuilder]$URI,
-
+
[Hashtable]$Headers = @{
},
-
+
[pscustomobject]$Body = $null,
-
- [ValidateRange(0, 60)]
- [uint16]$Timeout = 5,
-
+
+ [ValidateRange(1, 65535)]
+ [uint16]$Timeout = (Get-NetboxTimeout),
+
[ValidateSet('GET', 'PATCH', 'PUT', 'POST', 'DELETE', 'OPTIONS', IgnoreCase = $true)]
[string]$Method = 'GET',
-
+
[switch]$Raw
)
-
+
$creds = Get-NetboxCredential
-
+
$Headers.Authorization = "Token {0}" -f $creds.GetNetworkCredential().Password
-
+
$splat = @{
- 'Method' = $Method
- 'Uri' = $URI.Uri.AbsoluteUri # This property auto generates the scheme, hostname, path, and query
- 'Headers' = $Headers
- 'TimeoutSec' = $Timeout
+ 'Method' = $Method
+ 'Uri' = $URI.Uri.AbsoluteUri # This property auto generates the scheme, hostname, path, and query
+ 'Headers' = $Headers
+ 'TimeoutSec' = $Timeout
'ContentType' = 'application/json'
'ErrorAction' = 'Stop'
- 'Verbose' = $VerbosePreference
+ 'Verbose' = $VerbosePreference
}
-
+
+ $splat += Get-NetboxInvokeParams
+
if ($Body) {
Write-Verbose "BODY: $($Body | ConvertTo-Json -Compress)"
$null = $splat.Add('Body', ($Body | ConvertTo-Json -Compress))
}
-
+
$result = Invoke-RestMethod @splat
-
+
#region TODO: Handle errors a little more gracefully...
-
+
<#
try {
Write-Verbose "Sending request..."
@@ -3040,7 +3136,7 @@ function InvokeNetboxRequest {
Write-Verbose "RAW provided...throwing raw exception"
throw $_
}
-
+
Write-Verbose "Converting response to object"
$myError = GetNetboxAPIErrorBody -Response $_.Exception.Response | ConvertFrom-Json
} else {
@@ -3048,18 +3144,18 @@ function InvokeNetboxRequest {
$myError = $_
}
}
-
+
Write-Verbose "MyError is $($myError.GetType().FullName)"
-
+
if ($myError -is [Exception]) {
throw $_
} elseif ($myError -is [pscustomobject]) {
throw $myError.detail
- }
+ }
#>
-
+
#endregion TODO: Handle errors a little more gracefully...
-
+
# If the user wants the raw value from the API... otherwise return only the actual result
if ($Raw) {
Write-Verbose "Returning raw result by choice"
@@ -3936,37 +4032,50 @@ function Remove-NetboxVirtualMachine {
#endregion
+#region File Set-NetboxCipherSSL.ps1
+
+Function Set-NetboxCipherSSL {
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessforStateChangingFunctions", "")]
+ Param( )
+ # Hack for allowing TLS 1.1 and TLS 1.2 (by default it is only SSL3 and TLS (1.0))
+ $AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
+ [System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
+
+}
+
+#endregion
+
#region File Set-NetboxCredential.ps1
function Set-NetboxCredential {
[CmdletBinding(DefaultParameterSetName = 'CredsObject',
- ConfirmImpact = 'Low',
- SupportsShouldProcess = $true)]
+ ConfirmImpact = 'Low',
+ SupportsShouldProcess = $true)]
[OutputType([pscredential])]
param
(
[Parameter(ParameterSetName = 'CredsObject',
- Mandatory = $true)]
+ Mandatory = $true)]
[pscredential]$Credential,
-
+
[Parameter(ParameterSetName = 'UserPass',
- Mandatory = $true)]
+ Mandatory = $true)]
[securestring]$Token
)
-
+
if ($PSCmdlet.ShouldProcess('Netbox Credentials', 'Set')) {
switch ($PsCmdlet.ParameterSetName) {
'CredsObject' {
$script:NetboxConfig.Credential = $Credential
break
}
-
+
'UserPass' {
$script:NetboxConfig.Credential = [System.Management.Automation.PSCredential]::new('notapplicable', $Token)
break
}
}
-
+
$script:NetboxConfig.Credential
}
}
@@ -4277,14 +4386,14 @@ function Set-NetboxDCIMInterfaceConnection {
function Set-NetboxHostName {
[CmdletBinding(ConfirmImpact = 'Low',
- SupportsShouldProcess = $true)]
+ SupportsShouldProcess = $true)]
[OutputType([string])]
param
(
[Parameter(Mandatory = $true)]
[string]$Hostname
)
-
+
if ($PSCmdlet.ShouldProcess('Netbox Hostname', 'Set')) {
$script:NetboxConfig.Hostname = $Hostname.Trim()
$script:NetboxConfig.Hostname
@@ -4338,6 +4447,25 @@ function Set-NetboxHostScheme {
#endregion
+#region File Set-NetboxInvokeParams.ps1
+
+function Set-NetboxInvokeParams {
+ [CmdletBinding(ConfirmImpact = 'Low',
+ SupportsShouldProcess = $true)]
+ [OutputType([string])]
+ param(
+ [Parameter(Mandatory = $true)]
+ [array]$InvokeParams
+ )
+
+ if ($PSCmdlet.ShouldProcess('Netbox Invoke Params', 'Set')) {
+ $script:NetboxConfig.InvokeParams = $InvokeParams
+ $script:NetboxConfig.InvokeParams
+ }
+}
+
+#endregion
+
#region File Set-NetboxIPAMAddress.ps1
<#
@@ -4534,6 +4662,52 @@ function Set-NetboxIPAMPrefix {
+#endregion
+
+#region File Set-NetboxTimeout.ps1
+
+
+function Set-NetboxTimeout {
+ [CmdletBinding(ConfirmImpact = 'Low',
+ SupportsShouldProcess = $true)]
+ [OutputType([uint16])]
+ param
+ (
+ [Parameter(Mandatory = $false)]
+ [ValidateRange(1, 65535)]
+ [uint16]$TimeoutSeconds = 30
+ )
+
+ if ($PSCmdlet.ShouldProcess('Netbox Timeout', 'Set')) {
+ $script:NetboxConfig.Timeout = $TimeoutSeconds
+ $script:NetboxConfig.Timeout
+ }
+}
+
+#endregion
+
+#region File Set-NetboxUnstrustedSSL.ps1
+
+Function Set-NetboxUntrustedSSL {
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessforStateChangingFunctions", "")]
+ Param( )
+ # Hack for allowing untrusted SSL certs with https connections
+ Add-Type -TypeDefinition @"
+ using System.Net;
+ using System.Security.Cryptography.X509Certificates;
+ public class TrustAllCertsPolicy : ICertificatePolicy {
+ public bool CheckValidationResult(
+ ServicePoint srvPoint, X509Certificate certificate,
+ WebRequest request, int certificateProblem) {
+ return true;
+ }
+ }
+"@
+
+ [System.Net.ServicePointManager]::CertificatePolicy = New-Object -TypeName TrustAllCertsPolicy
+
+}
+
#endregion
#region File Set-NetboxVirtualMachine.ps1
@@ -4691,18 +4865,18 @@ function SetupNetboxConfigVariable {
(
[switch]$Overwrite
)
-
+
Write-Verbose "Checking for NetboxConfig hashtable"
if ((-not ($script:NetboxConfig)) -or $Overwrite) {
Write-Verbose "Creating NetboxConfig hashtable"
$script:NetboxConfig = @{
- 'Connected' = $false
- 'Choices' = @{
+ 'Connected' = $false
+ 'Choices' = @{
}
'APIDefinition' = $null
}
}
-
+
Write-Verbose "NetboxConfig hashtable already exists"
}
@@ -4783,11 +4957,11 @@ function ThrowNetboxRESTError {
function VerifyAPIConnectivity {
[CmdletBinding()]
param ()
-
+
$uriSegments = [System.Collections.ArrayList]::new(@('extras'))
-
- $uri = BuildNewURI -Segments $uriSegments -Parameters @{'format' = 'json'} -SkipConnectedCheck
-
+
+ $uri = BuildNewURI -Segments $uriSegments -Parameters @{'format' = 'json' } -SkipConnectedCheck
+
InvokeNetboxRequest -URI $uri
}