Skip to content

Bulk Operations

PowerNetbox supports high-performance bulk operations for creating, updating, and deleting multiple resources in a single API request. This significantly improves performance when working with large datasets.

Overview

Bulk operations use Netbox's native bulk API endpoints, which process arrays of objects in batches. This is much faster than making individual API calls for each resource.

Supported Functions

Function Operation Description
New-NBDCIMDevice POST Create multiple devices
New-NBDCIMInterface POST Create multiple device interfaces
New-NBIPAMAddress POST Create multiple IP addresses
New-NBIPAMPrefix POST Create multiple IP prefixes
New-NBIPAMVLAN POST Create multiple VLANs
New-NBVirtualMachine POST Create multiple VMs
New-NBVirtualMachineInterface POST Create multiple VM interfaces
Set-NBDCIMDevice PATCH Update multiple devices
Remove-NBDCIMDevice DELETE Delete multiple devices

Common Parameters

Parameter Type Default Description
-InputObject PSCustomObject - Pipeline input for bulk mode
-BatchSize int (1-1000) 50 Items per API request
-Force switch - Skip confirmation prompts

Basic Usage

Bulk Create Devices

# Create objects with required properties
$devices = 1..10 | ForEach-Object {
    [PSCustomObject]@{
        Name        = "server-$_"
        Role        = 1           # Device role ID
        Device_Type = 1           # Device type ID
        Site        = 1           # Site ID
        Status      = "planned"
    }
}

# Pipe to function with -Force to skip prompts
$created = $devices | New-NBDCIMDevice -BatchSize 5 -Force

# View results
$created | Select-Object id, name, status

Bulk Create VLANs

# Create VLAN range 100-199
$vlans = 100..199 | ForEach-Object {
    [PSCustomObject]@{
        VID    = $_
        Name   = "VLAN$_"
        Status = "active"
        Site   = 1
    }
}

$vlans | New-NBIPAMVLAN -BatchSize 50 -Force

Bulk Create IP Addresses

# Create all IPs in a /24 subnet
$addresses = 1..254 | ForEach-Object {
    [PSCustomObject]@{
        Address     = "192.168.1.$_/24"
        Status      = "active"
        Description = "Host $_"
    }
}

$addresses | New-NBIPAMAddress -BatchSize 100 -Force

Bulk Create VM Interfaces

# Get all VMs in a cluster
$vms = Get-NBVirtualMachine -Cluster 1

# Create eth0 interface for each VM
$interfaces = $vms | ForEach-Object {
    [PSCustomObject]@{
        Virtual_Machine = $_.id
        Name            = "eth0"
        Enabled         = $true
        Description     = "Primary interface"
    }
}

$interfaces | New-NBVirtualMachineInterface -BatchSize 50 -Force

Bulk Update

Update Device Status

# Get devices to update
$devices = Get-NBDCIMDevice -Status "planned"

# Create update objects (must include Id)
$updates = $devices | ForEach-Object {
    [PSCustomObject]@{
        Id       = $_.id
        Status   = "active"
        Comments = "Deployed on $(Get-Date -Format 'yyyy-MM-dd')"
    }
}

# Bulk update
$updated = $updates | Set-NBDCIMDevice -BatchSize 50 -Force

Write-Host "Updated $($updated.Count) devices"

Update Multiple Properties

# Update devices with multiple changes
$updates = @(
    [PSCustomObject]@{ Id = 100; Status = "active"; Serial = "SN001" }
    [PSCustomObject]@{ Id = 101; Status = "active"; Serial = "SN002" }
    [PSCustomObject]@{ Id = 102; Status = "staged"; Serial = "SN003" }
)

$updates | Set-NBDCIMDevice -Force

Bulk Delete

Delete by Status

# Get decommissioned devices
$toDelete = Get-NBDCIMDevice -Status "decommissioning"

# Bulk delete (WARNING: This cannot be undone!)
$toDelete | Remove-NBDCIMDevice -BatchSize 50 -Force

Delete by Query

# Delete all test devices
Get-NBDCIMDevice -Name "test-*" | Remove-NBDCIMDevice -Force

CSV Import

Import Devices from CSV

Name,Role,Device_Type,Site,Status,Serial
server-01,1,1,1,active,SN001
server-02,1,1,1,active,SN002
server-03,1,1,1,planned,SN003
Import-Csv devices.csv | New-NBDCIMDevice -BatchSize 100 -Force

Import VLANs from CSV

VID,Name,Status,Site,Description
100,Management,active,1,Management VLAN
101,Production,active,1,Production servers
102,DMZ,active,1,DMZ network
Import-Csv vlans.csv | New-NBIPAMVLAN -BatchSize 50 -Force

Import Prefixes from CSV

Prefix,Status,Site,Description,Is_Pool
10.0.0.0/24,active,1,Server network,false
10.0.1.0/24,active,1,Client network,false
10.0.2.0/24,container,1,DHCP pool,true
Import-Csv prefixes.csv | New-NBIPAMPrefix -BatchSize 50 -Force

Error Handling

Bulk operations track successes and failures individually:

# Capture results
$result = $items | New-NBDCIMDevice -BatchSize 50 -Force

# Check for errors in output
if ($Error.Count -gt 0) {
    Write-Host "Some items failed:" -ForegroundColor Yellow
    $Error | ForEach-Object { Write-Host $_.Exception.Message }
}

# Successful items are output to pipeline
Write-Host "Successfully created: $($result.Count) devices"

Verbose Output

# Use -Verbose to see batch progress
$items | New-NBDCIMDevice -BatchSize 50 -Force -Verbose

Automatic 500 Error Recovery (v4.4.9.3+)

When a bulk batch fails with a 500 Internal Server Error, PowerNetbox automatically falls back to sequential processing with exponential backoff retry. This provides resilience against transient server errors that can occur when referencing recently created objects.

What happens automatically: 1. Batch fails with 500 error 2. Waits 3 seconds for server to stabilize 3. Retries each item individually with delays (500ms → 1s → 2s) 4. Up to 3 retry attempts per item 5. Items that succeed are tracked; permanent failures are reported

# Resilient chain: create devices → interfaces → IPs
# Even if bulk batch fails, each item is retried individually
$devices = 1..5 | ForEach-Object {
    [PSCustomObject]@{ Name = "server-$_"; Role = 1; Device_Type = 1; Site = 1 }
} | New-NBDCIMDevice -Force

# Reference newly created devices (resilient to 500 errors)
$interfaces = $devices | ForEach-Object {
    [PSCustomObject]@{ Device = $_.id; Name = "eth0"; Type = "1000base-t" }
} | New-NBDCIMInterface -Force

Note: This fallback is transparent - you don't need to change your code. The module handles recovery automatically.

Performance Tips

Optimal Batch Size

Item Count Recommended BatchSize API Calls
1-50 50 (default) 1
51-200 50 1-4
201-1000 100 3-10
1000+ 200-500 5+
# For large imports, increase batch size
Import-Csv large-dataset.csv | New-NBDCIMDevice -BatchSize 200 -Force

Parallel Processing

For very large datasets, split into chunks and process in parallel:

# Split into 4 chunks for parallel processing
$items = Import-Csv huge-dataset.csv
$chunks = [System.Collections.ArrayList]@()
$chunkSize = [math]::Ceiling($items.Count / 4)

for ($i = 0; $i -lt $items.Count; $i += $chunkSize) {
    [void]$chunks.Add($items[$i..([math]::Min($i + $chunkSize - 1, $items.Count - 1))])
}

# Process chunks in parallel (PowerShell 7+)
$chunks | ForEach-Object -Parallel {
    Import-Module PowerNetbox
    Connect-NBAPI -Hostname $using:NetboxHost -Credential $using:cred
    $_ | New-NBDCIMDevice -BatchSize 100 -Force
} -ThrottleLimit 4

Real-World Examples

Provision Rack of Servers

# Define server template
$rackId = 1
$siteId = 1
$roleId = 1  # Server role
$typeId = 1  # Server type

# Create 42U worth of servers
$servers = 1..42 | ForEach-Object {
    [PSCustomObject]@{
        Name        = "rack01-u$_"
        Role        = $roleId
        Device_Type = $typeId
        Site        = $siteId
        Rack        = $rackId
        Position    = $_
        Face        = "front"
        Status      = "planned"
    }
}

$created = $servers | New-NBDCIMDevice -BatchSize 20 -Force
Write-Host "Provisioned $($created.Count) servers in rack"

Create VLAN Structure per Site

$sites = Get-NBDCIMSite

foreach ($site in $sites) {
    # Standard VLAN template per site
    $vlans = @(
        @{ VID = 10; Name = "Management"; Description = "Management network" }
        @{ VID = 20; Name = "Servers"; Description = "Server network" }
        @{ VID = 30; Name = "Clients"; Description = "Client network" }
        @{ VID = 40; Name = "Voice"; Description = "VoIP network" }
        @{ VID = 99; Name = "Native"; Description = "Native VLAN" }
    ) | ForEach-Object {
        [PSCustomObject]@{
            VID         = $_.VID
            Name        = "$($site.name)-$($_.Name)"
            Site        = $site.id
            Status      = "active"
            Description = $_.Description
        }
    }

    $vlans | New-NBIPAMVLAN -Force
    Write-Host "Created VLANs for site: $($site.name)"
}

Decommission Old Devices

# Find devices older than 5 years (using custom field)
$oldDevices = Get-NBDCIMDevice | Where-Object {
    $_.custom_fields.install_date -and
    ([datetime]$_.custom_fields.install_date) -lt (Get-Date).AddYears(-5)
}

# Update status to decommissioning
$updates = $oldDevices | ForEach-Object {
    [PSCustomObject]@{
        Id       = $_.id
        Status   = "decommissioning"
        Comments = "Scheduled for decommission - age > 5 years"
    }
}

$updates | Set-NBDCIMDevice -Force

Write-Host "Marked $($updates.Count) devices for decommissioning"

Migrate VMs Between Clusters

$sourceCluster = 1
$targetCluster = 2

# Get VMs from source cluster
$vms = Get-NBVirtualMachine -Cluster $sourceCluster

# Create update objects
$updates = $vms | ForEach-Object {
    [PSCustomObject]@{
        Id      = $_.id
        Cluster = $targetCluster
    }
}

# Bulk migrate
$updates | Set-NBVirtualMachine -Force

Write-Host "Migrated $($updates.Count) VMs to new cluster"

Comparison: Single vs Bulk

Without Bulk (Slow)

# 100 API calls - one per device
Measure-Command {
    1..100 | ForEach-Object {
        New-NBDCIMDevice -Name "server-$_" -Role 1 -Device_Type 1 -Site 1
    }
}
# Time: ~60 seconds

With Bulk (Fast)

# 2 API calls - batched
Measure-Command {
    $devices = 1..100 | ForEach-Object {
        [PSCustomObject]@{ Name = "server-$_"; Role = 1; Device_Type = 1; Site = 1 }
    }
    $devices | New-NBDCIMDevice -BatchSize 50 -Force
}
# Time: ~2 seconds (30x faster!)

See Also