Public/Set-nbObject.ps1
<#
.SYNOPSIS Sets properties on a object in Netbox .DESCRIPTION This should handle mapping a simple hashtable of values and looking up any references. .EXAMPLE $lookup = @{ device_type='dcim/device-types' device_role='dcim/device-roles' site='organization/sites' status='dcim/_choices' } $device = @{ name = 'example' serial = 'aka123457' device_type = 'dl380-g9' device_role = 'oracle' site = 'chicago' status = 'active' } Set-nbObject -resource dcim/devices -id 22 -lookup $lookup @device .EXAMPLE Set-nbObject -resource dcim/devices -id 22 -name example2 -serial madeup -device_type dl380-gen8 -site chicago -lookup device_type,site #> function Set-nbObject { [CmdletBinding()] Param ( # ID of the object to set [Parameter()] [Int] $Id, # Which resource to set [Parameter(Mandatory = $true)] [String] [Alias("type")] $Resource, # List of custom properties [Parameter()] [string[]] $CustomProperties, #List of properties to lookup [Parameter()] [hashtable] $Lookup, #Looks up the current object and only sets changed properties [Parameter()] [switch] $Patch, # The Object to set [Parameter(Mandatory=$true)] $Object ) if (!$id) { if (!($Object.id)) { $errorRecord = New-Object System.Management.Automation.ErrorRecord( (New-Object Exception "No ID specified to set. Maybe you wanted $($myinvocation.Line -replace 'Set-nb','New-nb')"), 'No.ID', [System.Management.Automation.ErrorCategory]::ObjectNotFound, $Resource ) $PSCmdlet.ThrowTerminatingError($errorRecord) } $id = $object.id } if ($Patch.IsPresent) { $OldObject = Get-nbobject -Resource $Resource/$id #-UnFlatten foreach ($property in $OldObject._lookup) { if ($OldObject."_$Property:id") { $OldObject."$property" = $OldObject."_$Property:id" } else { $Lookup += $property } } $OldObject = $OldObject | Select-Object -Property * -ExcludeProperty _* } #put ids that are still on the object back and maybe pull if ($Object._lookup) { foreach ($property in $Object._lookup) { if ($Object."_$Property:id") { $Object."$property" = $Object."_$Property:id" } else { $Lookup += $property } } } if ($Object._CustomProperties) { $CustomProperties += $Object._CustomProperties } #Automatically rip out all of the _ properties returned by get-nbobject $object = $Object | Select-Object -Property * -ExcludeProperty _* $mapObject = @{custom_fields = @{}} :maploop foreach ($property in $object.psobject.properties) { $Name = $Property.name -replace '-' -replace ':' $value = $Property.value if ($Patch.IsPresent) { if( [string]::IsNullOrEmpty( $($OldObject."$name") ) -and [string]::IsNullOrEmpty($value) ) { Write-Verbose "Bypassing property $name (values are empty)" continue :maploop } If( ($OldObject."$name" -eq $value) -and ( $object."$name" -isnot [System.Array]) ) { Write-Verbose "Bypassing property $name (Values are similar and object isn't an array)" continue :maploop } } if ($name -in $lookup.keys) { $value = ConvertTo-nbID -source $value -value $name } if ($name -in $CustomProperties) { $mapObject.custom_fields[$name] = $value } elseif ($name -eq 'custom_fields') { $mapObject.custom_fields += $value } else { Write-Verbose "Adding property $name" $mapObject[$name] = $value } } $mapObject = New-Object -TypeName psobject -Property $mapObject if ($Patch.IsPresent) { #$notChanged = $mapObject | compare-object -ReferenceObject $OldObject -ExcludeDifferent -PassThru #$mapObject = $mapObject | Select-Object -ExcludeProperty $notChanged return Invoke-nbApi -Resource $Resource/$id -HttpVerb Patch -Body ($mapObject | ConvertTo-Json) } return Invoke-nbApi -Resource $Resource/$id -HttpVerb Put -Body ($mapObject | ConvertTo-Json) } |