109 lines
3.6 KiB
PowerShell
109 lines
3.6 KiB
PowerShell
param(
|
|
[Parameter(Mandatory=$true)]
|
|
[string]$InputFile
|
|
)
|
|
|
|
# Read meta JSON
|
|
try {
|
|
$json = Get-Content -Raw -Path $InputFile -ErrorAction Stop
|
|
$meta = $json | ConvertFrom-Json
|
|
} catch {
|
|
Write-Output (@{ success = $false; message = "Failed to read/parse meta JSON: $($_.Exception.Message)" } | ConvertTo-Json -Compress)
|
|
exit 1
|
|
}
|
|
|
|
$csvFile = [string]$meta.input_file
|
|
# PowerShell 5.1 doesn't support the null-coalescing operator '??'.
|
|
# Use an explicit check here to set the default delimiter.
|
|
$delimiter = [string]$meta.delimiter
|
|
if ([string]::IsNullOrWhiteSpace($delimiter)) { $delimiter = ',' }
|
|
$hasHeader = [bool]($meta.has_header -as [bool])
|
|
$dryRun = [bool]($meta.dry_run -as [bool])
|
|
$defaultOu = [string]$meta.default_ou
|
|
|
|
|
|
if (-not (Test-Path -Path $csvFile)) {
|
|
Write-Output (@{ success = $false; message = "CSV file not found: $csvFile" } | ConvertTo-Json -Compress)
|
|
exit 1
|
|
}
|
|
|
|
# Ensure ActiveDirectory module is available
|
|
try {
|
|
Import-Module ActiveDirectory -ErrorAction Stop
|
|
} catch {
|
|
Write-Output (@{ success = $false; message = "ActiveDirectory PowerShell module not available: $($_.Exception.Message)" } | ConvertTo-Json -Compress)
|
|
exit 1
|
|
}
|
|
|
|
# Read CSV
|
|
try {
|
|
if ($hasHeader) {
|
|
$items = Import-Csv -Path $csvFile -Delimiter $delimiter -ErrorAction Stop
|
|
} else {
|
|
# Use default headers
|
|
$headers = 'samaccountname','displayname','mail','password','ou','groups'
|
|
$items = Import-Csv -Path $csvFile -Delimiter $delimiter -Header $headers -ErrorAction Stop
|
|
}
|
|
} catch {
|
|
Write-Output (@{ success = $false; message = "Failed to parse CSV: $($_.Exception.Message)" } | ConvertTo-Json -Compress)
|
|
exit 1
|
|
}
|
|
|
|
$actor = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
|
|
$results = @()
|
|
$successCount = 0
|
|
$failCount = 0
|
|
|
|
foreach ($row in $items) {
|
|
$sam = $row.samaccountname
|
|
$display = $row.displayname
|
|
$mail = $row.mail
|
|
$pass = $row.password
|
|
$ou = $row.ou
|
|
$groups = $row.groups
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ou) -and -not [string]::IsNullOrWhiteSpace($defaultOu)) {
|
|
$ou = $defaultOu
|
|
}
|
|
|
|
|
|
if ([string]::IsNullOrWhiteSpace($sam) -or [string]::IsNullOrWhiteSpace($pass)) {
|
|
$results += @{ sam = $sam; success = $false; message = 'Missing samaccountname or password' }
|
|
$failCount++
|
|
continue
|
|
}
|
|
|
|
if ($dryRun) {
|
|
$results += @{ sam = $sam; success = $true; message = 'DRY RUN: would create' }
|
|
$successCount++
|
|
continue
|
|
}
|
|
|
|
try {
|
|
$props = @{ Name = if ($display -and $display -ne '') { $display } else { $sam }; SamAccountName = $sam; Enabled = $true }
|
|
if ($mail -and $mail -ne '') { $props['EmailAddress'] = $mail }
|
|
if ($ou -and $ou -ne '') { $props['Path'] = $ou }
|
|
$securePass = ConvertTo-SecureString $pass -AsPlainText -Force
|
|
$props['AccountPassword'] = $securePass
|
|
|
|
New-ADUser @props -ErrorAction Stop
|
|
|
|
if ($groups -and $groups -ne '') {
|
|
$groupList = $groups -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne '' }
|
|
foreach ($g in $groupList) {
|
|
Add-ADGroupMember -Identity $g -Members $sam -ErrorAction Stop
|
|
}
|
|
}
|
|
|
|
$results += @{ sam = $sam; success = $true; message = 'Created' }
|
|
$successCount++
|
|
} catch {
|
|
$results += @{ sam = $sam; success = $false; message = $_.Exception.Message }
|
|
$failCount++
|
|
}
|
|
}
|
|
|
|
$output = @{ success = $failCount -eq 0; message = "Created $successCount users, $failCount failures"; details = $results; actor = $actor }
|
|
Write-Output ($output | ConvertTo-Json -Compress)
|
|
exit 0
|