Events
29 Apr, 2 pm - 30 Apr, 7 pm
Join the ultimate Windows Server virtual event April 29-30 for deep-dive technical sessions and live Q&A with Microsoft engineers.
Sign up nowThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Starting with AD FS in Windows Server 2016, you can run the cmdlet Install-AdfsFarm as a local administrator on your federation server, provided your Domain Administrator has prepared Active Directory. The script below in this article can be used to prepare AD. The steps are as follows:
Run the following as domain administrator
PS:\>$adminConfig=(.\New-AdfsDkmContainer.ps1 -ServiceAccount contoso\fssvcacct -AdfsAdministratorAccount contoso\localadmin)
$adminconfig.DkmContainerDN
CN=9530440c-bc84-4fe6-a3f9-8d60162a7bcf,CN=ADFS,CN=Microsoft,CN=Program Data,DC=contoso,DC=com
On the federation server as a local admin, execute the following in an elevated PowerShell command window.
First, if the federation server admin is not using the same PowerShell session as the above domain admin, re-create the adminConfig object using the output from the above.
PS:\>$adminConfig = @{"DKMContainerDn"="CN=9530440c-bc84-4fe6-a3f9-8d60162a7bcf,CN=ADFS,CN=Microsoft,CN=Program Data,DC=contoso,DC=com"}
Next, create the farm:
PS:\>$svcCred = (get-credential)
PS:\>$localAdminCred = (get-credential)
PS:\>Install-AdfsFarm -CertificateThumbprint 270D041785C579D75C1C981DA0F9C36ECFDB65E0 -FederationServiceName "fs.contoso.com" -ServiceAccountCredential $svcCred -Credential $localAdminCred -OverwriteConfiguration -AdminConfiguration $adminConfig -Verbose
PS:\>$adminConfig=(.\New-AdfsDkmContainer.ps1 -ServiceAccount contoso\FsGmsaAcct$ -AdfsAdministratorAccount contoso\localadmin)
$adminconfig.DkmContainerDN
CN=8065f653-af9d-42ff-aec8-56e02be4d5f3,CN=ADFS,CN=Microsoft,CN=Program Data,DC=contoso,DC=com
On the federation server as a local admin, execute the following in an elevated PowerShell command window.
First, if the federation server admin is not using the same PowerShell session as the above domain admin, re-create the adminConfig object using the output from the above.
PS:\>$adminConfig = @{"DKMContainerDn"="CN=8065f653-af9d-42ff-aec8-56e02be4d5f3,CN=ADFS,CN=Microsoft,CN=Program Data,DC=contoso,DC=com"}
Next, create the farm: Note that the local computer account and the AD FS admin account need to be granted retrieve password and delegate to account rights on the gMSA.
PS:\>$localAdminObj = Get-ADUser "localadmin"
PS:\>$adfsNodeComputerAcct = Get-ADComputer "contoso_adfs_node"
PS:\>Set-ADServiceAccount -Identity fsgmsaacct -PrincipalsAllowedToRetrieveManagedPassword @( Add=$localAdminObj.SID.Value, $adfsNodeComputerAcct.SID.Value) -PrincipalsAllowedToDelegateToAccount @( Add=$localAdminObj.SID.Value, $adfsNodeComputerAcct.SID.Value)
PS:\>$localAdminCred = (Get-Credential)
PS:\>Install-AdfsFarm -CertificateThumbprint 270D041785C579D75C1C981DA0F9C36ECFDB65E0 -FederationServiceName "fs.contoso.com" -Credential $localAdminCred -GroupServiceAccountIdentifier "contoso\fsgmsaacct$" -OverwriteConfiguration -AdminConfiguration $adminConfig
The following PowerShell script can be used to accomplish the examples above
[CmdletBinding(SupportsShouldProcess=$true)]
param (
[Parameter(Mandatory=$True)]
[string]$ServiceAccount,
[Parameter(Mandatory=$True)]
[string]$AdfsAdministratorAccount
)
$ServiceAccountSplit = $ServiceAccount.Split("\");
if ($ServiceAccountSplit.Length -ne 2)
{
Write-error "Specify the ServiceAccount identifier in 'domain\username' format"
exit 1
}
$AdfsAdministratorAccountSplit = $AdfsAdministratorAccount.Split("\");
if ($AdfsAdministratorAccountSplit.Length -ne 2)
{
Write-error "Specify the AdfsAdministratorAccount identifier in 'domain\username' format"
exit 1
}
#######################################
## Verify AD module is installed
#######################################
$m = "ActiveDirectory"
if (Get-Module | Where-Object {$_.Name -eq $m})
{
write-verbose "Module $m is already imported."
}
else
{
if (Get-Module -ListAvailable | Where-Object {$_.Name -eq $m})
{
Import-Module $m -Verbose
}
else
{
write-error "Module $m was not imported, install the Active Directory RSAT package and retry."
exit 1
}
}
push-location ad:
#######################################
## Generate random DKM container name
## The OU Name is a randomly generated Guid
#######################################
[string]$guid = [Guid]::NewGuid()
write-verbose ("OU Name" + $guid)
$ouName = $guid
$initialPath = "CN=Microsoft,CN=Program Data," + (Get-ADDomain).DistinguishedName
$ouPath = "CN=ADFS," + $initialPath
$ou = "CN=" + $ouName + "," + $ouPath
#######################################
## Create DKM container and assign default ACE which allows AD FS admin read access
#######################################
if ($pscmdlet.ShouldProcess("$ou", "Creating DKM container and assigning access"))
{
Write-Verbose ("Creating organizational unit with DN: " + $ou)
if ($AdfsAdministratorAccount.EndsWith("$"))
{
write-verbose "AD FS administrator account passed with $ suffix indicating a computer account"
$userNameSplit = $AdfsAdministratorAccount.Split("\");
$strSID = (Get-ADServiceAccount -Identity $userNameSplit[1]).SID
}
else
{
write-verbose "AD FS administrator account is a standard AD user"
$objUser = New-Object System.Security.Principal.NTAccount($AdfsAdministratorAccount)
$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
}
if ($null -eq (Get-ADObject -Filter {distinguishedName -eq $ouPath}))
{
Write-Verbose ("First creating initial path " + $ouPath)
New-ADObject -Name "ADFS" -Type Container -Path $initialPath
}
$acl = get-acl -Path $ouPath
[System.DirectoryServices.ActiveDirectorySecurityInheritance]$adSecInEnum = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::All
$ace1 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"GenericRead","Allow",$adSecInEnum
$acl.AddAccessRule($ace1)
set-acl -Path $ouPath -AclObject $acl
New-ADObject -Name $ouName -Type Container -Path $ouPath
}
#######################################
## Grant the following permission to the service account
# Read
# Create Child
# Write Owner
# Delete Tree
# Write DACL
# Write Property
#######################################
if ($ServiceAccount.EndsWith("$"))
{
write-verbose "service account passed with $ suffix indicating a gMSA"
$userNameSplit = $ServiceAccount.Split("\");
$strSID = (Get-ADServiceAccount -Identity $userNameSplit[1]).SID
}
else
{
write-verbose "service account is a standard AD user"
$objUser = New-Object System.Security.Principal.NTAccount($ServiceAccount)
$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
}
if ($pscmdlet.ShouldProcess("$strSID", "Granting GenericRead, CreateChild, WriteOwner, DeleteTree, WriteDacl and WriteProperty"))
{
[System.DirectoryServices.ActiveDirectorySecurityInheritance]$adSecInEnum = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::All
$ace1 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"GenericRead","Allow",$adSecInEnum
$ace2 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"CreateChild","Allow",$adSecInEnum
$ace3 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"WriteOwner","Allow",$adSecInEnum
$ace4 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"DeleteTree","Allow",$adSecInEnum
$ace5 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"WriteDacl","Allow",$adSecInEnum
$ace6 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"WriteProperty","Allow",$adSecInEnum
$acl = get-acl -Path $ou
$acl.AddAccessRule($ace1)
$acl.AddAccessRule($ace2)
$acl.AddAccessRule($ace3)
$acl.AddAccessRule($ace4)
$acl.AddAccessRule($ace5)
$acl.AddAccessRule($ace6)
$acl.SetOwner($strSID)
set-acl -Path $ou -AclObject $acl
}
#######################################
## Grant the following permission to the adfs admin account
# Read
# Create Child
# Write Owner
# Delete Tree
# Write DACL
# Write Property
#######################################
if ($AdfsAdministratorAccount.EndsWith("$"))
{
write-verbose "AD FS administrator account passed with $ suffix indicating a gMSA"
$userNameSplit = $AdfsAdministratorAccount.Split("\");
$strSID = (Get-ADServiceAccount -Identity $userNameSplit[1]).SID
}
else
{
write-verbose "AD FS administrator account is a standard AD user"
$objUser = New-Object System.Security.Principal.NTAccount($AdfsAdministratorAccount)
$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
}
if ($pscmdlet.ShouldProcess("$strSID", "Granting GenericRead, CreateChild, WriteOwner, DeleteTree, WriteDacl and WriteProperty"))
{
[System.DirectoryServices.ActiveDirectorySecurityInheritance]$adSecInEnum = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::All
$ace1 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"GenericRead","Allow",$adSecInEnum
$ace2 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"CreateChild","Allow",$adSecInEnum
$ace3 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"WriteOwner","Allow",$adSecInEnum
$ace4 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"DeleteTree","Allow",$adSecInEnum
$ace5 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"WriteDacl","Allow",$adSecInEnum
$ace6 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $strSID,"WriteProperty","Allow",$adSecInEnum
$acl = get-acl -Path $ou
$acl.AddAccessRule($ace1)
$acl.AddAccessRule($ace2)
$acl.AddAccessRule($ace3)
$acl.AddAccessRule($ace4)
$acl.AddAccessRule($ace5)
$acl.AddAccessRule($ace6)
$acl.SetOwner($strSID)
set-acl -Path $ou -AclObject $acl
$adminConfig = @{"DKMContainerDn"=$ou}
Write-Output $adminConfig
}
pop-location
Events
29 Apr, 2 pm - 30 Apr, 7 pm
Join the ultimate Windows Server virtual event April 29-30 for deep-dive technical sessions and live Q&A with Microsoft engineers.
Sign up nowTraining
Learning path
Administer Active Directory Domain Services AZ-1008 - Training
This learning path helps prepare you for the APL-1008 Administer Active Directory Domain Services modern credential. You'll learn how to create, deploy, and maintain an Active Directory Domain Services environment. (AZ-1008)
Certification
Microsoft Certified: Identity and Access Administrator Associate - Certifications
Demonstrate the features of Microsoft Entra ID to modernize identity solutions, implement hybrid solutions, and implement identity governance.