Skip to the main content.

ScriptRunner Blog

Onboarding, offboarding and everything in between – 5 ideas to simplify your Active Directory management

Table of contents

 

 

Post Featured Image

Managing Active Directory users and groups is one of the central, recurring tasks of IT administration. Participate in the webinar and read in this blog post, where and how PowerShell helps IT administrators to save time and to get rid of recurring, Sisyphean tasks. 

Organizations of all sizes can benefit from automation and scripting tools that can help reduce labor that it takes to manage an environment. Efficiencies of this sort can also be gained by using scripting tools like PowerShell and applying them to Active Directory scenarios. In this article, we will review what PowerShell brings to the table for day-to-day management tasks as well as handling background and end users management tasks.

 

Reporting

Gathering information can be a relative goldmine for the IT department of any organization as it can help with day-to-day tasks, troubleshooting issues and even for preparing future changes. This is also especially true when it comes to Active Directory (AD) as it is the heart of an environment providing authentication services and more. Creating reports helps make the inner workings of AD more transparent and IT admins more aware of AD's current state. What kinds of information can we gather?

 

Inactive users

$InActiveUsers = Get-ADUser -Properties lastlogondate -Filter * | where LastLogonDate -lt ((get-date).AddDays(-90)) | Select Name,UserPrincipalName,LastLogonDate | % { $Date = $_.LastLogonDate;if ($Null -eq $Date) { $_.LastLogonDate = 'Never'}; Return $_}

01_inactive users report

'InactiveUsers' report

Notice the LastLogonDate shows 'Never'. A new account with no logins will have an empty LastLogonDate value, so the one-liner used to generate this output translates this empty value into 'Never' to make the report more user consumable. The number of days chosen, 90, is arbitrary and can be tailored to an organization's own offboarding or inactive account policy (180 days? 365 days?). Be sure to exclude any service accounts or accounts that do not require an active login in Active Directory.

 

Locked out accounts

There are two ways to do this:

Search-ADAccount -LockedOut -UsersOnly

And

Get-ADUser -Properties AccountLockoutTime,LockedOut,lockoutTime -Filter * | Where LockedOut -eq $True | ft Name,*lock*

Running either of these on a scheduled basis could help reduce calls or provide security relevant information about compromised accounts.

 

Disabled accounts

Locating Disabled Accounts is as simple as location accounts with the 'Enabled' value set to False. There are many reasons why accounts are disabled, shared mailboxes, linked mailboxes, etc and while a disabled account may be valid, this report can also revealed accounts that may need cleanup.

Get-ADUser -Filter {Enabled -eq $False} | ft

02_disabled users

'DisabledUsers' report

 

Security reports

Active Directory Security is another important aspect administrators need tools to help surface information to grasp who has what roles and access to what functions in AD. This task can be performed by analyzing Security Groups in AD. Groups such as Schema, Enterprise and other Administrators need to be controlled to limit undue access to critical infrastructure. With PowerShell, we can pull memberships and determine how many users are in these groups. With this information, administrators can then determine if too many or too few users are in these important roles. Code used in this analysis can also be expanded beyond the Built-In security groups and applied to other groups an organization creates or for other systems such as On-Premises Exchange Servers. In addition, we can also use the code for Hybrid environments with Azure AD if necessary.

 

Membership and count (sample report)


# Membership list
$Admins = Get-ADGroup -filter * | where {$_.Name -eq "Administrators"} | Get-ADGroupMember
$DomainAdmins = Get-ADGroup -filter * | where {$_.Name -eq "Domain Admins"} | Get-ADGroupMember
$EnterpriseAdmins = Get-ADGroup -Identity 'Enterprise Admins' -Server $RootDomainDC | Get-ADGroupMember
$SchemaAdmins = Get-ADGroup -Identity 'Schema Admins' -Server $RootDomainDC | Get-ADGroupMember
# Membership count
$AdminCount = ($Admins).Count
$DomainAdminCount = ($DomainAdmins).Count
$EnterpriseAdminCount = ($EnterpriseAdmins).Count
$SchemaAdminCount = ($SchemaAdmins).Count

 

Administrators can then analyze these lists and counts to determine if there are too many users in each corresponding group. A good time to evaluate these groups is when their membership exceeds three and while this value is a bit arbitrary, these groups should be kept as small as is feasible.

 

Formatting reports

In addition to gathering information, proper formatting can also be key if the information is to be reviewed by Administrators or provided to management for daily consumption. Thus, knowing the intended audience of the report is key when creating its output.

 

TXT/CSV File

The easiest and simplest method is to export the contents of a PowerShell cmdlet to a raw file for later analysis. Refined properties and thus using Out-File or even ‘>’ can exported findings from PowerShell:

Example 1: DHCP Servers in AD

Get-DhcpServerInDC | Out-File $DHCPOutputDestination

Example 2: FSMO Role holder

Get-ADDomainController -Server $Domain -Filter * > DomainControllers.txt

 

HTML files

Outputting to an HTML file can provide reports/information that is easier read by administrators and management. There are a few ways in which to create these HTML reports. One is natively built into PowerShell with the 'ConvertTo-HTML' cmdlet and the other is to utilize the PSWriteHTML PowerShell module.

 

ConvertTo-HTML

With this simple one-liner, we can create a relatively good-looking chart. First, we need to define a header required for HTML files and use that to convert a CSV file into an HTML file for consumption.  Below is a basic set of code to do this:


# Define Style for HTML file
$Header = "<style>"
$Header = $Header + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$Header = $Header + "TH{border-width: 1px;padding: 2px;border-style: solid;border-color: black;}"
$Header = $Header + "TD{border-width: 1px;padding: 2px;border-style: solid;border-color: black;}"
$Header = $Header + "</style>"
# Convert CSV to HTML
$Output = Import-CSV <Output CSV File>
$Output | ConvertTo-HTML -Head $Header | Set-Content -Path <Output HTML file>

Sample output:

03_disabled users report in HTML format

'DisabledUsers' report in HTML format

 

PSWriteHTML

While this module is far more powerful than creating HTML charts, this exercise provides a good place to start using a powerful module for reporting. Similar to the ConvertTo-HTML, we have this quick one-liner using the Disabled Users variable:

$DisabledUsers | Out-HtmlView

04_disabled users report in PSWriteHTML format

'DisabledUsers' report in PSWriteHTML format

 

Reset Password

Resetting passwords can be tedious, so creating code that will create a random password as well as then set it on a specified user account simplifies matters. Note that we need to specify two criteria for success: the appropriate length and number of non-alphanumeric characters for the password.


Function RandomPassword {
Add-Type -AssemblyName 'System.Web'
$length = 10
$nonAlphaChars = 5
$NewPassword = [System.Web.Security.Membership]::GeneratePassword($length, $nonAlphaChars)
$SecurePassword = ConvertTo-SecureString -String $NewPassword -AsPlainText -Force
Return $SecurePassword
}

 

RandomPassword

Set-ADAccountPassword Sam -Reset -NewPassword $SecurePassword

*Follow-up reading on [System.Web.Security.Membership] can be found on Microsoft Learn.

 

Unlock account

First, find the users that are locked out:

Get-ADUSer -Filter * -Properties LockedOut | Where LockedOut -eq $True

We can modify this one line to allow an Administrator to choose which account to unlock:


$AccountsToUnlock = Get-ADUser -Filter * -Properties LockedOut | Where LockedOut -eq $True | Out-GridView -PassThru

Foreach ($AccountToUnlock in $AccountsToUnlock) { Unlock-ADAccount $AccountToUnlock }

When this code is run, a pop-up will be displayed from which the administrator can choose one or more accounts to unlock:

 05_select and unlock with unlock-ADAccount cmdlet

Once selected, the accounts selected are then unlocked with the 'Unlock-ADAccount' cmdlet

 

Onboarding new users

When onboarding a new user into an organization, some account setup is necessary and those responsible for this setup usually have a task list to perform to make sure that a new employee's first day is as easy as possible.

 

Assign groups, home drive and login script by department


 # Settings - Groups, HomeDirectory, HomeDrive, ScriptPath
Function ConfigureUserSettings {
 Param ($User)
 $Department = $User.Department
 write-host "department = $Department"
 If ($Department -eq 'Marketing') {
  Add-ADGroupMember -Identity Marketing -Members $User
  Set-ADUser $User -HomeDirectory '\\fs01\homedir\Marketing\$User' -HomeDrive 'M:' -ScriptPath '\\adlab01-dc01\netlogon\Marketing-Logon.bat'
 }
 If ($Department -eq 'Human Resources') {
  Add-ADGroupMember -Identity 'Human Resources' -Members $User
  Set-ADUser $User -HomeDirectory '\\fs01\homedir\Human Resources\$User' -HomeDrive 'H:' -ScriptPath '\\adlab01-dc01\netlogon\HR-Logon.bat'
 }
 If ($Department -eq 'Research and Development') {
  Add-ADGroupMember -Identity 'Research and Development' -Members $User
  Set-ADUser $User -HomeDirectory '\\fs01\homedir\Resource and Development\$User' -HomeDrive 'R:' -ScriptPath '\\adlab01-dc01\netlogon\RnD-Logon.bat'
 }
 If ($Department -eq 'Information Technology') {
  Add-ADGroupMember -Identity 'Information Technology' -Members $User
  Set-ADUser $User -HomeDirectory '\\fs01\homedir\Information Technology\$User' -HomeDrive 'I:' -ScriptPath '\\adlab01-dc01\netlogon\IT-Logon.bat'
 }
}
# Main Body
$OU = 'OU=Mailboxes,DC=ADLab01,DC=Local'
$Users = get-aduser -SearchBase $OU -Filter * -Properties Department
Foreach ($User in $Users) {
 ConfigureUserSettings $User
 Write-Host "... Completed User $User ..."
}
 

Now the above script can be modified to use other attributes to 'trigger' or determine which settings apply, such as a Custom Attribute, Organizational Unit (OU) or perhaps title. Similarly, the OU used can also be modified to an organization's OU structure.

 

Scheduling this task

As these changes cannot take place unless a script is run, automating the script could alleviate a manual run by IT staff if that is desired. Using a jump box and the Task Scheduler program, this script can be run on a daily basis (or more/less often) to make sure users are assigned the correct groups, home drive and login script. For tips on how to schedule it, see the Author's blog post 'Schedule It!'.

 

Offboarding

Disable account, move to 'disabled accounts' OU, change password

When a user leaves an organization, IT typically has a documented process for how to handle their user account. Sometimes this includes disabling the account, moving it to a Disabled Accounts OU and even changing the password and these tasks can all be accomplished with PowerShell.


$CSV = Import-CSV '\\fs01\Departments\HR\Terminations\Monthly.csv'
Foreach ($Account in $CSV) {
$User = Get-ADUser $Account
$DisabledOU = 'OU=Disabled Accounts,DC=ADLab01,DC=Local'
RandomPassword
Set-ADAccountPassword $User -Reset -NewPassword $SecurePassword
$UserId = $User.ObjectGUID
Move-ADObject $UserId -TargetPath $DisabledOU
Disable-ADAccount $User
}

Notice the use of the RandomPassword generator feature we used in the first part of this article. Reusing code is important as it helps reduce administrative efforts in not having to recreate code blocks with each task. 

In a Hybrid environment, some care needs to be taken if the OU an account is moved to is not synced as this would possibly lead to data loss and loss of access to the user's account in Azure AD, OneDrive, SharePoint, Teams, etc. In these scenarios, it is better to either disable the account/change the password, or just change the password.

 

Conclusion

Administrating Active Directory is a complicated task that requires administrators to have the right tools and knowledge for the job. Utilizing those same PowerShell skills with Active Directory can indeed make administration easier. Having automated daily tasks allows administrators to concentrate on other projects. In this article, we scratched the surface of what PowerShell can do in terms of managing Active Directory, but hopefully the real-world examples also helped stir your curiosity for what you may task it with in the future.

One further tip of advice, before your head off to explore how to make use of PowerShell for your environment, is that if you have a task that needs to be automated, make sure to secure your script, credentials, etc so that your code or access cannot be hijacked.

 

Good2know

Webinar: Active Directory Management

Managing Active Directory users and groups is one of the central, recurring tasks of IT administration.

For example, new users and groups have to be created, group memberships have to be managed or reports have to be generated.

In this webinar, we will show you how these tasks can be standardized, automated and delegated in a time-saving manner using PowerShell.

webinar-active-directory

 

In this webinar, we cover how to:


  • Automate repetitive tasks with the Active Directory PowerShell module
  • Implement typical use cases using our ScriptRunner ActionPack for Active Directory
  • Create scheduled reports with PowerShell and ScriptRunner
  • Securely delegate Active Directory management tasks and provide self services for end users
  • Monitor all PowerShell activities

 

 

Click here for the webinar recording

 

 

 

Related Links 

Related posts

2 min read

VMUG Webcast: Mastering VMware Management with PowerCLI

3 min read

Automate your spring cleaning with PowerShell

5 min read

Mastering PowerShell with Get-Help

About the author: