Useful AD PowerShell Commands

Having worked a lot with Active Directory over the years, I have learned to utilise AD PowerShell commands to help me analyse and assess the state of an Active Directory infrastructure quickly and easily.

I’ve seen many blog/web articles where people have shared complex scripts for gathering information from Active Directory, most of these can be easily achieved without the need for complex scripts. Many can be achieved with single-line PowerShell commands as we will find out below.

Count the Number of Disabled User Accounts in AD

The following command enables you to quickly count the number of disabled user accounts within Active Directory:

Get-ADUser -Filter * -Property Enabled -Server "contoso.com"| Where-Object {$_.Enabled -like “false”} | Measure-Object

Count the Number of Enabled User Accounts in AD

The following command enables you to quickly count the number of enabled user accounts within Active Directory:

Get-ADUser -Filter * -Property Enabled -Server "contoso.com"| Where-Object {$_.Enabled -like “true”} | Measure-Object

Count the Total Number of User Accounts in AD

The following command enables you to quickly count the number of user accounts within Active Directory:

Get-ADUser -Properties * -Filter * -Server "contoso.com"| Measure-Object

Count the Number of Domain Admin Accounts in AD

The following command enables you to quickly count the number of Domain Admin user accounts within Active Directory:

Get-ADGroupMember -Identity "Domain Admins" -Server "contoso.com" | Measure-Object

Count the Number of ‘Active’ Domain Admin Accounts in AD

The following script enables you to count the total number of ‘Active’ Domain Admin user accounts within Active Directory:

$Days = 90
$Date = ((Get-Date).AddDays(-$Days)).Date
$Members = (Get-ADGroupMember -Identity "Domain Admins" -Recursive -Server "contoso.com").DistinguishedName
$i = 0
ForEach ($Member in $Members)
{
$Active = Get-ADUser -Identity $Member -Property LastLogonDate -Server "contoso.com" | Where LastLogonDate -lt $Date | Select SamAccountName,UserPrincipalName,LastLogonDate
ForEach ($Active in $Active)
{
$i = $i + 1
}
}
Write-Host "Number of Active Admins: " $i

Count the Number of ‘Active’ User Accounts in AD

Again, the following script, with some slight modifications, enables you to count the number of ‘Active’ user accounts within Active Directory:

$Age = 90
$When = ((Get-Date).AddDays(-$Age)).Date
$Members = (Get-ADUser -Filter * -Property Enabled -Server "contoso.com" | Where-Object {$_.Enabled -like “true”} ).DistinguishedName
$i = 0
ForEach ($Member in $Members)
{
$Active = Get-ADUser -Identity $Member -Property LastLogonDate -Server "contoso.com" | Where LastLogonDate -lt $When | Select SamAccountName,UserPrincipalName,LastLogonDate
ForEach ($Active in $Active)
{
$i = $i + 1
}
}
Write-Host "Number of Active Users: " $i

Count the Number of Security Groups in AD

The following command enables you to quickly count the number of security groups within Active Directory:

Get-ADGroup -Properties * -Filter * -Server "contoso.com" | Measure-Object

Count the Number of Organisational Units (OU’s) in AD

The following command enables you to quickly count the number of Organisational Units (OU’s) within Active Directory.

Get-ADOrganizationalUnit -Properties * -Filter * -Server "contoso.com" | Measure-Object

Count the Number of GPO’s in AD

The following command enables you to quickly count the number of Group Policy Objects (GPO’s) within Active Directory.

Get-GPO -all -Server "contoso.com" | Measure-Object

Get Active Directory Forest Configuration

The following command enables you to quickly overview the Active Directory Forest Configuration.

Get-ADForest -Server "contoso.com"

Get Active Directory Domain Configuration

The following command enables you to quickly overview the Active Directory Domain configuration.

Get-ADDomain -Server "contoso.com"

ADFS Error When Adding a RP Trust

I run into an error that was being thrown when I was attempting to add a new Relying Party Trust for one of my customers. When executing the following PowerShell code:

Add-AdfsRelyingPartyTrust -Name "My App Name" `
-Notes "My App Notes" `
-MetadataUrl “https://somemetadataurl.com/saml”

I received the following error:

Add-AdfsRelyingPartyTrust : The request was aborted: Could not create SSL/TLS secure channel.
At line:1 char:1
+ Add-AdfsRelyingPartyTrust -Name "My App" -Notes "My App Notes"...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Add-AdfsRelyingPartyTrust], WebException
+ FullyQualifiedErrorId : The request was aborted: Could not create SSL/TLS secure channel.,Microsoft.IdentityServer.Management. 
Commands.AddRelyingPartyTrustCommand

After checking over the PowerShell CMDLET and some scouring of the internet I managed to find a solution which involved editing the registry to force .NET applications to use stronger cryptography.

I changed the following registry key values as instructed:

HKEY_LOCAL_MACHINE\SOFTWARE\
   \Microsoft\.NETFramework\\<version>
      SchUseStrongCrypto = (DWORD): 00000001

HKEY_LOCAL_MACHINE\SOFTWARE\
    Wow6432Node\Microsoft\\.NETFramework\\<version>
       SchUseStrongCrypto = (DWORD): 00000001

After making these changes, a reboot of the servers was required to ensure that the new registry values were picked-up correctly by all .NET applications on the server (including ADFS).

After the reboot had completed, I attempted to execute my PowerShell code mentioned earlier, this time the code executed without error and my new Relying Party Trust was created.

 

DNS Architecture

DNS Architecture

The following article describes and depicts the recommended architecture for integrated DNS with Active Directory. It is highly recommended that Active Directory Integrated DNS be deployed within enterprise networks that utilise Active Directory as the authoritative authorisation and authentication mechanism, the following diagram builds on the standard Active Directory Integrated DNS architecture to provide higher levels of DNS resiliency and security.

The following solution doesn’t account for deployment of DNSSEC. DNSSEC is a large topic, something that I hope to document in a future article.

Walking through the above diagram from bottom to top:

  1. The domain client devices are configured (using group policy) for a Primary and Secondary DNS settings pointing to the main Active Directory Integrated DNS Servers. In this diagram, Domain Controller 1 is the Primary and Domain Controller 2 is the secondary DNS server.
  2. TLD Root Hints have been removed from the DNS Service on the Domain Controllers. The Domain Controller DNS Service is configured to Forward all “unknown” DNS requests to DNS Server 1 and/or DNS Server 2, respectively.
  3. DNS Servers 1 and 2 have had their TLD Root Hints removed from the DNS Service configuration. Both DNS servers are configured with Forwarders to the ISP DNS Services.
  4. There are three layers to the network security boundaries for the depicted solution. Campus being the location for client devices and campus infrastructure. Intranet being the internal server boundary. Perimeter being the internet facing services boundary. Finally, internet being the far edge of the network boundary for the depicted enterprise infrastructure.

Closing

In this article we briefly examined the recommended architecture for DNS within an Active Directory Integrated DNS Environment.

ADFS Authentication Workflow

In this article we take a look at the Active Directory Federation Services (ADFS) Authentication Workflow that occurs when a client attempts to access a third-party federated web service.

The following diagram depicts the authentication workflow for ADFS when accessing third-party federated web services (applications).

CN_ADFS-Authentication-Workflow

Walking through the above diagram step-by-step:

  1. The user (client) accesses the web URL for the Fabrikam Web Server using their client web browser. The client doesn’t have an authentication token and must be federated to access this application.
  2. The website issues a HTTP redirect to the user’s web browser, directing them to visit the Fabrikam federation services URL.
  3. The user’s browser accesses the Fabrikam Federation Service.
  4. The Fabrikam federation service attempts to resolve the URL for Contoso Identity Provider (IDP) and issues an HTTP redirect to the user’s browser.
  5. The user’s browser accesses the Contoso ADFS server.
  6. The user initialises authentication with the Contoso ADFS server and is issued with a token signed by the ADFS server’s Token Signing Certificate. The ADFS service issues a HTTP redirect to the user’s browser, directing them back to the Fabrikam ADFS service.
  7. The user’s browser presents the token to the Fabrikam Federation service.
  8. The Fabrikam Federation service validates the token and issues the user with a new token which is valid for Fabrikam web service. The ADFS service issues a HTTP redirect to the Fabrikam web server.
  9. The user accesses the Fabrikam Web Server and presents the token which was issued by the Fabrikam ADFS service. The web server validates the token and authorises the user to access the application.

Closing

In this article we looked at the workflow process that occurs each time a user attempts to access an ADFS federated web service.

 

ADFS: WIA Supported User Agents

One of my customers had issues with SSO not working as expected. Upon investigation I found that this was because additional configuration was required in order to enable the SSO capabilities and support for Microsoft Edge and Mozilla Firefox web browsers. The following process enables you to modify the WIA Supported User Agents in ADFS which will enable SSO for various web browsers.

1. First we check the current configuration of the WIASupportedUserAgents properties using Get-ADFSProperties cmdlet as shown below:

1
Get-ADFSProperties | Select -ExpandProperty WIASupportedUserAgents

The following output was recorded for the existing configuration of WIASupportedUserAgents properties.

MSAuthHost/1.0/In-Domain
MSIE 6.0
MSIE 7.0
MSIE 8.0
MSIE 9.0
MSIE 10.0
Trident/7.0
MSIPC
Windows Rights Management Client
MS_WorkFoldersClient
=~Windows\s*NT.*Edge

2. Next we need to add support for Mozilla Firefox web browsers using the Set-ADFSProperties cmdlet as shown below:

1
Set-ADFSProperties -WIASupportedUserAgents (((Get-ADFSProperties).WIASupportedUserAgents)+'Mozilla/5.0')

3. Finally, add the configuration to support SSO for the Microsoft Edge web browsers using the Set-ADFSProperties cmdlet:

1
2
3
4
5
Set-ADFSProperties -WIASupportedUserAgents (((Get-ADFSProperties).WIASupportedUserAgents)+'Edge/12')
Set-ADFSProperties -WIASupportedUserAgents (((Get-ADFSProperties).WIASupportedUserAgents)+'Edge/13')
Set-ADFSProperties -WIASupportedUserAgents (((Get-ADFSProperties).WIASupportedUserAgents)+'Edge/14')
Set-ADFSProperties -WIASupportedUserAgents (((Get-ADFSProperties).WIASupportedUserAgents)+'Edge/15')
Set-ADFSProperties -WIASupportedUserAgents (((Get-ADFSProperties).WIASupportedUserAgents)+'Edge/16')

4. After applying the above changes, restart the ADFS Service on all ADFS Servers using:

1
Restart-Service adfssrv

5. After the services have been restarted, check that the configuration has applied successfully and test that the ADFS IDP Initiated Sign-on is fully operational.

1
Get-ADFSProperties | Select -ExpandProperty WIASupportedUserAgents

The following output was recorded for the configuration post-changes.

MSAuthHost/1.0/In-Domain
MSIE 6.0
MSIE 7.0
MSIE 8.0
MSIE 9.0
MSIE 10.0
Trident/7.0
MSIPC
Windows Rights Management Client
MS_WorkFoldersClient
=~Windows\s*NT.*Edge
Mozilla/5.0
Edge/12
Edge/13
Edge/14
Edge/15
Edge/16

From the above, we can note that support for the additional browsers has been added to the configuration as expected.

ADFS: Enable Sensible Logging

To enable sensible logging, perform the following steps.

1
AuditPol.exe /set /subcategory:”Application Generated” /failure:enable /success:enable

ADFS: Enable End-User Password Change Functionality

To enable the capability for users to be able to change their passwords via ADFS login page, the following command will enable the functionality.

1
2
3
Enable-ADFSEndPoint –TargetAddressPath “/adfs/portal/updatepassword/”
Set-ADFSEndPoint “/adfs/portal/updatepassword/” –Proxy:$true
Restart-Service ADFSSrv -Force

ADFS: Increase the Validity of ADFS Generated Certificates

To increase the validity period for ADFS Self-Generated Certificates for the Token-Signing and Token-Decrypting certificates, execute the command below to set them to three years.

1
2
Set-ADFSProperties –CertificateDuration 1095
Update-ADFSCertificate -Urgent

ADFS: Enable Automatic Certificate Rollover

To enable Automatic Certificate Rollover feature for  ADFS Token-Signing and Token-Decrypting certificates execute the following powershell command.

1
2
Set-ADFSProperties –AutoCertificateRollover $true
Update-ADFSCertificate -Urgent