In this post, I will share with you a script I use to run a report on a number of special accounts in my environment. It reports on admin accounts, service accounts and computer accounts. It will collect information like the name of the account, enabled or disabled, last logon date, account expiration date, password expiration date, is the password expired, is Password Never Expires ticked, employeeIF (if used), location, etc. The collection information will be saved in a .html file and also sent by email.
To use the script, the variables below need to be set:
- $Domain : change this to your domain name
- $AdminAccountsOU : we store our admin accounts in 1 OU. This report will query the accounts in this OU
- $DisabledAdminAccountsOU : We move our disabled admin accounts to a OU within the admin accounts OU
- ServiceAccountsOU : we store our service accounts in 1 OU. This report will query the accounts in this OU
- $ReportPath : the folder where the report will be save
- $ReportName : the file name of the report
- $FromAddress : located at the end of the script, enter here the sender email address
- ToAddress : located at the end of the script, enter here the email addresses to which the report will be send
- $SMTPServer : the address/IP address of the SMTP server
So here is the script:
Clear-Host
If (-not (Get-Module -Name 'ActiveDirectory' -ErrorAction SilentlyContinue)) {
Import-Module ActiveDirectory
}
# Get domain specific variables
$Domain = "contoso.com"
$DomainData = Get-ADDomain -Server $Domain
$DomainDistinguishedName = $DomainData.DistinguishedName
$DomainDNSRoot = $DomainData.DNSRoot
$DomainDC = $DomainData.PDCEmulator
$DomainNetBIOSName = $DomainData.NetBIOSName
$DomainNetlogonDir = "\" + $DomainNetBIOSName + "\NetLogon"
$AdminAccountsOU = "OU=Admins," + $DomainDistinguishedName
$DisabledAdminAccountsOU = "OU=Disabled," + $AdminAccountsOU
$ServiceAccountsOU = "OU=Service Accounts," + $DomainDistinguishedName
# Variable declaration
$ErrorActionPreference = 'Stop'
$WeekNumber = Get-Date -UFormat %V
$ReportPath = "D:\Scripts\ICT-Administration\AD-SpecialAccounts-WeeklyReport"
$ReportName = "Week $WeekNumber - Weekly special accounts report - $DomainDNSRoot"
$ReportFile = $ReportPath + "" + $ReportName + ".html"
If ( -Not (Test-Path -Path $ReportPath)) {
New-Item -ItemType directory -Path $ReportPath
}
## Disabled admin accounts
$ReportDisabledAdminAccounts = @()
$DisabledAdminAccounts = @()
$DisabledAdminAccounts = Search-ADAccount -Server $DomainDC -AccountDisabled -SearchBase $AdminAccountsOU
ForEach ($DisabledAdminAccount in $DisabledAdminAccounts) {
$a1 = $null
$a1 = ((Get-ADUser -Server $DomainDC -Identity $DisabledAdminAccount -Properties LastLogonDate).LastLogonDate)
If ($a1) {
$a1 = ($a1).ToString("dd-MMM-yyyy")
} Else {
$a1 = ""
}
$b1 = $null
$b1 = ((Get-ADUser -Server $DomainDC -Identity $DisabledAdminAccount -Properties AccountExpirationDate).AccountExpirationDate)
If ($b1) {
$b1 = ($b1).ToString("dd-MMM-yyyy")
} Else {
$b1 = ""
}
$c1 = $null
$c1 = (Get-ADUser -Server $DomainDC -Identity $DisabledAdminAccount -Properties "msDS-UserPasswordExpiryTimeComputed" | `
Select-Object -Property @{Name = "ExpiryDate"; Expression = { [datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed") } }).ExpiryDate
If ($c1) {
$c1 = ($c1).ToString("dd-MMM-yyyy")
} Else {
$c1 = ""
}
$d1 = $null
$d1 = ($DisabledAdminAccount.DistinguishedName).Split(",", 2)[1]
$e1 = $null
$e1 = (Get-ADUser -Server $DomainDC -Identity $DisabledAdminAccount -Property EmployeeID).EmployeeID
$ItemDisabledAdminAccounts = [PSCustomObject]@{
'Name' = $DisabledAdminAccount.Name
'Enabled' = $DisabledAdminAccount.Enabled
'Last Logon Date' = $a1
'Account Expiration Date' = $b1
'Password Expiration Date' = $c1
'Employee ID' = $e1
'Account location' = $d1
}
$ReportDisabledAdminAccounts += $ItemDisabledAdminAccounts
}
## Enabled admin accounts
$ReportEnabledAdminAccounts = @()
$EnabledAdminAccounts = @()
#$EnabledAdminAccounts += Get-ADUser -Server $DomainDC -SearchBase $AdminAccountsOU -Filter * -Properties * | Where-Object { $_.Enabled -eq $True -AND $_.Name -like "adm-*" }
$EnabledAdminAccounts += Get-ADUser -Server $DomainDC -SearchBase $AdminAccountsOU -Filter * -Properties * | Where-Object { $_.Enabled -eq $True }
ForEach ($EnabledAdminAccount in $EnabledAdminAccounts) {
$a1 = $null
$a1 = ((Get-ADUser -Server $DomainDC -Identity $EnabledAdminAccount -Properties LastLogonDate).LastLogonDate)
If ($a1) {
$a1 = ($a1).ToString("dd-MMM-yyyy")
} Else {
$a1 = ""
}
$b1 = $null
$b1 = ((Get-ADUser -Server $DomainDC -Identity $EnabledAdminAccount -Properties AccountExpirationDate).AccountExpirationDate)
If ($b1) {
$b1 = ($b1).ToString("dd-MMM-yyyy")
} Else {
$b1 = ""
}
$c1 = $null
$c1 = (Get-ADUser -Server $DomainDC -Identity $EnabledAdminAccount -Properties "msDS-UserPasswordExpiryTimeComputed" | `
Select-Object -Property @{Name = "ExpiryDate"; Expression = { [datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed") } }).ExpiryDate
If ($c1) {
$c1 = ($c1).ToString("dd-MMM-yyyy")
} Else {
$c1 = ""
}
$ItemEnabledAdminAccounts = [PSCustomObject]@{
'Name' = $EnabledAdminAccount.Name
'Enabled' = $EnabledAdminAccount.Enabled
'Last Logon Date' = $a1
'Account Expiration Date' = $b1
'Password expired?' = $EnabledAdminAccount.PasswordExpired
'Password Expiration Date' = $c1
'Password Never Expires' = $EnabledAdminAccount.PasswordNeverExpires
'Employee ID' = $EnabledAdminAccount.EmployeeID
'Account location' = ($EnabledAdminAccount.DistinguishedName).Split(",", 2)[1]
}
$ReportEnabledAdminAccounts += $ItemEnabledAdminAccounts
}
## Service accounts
$ReportServiceAccounts = @()
#$AllServiceAccounts = Get-ADUser -Server $DomainDC -Filter { Name -like "svc*" -or Name -like "srvc*" } -Properties Name, Enabled, LastLogonDate, PasswordNeverExpires, DistinguishedName
$AllServiceAccounts = Get-ADUser -Server $DomainDC -SearchBase $ServiceAccountsOU -Filter * -Properties Name, Enabled, LastLogonDate, PasswordNeverExpires, DistinguishedName
ForEach ($ServiceAccount in $AllServiceAccounts) {
$a1 = $null
$a1 = ((Get-ADUser -Server $DomainDC -Identity $ServiceAccount -Properties LastLogonDate).LastLogonDate)
If ($a1) {
$a1 = ($a1).ToString("dd-MMM-yyyy")
} Else {
$a1 = ""
}
$ItemServiceAccounts = [PSCustomObject]@{
'Name' = $ServiceAccount.Name
'Enabled' = $ServiceAccount.Enabled
'Last Logon Date' = $a1
'Password Never Expires' = $ServiceAccount.PasswordNeverExpires
'Account location' = ($ServiceAccount.DistinguishedName).Split(",", 2)[1]
}
$ReportServiceAccounts += $ItemServiceAccounts
}
## Computer accounts
$ReportComputerAccounts = @()
$AllComputerAccounts = Get-ADComputer -Server $DomainDC -Filter { Name -notlike "SS-DC*" } -Properties Name, Enabled, LastLogonDate, DistinguishedName
ForEach ($ComputerAccount in $AllComputerAccounts) {
$a1 = $null
$a1 = $ComputerAccount.LastLogonDate
If ($a1) {
$a1 = ($a1).ToString("dd-MMM-yyyy")
} Else {
$a1 = ""
}
$ItemComputerAccounts = [PSCustomObject]@{
'Name' = $ComputerAccount.Name
'Enabled' = $ComputerAccount.Enabled
'Last Logon Date' = $a1
'Account location' = ($ComputerAccount.DistinguishedName).Split(",", 2)[1]
}
$ReportComputerAccounts += $ItemComputerAccounts
}
### Create report section : Build HTML report
$ReportHTML1 = $ReportDisabledAdminAccounts | Sort-Object 'Name' | ConvertTo-Html -Fragment -PreContent "<h2>Disabled admin accounts</h2>"
$ReportHTML2 = $ReportEnabledAdminAccounts | Sort-Object 'Name' | ConvertTo-Html -Fragment -PreContent "<h2>Enabled admin accounts</h2>"
$ReportHTML3 = $ReportServiceAccounts | Sort-Object 'Name' | ConvertTo-Html -Fragment -PreContent "<h2>Service accounts</h2>"
$ReportHTML4 = $ReportComputerAccounts | Sort-Object 'Name' | ConvertTo-Html -Fragment -PreContent "<h2>Computer accounts</h2>"
$Body = "
<style>
TABLE {<br />
border-width: 1px;<br />
border-style: solid;b<br />
order-color: black;<br />
border-collapse: collapse;<br />
white-space:nowrap;<br />
}<br />
TH {<br />
border-width: 1px;<br />
padding: 4px;<br />
border-style: solid;<br />
border-color: black<br />
}<br />
TD {border-width: 1px;<br />
padding: 2px 10px;<br />
border-style: solid;<br />
border-color: black;<br />
}<br />
TR:NTH-CHILD(odd) {<br />
background-color:#eee;<br />
}<br />
TR:NTH-CHILD(even) {<br />
background-color:#fff;<br />
}<br />
</style>
<h1>Week $WeekNumber - Weekly special accounts report - $DomainDNSRoot</h1>
$ReportHTML1
$ReportHTML2
$ReportHTML3
$ReportHTML4
"
ConvertTo-Html -Title "Week $WeekNumber - Weekly special accounts report - $DomainDNSRoot" -Body $Body | Set-Content $ReportFile -Force
Start-Process -FilePath $ReportFile
# Mail report
$FromAddress = '<From email address'
$ToAddress = '<To email address 1>', '<To email address 2>'
$SMTPServer = '<SMTP server>'
$Subject = "Week $WeekNumber - Weekly special accounts report - $DomainDNSRoot"
Send-MailMessage `
-From $FromAddress `
-To $ToAddress `
-Subject $Subject `
-SmtpServer $SMTPServer `
-Attachments $ReportFile
As always, please keep in mind this script is tailored to my environment, As always, please keep in mind this script is tailored to my environment, but can be used as a template for your environment. I do not pretend to be a PowerShell guru and as such my script may not be perfect. I am open to suggestions 🙂 . If you found this script useful, I’d appreciate it if you leave a comment.