Skip to content

CSV Parameters — Advanced Usage

CSV parameters let scenario architects provide tabular data — rows of users, groups, OUs, computers — that your plugin processes in bulk. This is the most powerful parameter type but requires specific handling in your YAML.

When you create a parameter with type CSV, the scenario architect sees a spreadsheet-like grid in the UI. They fill in rows of data, and the platform passes it to your plugin as a CSV-formatted string.

In the Parameters tab, when you select the CSV type, you can define column headers using draggable chips. These headers determine the columns shown in the grid UI.

For example, the Root DC plugin defines a CreateUsers CSV parameter with headers:

samaccountname, firstname, lastname, password, displayname, email, title, department, location, description, groups, assignedOU

CSV data from the UI may contain BOM (byte order mark) characters or Windows-style carriage returns. Always normalize before parsing:

- name: Normalize CSV-style variables
ansible.builtin.set_fact:
CreateOUs: "{{ CreateOUs | default('') | regex_replace('^\\ufeff','') | regex_replace('\\r','') | trim }}"
CreateGroups: "{{ CreateGroups | default('') | regex_replace('^\\ufeff','') | regex_replace('\\r','') | trim }}"
CreateUsers: "{{ CreateUsers | default('') | regex_replace('^\\ufeff','') | regex_replace('\\r','') | trim }}"
CreateFakeComputers: "{{ CreateFakeComputers | default('') | regex_replace('^\\ufeff','') | regex_replace('\\r','') | trim }}"

After normalizing, convert the CSV string into Ansible record lists:

- name: Parse CSV into records
ansible.builtin.set_fact:
ou_records: >-
{{ (CreateOUs | length > 0) | ternary(CreateOUs | community.general.from_csv, []) }}
group_records: >-
{{ (CreateGroups | length > 0) | ternary(CreateGroups | community.general.from_csv, []) }}
user_records: >-
{{ (CreateUsers | length > 0) | ternary(CreateUsers | community.general.from_csv, []) }}
computer_records: >-
{{ (CreateFakeComputers | length > 0) | ternary(CreateFakeComputers | community.general.from_csv, []) }}

The ternary guard prevents errors when a CSV parameter is left empty.

For complex operations (like bulk AD provisioning), it’s often easier to write the CSV to disk and process it in a single PowerShell script. This avoids Ansible loop overhead and gives you full error handling:

Write each CSV to the VM:

- name: Write OU CSV to C:\
ansible.windows.win_copy:
content: "{{ CreateOUs | regex_replace('^\\ufeff','') | regex_replace('\\r','') | trim }}"
dest: 'C:\ad_ous.csv'
when: CreateOUs | default('') | trim != ''
- name: Write User CSV to C:\
ansible.windows.win_copy:
content: "{{ CreateUsers | regex_replace('^\\ufeff','') | regex_replace('\\r','') | trim }}"
dest: 'C:\ad_users.csv'
when: CreateUsers | default('') | trim != ''

Then process in bulk with PowerShell:

- name: Bulk-create AD OUs, Groups, Users, and Computers via PowerShell
ansible.windows.win_powershell:
error_action: stop
script: |-
$ErrorActionPreference = 'Stop'
Import-Module ActiveDirectory -ErrorAction Stop
$results = @()
$changed = $false
# Import CSV files written by Ansible
$ous = Import-Csv 'C:\ad_ous.csv' -ErrorAction SilentlyContinue
$users = Import-Csv 'C:\ad_users.csv' -ErrorAction SilentlyContinue
# Process OUs
foreach ($ou in $ous) {
$ouName = $ou.name
$parentDn = $ou.parentOUFQN
$dn = "OU=$ouName,$parentDn"
try {
New-ADOrganizationalUnit -Name $ouName -Path $parentDn -ErrorAction Stop
$changed = $true
$results += @{ type='ou'; name=$ouName; status='created' }
} catch {
$results += @{ type='ou'; name=$ouName; status='error'; error="$($_.Exception.Message)" }
}
}
# Process Users
foreach ($u in $users) {
$sam = $u.samaccountname
New-ADUser -Name $sam -SamAccountName $sam -GivenName $u.firstname -Surname $u.lastname -Enabled $false
# Set password and enable
Set-ADAccountPassword -Identity $sam -Reset -NewPassword (ConvertTo-SecureString $u.password -AsPlainText -Force)
Enable-ADAccount -Identity $sam
$changed = $true
$results += @{ type='user'; user=$sam; status='created' }
}
# Cleanup
Remove-Item 'C:\ad_ous.csv','C:\ad_users.csv' -Force -ErrorAction SilentlyContinue
[pscustomobject]@{ changed = $changed; results = $results } | ConvertTo-Json -Depth 6
register: ad_bulk
changed_when: ad_bulk.output is search('"changed"\s*:\s*true')

This pattern — CSV parameter → normalize → write to disk → PowerShell bulk processing → cleanup — is the recommended approach for any plugin that needs to create multiple AD objects or process tabular input.

Here are the column definitions used in the Root DC plugin:

CSV ParameterHeaders
CreateOUsname, parentOUFQN, description
CreateGroupsname, description, assignedOU
CreateUserssamaccountname, firstname, lastname, password, displayname, email, title, department, location, description, groups, assignedOU
CreateFakeComputerscomputername, description, operatingsystem, oupath