ps/Modules/Alkami.DevOps.SystemEngineering/Private/New-ServerlessServiceAccountActiveDirectoryUserPair.ps1

131 lines
5.2 KiB
PowerShell
Raw Normal View History

2023-05-30 22:51:22 -07:00
function New-ServerlessServiceAccountActiveDirectoryUserPair {
<#
.SYNOPSIS
Create a pair of serverless service accounts in Active Directory.
.DESCRIPTION
Creates a pair of serverless service accounts in Active Directory and adds the newly
created accounts to the SQL access security group for the appropriate environment.
.PARAMETER Cred
[PSCredential] A credential object for the FH user that has permissions to create new accounts
on the domain.
.PARAMETER UserDataList
[PSCredential[]] An array with exactly two credential objects containing the usernames and passwords to use
during account creation.
.PARAMETER UserOuPathCommon
[string] The OU Path on the domain to create the users within. Formatted as a filesystem path
by the calling module to synchronize the AD implementation with the AWS Secrets Manager implementation.
.PARAMETER Environment
[string] The target environment for the user accounts.
.PARAMETER TicketNumber
[string] The Jira ticket identifier requesting the new accounts.
.EXAMPLE
New-ServerlessServiceAccountActiveDirectoryUserPair -Cred (Get-AlkamiCredential) `
-UserDataList @(( Get-AlkamiCredential -UserName 'ExampleA' -Password 'ExampleA!1Pass'), ( Get-AlkamiCredential -UserName 'ExampleB' -Password 'ExampleB!1Pass')) `
-UserOuPathCommon '/ServiceAccounts/Dev' `
-Environment 'Dev' `
-TicketNumber 'SYSENG-1234'
#>
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[PSCredential] $Cred,
[Parameter(Mandatory = $true)]
[ValidateCount(2, 2)]
[PSCredential[]] $UserDataList,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $UserOuPathCommon,
[Parameter(Mandatory = $true)]
[ValidateSet('Dev', 'Qa', 'LoadTest', 'Staging', 'Prod', IgnoreCase = $false)]
[string] $Environment,
[Parameter(Mandatory = $true)]
[ValidatePattern("^[a-z]+-\d+$")]
[string]$TicketNumber
)
$logLead = (Get-LogLeadName)
$domainName = "fh.local"
$domainNameDn = Get-DomainNameDistinguishedName $domainName
$serviceAccountGroupOuPath = "OU=ServiceAccounts,OU=${Environment},OU=SecurityGroups,${domainNameDn}"
# Convert the user OU Path into DistinguisedName format
$userOuDnParts = $UserOuPathCommon.Split('/', [System.StringSplitOptions]::RemoveEmptyEntries) | ForEach-Object { "OU=$_" }
[array]::Reverse($userOuDnParts)
$userOuDn = ( "{0},{1}" -f ($userOuDnParts -join ','), $domainNameDn)
Write-Verbose "$logLead : Calculated user OU DistinguishedName as '$userOuDn'"
# Get the required security group for the user or die trying.
$sqlGroupName = "SQL-$Environment-ServerlessApplicationServices"
$sqlGroup = Get-ADGroup -filter { GroupCategory -eq "Security" -and Name -eq $sqlGroupName } `
-SearchBase $serviceAccountGroupOuPath `
-Server $domainName `
-Credential $Cred
if ( $null -eq $sqlGroup ) {
$errorMsg = "$logLead : Unable to find Active Directory group named '$sqlGroupName'; verify AD configuration."
Write-Error $errorMsg
throw $errorMsg
}
# Pre-flight that the users do not exist; die early if they do.
foreach ( $userAcct in $UserDataList ) {
$userName = $userAcct.UserName
$userSearchResults = Get-ADUser -Filter { Name -eq $userName } -Credential $Cred -Server $domainName -SearchBase $userOuDn
if ( $null -ne $userSearchResults ) {
$errorMsg = "$logLead : Found pre-existing user named '$userName' at '$userOuDn'; aborting."
Write-Error $errorMsg
throw $errorMsg
}
}
Write-Host "$logLead : Creating accounts in security group $sqlGroupName"
foreach ($userAcct in $UserDataList) {
$userName = $userAcct.UserName
try {
Write-Verbose "$logLead : Creating User '$userName'"
New-ADUser -AccountPassword $userAcct.Password `
-CannotChangePassword $false `
-ChangePasswordAtLogon $false `
-Credential $Cred `
-Description $TicketNumber `
-Enabled $true `
-Name $userName `
-PasswordNeverExpires $false `
-PasswordNotRequired $false `
-Path $userOuDn `
-SamAccountName $userName `
-Server $domainName `
-UserPrincipalName "$userName@$domainName"
# Add the new account to the SQL group.
Add-ADGroupMember -Identity $sqlGroup -Members $userName
# Add the new account to the Disable Interactive Logon group.
Add-ADGroupMember -Identity "Disable Interactive Logon" -Members $userName
Write-Host "$logLead : Created user '$userName'"
} catch {
$errorMsg = "$logLead : Creation of user '$userName' failed. Error encountered was: [$PSItem]"
Write-Error $errorMsg
throw $errorMsg
}
}
}