Short answer: run .\Get-KerberosRC4Usage.ps1 to list service accounts, computers, managed service accounts and trusts whose msDS-SupportedEncryptionTypes allows RC4, allows only RC4, or is not set. Add -Events to read events 4769 (and with -IncludeTgt 4768) on every DC and count the tickets that were actually issued with RC4 (TicketEncryptionType 0x17 or 0x18), grouped by client, service and source IP. Fix the “RC4Only” accounts and the services in the usage list before you turn RC4 off.
We ran this script on 6 October 2026 on a Windows Server 2025 Standard domain controller (build 26100.33438, September 2026 update, Windows PowerShell 5.1) and a Windows 11 Pro member PC in our lab domain contoso.com. The example output below is from that run; the lab domain is small and new, so your numbers will be bigger. It was also syntax-checked with PowerShell 7.4.6 and PSScriptAnalyzer 1.25.
Table of Contents
What it does
Microsoft is moving Kerberos away from RC4 and has said it will change the default encryption types that domain controllers assume for accounts with no explicit setting. Before RC4 is gone from your domain you need two lists: which accounts are configured so that they still need RC4, and which clients and services are really getting RC4 tickets today. This read-only script builds both.
Part 1: account configuration
The script reads msDS-SupportedEncryptionTypes on the objects that receive Kerberos service tickets: user accounts with a servicePrincipalName (service accounts), all computer accounts, group and standalone managed service accounts, and trust objects. -AllUsers adds every user account. Each one gets a classification:
| Classification | Meaning | Action |
|---|---|---|
| NotSet | Attribute empty or 0. The KDC applies the DC’s DefaultDomainSupportedEncTypes value instead | Depends on your DC settings; set an explicit value for important service accounts |
| RC4Only | RC4 (0x4) set, no AES bit (0x8 or 0x10) | Fix first: these break when RC4 is disabled |
| RC4AndAES | RC4 and at least one AES type | Remove RC4 once nothing needs it |
| AESOnly | AES allowed, RC4 not | Hidden unless you use -IncludeAesOnly |
| DESOnly | Only DES bits (0x1, 0x2) | Legacy; DES is disabled by default since Windows 7 and Server 2008 R2 |
The bit values come from Microsoft’s Kerberos protocol specification (MS-KILE): 0x1 DES-CBC-CRC, 0x2 DES-CBC-MD5, 0x4 RC4-HMAC, 0x8 AES128-CTS-HMAC-SHA1-96, 0x10 AES256-CTS-HMAC-SHA1-96. Other bits are shown as “other bits 0x…” without guessing a name. Separate columns flag any DES bit and the userAccountControl flag USE_DES_KEY_ONLY (0x200000). PasswordLastSet is included because an account whose password was last set before the domain had Windows Server 2008 or later DCs may have no AES keys at all: changing the password creates them.
Part 2: RC4 tickets actually issued
With -Events the script reads the Security log of each DC for event 4769 (“A Kerberos service ticket was requested”) where the TicketEncryptionType field is 0x17 (RC4-HMAC) or 0x18 (RC4-HMAC-EXP). -IncludeTgt adds event 4768 (TGT requests). Rows are grouped by event ID, client (TargetUserName), service (ServiceName), source IP and encryption type, with a count, first and last time seen, and the DCs that issued them. On DCs with the January 2025 or later security update the events also carry AccountAvailableKeys, ServiceAvailableKeys and ClientAdvertizedEncryptionTypes; the script copies them into the report, which tells you whether the problem is a missing AES key or a client that only offers RC4.
Requirements
- Windows PowerShell 5.1 or PowerShell 7 on Windows, with the ActiveDirectory module (RSAT).
- Read access to AD for Part 1 (default for domain users).
- For
-Events: “Audit Kerberos Service Ticket Operations” (and for 4768 “Audit Kerberos Authentication Service”) success auditing on the DCs; see Active Directory audit policy. Rights to read each DC’s Security log (Domain Admins or Event Log Readers) and the Remote Event Log Management firewall rules. - Busy DCs log a lot of 4769 events. The XPath filter is evaluated on the DC, so only RC4 events travel over the network, but keep
-Hoursmodest on large domains.
Download and first run
- Copy the script from the box on this page (or use the download button) and save it as
C:\Scripts\Get-KerberosRC4Usage.ps1. - If you downloaded the file, remove the “downloaded from the internet” mark so the execution policy lets it run:
Unblock-File C:\Scripts\Get-KerberosRC4Usage.ps1. - Run it on a domain-joined machine that has the ActiveDirectory module: a domain controller, a management server, or a Windows 11 PC with RSAT (see Install RSAT on Windows 11).
- Read the built-in help once, then run it with no options to see the result on screen before you export anything.
cd C:\Scripts
Get-Help .\Get-KerberosRC4Usage.ps1 -Full
.\Get-KerberosRC4Usage.ps1
.\Get-KerberosRC4Usage.ps1 -Events -Hours 24
Options
| Parameter | What it does | Default |
|---|---|---|
-Server | Domain to check | Current domain |
-SearchBase | Limit the account scan to one OU | Whole domain |
-AllUsers | Include every user, not only those with an SPN | Off |
-IncludeAesOnly | Also output AES-only accounts | Off |
-Events | Read RC4 ticket events from the DCs | Off |
-IncludeTgt | With -Events, also read 4768 | Off |
-Hours | With -Events, look-back window (1 to 720) | 24 |
-MaxEvents | With -Events, maximum events per DC; a warning shows if reached | 5000 |
-DomainController | With -Events, only these DCs | All DCs |
-ExportCsv | Account CSV; with -Events a second file “<name>-events.csv” | Not written |
-PassThru | Return the objects (accounts, then usage rows) | Off |
Usage examples
# Configuration only
.\Get-KerberosRC4Usage.ps1
# Configuration plus three days of RC4 tickets, both to CSV
.\Get-KerberosRC4Usage.ps1 -Events -Hours 72 -ExportCsv C:\Reports\rc4.csv
# -> C:\Reports\rc4.csv and C:\Reports\rc4-events.csv
# Count every account by classification, including AES-only and all users
.\Get-KerberosRC4Usage.ps1 -AllUsers -IncludeAesOnly -PassThru | Group-Object Classification
# Service accounts that will break without RC4
.\Get-KerberosRC4Usage.ps1 -PassThru | Where-Object { $_.Classification -eq 'RC4Only' }
CSV columns
The example output further down is from our lab run.
| File | Columns |
|---|---|
| Accounts | Name, SamAccountName, Kind (User, Computer, ManagedSvcAccount, Trust), Classification, SupportedEncTypes (hex), EncTypesDecoded, DESAllowed, UseDesKeyOnly, Enabled, PasswordLastSet, SPNCount, OperatingSystem, DistinguishedName |
| Usage (-events) | EventId, Client, Service, SourceIP, TicketEncryptionType, Count, FirstSeen, LastSeen, DomainControllers, AccountAvailableKeys, ServiceAvailableKeys, ClientAdvertizedEncryptionTypes |
Fixing what it finds
- RC4Only service account: set AES only, either with the two “This account supports Kerberos AES 128/256 bit encryption” boxes on the Account tab in Active Directory Users and Computers or with
Set-ADUser svc-web -Replace @{'msDS-SupportedEncryptionTypes'=24}(24 = 0x18 = AES128 + AES256), then reset the account password so AES keys exist, then test the service. The application side may need a new keytab if it is not Windows. - NotSet service accounts with an old PasswordLastSet: reset the password first, then set explicit AES types.
- Usage rows with an empty AES key list: the account or service lacks AES keys; a password reset normally fixes it.
- Clients that advertise only RC4: old operating systems, appliances and some Java or Linux Kerberos configurations. Update or reconfigure them.
Test before you change service accounts. Changing encryption types or resetting the password of a service account can stop the service until every server using it has the new password. Do one account at a time, in a maintenance window, and note the old value from the CSV.
Example output
We gave the test service account svc-legacyapp RC4 only (msDS-SupportedEncryptionTypes = 0x4), requested a ticket for its SPN from the member PC, then ran the script with and without -Events:
Classification Count
-------------- -----
NotSet 3
RC4AndAES 2
RC4Only 1
Name Kind Classification SupportedEncTypes EncTypesDecoded PasswordLastSet
---- ---- -------------- ----------------- --------------- ---------------
Legacy App User RC4Only 0x4 RC4-HMAC 10/6/2026 2:17:13 PM
WINCLIENT Computer RC4AndAES 0x1C RC4-HMAC, AES128, AES256 10/6/2026 2:17:06 PM
WINSRV Computer RC4AndAES 0x1C RC4-HMAC, AES128, AES256 10/6/2026 2:09:52 PM
Count EventId Client Service SourceIP LastSeen
----- ------- ------ ------- -------- --------
1 4769 WINCLIENT$@CONTOSO.COM svc-legacyapp 192.168.0.14 10/6/2026 2:31:55 PM
On this September 2026 build the DC still issued an RC4 ticket because the account explicitly allows only RC4 (klist on the PC showed RSADSI RC4-HMAC(NT)). Accounts with the attribute not set did not get RC4 tickets.
Schedule it
During an RC4 clean-up, run it daily: the usage list should shrink as you fix accounts, and anything new shows up quickly. The task account needs to read the DCs’ Security logs, so add the gMSA to Event Log Readers (see our gMSA guide).
$action = New-ScheduledTaskAction -Execute 'powershell.exe' `
-Argument '-NoProfile -ExecutionPolicy Bypass -File C:\Scripts\Get-KerberosRC4Usage.ps1 -Events -Hours 24 -ExportCsv C:\Reports\rc4.csv'
$trigger = New-ScheduledTaskTrigger -Daily -At 6am
$principal = New-ScheduledTaskPrincipal -UserId 'CONTOSO\gmsa-adreport$' -LogonType Password
Register-ScheduledTask -TaskName 'Kerberos RC4 audit' -Action $action -Trigger $trigger -Principal $principal
The file is overwritten on every run. If you need history, point the task at a small wrapper script that adds the date to the file name, or copy the file away after each run.
How it works
- Four LDAP queries with
Get-ADObjectcollect user accounts with an SPN (or all users), computers, managed service accounts andtrustedDomainobjects, withmsDS-SupportedEncryptionTypes,userAccountControlandpwdLastSet. - The value is classified with bitwise tests and decoded into names.
- With
-Events,Get-ADDomainController -Filter *lists the DCs andGet-WinEvent -FilterXPathasks each one only for 4769/4768 events in the window whoseTicketEncryptionTypeis 0x17 or 0x18. - Each event is read as XML by field name and aggregated by client, service, IP and type.
Limitations
- The NotSet classification cannot tell you whether RC4 will be used: that depends on DefaultDomainSupportedEncTypes and the update level of your DCs. Check the usage report for the real answer.
- Only service-ticket and TGT encryption types are checked; session key types are not used for the classification.
- Events exist only while the Security log keeps them; on busy DCs that may be hours. Forward events to a collector for longer windows.
- Microsoft also publishes Kerberos audit scripts (Get-KerbEncryptionUsage.ps1 and List-AccountKeys.ps1) in its Kerberos-Crypto GitHub repository, referenced from the RC4 guidance linked below; they are worth running alongside this report.
- Not yet run against a live domain (see the note at the top).
Official documentation: Detect and remediate RC4 usage in Kerberos · Event 4769: a Kerberos service ticket was requested · MS-KILE 2.2.7: supported encryption types bit flags · Event 4768: a Kerberos TGT was requested
Related: Disable NTLM Active Directory-Wide: 5 Safe Audit and Block Steps · Active Directory Audit Policy: DC Settings and 35 Key Event IDs · Group Managed Service Accounts (gMSA): Complete Windows Server 2025 Guide · Raise AD Functional Level Safely: Forest and Domain
See also: Reset krbtgt Password Safely: Two Resets, Replication and RODCs · Kerberos RC4 Removal: Find and Fix RC4 Accounts (2026) · BadSuccessor dMSA on Server 2025: Audit OU Rights and Patch
The script
# Kerberos RC4 Audit Script: Find RC4 Accounts and Tickets (v1.0.0) - from srvScripts.com
# Source, docs and updates: https://srvscripts.com/scripts/kerberos-rc4-audit/
# Copyright (c) 2026 srvScripts.com. MIT licence: if you copy, share or adapt this script, keep this notice and credit srvScripts.com.
<#
.SYNOPSIS
Find AD accounts that still allow (or only allow) Kerberos RC4, and optionally the RC4 tickets your DCs
actually issued (events 4768/4769 with encryption type 0x17).
.DESCRIPTION
Read-only.
Part 1 - configuration. Reads msDS-SupportedEncryptionTypes on the accounts that matter for Kerberos
service tickets: user and managed service accounts with a servicePrincipalName, computer accounts, and
trust objects (trustedDomain). Use -AllUsers to include every user account. Each account is classified:
NotSet attribute empty or 0: the KDC uses the DefaultDomainSupportedEncTypes value of the DC,
so the result depends on your DCs' configuration and update level
RC4Only RC4 (0x4) allowed and no AES bit (0x8, 0x10)
RC4AndAES RC4 and at least one AES type allowed
AESOnly AES allowed, RC4 not allowed
DESOnly only DES bits (0x1, 0x2) set
A separate DESAllowed column is True whenever a DES bit is set (DES is disabled by default since
Windows 7 / Server 2008 R2), for example the common value 0x1F (DES, RC4, AES128, AES256).
It also flags userAccountControl USE_DES_KEY_ONLY (0x200000) and shows when the password was last set:
an account whose password has not changed since the domain first ran Windows Server 2008 domain
controllers may have no AES keys at all.
Part 2 - usage (-Events). Reads the Security log of each DC for 4769 (service ticket) and, with
-IncludeTgt, 4768 (TGT) events whose TicketEncryptionType is 0x17 (RC4-HMAC) or 0x18 (RC4-HMAC-EXP),
and groups them by client, service and source IP. On DCs with the January 2025 or later security update
the events also carry AccountAvailableKeys / ServiceAvailableKeys, which the report includes.
Requires "Audit Kerberos Service Ticket Operations" (and for 4768 "Audit Kerberos Authentication
Service") success auditing on the DCs.
.PARAMETER Server
Domain to check (default: current domain).
.PARAMETER SearchBase
Limit the account scan to this OU (DN).
.PARAMETER AllUsers
Include all user accounts, not only those with a servicePrincipalName.
.PARAMETER IncludeAesOnly
Also output accounts classified AESOnly (default: only accounts that need attention).
.PARAMETER Events
Also read RC4 ticket events from the domain controllers.
.PARAMETER IncludeTgt
With -Events, also read 4768 (TGT) events, not only 4769.
.PARAMETER Hours
With -Events, how far back to read (default 24, maximum 720).
.PARAMETER MaxEvents
With -Events, maximum events read per DC (default 5000).
.PARAMETER DomainController
With -Events, read only these DCs.
.PARAMETER ExportCsv
Write the account report to this CSV file. With -Events the usage report is written next to it with
"-events" added to the file name.
.PARAMETER PassThru
Output objects (accounts, then usage rows) to the pipeline.
.EXAMPLE
.\Get-KerberosRC4Usage.ps1
.EXAMPLE
.\Get-KerberosRC4Usage.ps1 -Events -Hours 72 -ExportCsv C:\Reports\rc4.csv
.EXAMPLE
.\Get-KerberosRC4Usage.ps1 -AllUsers -IncludeAesOnly -PassThru | Group-Object Classification
.NOTES
Name: Get-KerberosRC4Usage.ps1
Version: 1.0.0
Source: https://srvscripts.com/scripts/kerberos-rc4-audit/
License: MIT
Requires: Windows PowerShell 5.1 or PowerShell 7 on Windows, ActiveDirectory module (RSAT); for -Events,
rights to read the DC Security logs (Domain Admins or Event Log Readers) and the Remote Event Log
Management firewall rules on the DCs.
Microsoft also publishes Kerberos audit scripts (Get-KerbEncryptionUsage.ps1, List-AccountKeys.ps1) in
its Kerberos-Crypto GitHub repository; see https://learn.microsoft.com/windows-server/security/kerberos/detect-remediate-rc4-kerberos
#>
[CmdletBinding()]
param(
[ValidateNotNullOrEmpty()]
[string]$Server,
[ValidateNotNullOrEmpty()]
[string]$SearchBase,
[switch]$AllUsers,
[switch]$IncludeAesOnly,
[switch]$Events,
[switch]$IncludeTgt,
[ValidateRange(1, 720)]
[int]$Hours = 24,
[ValidateRange(1, 1000000)]
[int]$MaxEvents = 5000,
[ValidateNotNullOrEmpty()]
[string[]]$DomainController,
[ValidateNotNullOrEmpty()]
[string]$ExportCsv,
[switch]$PassThru
)
Set-StrictMode -Version 2
$ErrorActionPreference = 'Stop'
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
throw "The ActiveDirectory module is not installed. Install RSAT: Active Directory Domain Services tools, then run again."
}
Import-Module ActiveDirectory -Verbose:$false
function ConvertFrom-FileTimeValue {
param($Value)
if ($null -eq $Value) { return $null }
$v = [int64]$Value
if ($v -le 0 -or $v -eq [int64]::MaxValue) { return $null }
[DateTime]::FromFileTime($v)
}
function Get-AttributeValue {
param($Entity, [string]$Name)
if ($Entity.PropertyNames -contains $Name) { return $Entity[$Name].Value }
$null
}
function Get-EncTypeName {
param([int64]$Value)
$n = @()
if ($Value -band 0x1) { $n += 'DES-CBC-CRC' }
if ($Value -band 0x2) { $n += 'DES-CBC-MD5' }
if ($Value -band 0x4) { $n += 'RC4-HMAC' }
if ($Value -band 0x8) { $n += 'AES128' }
if ($Value -band 0x10) { $n += 'AES256' }
if ($Value -band -bnot 0x1F) { $n += ('other bits 0x{0:X}' -f ($Value -band -bnot 0x1F)) }
$n -join ', '
}
function Get-EncClassification {
param($Value)
if ($null -eq $Value -or [int64]$Value -eq 0) { return 'NotSet' }
$v = [int64]$Value
$rc4 = [bool]($v -band 0x4)
$aes = [bool]($v -band 0x18)
$des = [bool]($v -band 0x3)
if ($rc4 -and -not $aes) { return 'RC4Only' }
if ($rc4 -and $aes) { return 'RC4AndAES' }
if ($aes) { return 'AESOnly' }
if ($des) { return 'DESOnly' }
'NoKerberosEtype'
}
$domArgs = @{}
if ($Server) { $domArgs.Server = $Server }
$domain = Get-ADDomain @domArgs
$srv = $domain.DNSRoot
# ---- Part 1: account configuration ----------------------------------------------------------------------
$attrs = 'msDS-SupportedEncryptionTypes', 'userAccountControl', 'pwdLastSet', 'servicePrincipalName', 'sAMAccountName', 'objectClass', 'name', 'operatingSystem'
$userFilter = if ($AllUsers) { '(&(objectCategory=person)(objectClass=user))' } else { '(&(objectCategory=person)(objectClass=user)(servicePrincipalName=*))' }
$filters = [ordered]@{
'User' = $userFilter
'Computer' = '(objectCategory=computer)'
'ManagedSvcAccount' = '(|(objectClass=msDS-GroupManagedServiceAccount)(objectClass=msDS-ManagedServiceAccount))'
'Trust' = '(objectClass=trustedDomain)'
}
$q = @{ Server = $srv; Properties = $attrs; ResultPageSize = 500 }
if ($SearchBase) { $q.SearchBase = $SearchBase }
$accounts = [System.Collections.Generic.List[object]]::new()
$seen = @{}
foreach ($kind in $filters.Keys) {
Write-Verbose "Scanning $kind objects"
$objs = @(Get-ADObject -LDAPFilter $filters[$kind] @q)
foreach ($o in $objs) {
if ($seen.ContainsKey($o.DistinguishedName)) { continue }
$seen[$o.DistinguishedName] = $true
$et = Get-AttributeValue $o 'msDS-SupportedEncryptionTypes'
$uac = Get-AttributeValue $o 'userAccountControl'
$cls = Get-EncClassification $et
$desOnly = ($null -ne $uac -and ([int]$uac -band 0x200000))
$desAllowed = ($null -ne $et -and ([int64]$et -band 0x3))
if ($cls -eq 'AESOnly' -and -not $desOnly -and -not $desAllowed -and -not $IncludeAesOnly) { continue }
$spn = @(Get-AttributeValue $o 'servicePrincipalName' | Where-Object { $_ })
$etText = 'Not set'
$etHex = ''
if ($null -ne $et -and [int64]$et -ne 0) { $etText = Get-EncTypeName ([int64]$et); $etHex = '0x{0:X}' -f [int64]$et }
$accounts.Add([pscustomobject]@{
Name = [string](Get-AttributeValue $o 'name')
SamAccountName = [string](Get-AttributeValue $o 'sAMAccountName')
Kind = $kind
Classification = $cls
SupportedEncTypes = $etHex
EncTypesDecoded = $etText
DESAllowed = [bool]$desAllowed
UseDesKeyOnly = [bool]$desOnly
Enabled = if ($null -ne $uac) { -not ([int]$uac -band 2) } else { $null }
PasswordLastSet = ConvertFrom-FileTimeValue (Get-AttributeValue $o 'pwdLastSet')
SPNCount = $spn.Count
OperatingSystem = [string](Get-AttributeValue $o 'operatingSystem')
DistinguishedName = $o.DistinguishedName
})
}
}
$accountRows = @($accounts | Sort-Object @{ Expression = { switch ($_.Classification) { 'RC4Only' { 0 } 'DESOnly' { 1 } 'RC4AndAES' { 2 } 'NotSet' { 3 } default { 4 } } } }, Kind, Name)
# ---- Part 2: RC4 tickets issued -------------------------------------------------------------------------
$usageRows = @()
if ($Events) {
$dcs = @(Get-ADDomainController -Filter * -Server $srv | ForEach-Object { $_.HostName })
if ($DomainController) { $dcs = @($dcs | Where-Object { $DomainController -contains $_ }) }
$ms = [int64]$Hours * 3600 * 1000
$ids = if ($IncludeTgt) { '(EventID=4769 or EventID=4768)' } else { 'EventID=4769' }
$xpath = "*[System[$ids and TimeCreated[timediff(@SystemTime) <= $ms]]] and " +
"*[EventData[Data[@Name='TicketEncryptionType']='0x17' or Data[@Name='TicketEncryptionType']='0x18']]"
$agg = @{}
foreach ($dc in $dcs) {
Write-Verbose "Reading RC4 ticket events on $dc"
$evs = @()
try {
$evs = @(Get-WinEvent -ComputerName $dc -LogName Security -FilterXPath $xpath -MaxEvents $MaxEvents)
} catch {
if ($_.FullyQualifiedErrorId -match 'NoMatchingEventsFound' -or $_.Exception.Message -match 'No events were found') { continue }
Write-Warning "Cannot read the Security log on ${dc}: $($_.Exception.Message)"
continue
}
if ($evs.Count -ge $MaxEvents) { Write-Warning "$dc returned $MaxEvents events (the -MaxEvents limit); counts for this DC are incomplete." }
foreach ($e in $evs) {
$d = @{}
foreach ($n in ([xml]$e.ToXml()).Event.EventData.Data) { $d[$n.Name] = [string]$n.InnerText }
$ip = ([string]$d['IpAddress']) -replace '^::ffff:', ''
$key = '{0}|{1}|{2}|{3}|{4}' -f $e.Id, $d['TargetUserName'], $d['ServiceName'], $ip, $d['TicketEncryptionType']
if (-not $agg.ContainsKey($key)) {
$agg[$key] = [pscustomobject]@{
EventId = $e.Id
Client = [string]$d['TargetUserName']
Service = [string]$d['ServiceName']
SourceIP = $ip
TicketEncryptionType = [string]$d['TicketEncryptionType']
Count = 0
FirstSeen = $e.TimeCreated
LastSeen = $e.TimeCreated
DomainControllers = ''
AccountAvailableKeys = [string]$d['AccountAvailableKeys']
ServiceAvailableKeys = [string]$d['ServiceAvailableKeys']
ClientAdvertizedEncryptionTypes = [string]$d['ClientAdvertizedEncryptionTypes']
}
}
$a = $agg[$key]
$a.Count++
if ($e.TimeCreated -lt $a.FirstSeen) { $a.FirstSeen = $e.TimeCreated }
if ($e.TimeCreated -gt $a.LastSeen) { $a.LastSeen = $e.TimeCreated }
if (($a.DomainControllers -split '; ') -notcontains $dc) { $a.DomainControllers = (@($a.DomainControllers -split '; ' | Where-Object { $_ }) + $dc) -join '; ' }
}
}
$usageRows = @($agg.Values | Sort-Object Count -Descending)
}
# ---- Output ---------------------------------------------------------------------------------------------
if ($ExportCsv) {
$accountRows | Export-Csv -LiteralPath $ExportCsv -NoTypeInformation -Encoding UTF8
Write-Information ("{0} account(s) written to {1}" -f $accountRows.Count, $ExportCsv) -InformationAction Continue
if ($Events) {
$evFile = [System.IO.Path]::ChangeExtension($ExportCsv, $null).TrimEnd('.') + '-events.csv'
$usageRows | Export-Csv -LiteralPath $evFile -NoTypeInformation -Encoding UTF8
Write-Information ("{0} RC4 usage row(s) written to {1}" -f $usageRows.Count, $evFile) -InformationAction Continue
}
}
if ($PassThru) { $accountRows; $usageRows; return }
$accountRows | Group-Object Classification | Sort-Object Name | Format-Table @{ n = 'Classification'; e = { $_.Name } }, Count -AutoSize
$accountRows | Where-Object { $_.Classification -in 'RC4Only', 'DESOnly', 'RC4AndAES' -or $_.DESAllowed -or $_.UseDesKeyOnly } |
Format-Table Name, Kind, Classification, SupportedEncTypes, EncTypesDecoded, PasswordLastSet -AutoSize
if ($Events) {
if ($usageRows.Count) {
$usageRows | Select-Object -First 50 | Format-Table Count, EventId, Client, Service, SourceIP, LastSeen -AutoSize
} else {
Write-Information "No RC4 (0x17/0x18) ticket events found in the last $Hours hour(s) on: $($dcs -join ', ')" -InformationAction Continue
}
}
81b45767c36dfb6e12f73c18143b025b460fd7609cff2c2f682f1ea873017e83curl -fsSL -o Get-KerberosRC4Usage.ps1 https://scr.srvscripts.com/kerberos-rc4-audit/Get-KerberosRC4Usage.ps1 && curl -fsSL https://scr.srvscripts.com/kerberos-rc4-audit/Get-KerberosRC4Usage.ps1.sha256 | sha256sum -cInvoke-WebRequest -Uri 'https://scr.srvscripts.com/kerberos-rc4-audit/Get-KerberosRC4Usage.ps1' -OutFile 'Get-KerberosRC4Usage.ps1'; if ((Get-FileHash 'Get-KerberosRC4Usage.ps1' -Algorithm SHA256).Hash -eq '81B45767C36DFB6E12F73C18143B025B460FD7609CFF2C2F682F1EA873017E83') { 'OK: the file is intact' } else { 'MISMATCH: do not run this file' }Copy the whole line. In Windows PowerShell, curl and sha256sum are not the Linux tools, so use the PowerShell line there.Also on GitHub: github.com/srvscripts/scripts
Frequently asked questions
How do I find accounts that use RC4 for Kerberos?
Check msDS-SupportedEncryptionTypes on service accounts, computers and trusts (value 0x4 alone means RC4 only), and look for events 4769 with TicketEncryptionType 0x17 on your DCs. This script does both.
What does TicketEncryptionType 0x17 mean?
RC4-HMAC. 0x11 and 0x12 are AES128 and AES256, and 0x18 is RC4-HMAC-EXP.
What happens if msDS-SupportedEncryptionTypes is not set?
The KDC uses the DefaultDomainSupportedEncTypes value configured on the domain controller instead, so the result depends on your DC settings and updates.
Why does an account have no AES keys?
AES keys are created when the password is set on a domain controller that supports AES. An account whose password has not changed since before Windows Server 2008 DCs may only have RC4 keys. Reset the password.
How do I set a service account to AES only?
Tick the two Kerberos AES boxes on the Account tab in Active Directory Users and Computers, or set msDS-SupportedEncryptionTypes to 24 (AES128 plus AES256) with Set-ADUser -Replace. Then reset the password and test the service in a maintenance window.
Does the script change encryption settings?
No. It only reads AD and the Security logs.