It would be useful to import a list of groups. My organisation supports 15,000 devices across 5 geographical area's with hundreds of separate locations. Having the ability to import via a CSV file would be great.
Does anyone have a solution to this?
I know this is a bit of an old post, but I do have a resolution to this. I was able to use the SolarWinds SDK and write a PowerShell script that essentially uploads groups in bulk from a predefined CSV file.It’s intentionally “fill-in-the-blanks,” prompts for login, works with IP or hostname (use 127.0.0.1 if running on the Orion server), skips duplicates, and has a modular custom-property block you can duplicate or delete.
First, you will want to create a CSV file with the following rows:| GroupName | Description | StatusRollup | RefreshSeconds
You can add more rows to the right in order to define your Custom Properties.(ex. Your Group Name | Your Description | 0 | 60 | Your Optional Custom Property)
Here is what SolarWinds uses to define the StatusRollup:0 (mixed shows warning), 1 (worst status), 2 (best status). If unsure, use 0.
You will need to download the SolarWinds SDK SwisPowerShell to run these scripts and interact with the Orion platform.Run the following commands in your PowerShell console running as an Administrator.
Install-Module SwisPowerShell -Scope CurrentUser -ForceImport-Module SwisPowerShell
When you're ready to run the script, you just need to run this command to allow the script to run.
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force
Once you've got all those things ready, you can use the following script to bulk-create groups in SolarWinds.
Paste the script below into Notepad and save as a .ps1 file, which will be executable through PowerShell:
# ======= FILL THESE IN =======$OrionHost = "" # e.g. "OrionServer.domain.local" (or "127.0.0.1" if you're on the Orion server)$CsvPath = "" # e.g. "C:\Path\To\YourFile.csv"# =============================if ([string]::IsNullOrWhiteSpace($OrionHost) -or [string]::IsNullOrWhiteSpace($CsvPath)) { throw "Please set OrionHost and CsvPath at the top of the script."}$ErrorActionPreference = 'Stop'Write-Host "OrionHost: $OrionHost"Write-Host "CSV Path : $CsvPath"Write-Host ("CSV exists? {0}" -f (Test-Path -LiteralPath $CsvPath))# -- Ensure SwisPowerShell is availableif (-not (Get-Module -ListAvailable -Name SwisPowerShell)) { try { if (-not (Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue)) { Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force } [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Install-Module SwisPowerShell -Scope CurrentUser -Force } catch { throw "Failed to install SwisPowerShell module: $($_.Exception.Message)" }}Import-Module SwisPowerShell# -- If you connect by IP or cert doesn't match the name, uncomment this line:# [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }# -- Prompt for login (SolarWinds local OR AD account with rights)$cred = Get-Credential -Message "Enter SolarWinds (or AD) credentials for SWIS"$swis = Connect-Swis -Host $OrionHost -Credential $cred# Quick API sanity check$null = Get-SwisData $swis "SELECT TOP 1 ContainerID, Name FROM Orion.Container"# -- Confirm CSV exists (print listing if not)if (-not (Test-Path -LiteralPath $CsvPath)) { Get-ChildItem -Force (Split-Path $CsvPath) | Select Name,Length,LastWriteTime throw "CSV not found: $CsvPath"}# Load rows$rows = Import-Csv -LiteralPath $CsvPath# Prepare EMPTY members for CreateContainer (some builds dislike $null)$emptyMembersXml = ([xml]'<ArrayOfMemberDefinitionInfo xmlns="">schemas.solarwinds.com/.../Orion" />').DocumentElementforeach ($r in $rows) { try { $nameRaw = $r.GroupName if ([string]::IsNullOrWhiteSpace($nameRaw)) { Write-Warning "Skipping row with blank GroupName."; continue } $name = $nameRaw.Trim() # -- Skip duplicates (by Name) $existingId = Get-SwisData $swis "SELECT ContainerID FROM Orion.Container WHERE Name=@n" @{ n = $name } if ($existingId) { Write-Host "Skipped '$name' (already exists as ContainerID=$existingId)" continue } # Inputs (with safe defaults) $desc = if ($null -ne $r.Description) { [string]$r.Description } else { "" } $rollup = if ($r.StatusRollup) { [int]$r.StatusRollup } else { 0 } # 0 typical ("mixed shows warning") $freq = if ($r.RefreshSeconds) { [int]$r.RefreshSeconds } else { 60 } # -- Create EMPTY group (no members yet) # CreateContainer(name, owner, frequency, statusCalculator, description, pollingEnabled, memberDefsXml) $args = @($name, "Core", $freq, $rollup, $desc, $true, $emptyMembersXml) $containerId = (Invoke-SwisVerb $swis "Orion.Container" "CreateContainer" $args).InnerText # ========= OPTIONAL: CUSTOM PROPERTY BLOCKS ========= # Copy/paste one of these lines per custom property you use. # Make sure the CP exists as a Group (Orion.Container) Custom Property first. # Example 1: set ServiceArea = "Network" # Set-SwisObject $swis -Uri "$(Get-SwisData $swis 'SELECT Uri FROM Orion.Container WHERE ContainerID=@id'; @{ id = [int]$containerId })/CustomProperties" ` # -Properties @{ ServiceArea = "Network" } | Out-Null # Example 2: set OwnerTeam = "NOC" # Set-SwisObject $swis -Uri "$(Get-SwisData $swis 'SELECT Uri FROM Orion.Container WHERE ContainerID=@id'; @{ id = [int]$containerId })/CustomProperties" ` # -Properties @{ OwnerTeam = "NOC" } | Out-Null # Example 3: set multiple CPs at once # Set-SwisObject $swis -Uri "$(Get-SwisData $swis 'SELECT Uri FROM Orion.Container WHERE ContainerID=@id'; @{ id = [int]$containerId })/CustomProperties" ` # -Properties @{ ServiceArea = "Network"; Environment = "Prod" } | Out-Null # ========= END CUSTOM PROPERTY BLOCKS ========= Write-Host "Created '$name' (ContainerID=$containerId)" } catch { Write-Warning "Failed row (GroupName='$($r.GroupName)'): $($_.Exception.Message)" }}Write-Host "Done."
And that's pretty much it. This script will create your groups for you and save you a lot of time.