diff --git a/Functions/DCIM/DCIM.ps1 b/Functions/DCIM/DCIM.ps1
new file mode 100644
index 0000000..3e3bb6d
--- /dev/null
+++ b/Functions/DCIM/DCIM.ps1
@@ -0,0 +1,127 @@
+<#
+ .NOTES
+ ===========================================================================
+ Created with: SAPIEN Technologies, Inc., PowerShell Studio 2018 v5.5.152
+ Created on: 5/22/2018 4:47 PM
+ Created by: Ben Claussen
+ Organization: NEOnet
+ Filename: DCIM.ps1
+ ===========================================================================
+ .DESCRIPTION
+ A description of the file.
+#>
+
+function Get-NetboxDCIMChoices {
+ [CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")]
+ param ()
+
+ $uriSegments = [System.Collections.ArrayList]::new(@('dcim', '_choices'))
+
+ $uri = BuildNewURI -Segments $uriSegments -Parameters $Parameters
+
+ InvokeNetboxRequest -URI $uri
+}
+
+function ValidateDCIMChoice {
+<#
+ .SYNOPSIS
+ Internal function to validate provided values for static choices
+
+ .DESCRIPTION
+ When users connect to the API, choices for each major object are cached to the config variable.
+ These values are then utilized to validate if the provided value from a user is valid.
+
+ .PARAMETER ProvidedValue
+ The value to validate against static choices
+
+ .PARAMETER PowerConnectionStatus
+ Validate against power connection status values
+
+ .PARAMETER InterfaceTemplateFormFactor
+ Validate against interface template form factor values
+
+ .PARAMETER InterfaceConnectionStatus
+ Validate against interface connection status values
+
+ .PARAMETER InterfaceFormFactor
+ Validate against interface form factor values
+
+ .PARAMETER ConsolePortConnectionStatus
+ Validate against console port connection status values
+
+ .PARAMETER DeviceStatus
+ Validate against device status values
+
+ .PARAMETER DeviceFace
+ Validate against device face values
+
+ .PARAMETER RackType
+ Validate against rack type values
+
+ .PARAMETER RackWidth
+ Validate against rack width values.
+
+ .EXAMPLE
+ PS C:\> ValidateDCIMChoice -ProvidedValue 'rear' -DeviceFace
+
+ .EXAMPLE
+ PS C:\> ValidateDCIMChoice -ProvidedValue 'middle' -DeviceFace
+ >> Invalid value middle for device:face. Must be one of: 0, 1, Front, Rear
+
+ .OUTPUTS
+ This function returns the integer value if valid. Otherwise, it will throw an error.
+
+ .NOTES
+ Additional information about the function.
+
+ .FUNCTIONALITY
+ This cmdlet is intended to be used internally and not exposed to the user
+#>
+
+ [CmdletBinding()]
+ [OutputType([uint16])]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [object]$ProvidedValue,
+
+ [Parameter(ParameterSetName = 'power-port:connection_status',
+ Mandatory = $true)]
+ [switch]$PowerConnectionStatus,
+
+ [Parameter(ParameterSetName = 'interface-template:form_factor',
+ Mandatory = $true)]
+ [switch]$InterfaceTemplateFormFactor,
+
+ [Parameter(ParameterSetName = 'interface-connection:connection_status',
+ Mandatory = $true)]
+ [switch]$InterfaceConnectionStatus,
+
+ [Parameter(ParameterSetName = 'interface:form_factor',
+ Mandatory = $true)]
+ [switch]$InterfaceFormFactor,
+
+ [Parameter(ParameterSetName = 'console-port:connection_status',
+ Mandatory = $true)]
+ [switch]$ConsolePortConnectionStatus,
+
+ [Parameter(ParameterSetName = 'device:status',
+ Mandatory = $true)]
+ [switch]$DeviceStatus,
+
+ [Parameter(ParameterSetName = 'device:face',
+ Mandatory = $true)]
+ [switch]$DeviceFace,
+
+ [Parameter(ParameterSetName = 'rack:type',
+ Mandatory = $true)]
+ [switch]$RackType,
+
+ [Parameter(ParameterSetName = 'rack:width',
+ Mandatory = $true)]
+ [switch]$RackWidth
+ )
+
+ ValidateChoice -MajorObject 'DCIM' -ChoiceName $PSCmdlet.ParameterSetName -ProvidedValue $ProvidedValue
+}
\ No newline at end of file
diff --git a/Functions/Setup.ps1 b/Functions/Setup.ps1
index 55134d7..7442de0 100644
--- a/Functions/Setup.ps1
+++ b/Functions/Setup.ps1
@@ -183,7 +183,7 @@ function Connect-NetboxAPI {
Write-Verbose "Caching static choices"
$script:NetboxConfig.Choices.Circuits = Get-NetboxCircuitsChoices
- #$script:NetboxConfig.Choices.DCIM = Get-NetboxDCIMChoices # Not completed yet
+ $script:NetboxConfig.Choices.DCIM = Get-NetboxDCIMChoices # Not completed yet
$script:NetboxConfig.Choices.Extras = Get-NetboxExtrasChoices
$script:NetboxConfig.Choices.IPAM = Get-NetboxIPAMChoices
#$script:NetboxConfig.Choices.Secrets = Get-NetboxSecretsChoices # Not completed yet
diff --git a/NetboxPS.psproj b/NetboxPS.psproj
index 50531cb..2028c89 100644
--- a/NetboxPS.psproj
+++ b/NetboxPS.psproj
@@ -28,6 +28,8 @@
Functions\IPAM\IPAM.ps1
Tests\IPAMChoices.json
Tests\VirtualizationChoices.json
+ Functions\DCIM\DCIM.ps1
+ Tests\DCIM.Tests.ps1
R:\Netbox\NetboxPS\Test-Module.ps1
\ No newline at end of file
diff --git a/Tests/DCIM.Tests.ps1 b/Tests/DCIM.Tests.ps1
new file mode 100644
index 0000000..759e80b
--- /dev/null
+++ b/Tests/DCIM.Tests.ps1
@@ -0,0 +1,53 @@
+<#
+ .NOTES
+ ===========================================================================
+ Created with: SAPIEN Technologies, Inc., PowerShell Studio 2018 v5.5.152
+ Created on: 5/22/2018 4:48 PM
+ Created by: Ben Claussen
+ Organization: NEOnet
+ Filename: DCIM.Tests.ps1
+ ===========================================================================
+ .DESCRIPTION
+ DCIM tests.
+#>
+
+Import-Module Pester
+Remove-Module NetboxPS -Force -ErrorAction SilentlyContinue
+
+$ModulePath = "$PSScriptRoot\..\dist\NetboxPS.psd1"
+
+if (Test-Path $ModulePath) {
+ Import-Module $ModulePath -ErrorAction Stop
+}
+
+Describe -Name "DCIM Tests" -Tag 'DCIM' -Fixture {
+ Mock -CommandName 'CheckNetboxIsConnected' -Verifiable -ModuleName 'NetboxPS' -MockWith {
+ return $true
+ }
+
+ Mock -CommandName 'Invoke-RestMethod' -Verifiable -ModuleName 'NetboxPS' -MockWith {
+ # Return a hashtable of the items we would normally pass to Invoke-RestMethod
+ return [ordered]@{
+ 'Method' = $Method
+ 'Uri' = $Uri
+ 'Headers' = $Headers
+ 'Timeout' = $Timeout
+ 'ContentType' = $ContentType
+ 'Body' = $Body
+ }
+ }
+
+ Mock -CommandName 'Get-NetboxCredential' -Verifiable -ModuleName 'NetboxPS' -MockWith {
+ return [PSCredential]::new('notapplicable', (ConvertTo-SecureString -String "faketoken" -AsPlainText -Force))
+ }
+
+ Mock -CommandName 'Get-NetboxHostname' -Verifiable -ModuleName 'NetboxPS' -MockWith {
+ return 'netbox.domain.com'
+ }
+
+ InModuleScope -ModuleName 'NetboxPS' -ScriptBlock {
+ $script:NetboxConfig.Choices.DCIM = (Get-Content "$PSScriptRoot\DCIMChoices.json" -ErrorAction Stop | ConvertFrom-Json)
+
+
+ }
+}
\ No newline at end of file
diff --git a/Tests/DCIMChoices.json b/Tests/DCIMChoices.json
new file mode 100644
index 0000000..f65d97b
--- /dev/null
+++ b/Tests/DCIMChoices.json
@@ -0,0 +1 @@
+{"device:face":[{"value":0,"label":"Front"},{"value":1,"label":"Rear"}],"device:status":[{"value":1,"label":"Active"},{"value":0,"label":"Offline"},{"value":2,"label":"Planned"},{"value":3,"label":"Staged"},{"value":4,"label":"Failed"},{"value":5,"label":"Inventory"}],"console-port:connection_status":[{"value":false,"label":"Planned"},{"value":true,"label":"Connected"}],"interface:form_factor":[{"value":0,"label":"Virtual"},{"value":200,"label":"Link Aggregation Group (LAG)"},{"value":800,"label":"100BASE-TX (10/100ME)"},{"value":1000,"label":"1000BASE-T (1GE)"},{"value":1150,"label":"10GBASE-T (10GE)"},{"value":1170,"label":"10GBASE-CX4 (10GE)"},{"value":1050,"label":"GBIC (1GE)"},{"value":1100,"label":"SFP (1GE)"},{"value":1200,"label":"SFP+ (10GE)"},{"value":1300,"label":"XFP (10GE)"},{"value":1310,"label":"XENPAK (10GE)"},{"value":1320,"label":"X2 (10GE)"},{"value":1350,"label":"SFP28 (25GE)"},{"value":1400,"label":"QSFP+ (40GE)"},{"value":1500,"label":"CFP (100GE)"},{"value":1510,"label":"CFP2 (100GE)"},{"value":1520,"label":"CFP4 (100GE)"},{"value":1550,"label":"Cisco CPAK (100GE)"},{"value":1600,"label":"QSFP28 (100GE)"},{"value":2600,"label":"IEEE 802.11a"},{"value":2610,"label":"IEEE 802.11b/g"},{"value":2620,"label":"IEEE 802.11n"},{"value":2630,"label":"IEEE 802.11ac"},{"value":2640,"label":"IEEE 802.11ad"},{"value":3010,"label":"SFP (1GFC)"},{"value":3020,"label":"SFP (2GFC)"},{"value":3040,"label":"SFP (4GFC)"},{"value":3080,"label":"SFP+ (8GFC)"},{"value":3160,"label":"SFP+ (16GFC)"},{"value":4000,"label":"T1 (1.544 Mbps)"},{"value":4010,"label":"E1 (2.048 Mbps)"},{"value":4040,"label":"T3 (45 Mbps)"},{"value":4050,"label":"E3 (34 Mbps)"},{"value":5000,"label":"Cisco StackWise"},{"value":5050,"label":"Cisco StackWise Plus"},{"value":5100,"label":"Cisco FlexStack"},{"value":5150,"label":"Cisco FlexStack Plus"},{"value":5200,"label":"Juniper VCP"},{"value":32767,"label":"Other"}],"interface-connection:connection_status":[{"value":false,"label":"Planned"},{"value":true,"label":"Connected"}],"interface-template:form_factor":[{"value":0,"label":"Virtual"},{"value":200,"label":"Link Aggregation Group (LAG)"},{"value":800,"label":"100BASE-TX (10/100ME)"},{"value":1000,"label":"1000BASE-T (1GE)"},{"value":1150,"label":"10GBASE-T (10GE)"},{"value":1170,"label":"10GBASE-CX4 (10GE)"},{"value":1050,"label":"GBIC (1GE)"},{"value":1100,"label":"SFP (1GE)"},{"value":1200,"label":"SFP+ (10GE)"},{"value":1300,"label":"XFP (10GE)"},{"value":1310,"label":"XENPAK (10GE)"},{"value":1320,"label":"X2 (10GE)"},{"value":1350,"label":"SFP28 (25GE)"},{"value":1400,"label":"QSFP+ (40GE)"},{"value":1500,"label":"CFP (100GE)"},{"value":1510,"label":"CFP2 (100GE)"},{"value":1520,"label":"CFP4 (100GE)"},{"value":1550,"label":"Cisco CPAK (100GE)"},{"value":1600,"label":"QSFP28 (100GE)"},{"value":2600,"label":"IEEE 802.11a"},{"value":2610,"label":"IEEE 802.11b/g"},{"value":2620,"label":"IEEE 802.11n"},{"value":2630,"label":"IEEE 802.11ac"},{"value":2640,"label":"IEEE 802.11ad"},{"value":3010,"label":"SFP (1GFC)"},{"value":3020,"label":"SFP (2GFC)"},{"value":3040,"label":"SFP (4GFC)"},{"value":3080,"label":"SFP+ (8GFC)"},{"value":3160,"label":"SFP+ (16GFC)"},{"value":4000,"label":"T1 (1.544 Mbps)"},{"value":4010,"label":"E1 (2.048 Mbps)"},{"value":4040,"label":"T3 (45 Mbps)"},{"value":4050,"label":"E3 (34 Mbps)"},{"value":5000,"label":"Cisco StackWise"},{"value":5050,"label":"Cisco StackWise Plus"},{"value":5100,"label":"Cisco FlexStack"},{"value":5150,"label":"Cisco FlexStack Plus"},{"value":5200,"label":"Juniper VCP"},{"value":32767,"label":"Other"}],"power-port:connection_status":[{"value":false,"label":"Planned"},{"value":true,"label":"Connected"}],"rack:type":[{"value":100,"label":"2-post frame"},{"value":200,"label":"4-post frame"},{"value":300,"label":"4-post cabinet"},{"value":1000,"label":"Wall-mounted frame"},{"value":1100,"label":"Wall-mounted cabinet"}],"rack:width":[{"value":19,"label":"19 inches"},{"value":23,"label":"23 inches"}]}