Migrating from traditional on-prem Active Directory (AD) to Azure is a strategic step toward a modern, cloud-native identity architecture. Manual migration methods are time-consuming and error-prone, especially at scale. By combining PowerShell, JSON, and Terraform, you can create a repeatable and version-controlled process to export AD users and recreate them in Azure AD using infrastructure as code (IaC).
In this blog, you'll learn how to:
This approach is clean, auditable, and scalable.
β
PowerShell provides native access to AD through the ActiveDirectory
module. The following script:
ad_users
)terraform_users.json
param (
[Parameter(Mandatory = $true)]
[string]$TerraformVar
)
# Ensure Active Directory module is loaded
Import-Module ActiveDirectory
# Query AD users and build a dictionary of user data
$users = Get-ADUser -Filter * -Properties DisplayName, EmailAddress, Department | ForEach-Object {
$key = $_.SamAccountName.ToLower()
[PSCustomObject]@{
Key = $key
Value = @{
display_name = $_.DisplayName
email = $_.EmailAddress
department = $_.Department
}
}
}
# Build top-level JSON structure
$exportData = @{}
$exportData[$TerraformVar] = @{}
foreach ($user in $users) {
$exportData[$TerraformVar][$user.Key] = $user.Value
}
# Output to JSON file
$exportData | ConvertTo-Json -Depth 5 | Out-File -Encoding UTF8 "terraform_users.json"
Write-Host "Export complete. JSON written with top-level key '$TerraformVar'"
β
.\Export-AdUsers.ps1 -TerraformVar "ad_users"
terraform_users.json
{
"ad_users": {
"jdoe": {
"display_name": "John Doe",
"email": "jdoe@example.com",
"department": "Engineering"
},
"asmith": {
"display_name": "Alice Smith",
"email": "asmith@example.com",
"department": "Finance"
}
}
}
β
main.tf
# Configure Terraform
terraform {
required_providers {
azuread = {
source = "hashicorp/azuread"
version = "~> 2.47"
}
}
}
# Configure the Azure Active Directory Provider
provider "azuread" {
tenant_id = "00000000-0000-0000-0000-000000000000"
client_id = "foo" # For demo purposes only; secure with real logic
client_secret = "bar" # For demo purposes only; secure with real logic
}
# Define ad_users as a map of objects
variable "ad_users" {
description = "Map of AD users to create in Azure AD"
type = map(object({
display_name = string
email = string
department = string
}))
}
# Create AD Users from json data
resource "azuread_user" "from_ad" {
for_each = var.ad_users
user_principal_name = "${each.key}@yourdomain.com"
display_name = each.value.display_name
mail_nickname = each.key
department = each.value.department
account_enabled = true
password = "ChangeM3Now!" # For demo purposes only; secure with real logic
force_password_change = true
}
ad_users
) as input.for_each
to dynamically create each userforce_password_change = true
.β
$ terraform init
$ terraform apply -var-file="terraform_users.json"
β
Cloud-Ready β Migrates AD users directly into Azure
β
Repeatable β Export once, reuse and track changes
β
Terraform-Compatible β Works with native Azure provider
β
Secure & Auditable β Store in version control, review diffs
β
Parameter-Driven β Works with any Terraform variable name
β
This export method can be extended to:
For larger environments, this process scales cleanly and avoids error-prone manual entry.
β
Hypercumulus specializes in infrastructure automation, Azure migrations, and cost-effective identity modernization. Reach out if you need a tailored solution.
β