Damien Coles f172d00514 Initial release: Declarative AD Framework v2.1.0
Infrastructure-as-code framework for Active Directory objects and Group Policy.
Sanitized from production deployment for public sharing.
2026-02-19 17:02:42 +00:00

56 lines
1.7 KiB
PowerShell

# ADCore.ps1
# Shared utility functions used by multiple AD modules.
# Must be loaded before other AD modules (ADUser.ps1 depends on New-RandomPassword).
function Get-CryptoRandomInt {
<#
.SYNOPSIS
Returns a cryptographically secure random integer in [0, $Max).
#>
param([int]$Max)
$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
$bytes = [byte[]]::new(4)
$rng.GetBytes($bytes)
$rng.Dispose()
return [Math]::Abs([BitConverter]::ToInt32($bytes, 0)) % $Max
}
function New-RandomPassword {
<#
.SYNOPSIS
Generates a cryptographically secure random password that meets AD complexity requirements.
#>
param(
[int]$Length = 16
)
$upper = 'ABCDEFGHJKLMNPQRSTUVWXYZ'
$lower = 'abcdefghjkmnpqrstuvwxyz'
$digits = '23456789'
$special = '!@#$%&*?'
# Guarantee at least one of each type
$chars = [System.Collections.Generic.List[char]]::new()
$chars.Add($upper[(Get-CryptoRandomInt -Max $upper.Length)])
$chars.Add($lower[(Get-CryptoRandomInt -Max $lower.Length)])
$chars.Add($digits[(Get-CryptoRandomInt -Max $digits.Length)])
$chars.Add($special[(Get-CryptoRandomInt -Max $special.Length)])
# Fill the rest randomly from all character sets
$all = $upper + $lower + $digits + $special
for ($i = $chars.Count; $i -lt $Length; $i++) {
$chars.Add($all[(Get-CryptoRandomInt -Max $all.Length)])
}
# Fisher-Yates shuffle using CSPRNG
for ($i = $chars.Count - 1; $i -gt 0; $i--) {
$j = Get-CryptoRandomInt -Max ($i + 1)
$temp = $chars[$i]
$chars[$i] = $chars[$j]
$chars[$j] = $temp
}
return -join $chars
}