Tag Archives: Domain Controllers

Step-by-Step Guide to work with Group Managed Service Accounts (gMSA) (PowerShell Guide)

In one of my previous blog posts I talked about managed service accounts. Before start on this I really recommend you to read it to have better understanding. It can find on http://www.rebeladmin.com/2018/01/active-directory-managed-service-accounts-powershell-guide/ . As I explained in there one managed service account only can use with one computer. But there are operation requirements which required to share same service account in multiple hosts. Microsoft network load balancer, IIS server farms are good example for these. All the hosts in these server groups required to use same service principal for authentications. Group Managed service accounts provides the same functionalities as managed service accounts but its extend its capabilities to host group levels. This is first introduced with windows server 2012. 

Group managed service accounts got following capabilities,

No Password Management 

Supports to share across multiple hosts

Can use to run schedule tasks (Managed service accounts do not support to run schedule tasks)

It is uses Microsoft Key Distribution Service (KDC) to create and manage the passwords for the gMSA. 

Key Distribution Service was introduced with the windows server 2012. KDS shares a secret (root Key ID) among all the KDS instance in the domain. This value will change periodically. When gMSA required a password, windows server 2012 domain controller will be generated password based on common algorithm which includes root key ID. Then all the hosts which shares the gMSA will query from domain controllers to retrieve the latest password. 

Requirements for gMSA

Windows server 2012 or higher forest level

Widows server 2012 or higher domain member servers (Windows 8 or upper domain joined computers also supported)

64-bit architecture to run PowerShell command to manage gMSA

Tip – gMSA not supported for the Failover Clustering setup. But it is supported for services which is run upon Failover clusters. 

In order to start the configuration process, we need to create KDS root key. This need to run from domain controller with domain admin or enterprise admin privileges. 

Add-KdsRootKey –EffectiveImmediately

Once this is executed, it has default 10 hours’ time limit to replicate it to all the domain controllers and start response to gMSA requests. In testing environment with one domain controller, it can force to remove this waiting time and start to response gMSA immediately. This is NOT recommended for production environment. 

Add-KdsRootKey –EffectiveTime ((get-date).addhours(-10))

After that we can create the first gMSA account. First I have created an AD group “IISFARM” and add all my IIS servers to it. This farm will be using the new gMSA account. 

New-ADServiceAccount "Mygmsa1" -DNSHostName "web.rebeladmin.com" –PrincipalsAllowedToRetrieveManagedPassword "IISFARM"

In above Mygmsa1 is the service account and web.rebeladmin.com is the FQDN of the service. Once its processed we can verify the new account using,

Get-ADServiceAccount “Mygmsa1”


Next step is to install it on server in IIS Farm. It needs active directory PowerShell module to run it. It can be install using RSAT. 

Install-ADServiceAccount -Identity "Mygmsa1"

Tip – If you created the server group recently and add the host, you need to restart the host computer to reflect the group membership. Otherwise above command will fail. 

Once its executed we can test the service account by running,

Test-ADServiceAccount " Mygmsa1"


Similar to managed service account, when you configure the gMSA with any service, leave the password as blank. 

Uninstall Service Account

There can be requirements to remove the managed service accounts. This can be done by executing, 

Remove-ADServiceAccount –identity “Mygmsa1”

Above command will remove the service account Mygmsa1. This is applying to both type of managed service accounts. 

This marks the end of this blog post. Hope this was useful. If you have any questions feel free to contact me on rebeladm@live.com also follow me on twitter @rebeladm to get updates about new blog posts. 

Understanding Group Policy Conflicts

In an organization, there can be many group policies in used. Sometime multiple policies may target same thing. In that case it is important to understand which policy going to win. Group Polices precedence order LSDOU and Group Policy Inheritance decides which policy will win in Active Directory structure.  Let’s look in to this further with an example, 


As per above figure we have two policies inherited to “Users” OU. Policy 01 is Domain linked group policy. Policy 02 is OU linked group policy. Each of the group policy have its own values defined for the three selected settings. Based on the default group policy inheritance, Users OU will have both policies applied. According to LSDOU, Policy 02 will have lowest precedence valve as it is the closest policy for the Users OU. For Password Policy Settings, only Policy 01 has a valve defined. There for even it’s the least preferred group policy, that valve will apply to Users OU. For Windows Firewall Settings, only Policy 02 has a valve. It will also apply to the Users OU. When it comes to the Internet Explorer Settings both policies have values. That makes a conflict. The winning valve of conflicting policy settings will be decided based on LSDOU. There for the wining valve will be from Policy 02

Microsoft allows to change this default policy winning procedure by enforcing policies. When group policy been enforced, it will have the lowest precedence valve regardless where it’s been linked. Another advantage of the enforced policy is, it will apply even OU is blocked inheritance. If domain linked policy been enforced, it will apply to any OU under the domain and it will hold the lowest precedence. If multiple policies been enforced, all of them will take the lowest precedence numbers in order. 

To enforced a policy, load GPMC, right click on the selected group policy and then select “Enforced” option. It will enforce the policy and, change the policy icon with small padlock mark. It allows to identify enforced policies quickly from policy list. 


In above example, Policy 01 been enforced. It is domain linked group policy. In normal circumstances Policy 02 will gets a lowest precedence value when its applies to the Users OU. But when policy been enforced Policy 01 will have the lowest precedence valve. When we look in to winning policy values of the Users OU, For Password Policy Settings it will process the Policy 01 value as it is the only one have value for it. For Windows Firewall Settings, Policy 01 do not have any value defined. So even its been enforced the winning policy setting will be from Policy 02 as it’s the only one have a valve defined. Policy 01 and Policy 02 both have values for Internet Explorer Settings. But enforced Policy 01 is in top of the policy list and winning policy setting will be from it. 

So far, we talked about conflicting policy settings from different level on domain structure. How it will work if it’s in same level? Policies in same level also apply according to precedence order. When policies are in same level the LSDOU process is no use. The winning policy will decide based on its position in the policy list. The order of the list decided based on “Linked Group Policy Objects” list. This list can view using the Linked Group Policy Objects tab in the OU detail window in GPMC


The order of policy in same level can be change using two methods. One method is to enforced the policy. When policy is enforced, it will take the priority from the other policies in the same level. but it will not change the “Link Order” of the policy. The order of the list can change using the up and down buttons in the Linked Group Policy Objects Tab. Link order will match the precedence order of the group policies. 


This marks the end of this blog post. Hope this was useful. If you have any questions feel free to contact me on rebeladm@live.com also follow me on twitter @rebeladm to get updates about new blog posts.

Manage Active Directory Organizational Units (OU) with PowerShell

Similar to any other active directory object, OU structure can manage using Active Directory Administrative Center (ADAC), Active Directory Users and Computers (ADUC) MMC and PowerShell. In this post, I am going to demonstrate how to manage OU structure using PowerShell. 

New Organization Unit can create using New-ADOrganizationalUnit cmdlet. The complete syntax can review using,

Get-Command New-ADOrganizationalUnit -Syntax

As the first step, I am going to create new OU called “Asia” to represent Asia Branch. 

New-ADOrganizationalUnit -Name "Asia" -Description "Asia Branch"

In above command -Description defines description for new OU. When there is no path defined, it will create the OU under the root. We can review the details of the new OU using,

Get-ADOrganizationalUnit -Identity “OU=Asia,DC=rebeladmin,DC=com”


We can add/change values of OU attributes using, 

Get-ADOrganizationalUnit -Identity “OU=Asia,DC=rebeladmin,DC=com” | Set-ADOrganizationalUnit -ManagedBy “Asia IT Team”

Above command will set ManagedBy Attribute to “Asia IT Team”

Tip – When you use ManagedBy attribute, make sure to use existing active directory object for the value. It can be individual user object or group object. If not, command will fail. 

 “Protect from Accidental Deletion” for OU object is nice small safe guard we can apply. It will prevent Accidental OU object deletion. This will be apply by default if you create OU using ADAC or ADUC. 

Get-ADOrganizationalUnit -Identity “OU=Asia,DC=rebeladmin,DC=com” | Set-ADOrganizationalUnit -ProtectedFromAccidentalDeletion $true

As the next step, I am going to create Sub OU under Asia OU Called “Users”.

New-ADOrganizationalUnit -Name "Users" -Path “OU=Asia,DC=rebeladmin,DC=com” -Description “Users in Asia Branch” -ProtectedFromAccidentalDeletion $true

Above command will create OU called Users under path OU=Asia,DC=rebeladmin,DC=com. It is also protected from accidental deletion. 

Now we have OU structure created and next step is move objects to it. for that we can use Move-ADObject cmdlet. 

Get-ADUser “tuser3” | Move-ADObject -TargetPath “OU=Users,OU=Asia,DC=rebeladmin,DC=com”

Above command will find user “tuser3” and move object to OU=Users,OU=Asia,DC=rebeladmin,DC=com

We also can move multiple object to the new OU. 

Get-ADUser -Filter 'Name -like "Test*"' -SearchBase “OU=Users,OU=Europe,DC=rebeladmin,DC=com” | Move-ADObject -TargetPath “OU=Users,OU=Asia,DC=rebeladmin,DC=com”

In above command, It will first search all the user accounts what is starts with “Test” in OU=Users,OU=Europe,DC=rebeladmin,DC=com and then move all objects it found to new OU path. 

Tip – If you have ProtectedFromAccidentalDeletion enable on objects, it will not allow to move object to different OU. It need to remove before object move.

If we need to remove OU object it can be done using Remove-ADOrganizationalUnit cmdlet. 

Remove-ADOrganizationalUnit “OU=Laptops,OU=Europe,DC=rebeladmin,DC=com”

Above command will remove OU=Laptops,OU=Europe,DC=rebeladmin,DC=com Organization Unit. 

This marks the end of this blog post. Hope this was useful. If you have any questions feel free to contact me on rebeladm@live.com also follow me on twitter @rebeladm to get updates about new blog posts.

Azure AD Connect Staging Mode

Azure AD Connect is the tool use to connect on-premises directory service with Azure AD. It allows users to use same on-premises ID and passwords to authenticate in to Azure AD, Office 365 or other Applications hosted in Azure. Azure AD connect can install on any server if its meets following,

The AD forest functional level must be Windows Server 2003 or later. 

If you plan to use the feature password writeback, then the Domain Controllers must be on Windows Server 2008 (with latest SP) or later. If your DCs are on 2008 (pre-R2), then you must also apply hotfix KB2386717.

The domain controller used by Azure AD must be writable. It is not supported to use a RODC (read-only domain controller) and Azure AD Connect does not follow any write redirects.

It is not supported to use on-premises forests/domains using SLDs (Single Label Domains).

It is not supported to use on-premises forests/domains using "dotted" (name contains a period ".") NetBios names.

Azure AD Connect cannot be installed on Small Business Server or Windows Server Essentials. The server must be using Windows Server standard or better.

The Azure AD Connect server must have a full GUI installed. It is not supported to install on server core.

Azure AD Connect must be installed on Windows Server 2008 or later. This server may be a domain controller or a member server when using express settings. If you use custom settings, then the server can also be stand-alone and does not have to be joined to a domain.

If you install Azure AD Connect on Windows Server 2008 or Windows Server 2008 R2, then make sure to apply the latest hotfixes from Windows Update. The installation is not able to start with an unpatched server.

If you plan to use the feature password synchronization, then the Azure AD Connect server must be on Windows Server 2008 R2 SP1 or later.

If you plan to use a group managed service account, then the Azure AD Connect server must be on Windows Server 2012 or later.

The Azure AD Connect server must have .NET Framework 4.5.1 or later and Microsoft PowerShell 3.0 or later installed.

If Active Directory Federation Services is being deployed, the servers where AD FS or Web Application Proxy are installed must be Windows Server 2012 R2 or later. Windows remote management must be enabled on these servers for remote installation.

If Active Directory Federation Services is being deployed, you need SSL Certificates.

If Active Directory Federation Services is being deployed, then you need to configure name resolution.

If your global administrators have MFA enabled, then the URL https://secure.aadcdn.microsoftonline-p.com must be in the trusted sites list. You are prompted to add this site to the trusted sites list when you are prompted for an MFA challenge and it has not added before. You can use Internet Explorer to add it to your trusted sites.

Azure AD Connect requires a SQL Server database to store identity data. By default a SQL Server 2012 Express LocalDB (a light version of SQL Server Express) is installed. SQL Server Express has a 10GB size limit that enables you to manage approximately 100,000 objects. If you need to manage a higher volume of directory objects, you need to point the installation wizard to a different installation of SQL Server.

What is staging mode? 
In a given time, only one Azure AD connect instance can involve with sync process for a directory. But this gives few challenges. 
Disaster Recovery – If the server with Azure AD connect involves in a disaster it going to make impact on sync process. This can be worse if you using features such as password pass-through, single-sing-on, password writeback through AD connect.
Upgrades – If the system which running Azure AD connect needs upgrade or if Azure AD connect itself needs upgrade, will make impact for sync process. Again, the affordable downtime will be depending on the features and organization dependencies over Azure AD connect and its operations. 
Testing New Features – Microsoft keep adding new features to Azure AD connect. Before introduce those to production its always good to simulate and see how it will impact. But if its only one instance, it is not possible to do so. Even you have demo environment it may not simulate same impact as production in some occasions. 
Microsoft introduced the staging mode of Azure AD connect to overcome above challenges. With staging mode, it allows you to maintain another copy of Azure AD connect instance in another server. it can have same config as primary server. It will connect to Azure AD and receive changes and keep a latest copy to make sure the switch over is seamless as possible. However, it will not sync Azure AD connect configuration from primary server. it is engineer’s responsibility to update staging server AD connect configuration, if primary server AD connects config modified. 
Let’s see how we can configure Azure AD connect in staging mode.
1) Prepare a server according to guidelines given in prerequisites section to install Azure AD Connect. 
2) Review current configuration of Azure AD connect running on primary server. you can check this by Azure AD Connect | View current configuration 

3) Log in to server as Domain Administrator and download latest Azure Ad Connect from https://www.microsoft.com/en-us/download/details.aspx?id=47594
4) During the installation, please select customize option. 
5) Then proceed with the configuration according to settings used in primary server. 
6) At the last step of the configuration, select Enable staging mode: When selected, synchronization will not export any data to Ad or Azure AD and then click install
7) Once installation completed, in Synchronization Service (Azure AD Connect | Synchronization Service) we can confirm there is no sync jobs. 
Verify data
As I mentioned before, staging server allows to simulate export before it make as primary. This is important if you implement new configuration changes. 
In order to prepare a staged copy of export, 
1) Go to Start | Azure AD Connect | Synchronization Service | Connectors 
2) Select the Active Directory Domain Services connector and click on Run from the right-hand panel. 
3) Then in next window select Full Import and click OK.
4) Repeat same for Windows Azure Active Directory (Microsoft) 
5) Once both jobs completed, Select the Active Directory Domain Services connector and click on Run from the right-hand panel again. But this time select Delta Synchronization, and click OK.
6) Repeat same for Windows Azure Active Directory (Microsoft)
7) Once both jobs finished, go to Operation tab and verify if jobs were completed successfully. 
Now we have the staging copy, next step is to verify if the data is presented as expected. to do that we need to get help of a PowerShell script.  

    [Parameter(Mandatory=$true, HelpMessage="Must be a file generated using csexport 'Name of Connector' export.xml /f:x)")]
    [Parameter(Mandatory=$false, HelpMessage="Maximum number of users per output file")][int]$batchsize=1000,
    [Parameter(Mandatory=$false, HelpMessage="Show console output")][bool]$showOutput=$false

#LINQ isn't loaded automatically, so force it
[Reflection.Assembly]::Load("System.Xml.Linq, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089") | Out-Null


#XML must be generated using "csexport "Name of Connector" export.xml /f:x"
write-host "Importing XML" -ForegroundColor Yellow

#XmlReader.Create won't properly resolve the file location,
#so expand and then resolve it
$resolvedXMLtoimport=Resolve-Path -Path ([Environment]::ExpandEnvironmentVariables($xmltoimport))

#use an XmlReader to deal with even large files
$result=$reader = [System.Xml.XmlReader]::Create($resolvedXMLtoimport) 
    #create the object placeholder
    #adding them up here means we can enforce consistency
    $objOutputUser=New-Object psobject
    Add-Member -InputObject $objOutputUser -MemberType NoteProperty -Name ID -Value ""
    Add-Member -InputObject $objOutputUser -MemberType NoteProperty -Name Type -Value ""
    Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name DN -Value ""
    Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name operation -Value ""
    Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name UPN -Value ""
    Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name displayName -Value ""
    Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name sourceAnchor -Value ""
    Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name alias -Value ""
    Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name primarySMTP -Value ""
    Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name onPremisesSamAccountName -Value ""
    Add-Member -inputobject $objOutputUser -MemberType NoteProperty -Name mail -Value ""

    $user = [System.Xml.Linq.XElement]::ReadFrom($reader)
    if ($showOutput) {Write-Host Found an exported object... -ForegroundColor Green}

    #object id
    if ($showOutput) {Write-Host ID: $outID}

    #object type
    if ($showOutput) {Write-Host Type: $outType}

    $outDN= $user.Element('unapplied-export').Element('delta').Attribute('dn').Value
    if ($showOutput) {Write-Host DN: $outDN}

    $outOperation= $user.Element('unapplied-export').Element('delta').Attribute('operation').Value
    if ($showOutput) {Write-Host Operation: $outOperation}

    #now that we have the basics, go get the details

    foreach ($attr in $user.Element('unapplied-export-hologram').Element('entry').Elements("attr"))
        $internalvalue= $attr.Element('value').Value

        switch ($attrvalue)
                if ($showOutput) {Write-Host UPN: $internalvalue}
                if ($showOutput) {Write-Host displayName: $internalvalue}
                if ($showOutput) {Write-Host sourceAnchor: $internalvalue}
                if ($showOutput) {Write-Host alias: $internalvalue}
                if ($showOutput) {Write-Host primarySMTP: ($internalvalue -replace "SMTP:","")}
                $objOutputUser.primarySMTP=$internalvalue -replace "SMTP:",""

    $objOutputUsers += $objOutputUser

    Write-Progress -activity "Processing ${xmltoimport} in batches of ${batchsize}" -status "Batch ${outputfilecount}: " -percentComplete (($objOutputUsers.Count / $batchsize) * 100)

    #every so often, dump the processed users in case we blow up somewhere
    if ($count % $batchsize -eq 0)
        Write-Host Hit the maximum users processed without completion... -ForegroundColor Yellow

        #export the collection of users as as CSV
        Write-Host Writing processedusers${outputfilecount}.csv -ForegroundColor Yellow
        $objOutputUsers | Export-Csv -path processedusers${outputfilecount}.csv -NoTypeInformation

        #increment the output file counter

        #reset the collection and the user counter
        $objOutputUsers = $null


    #need to bail out of the loop if no more users to process
    if ($reader.NodeType -eq [System.Xml.XmlNodeType]::EndElement)

} while ($reader.Read)

#need to write out any users that didn't get picked up in a batch of 1000
#export the collection of users as as CSV
Write-Host Writing processedusers${outputfilecount}.csv -ForegroundColor Yellow
$objOutputUsers | Export-Csv -path processedusers${outputfilecount}.csv -NoTypeInformation

Save this as .ps1 on C Drive. 
1) Open PowerShell and type cd "C:\Program Files\Microsoft Azure AD Sync\Bin" (if your install path is different use the relevant path)
2) Then run .\csexport "myrebeladmin.onmicrosoft.com – AAD" C:\export.xml /f:x in here myrebeladmin.onmicrosoft.com -AAD should replace with your Azure AD connector name. This will export config to C:\export.xml
3) Then type .\analyze.ps1 -xmltoimport C:\export.xml in here analyze.ps1 is the script we saved in beginning of this section. 
4) Then it will create CSV file called processedusers1.csv and it’s contain all changes which will sync to Azure AD. 
However, this step is always not required. It can make as primary server without import and verify process. 
How to make it as primary Server?
In order to make staging server as primary server,
1) Go to Start | Azure AD Connect | Azure AD Connect
2) Then click on Configure in next page. 
3) In next page select option Configure staging mode and click Next
4) In next page provide the Azure AD login credentials for directory sync account. 
5) In next window, untick Enable staging mode and click Next
6) In next window select start the synchronization process… and click Configure
This completes the process of promoting staging server in to primary. Hope this was useful and if you have any questions feel free to contact me on rebeladm@live.com also follow me on twitter @rebeladm to get updates about new blog posts.