BulkAddAwsAccounts Verb Documentation
BulkAddAwsAccounts
Adds multiple AWS accounts in a single call. The operation uses partial-success semantics: failed accounts are reported in the response while the remaining ones are added successfully.
Input limits & validation (rejected up front with an
ArgumentException— no accounts are created):
- Batch size: at most 100 accounts per call. To add more, split into batches of ≤ 100.
- Payload size: the JSON string must be ≤ 1 MB.
Per-account validation (reported as a failure entry, other accounts still processed):
Nameis required, non-empty, and at most 255 characters.- Duplicate
Namevalues within the same request (case-insensitive) — the first wins, later ones fail.
Connecting to SWIS
$swis = Connect-Swis -Hostname "orion.example.com" -Username "admin" -Password "password"
Signature
Invoke-SwisVerb $swis Orion.Cloud.Aws.Accounts BulkAddAwsAccounts @(, $json)
$json is a JSON string containing an array of account objects.
Input structure
AwsBulkAddAccountInput
| Field | Type | Required | Description |
|---|---|---|---|
Name |
string | yes | Unique account name in Orion |
AccessKeyId |
string | no¹ | AWS Access Key ID |
SecretAccessKey |
string | no¹ | AWS Secret Access Key |
RoleArn |
string | no | AssumeRole chain (see below) |
ExistingCredentialsId |
int | no | ID of existing credentials to reuse instead of providing keys |
AutoMonitoring |
bool | no | Automatically monitor newly discovered resources (default true) |
PollingIntervalInSeconds |
int | no | Polling frequency in seconds (default 300). Recommended range: 60–3600. |
SelectedRegions |
string[] | no | AWS region system names (e.g."us-east-1"). Null or empty = all regions |
MonitorResourceType |
int | no | Resources monitoring method:0 = All resources (default), 1 = Monitor selected entities, 2 = Monitor by tags |
EnableCostManagement |
bool | no | Enable daily AWS Cost polling (default false). Independent from MonitorResourceType. |
RunCostManagementAtTime |
string | no | Daily time to poll AWS Cost data, e.g."2024-01-01T14:30:00". Only used when EnableCostManagement = true. Defaults to the current server time if not specified (same as the UI). |
JobSettings |
object | no | Additional scan settings (see below).Tags are only applied when MonitorResourceType = 2. |
AwsPollersSettings |
object | no | Enable/disable individual AWS services (see below). Only used when MonitorResourceType = 1 — for 0 all services are enabled automatically, for 2 pollers are not set at all. |
¹ Required unless ExistingCredentialsId is provided or an IAM role without keys is used (Instance Profile).
RoleArn format — role chaining
Each hop is separated by a semicolon (;). An optional External ID is appended after a pipe (|).
<ARN1>[|<externalId1>][;<ARN2>[|<externalId2>];...]
Examples:
- Single role:
arn:aws:iam::123456789012:role/OrionRole - Single role with External ID:
arn:aws:iam::123456789012:role/OrionRole|myExternalSecret - Two-hop chain:
arn:aws:iam::111111111111:role/HubRole;arn:aws:iam::222222222222:role/TargetRole - Two-hop chain with External IDs:
arn:aws:iam::111111111111:role/HubRole|extId1;arn:aws:iam::222222222222:role/TargetRole|extId2
JobSettings
| Field | Type | Default | Description |
|---|---|---|---|
NetworkScanEnabled |
bool | false |
Enable network scanning |
DnsScanEnabled |
bool | false |
Enable DNS scanning |
VirtualNetworkGatewaysPollingEnabled |
bool | false |
Enable Virtual Network Gateways polling |
NetworkScanInterval |
int | 240 |
Network scan interval (seconds).0 or omitted falls back to 240. |
DnsScanInterval |
int | 240 |
DNS scan interval (seconds).0 or omitted falls back to 240. |
AwsPollersSettings
All fields are bool. Default value is false.
| Field | AWS service |
|---|---|
AwsSqlDatabasesPollingEnabled |
RDS |
AwsLoadBalancersPollingEnabled |
ALB / NLB |
AwsBucketStoragePollingEnabled |
S3 |
AwsDirectConnectPollingEnabled |
Direct Connect |
AwsDynamoDbPollingEnabled |
DynamoDB |
AwsElasticKubernetesPollingEnabled |
EKS |
AwsLambdaFunctionPollingEnabled |
Lambda |
AwsElasticBeanstalkPollingEnabled |
Elastic Beanstalk |
AwsTransitGatewayPollingEnabled |
Transit Gateway |
Response structure
$result = Invoke-SwisVerb $swis Orion.Cloud.Aws.Accounts BulkAddAwsAccounts @(, $json)
# $result is an XmlElement:
$result.Succeeded.AwsAccountAddSuccess | Select-Object `
@{ N = 'Name'; E = { $_.SelectSingleNode('*[local-name()="Name"]').InnerText } },
@{ N = 'AccountId'; E = { $_.AccountId } }
$result.Succeeded.AwsAccountAddFailure | Select-Object `
@{ N = 'Name'; E = { $_.SelectSingleNode('*[local-name()="Name"]').InnerText } },
@{ N = 'ErrorMessage'; E = { $_.ErrorMessage } }
Example response (as XML returned by SWIS):
<BulkAddAwsAccountsResult>
<Succeeded>
<AwsAccountAddSuccess>
<Name>prod-account-1</Name>
<AccountId>42</AccountId>
</AwsAccountAddSuccess>
</Succeeded>
<Failed>
<AwsAccountAddFailure>
<Name>prod-account-2</Name>
<ErrorMessage>An account with name 'prod-account-2' already exists.</ErrorMessage>
</AwsAccountAddFailure>
</Failed>
</BulkAddAwsAccountsResult>
Examples
1. Minimal — single account, Access Key, all regions
$json = '[{"Name":"prod-account-1","AccessKeyId":"AKIAIOSFODNN7EXAMPLE","SecretAccessKey":"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}]'
Invoke-SwisVerb $swis Orion.Cloud.Aws.Accounts BulkAddAwsAccounts @(, $json)
2. Multiple accounts — mixed configuration
If the first one fails (e.g. duplicate name), the second is still added.
$json = @'
[
{
"Name": "prod-account-us",
"AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"AutoMonitoring": true,
"PollingIntervalInSeconds": 300
},
{
"Name": "prod-account-eu",
"AccessKeyId": "AKIAI44QH8DHBEXAMPLE",
"SecretAccessKey": "je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY",
"AutoMonitoring": true,
"PollingIntervalInSeconds": 600
}
]
'@
$result = Invoke-SwisVerb $swis Orion.Cloud.Aws.Accounts BulkAddAwsAccounts @(, $json)
$result.Succeeded.AwsAccountAddSuccess | Select-Object `
@{ N = 'Name'; E = { $_.SelectSingleNode('*[local-name()="Name"]').InnerText } },
@{ N = 'AccountId'; E = { $_.AccountId } }
$result.Succeeded.AwsAccountAddFailure | Select-Object `
@{ N = 'Name'; E = { $_.SelectSingleNode('*[local-name()="Name"]').InnerText } },
@{ N = 'ErrorMessage'; E = { $_.ErrorMessage } }
3. Restricted regions
$json = @'
[
{
"Name": "prod-account-limited",
"AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"AutoMonitoring": true,
"PollingIntervalInSeconds": 300,
"SelectedRegions": ["us-east-1", "us-west-2", "eu-west-1", "eu-central-1"]
}
]
'@
Invoke-SwisVerb $swis Orion.Cloud.Aws.Accounts BulkAddAwsAccounts @(, $json)
4. All resources with cost monitoring
MonitorResourceType = 0 (default) — all services are enabled automatically. Cost monitoring is off by default; enable it with EnableCostManagement = true:
$json = '[{"Name":"prod-account-all","AccessKeyId":"AKIAIOSFODNN7EXAMPLE","SecretAccessKey":"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY","AutoMonitoring":true,"PollingIntervalInSeconds":300,"EnableCostManagement":true,"RunCostManagementAtTime":"2024-01-01T02:00:00Z"}]'
Invoke-SwisVerb $swis Orion.Cloud.Aws.Accounts BulkAddAwsAccounts @(, $json)
5. Monitor selected entities — specific services only
MonitorResourceType = 1 — only services listed in AwsPollersSettings are polled. Cost polling runs daily at 02:00 UTC:
$json = @'
[
{
"Name": "prod-account-selective",
"AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"AutoMonitoring": true,
"PollingIntervalInSeconds": 300,
"MonitorResourceType": 1,
"EnableCostManagement": true,
"RunCostManagementAtTime": "2024-01-01T02:00:00Z",
"AwsPollersSettings": {
"AwsSqlDatabasesPollingEnabled": true,
"AwsElasticKubernetesPollingEnabled": true
}
}
]
'@
Invoke-SwisVerb $swis Orion.Cloud.Aws.Accounts BulkAddAwsAccounts @(, $json)
MonitorResourceType = 0(default) enables all services automatically —AwsPollersSettingsis ignored in that case.
6. Tag-based monitoring
Monitor only resources tagged Environment=Production. Set MonitorResourceType to 2 — when tag filtering is active, AwsPollersSettings is ignored.
$json = @'
[
{
"Name": "prod-account-tagged",
"AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"AutoMonitoring": true,
"PollingIntervalInSeconds": 300,
"MonitorResourceType": 2,
"JobSettings": {
"Tags": [
{ "Key": "Environment", "Value": "Production" }
]
}
}
]
'@
Invoke-SwisVerb $swis Orion.Cloud.Aws.Accounts BulkAddAwsAccounts @(, $json)
7. AssumeRole — single role
$json = '[{"Name":"prod-account-assumerole","RoleArn":"arn:aws:iam::123456789012:role/OrionMonitoringRole","AutoMonitoring":true,"PollingIntervalInSeconds":300}]'
Invoke-SwisVerb $swis Orion.Cloud.Aws.Accounts BulkAddAwsAccounts @(, $json)
8. AssumeRole with External ID
$json = '[{"Name":"prod-account-external-id","RoleArn":"arn:aws:iam::123456789012:role/OrionMonitoringRole|my-secret-external-id","AutoMonitoring":true,"PollingIntervalInSeconds":300}]'
Invoke-SwisVerb $swis Orion.Cloud.Aws.Accounts BulkAddAwsAccounts @(, $json)
9. Role chaining — Landing Zone / hub-and-spoke
$json = '[{"Name":"spoke-account-prod","RoleArn":"arn:aws:iam::111111111111:role/HubRole|hub-external-id;arn:aws:iam::222222222222:role/TargetRole","AutoMonitoring":true,"PollingIntervalInSeconds":300}]'
Invoke-SwisVerb $swis Orion.Cloud.Aws.Accounts BulkAddAwsAccounts @(, $json)
10. Bulk import from AWS Organizations — shared role, different Account IDs
$accountIds = @("111111111111", "222222222222", "333333333333")
$accounts = $accountIds | ForEach-Object {
@{
Name = "org-account-$_"
RoleArn = "arn:aws:iam::${_}:role/OrionMonitoringRole|shared-external-id"
AutoMonitoring = $true
PollingIntervalInSeconds = 300
MonitorResourceType = 1
SelectedRegions = @("us-east-1", "eu-west-1")
AwsPollersSettings = @{
AwsSqlDatabasesPollingEnabled = $true
AwsLoadBalancersPollingEnabled = $true
AwsElasticKubernetesPollingEnabled = $true
}
}
}
$json = $accounts | ConvertTo-Json -Depth 5
$result = Invoke-SwisVerb $swis Orion.Cloud.Aws.Accounts BulkAddAwsAccounts @(, $json)
$result.Succeeded.AwsAccountAddSuccess | Select-Object `
@{ N = 'Name'; E = { $_.SelectSingleNode('*[local-name()="Name"]').InnerText } },
@{ N = 'AccountId'; E = { $_.AccountId } }
$result.Succeeded.AwsAccountAddFailure | Select-Object `
@{ N = 'Name'; E = { $_.SelectSingleNode('*[local-name()="Name"]').InnerText } },
@{ N = 'ErrorMessage'; E = { $_.ErrorMessage } }
11. Reusing existing credentials
To find the credential ID, query either by account name or directly from Orion.Credential:
# Option A — look up from an existing account
$credId = (Get-SwisData $swis "SELECT CredentialId FROM Orion.Cloud.Aws.Accounts WHERE Name = 'existing-account'").CredentialId
# Option B — list all AWS credentials stored in Orion
Get-SwisData $swis "SELECT ID, Name FROM Orion.Credential WHERE CredentialOwner = 'CloudMonitoring' AND CredentialType LIKE '%AwsCredentials%' ORDER BY Name"
$credId = 123 # use the ID from the query above
$json = @"
[
{
"Name": "prod-account-shared-creds-1",
"ExistingCredentialsId": $credId,
"RoleArn": "arn:aws:iam::333333333333:role/OrionMonitoringRole",
"AutoMonitoring": true,
"PollingIntervalInSeconds": 300
},
{
"Name": "prod-account-shared-creds-2",
"ExistingCredentialsId": $credId,
"RoleArn": "arn:aws:iam::444444444444:role/OrionMonitoringRole",
"AutoMonitoring": true,
"PollingIntervalInSeconds": 300
}
]
"@
Invoke-SwisVerb $swis Orion.Cloud.Aws.Accounts BulkAddAwsAccounts @(, $json)
12. Full configuration
$json = @'
[
{
"Name": "prod-account-full",
"RoleArn": "arn:aws:iam::111111111111:role/HubRole|hub-ext-id;arn:aws:iam::999999999999:role/TargetRole|target-ext-id",
"AutoMonitoring": true,
"PollingIntervalInSeconds": 300,
"MonitorResourceType": 1,
"EnableCostManagement": true,
"RunCostManagementAtTime": "2024-01-01T02:00:00Z",
"SelectedRegions": ["us-east-1", "us-west-2", "eu-west-1"],
"JobSettings": {
"NetworkScanEnabled": true,
"DnsScanEnabled": true,
"NetworkScanInterval": 3600,
"DnsScanInterval": 3600
},
"AwsPollersSettings": {
"AwsSqlDatabasesPollingEnabled": true,
"AwsLoadBalancersPollingEnabled": true,
"AwsBucketStoragePollingEnabled": true,
"AwsElasticKubernetesPollingEnabled": true,
"AwsLambdaFunctionPollingEnabled": true,
"AwsTransitGatewayPollingEnabled": true
}
}
]
'@
$result = Invoke-SwisVerb $swis Orion.Cloud.Aws.Accounts BulkAddAwsAccounts @(, $json)
$result.Succeeded.AwsAccountAddSuccess | Select-Object `
@{ N = 'Name'; E = { $_.SelectSingleNode('*[local-name()="Name"]').InnerText } },
@{ N = 'AccountId'; E = { $_.AccountId } }
$result.Succeeded.AwsAccountAddFailure | Select-Object `
@{ N = 'Name'; E = { $_.SelectSingleNode('*[local-name()="Name"]').InnerText } },
@{ N = 'ErrorMessage'; E = { $_.ErrorMessage } }
Error handling
The operation uses partial-success semantics — a single failed account does not block the others.
Common ErrorMessage values:
An account with name '...' already exists.— duplicate account nameUnknown AWS region name(s): ap-southeast-99. Use SystemName values such as 'us-east-1'.— region does not exist in OrionAWS region(s) not available for monitoring: ap-southeast-99.— region exists but is disabled in Orion
To retrieve all available region names:
Get-SwisData $swis "SELECT SystemName, DisplayName FROM Orion.Cloud.Aws.Regions ORDER BY SystemName"