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." } } }