Active Directory – Securely Set Local Account Passwords

How it works

A token is generated for a supplied account with the desired password. 

Example of a token: k8vVeIYZeI+6rkvlvw8eLOEnHK2yTcBfHQP4UEZrCgigcagy7+qt969LISkmHH/7CS5KfVWLEZh8cZMzCkVYGw==

This token (an AES-256 encrypted version of the username and the password) is passed to the SecurelySetPassword tool which is executed at start-up via an Active Directory Group Policy.

The token is decrypted and used to set the password for the specified account to the desired password.

Step 1: Download

Download SecurelySetPassword tool

Step 2: Create and Test Token

1) Run SecurelySetPassword.exe USERNAME PASSWORD (Note how the generated token is different on each run, this is because the value is salted for added security)

2) Copy token. It will be used in the implementation steps

3) To test the token, run SecurelySetPassword.exe TOKEN (Note for a successful test the user needs to exists)

Step 3: Copy SecurelySetPassword.exe to a network share

Copy SecurelySetPassword.exe to a network share accessible by all users (such as NETLOGON share)

Step 4: Implement Active Directory Group Policy

1) Start Microsoft Group Policy Management Console (GPMC.msc

2) Create and link a new Group Policy with the desired scope

3) Browse to Computer Configuration > Preferences > Windows Settings > Files and add a new file object

4) Set the Source files(s) path to the location of SecurelySetPassword.exe (\\ittelligence.com\NETLOGON\Software\SecurelySetPassword\SecurelySetPassword.exe in my case)

5) Set the Destination file to %CommonAppdataDir%\SecurelySetPassword\SecurelySetPassword.exe

6) Browse to Computer Configuration > Preferences > Control Panel Settings > Scheduled Tasks and add a new scheduled task object 

7) On the Triggers tab create new trigger and set to At startup

8) On the Actions tab create a Start a program action to %CommonAppdataDir%\SecurelySetPassword\SecurelySetPassword.exe with token as argument

I hope you found this tutorial useful. You are encouraged to ask questions, report any bugs or make any other comments about it below.

Active Directory – Securely Set Local Account Passwords

Prerequisites: The following assumptions have been made in this tutorial. Readers should have a basic working knowledge of Microsoft Active Directory, SQL Server and Visual Studio software.

Step 1:  Create ACTIVE DIRECTORY SERVICE ACCOUNT

Create an Active directory service account with password reset as well as user account unlock permissions.

Step 2:  Download Visual Studio Project

1) Download the provided source zip file by clicking this link  (See below)

2) Extract and open the project in Visual Studio

Step 3:  Create database

Note: The basic steps for creating the database are listed below. Explaining MS SQL functionality is beyond the scope of this article, but I am happy to answer any questions in the comments section below.

1) From the Open Project in Visual Studio, open ModelSSPR.edmx

2) Right-click on white-space on the diagram page

3) Then select Generate Database from Model as shown below

4) Save the SQL script and use it on Microsoft SQL Server to build the database schema

5) Create an MS SQL user and grant it DB owner rights

step 4:  Modify config file

1) From the open project in Visual Studio

2) Replace the ADConnectionString connection string with the Active Directory LDAP string for the domain used in the Create Active Directory Service Account (Step 1)

3) Replace the SSPREntities connection string with the connection string of the database used in the Create Database (Step 3)

4) Configure ADMembershipProvider to the account created in the Create Active Directory Service Account (Step 1)

5) Replace the appSettings values with the correct information for the domain and account used in the Create Active Directory Service Account (Step 1)

Step 5:  Publish Site

Please Note: Explaining Visual Studio publishing is beyond the scope of this article, but I am happy to answer any questions in the comments section below.

1) From the open project in Visual Studio

2) Publish site with the Visual Studio Publishing wizard

step 6:  Testing Site

Registering password hints

1) Browse to site published in Publish Site (Step 5)

2) Click on Log in

3) Specify the Username and Password for the account to register for self-service password reset.

Note: Username must be in UPN format

4) Create password hints by adding questions and answers

Note: At least four hints need to be specified to utilize the self-service password reset function.

Self-Service Password Reset Request

1) Browse to the site published in the Publish Site (Step 5)

2) Click on Reset Password

3) Enter the Username for the account to reset the password for as shown below

Note: Username must be in UPN format

4) Enter answers to the security questions and provide new password

Note: Three random questions will be selected out of the hints configured

5) Click Reset Password

6) If the password was successfully reset, the following screen will display

I hope you found this tutorial useful. You are encouraged to ask questions, report any bugs or make any other comments about it below.

UserResourceCleanup

INTRODUCTION

A GPO exist that can be configured to automatically delete old user profiles and a process such as CircularLogArchivercan be used to clean up log or old data but what about user data?

UserResouceCleanup can take care of this by monitoring the user data folders and Active Directory.

CONFIGURING USERRESOURCECLEANUP

a) Download and extract UserResourceCleanup.zip (here is VirusTotal scan) to a folder of your choice on the computer which it will be scheduled to run on.

b) Run Configurator.exe (Configurator Editor).

c) On the Encrypt tab, enter the password for the account that will be performing the automated placement task. Encrypt it with key bRK92kDpCqpnPMEtFp1cdJXixgqOqSKFUZ and record encrypted password

d) On the Settings tab, enter the domain information, connection username and the encrypted password recorded in step c. Configure UserNameMatch to a RegEx query that will match user account format. If you do not have a specific format, use .*

e) On the UserFolderLocations tab, specify folders to monitor to redundant user data

f) On the UsersToSkip tab, specify user folders to skip

g) Save configuration files

h) Schedule UserResourceCleanup.ConsoleApp.exe as a scheduled tasks

CONCLUSION

Using this process will keep recover space by removing old/redundant user data, just make sure that you have backups to cheap/slower storage in case you need to recover data.

Automated object placement using AutoAD

IMPLEMENTATION

1) Computer Description Update Process

a) Delegation

To be able to update computer descriptions you need to delegate rights.

Add the following permissions to Active Directory either to the root of the domain or any other Organizational Unit. You would add it to an Organizational Unit if you only want to use this process for some computers

b) Powershell Script

Below is the Powershell script used to update the computer description.

It is important to note that you should not change the format of the message if you are planning to use my automated object placement process.

This script will be used within a group policy in step c

try
    {
        # Get current user name
        $strUserName = $env:username;

        # Get current computer name
        $strComputerName = $env:computername;

        $objADSystemInfo = New-Object -ComObject ADSystemInfo;
        $objType = $objADSystemInfo.GetType();

        # Get current site name
        $strSiteName = $objType.InvokeMember('SiteName', 'GetProperty', $null, $objADSystemInfo, $null);

        # Get current date and time
        $strLogonDate = Get-Date -Format "dd-MM-yyyy HH:mm:ss";

        # Build message
        $strMessage = "$($strUserName) logged in on $($strLogonDate) at $($strSiteName) site";

        # Get computer object from Active Directory
        $strFilter = "(&(objectCategory=Computer)(name=$strComputerName))"
        $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
        $objSearcher.Filter = $strFilter
        $objPath = $objSearcher.FindOne()
        $objComputer = $objPath.GetDirectoryEntry()

        # Update computer object description with message in Active Directory
        $objComputer.InvokeSet("Description", $strMessage)
        $objComputer.CommitChanges()
    }
catch
    {
        throw
    }

c) Group Policy Object

Create a GPO and link it to the root of a domain or Organizational Unit used in step a

Add the PowerShell script from step b as a User Logon script

d) Result

After these steps, notice how the computer descriptions are automatically populated once the users log on to their computers

2) AutoAD

a) Download and extract AutoAD.zip (here is VirusTotal scan) to a folder of your choice on the computer which it will be scheduled to run on.

b) Run Configurator.exe (Configurator Editor).

c) On the Encrypt tab, enter the password for the account that will be performing the automated placement task. Encrypt it with key 2xCJvezFBYWQPBeHy7USdajK55M8skww and record encrypted password

d) On the Settings tab, enter the domain information, connection user name and the encrypted password recorded in step 2c.

Specify which objects AutoAD should create automatically

e) Specify Active Directory information. The format for these are Subnet/Bit Mask|AD Site Name|Computer DN|User DN

Subnet/Bit Mask: The subnet and mask (in bit format) for the specific entry

AD Site: The Active Directory site to which the subnet belongs

Computer DN: The distinguished name of the organizational unit where to move computers to for computer objects in this subnet

User DN: The distinguished name of the organizational unit where to move users to for user objects in this subnet

Please Note: Ensure that you do not allow users/admins to gain any additional permissions by moving users from one container to another. The reason for this is that a user move might be forced to an incorrect OU if descriptions are tampered with. 

f) Specify any user DNs that should be skipped

g) Specify any computer DNs that should be skipped

DEMO EXECUTION

After implementing ComputerDescriptionUpdate.ps1 notice how computer descriptions are automatically updated

AutoAD.exe output

Sites and subnets automatically created by AutoAD

Organizational Units automatically created by AutoAD

Object placement (example 1)

Object placement (example 2)

Object placement (example 3)

Object placement (example 4)

CONCLUSION

Using this process will keep Active Directory organized and objects in the correct Organizational Units

Active Directory Password Reset Tool

BENEFITS

  • Sets a unique, secure password on each password reset
  • Helpdesk employee users do not need to use or install RSAT (at least not for those only resetting passwords)
  • End-users do not get passwords such as Password1 or Company1 and continue with this bad practice by continuing with passwords such as Password2 or Company2

IMPLEMENTATION

1) Download and extract PasswordResetTool.zip (here is VirusTotal scan) to a folder of your choice.

2) Run Configurator.exe (Configurator Editor).

a) On the Settings tab, enter the FQDN and NetBIOS for the domain on for which Password Reset Tool needs to reset passwords for

b) Specify length that passwords should be reset to for user and administrator accounts

c) Save the configuration file

DEMO EXECUTION

Once configuration has been completed, the Password Reset Tool can be executed

Once the Reset Password button is pressed, the specified user account password is reset to a pronounceable, random password

After the process, the connection password and user field are cleared.

RELEVANT CODE

DirectoryEntry directionEntry = new DirectoryEntry(domainPath, domainName + "\\" + connectionUserName, @connectionPassword);
    if (directionEntry != null)
    {
        DirectorySearcher search = new DirectorySearcher(directionEntry);
        search.Filter = "(SAMAccountName=" + userToReset + ")";
        SearchResult result = search.FindOne();
        if (result != null)
        {
            DirectoryEntry userEntry = result.GetDirectoryEntry();
            if (userEntry != null)
            {
                userEntry.Invoke("SetPassword", new object[] { password });
                userEntry.Properties["pwdLastSet"].Value = 0;
                userEntry.Properties["LockOutTime"].Value = 0x0000;
                userEntry.CommitChanges();
            }
        }
    }
    return password;

CONCLUSION

Using initial secure and unique passwords during reset contributes to a far more secure environment.

Active Directory Cleanup Tool (ADCleanup)

INTRODUCTION

ADCleanup is my implementation of a set-and-forget Active Directory cleanup tool. Once this tool is implemented correctly, you never need to worry about dormant accounts ever again.

IMPLEMENTATION

1) Download and extract ADCleanup.zip (here is VirusTotal scan) to a folder of your choice, saved on the computer on which it will be scheduled to run.

2) Create a location in Active Directory to store inactive user accounts and record the distinguished name (DN).

3) Create a location in Active Directory to store inactive computer accounts and record the distinguished name (DN).

4) Run Configurator.exe (Configurator Editor).

a) On the Encrypt tab, enter the password for the account that will be performing the cleanup task. Encrypt it with key 9hOK7AtlGOCRyBtBdhF9pnTQuk8ES176 and record encrypted password

b) On the Settings tab, enter the fully qualified domain name, cleanup account user name and the encrypted password recorded in step 4a

c) Set userCleanup to true to enable the process to clean up user accounts. Set user cleanup parameters

d) Set userDisabledOUto value recorded in step 2

e) Set computerCleanup to true to enable the process to clean up user accounts. Set computer cleanup parameters

f) Set computerDisabledOU to value recorded in step3

g) On the userExcludedDNs tab, specify any distinguished name of an organizational unit that should be excluded from the cleanup process  (+ or INS to add, – or DEL to delete, Enter or double-click to edit)

g) On the computerExcludedDN stab, specify any distinguished name of an organizational unit that should be excluded from the cleanup process (+ or INS to add, – or DEL to delete, Enter or double-click to edit)

h) Schedule ADCleanup.exe to execute via a scheduled task. Upon every execution, the tool will clean up user and computer objects as per your configuration

CONCLUSION

Using this process, (or one similar) will keep Active Directory clean from the unused computer and user objects, and increases server security in the process.

MoveSysvol – Automate the relocation of the Sysvol folder (DFSR Version)

MoveSysvol (DFSR version) automated by Shaun Vermaak is a batch to automatically relocate the Sysvol folder as per https://technet.microsoft.com/en-us/library/cc816594(v=ws.10).aspx

The following must be in the working folder or in path:
MoveSysvol.bat
SetDFSR.vbs
sysvol.inf

UPDATE: Please ensure that all DCs are in the default Domain Controllers OU

Usage: MoveSysvol.bat OLDSYSVOLPATH NEWSYSVOLPATH DOMAINFQDN
Example: MoveSysvol.bat C:WindowsSYSVOL D:SYSVOL TESTDOMAIN.COM

Attachment(s):

Test Passwords Against Active Directory User

Tool to test password against Active Directory user. Multiple passwords can be tested by ; separating them

Usage: CheckCredentials.exe FQDN USERNAME PASSWORD1[;PASSWORD2;PASSWORD3..]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.DirectoryServices.AccountManagement;
using System.Diagnostics;

namespace CheckCredentials
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.GetUpperBound(0) == 2)
            {
                foreach (string password in args[2].Split(';'))
                {
                    using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, args[0]))
                    {

                        // validate the credentials
                        bool isValid = pc.ValidateCredentials(args[1], password);

                        if (isValid)
                        {
                            Console.WriteLine(@"{1}@{0} has password {2}", args[0], args[1], password);
                        }

                    }
                }
            }
            else
            {
                Console.WriteLine("Usage:{0} FQDN USERNAME PASSWORD1[;PASSWORD2;PASSWORD3..]", Process.GetCurrentProcess().ProcessName + ".exe");
            }
        }
    }
}

Attachment(s):

View Shaun Vermaak's profile on LinkedIn

VBS implementation of REG.exe for use in GPOs

Usage: REG.vbs /Action:ADD|/Action:DELETE /Key:REGISTRYKEY [/Value:REGISTRYVALUE] [/DATA:REGISTRYVALUEDATA] [/TYPE:REGISTRYVALUETYPE]

Examples:
REG.vbs /Action:Add /Key:HKLM\SOFTWARE\NewKey
REG.vbs /Action:Add /Key:HKLMSOFTWARENewKey /Value:New_REG_SZ /Data:Value /Type:REG_SZ
REG.vbs /Action:Add /Key:HKLMSOFTWARENewKey /Value:New_REG_Binary /Data:”0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0″ /Type:REG_BINARY
REG.vbs /Action:Add /Key:HKLMSOFTWARENewKey /Value:New_REG_DWORD /Data:0 /Type:REG_DWORD
REG.vbs /Action:Add /Key:HKLMSOFTWARENewKey /Value:New_REG_EXPAND_SZ /Data:Value /Type:REG_EXPAND_SZ
REG.vbs /Action:Add /Key:HKLMSOFTWARENewKey /Value:New_REG_MULTI_SZ /Data:”Value1,Value2,Value3″ /Type:REG_MULTI_SZ
REG.vbs /Action:Delete /Key:HKLMSOFTWARENewKey /Value:New_REG_SZ
REG.vbs /Action:Delete /Key:HKLMSOFTWARENewKey

Attachment(s):

Enumerate All Empty Active Directory Groups

Enumerate All Empty Active Directory Groups

The following script was created to enumerate all the empty groups that exist in an Active Directory.

This output of the script can be piped to a text file.

Basic steps are
1) Create connection to Active Directory domain
2) Create recordset from query, filtering in only empty groups
3) Enumerate through recordset, displaying name of group
4) Cleanup

Option Explicit

On Error Resume Next

Dim objCommand
Dim objConnection
Dim objRootDSE
Dim strDNSDomain
Dim strBase
Dim objSystemInfo
Dim strDomain
Dim strFilter
Dim strAttributes
Dim strQuery
Dim objRecordset
Dim strGroupName

Set objCommand = CreateObject("ADODB.Command")
Set objConnection = CreateObject("ADODB.Connection")

objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
objCommand.ActiveConnection = objConnection

Set objRootDSE = GetObject("LDAP://RootDSE")

strDNSDomain = objRootDSE.Get("defaultNamingContext")
strBase = ""

Set objSystemInfo = CreateObject("ADSystemInfo")
strDomain = objSystemInfo.DomainShortName

strFilter = "(&(objectCategory=group)(!member=*))"

strAttributes = "sAMAccountName"

strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
objCommand.CommandText = strQuery
objCommand.Properties("Page Size") = 100
objCommand.Properties("Timeout") = 30
objCommand.Properties("Cache Results") = False

Set objRecordset = objCommand.Execute

Do Until objRecordset.EOF
strGroupName = objRecordset.Fields("sAMAccountName").Value
WScript.Echo strGroupName
objRecordset.MoveNext
Loop

objRecordset.Close
objConnection.Close

Set objRecordset = Nothing
Set objSystemInfo = Nothing
Set objRootDSE = Nothing
Set objConnection = Nothing
Set objCommand = Nothing

Attachment(s):