ps/Modules/Alkami.DevOps.SystemEngineering/Public/New-GMSAStack.ps1
2023-05-30 22:51:22 -07:00

172 lines
6.3 KiB
PowerShell

function New-GMSAStack {
<#
.SYNOPSIS
Creates new GMSA accounts for ORB.
.DESCRIPTION
Creates new GMSA accounts for ORB. This function creates a new security group (if not pre-existing) and creates a set of gMSA accounts associated with the security group.
Domain Administrator credentials are required to run this function.
.PARAMETER UserPrefix
[string] The name prefix for the gMSA accounts. Must be alphanumeric not exceeding 5 characters in length (e.g. 'pod99').
.PARAMETER TicketNumber
[string] The Jira ticket that is being used for tracking the creation of the gMSA accounts (e.g. 'SYSENG-123456').
.PARAMETER TargetEnvironment
[string] The name of the target environment for the gMSA accounts; used to determine the correct pre-existing AD groups for ORB functionality.
.PARAMETER DomainPostfix
[string] The domain postfix for the domain that the gMSA accounts and the security group will be created in.
.PARAMETER OUPath
[string] The path where the group account will be created in Active Directory.
.PARAMETER GroupName
[string] The name of the security group that the gMSA accounts will be associated with. If not existing, a new group will be created.
The group name must be alphanumeric ending in ' - GMSA'.
.PARAMETER PasswordIntervalDays
[UInt16] The maximum value of days for the password to be valid. Minimum is 30 days; maximum is 365 days.
.Example
New-GMSAStack -UserPrefix "POD99" -TicketNumber "SYSENG-123456"
.Example
New-GMSAStack -UserPrefix "POD99" -TicketNumber "SYSENG-123456" -DomainPostfix "domain.local" -OUPath "OU=ServiceAccounts,OU=Prod,OU=SecurityGroups,DC=domain,DC=local" -GroupName "POD99 - GMSA" -PasswordIntervalDays 365 -TargetEnvironment 'Prod'
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[ValidatePattern("^[a-z0-9]{1,5}$")]
[string]$UserPrefix,
[Parameter(Mandatory = $true)]
[ValidatePattern("^[a-z]+-\d+$")]
[string]$TicketNumber,
[Parameter(Mandatory = $false)]
[ValidateSet('Dev', 'QA', 'Staging', 'Prod')]
[string]$TargetEnvironment = 'Prod',
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string]$DomainPostfix = 'fh.local',
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string]$OUPath = "OU=ServiceAccounts,OU=$TargetEnvironment,OU=SecurityGroups,DC=fh,DC=local",
[Parameter(Mandatory = $false)]
[ValidatePattern("^[a-z0-9]+ - GMSA$")]
[string]$GroupName = "$UserPrefix - GMSA",
[Parameter(Mandatory = $false)]
[ValidateRange(30, 365)]
[uint16]$PasswordIntervalDays = 365
)
$logLead = (Get-LogLeadName)
# Fast fail if user is not a domain admin.
if (!(Test-IsUserDomainAdmin)) {
Write-Error "$logLead : You must have domain administrative privileges to run this command."
return
}
# Search for a pre-existing gMSA security group. If not found, attempt to create the group.
$actualGroupName = $GroupName.ToUpperInvariant()
$adGroup = Get-ADGroup -Filter { Name -eq $actualGroupName }
if ( $null -eq $adGroup ) {
try {
Write-Host "$logLead : Creating group '$actualGroupName' in '$OUPath'"
$adGroup = (New-ADGroup -Name $actualGroupName -SamAccountName $actualGroupName -GroupCategory Security -GroupScope Global -Path $OUPath -Description $TicketNumber -PassThru)
} catch {
Write-Error "$logLead : Creation of group [$actualGroupName] failed. Error encountered was: [$PSItem]"
return
}
} else {
Write-Host "$logLead : Found pre-existing group named $actualGroupName; using this group."
}
# Search for the ORB logs group associated with the target environment. If not found, fail with error.
$orbLogsGroupName = "OrbLogs-$TargetEnvironment"
$orbLogsGroup = Get-ADGroup -Filter { Name -eq $orbLogsGroupName }
if ( $null -eq $orbLogsGroup ) {
Write-Error "$logLead : Unable to find ORB logs AD group named [$orbLogsGroupName]; verify AD configuration."
return
}
# Search for the NYDIG SMB access group associated with the target environment. If not found, fail with error.
$nydigAccessGroupName = "NYDIG-SMB-Access-$TargetEnvironment"
$nydigAccessGroup = Get-ADGroup -Filter { Name -eq $nydigAccessGroupName }
if ( $null -eq $nydigAccessGroup ) {
Write-Error "$logLead : Unable to find NYDIG SMB access AD group named [$nydigAccessGroupName]; verify AD configuration."
return
}
$listOfAccounts = @(
"$UserPrefix.audit$",
"$UserPrefix.bank$",
"$UserPrefix.content$",
"$UserPrefix.core$",
"$UserPrefix.dbms$",
"$UserPrefix.exception$",
"$UserPrefix.micro$",
"$UserPrefix.msgctr$",
"$UserPrefix.multiplx$",
"$UserPrefix.nag$",
"$UserPrefix.notify$",
"$UserPrefix.radium$",
"$UserPrefix.rpsts$",
"$UserPrefix.schedule$",
"$UserPrefix.secmgr$",
"$UserPrefix.stsconf$"
)
Write-Host "$logLead : Creating GMSA accounts in security group $actualGroupName"
foreach ($gmsa in $listOfAccounts) {
if ( $null -eq (Get-ADServiceAccount -Filter { Name -eq $gmsa }) ) {
$gmsaFqdn = "$gmsa.$DomainPostfix"
try {
Write-Verbose "$logLead : Creating User [$gmsa] as [$gmsaFqdn]"
( New-ADServiceAccount -name $gmsa -PrincipalsAllowedToRetrieveManagedPassword $adGroup -DNSHostName $gmsaFqdn -Description $TicketNumber -ManagedPasswordIntervalInDays $PasswordIntervalDays ) | Out-Null
# Add the new account to the ORB logs group.
Add-ADGroupMember -Identity $orbLogsGroup -Members $gmsa
# Add the micro and DBMS accounts to the NYDIG SMB access group.
if ( $gmsa -match '(micro|dbms)') {
Add-ADGroupMember -Identity $nydigAccessGroup -Members $gmsa
}
Write-Host "$logLead : Created [$gmsa]"
} catch {
Write-Warning "$logLead : Creation of user [$gmsa] failed. Error encountered was: [$PSItem]"
}
} else {
Write-Warning "$logLead : Found pre-existing user named $gmsa; check the configuration of this user."
}
}
}