phillips321 / adaudit Goto Github PK
View Code? Open in Web Editor NEWPowershell script to do domain auditing automation
Home Page: https://www.phillips321.co.uk
Powershell script to do domain auditing automation
Home Page: https://www.phillips321.co.uk
Hi,
There are 2 checks with the Administrator name hardcoded (check if the account has been renamed/replaced)
This name depends on your OS language so we can't use the SID to compute it.
To fix the hardcoded checks and make it more reliable, I've added a array to store the default Administrator name for different languages (far from being complete).
$AdministratorTranslation = @("Administrator","Administrateur","Administrador")
Hi,
I would like to run a AD Audit against a headless (non graphical) Azure AD in my tenancy. I have access to powershell as DA remotely, but was unsure if there where was a method where the results could be mapped back to my workstation rather than the server?
Thanks in advance.
Hi,
Group names should be retrieved from their known SIDs.
# Users/Groups SIDs
$AdministratorSID = ((Get-ADDomain -Current LoggedOnUser).domainsid.value)+"-500"
$DomainAdminsSID = ((Get-ADDomain -Current LoggedOnUser).domainsid.value)+"-512"
$DomainUsersSID = ((Get-ADDomain -Current LoggedOnUser).domainsid.value)+"-513"
$DomainControllersSID = ((Get-ADDomain -Current LoggedOnUser).domainsid.value)+"-516"
$SchemaAdminsSID = ((Get-ADDomain -Current LoggedOnUser).domainsid.value)+"-518"
$EnterpriseAdminsSID = ((Get-ADDomain -Current LoggedOnUser).domainsid.value)+"-519"
$ProtectedUsersSID = ((Get-ADDomain -Current LoggedOnUser).domainsid.value)+"-525"
EveryOneSID = New-Object System.Security.Principal.SecurityIdentifier "S-1-1-0"
$AuthenticatedUsersSID = New-Object System.Security.Principal.SecurityIdentifier "S-1-5-11"
# Users/Groups real names
$Administrators = (Get-AD -Identity S-1-5-32-544).SamAccountName
$Users = (Get-AD -Identity S-1-5-32-545).SamAccountName
$Administrator = (Get-AD -Identity $AdministratorSID).SamAccountName
$DomainAdmins = (Get-AD -Identity $DomainAdminsSID).SamAccountName
$DomainUsers = (Get-AD -Identity $DomainUsersSID).SamAccountName
$DomainControllers = (Get-AD -Identity $DomainControllersSID).SamAccountName
$SchemaAdmins = (Get-AD -Identity $SchemaAdminsSID).SamAccountName
$EnterpriseAdmins = (Get-AD -Identity $EnterpriseAdminsSID).SamAccountName
$ProtectedUsers = (Get-AD -Identity $ProtectedUsersSID).SamAccountName
$EveryOne = $EveryOneSID.Translate([System.Security.Principal.NTAccount]).Value
$AuthenticatedUsers = $AuthenticatedUsersSID.Translate([System.Security.Principal.NTAccount]).Value
Using these variables, I was able to make it work on a French version of Active Directory.
Don't know how to send the modified version up here...
Hello
With which software do you recommend using the adaudit.nessus file?
Thank you
Useful to list the "Administrators" group for the domain as well
These lines have been added throughout the script, although not fully tested yet
$script:Administrators = New-Object System.Security.Principal.SecurityIdentifier "S-1-5-32-544"
Write-Both " [+] Administrators : $Administrators"
if(($Administrators | measure).count -ne 0){
Write-Both " [!] Administrators!!!"
foreach($member in $Administrators){
Add-Content -Path "$outputdir\administrators.txt" -Value "$($member.objectClass) $($member.SamAccountName) $($member.Name)"
}
}
Looks like script counts disabled accounts in following reports:
Such accounts are disabled and usually kept for audit purposes, should be included in above provided figures I think.
anyway - nice work!
Hi,
Has anyone seen the below on a Windows2012R2 machine?
Does this relate to this reference?
[+] PS>Import-Module Grouper.psm1 ; Invoke-AuditGPOReport -Path C:\GPOReport.xml -Level 3
Method invocation failed because [Microsoft.ActiveDirectory.Management.ADPropertyValueCollection] does not contain a
method named 'op_Division'.
At C:\Users\Administrator\Desktop\xxxxx\AdAudit.ps1:258 char:9
Write-Progress -Activity "Identifying which GPOs apply to which OUs..." ...
+ CategoryInfo : InvalidOperation: (op_Division:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Hi,
How/Where do you retrieve Nessus KB numbers?
I want to add a few tests but I'd like to point to the corresponding KB if it exists
Thanks
Hi
Version 4.1 works ok
The lasted lines from 878 to 886
#Dirty fix for .nessus characters (will do this properly or as a function later. Will need more characters adding here...)
$originalnessusoutput = Get-Content $outputdir\adaudit.nessus
$nessusoutput = $originalnessusoutput -Replace "&", "&"
$nessusoutput = $nessusoutput -Replace "`“", """
$nessusoutput = $nessusoutput -Replace "ü", "u"
$nessusoutput | Out-File $outputdir\adaudit-replaced.nessus
$endtime = get-date
Write-Both "[*] Script end time $endtime"
Version 4.2 didn't works
The lasted lines from 879 to 888
#Dirty fix for .nessus characters (will do this properly or as a function later. Will need more characters adding here...)
$originalnessusoutput = Get-Content $outputdir\adaudit.nessus
$nessusoutput = $originalnessusoutput -Replace "&", "&"
$nessusoutput = $nessusoutput -Replace "`“", """
$nessusoutput = $nessusoutput -Replace "ü", "u"
$nessusoutput | Out-File $outputdir\adaudit-replaced.nessus
~
$endtime = get-date
Write-Both "[*] Script end time $endtime"
~
I run this commando
PS C:\Users\Administrator\Downloads\ADaudit-master> .\AdAudit.ps1 -all
Error
At C:\Users\Administrator\Downloads\ADaudit-master\AdAudit.ps1:882 char:48
~
Unexpected token '&' in expression or statement.
At C:\Users\Administrator\Downloads\ADaudit-master\AdAudit.ps1:883 char:41
~~~~~~~~
Unexpected token 'ü", "u"
$nessusoutput | Out-File $outputdir\adaudit-replaced.nessus
$endtime = get-date
Write-Both "[*]' in expression or statement.
At C:\Users\Administrator\Downloads\ADaudit-master\AdAudit.ps1:887 char:41
~
The string is missing the terminator: ".
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken
Best regards
Henrik
Greetings,
Can you please give me a references for a KB numbers you are using in your script?
I was getting a "Get-Acl : The object name has bad syntax" when the Get-OUPerms function was running. According to this reddit post, it's a known issue. I simply changed Get-Acl AD:$object
to Get-Acl "Microsoft.ActiveDirectory.Management.dll\ActiveDirectory:://RootDSE/$object"
and everything seems to be working again. By the way, thanks for taking the time to create and share this script. It pulls all the good stuff I would care about and saved me many hours by not having to put something together myself.
Hi, thanks for sharing. I was wondering whether you could add something to identify newly created accounts to the effects of:
$DateCutOff = (Get-Date).AddDays(-30)
Get-ADUser -Filter * -Properties whenCreated | where {$_.whenCreated -gt $DateCufOff} | FT Name, whenCreated
please include a check for GenericAll active directory rights given to all domain users.
Line 249 uses "-TimeSpan 180". The comment on line 246 indicates that the intention here is to list accounts that have not been active for 180 days but on my Windows Server 2012 R2 machine with PowerShell 4.0 that is not the actual outcome. The "180" is some time period that is shorter than 180 days.
Changing the "180" to (New-TimeSpan -Days 180) gave more accurate results:
$inactiveaccounts = Search-ADaccount -AccountInactive -Timespan (New-TimeSpan -Days 180) -UsersOnly
Top rate tool for doing a basic audit. Thank you for the work.
Would it be possible to include a list of all empty groups and the last time they were potentially modified?
Missing expression after unary operator '-'.
At C:\Users\Administrator\Downloads\adaudit-master\adaudit-master\AdAudit.ps1:6 char:10
- <<<< added check for transitive trusts
Hi,
I'm testing DSInternals PS Module and I found it very nice.
https://github.com/MichaelGrafnetter/DSInternals
It quickly generates a password quality report like this (empty for this example) :
Active Directory Password Quality Report
----------------------------------------
Passwords of these accounts are stored using reversible encryption:
LM hashes of passwords of these accounts are present:
These accounts have no password set:
Passwords of these accounts have been found in the dictionary:
These groups of accounts have the same passwords:
These computer accounts have default passwords:
Kerberos AES keys are missing from these accounts:
Kerberos pre-authentication is not required for these accounts:
Only DES encryption is allowed to be used with these accounts:
These accounts are susceptible to the Kerberoasting attack:
These administrative accounts are allowed to be delegated to a service:
Passwords of these accounts will never expire:
These accounts are not required to have a password:
These accounts that require smart card authentication have a password:
It's easy to install as it's in PSGallery (at least for WS 2016+): Install-Module -Name DSInternals
It would be great to add this toy to go deeper in password auditing, but I don't know how much to integrate it as it needs to be installed first.
What do you think about it?
I think the better way to integrate it would be to do the checks only if the module is found and tell the user to download/install it manually if not present (I wouldn't like a script to do this for me)
Hi
I recently ran the script on a server and noticed it returned an incorrect complexity enable result.
We determined that an alternate command fixed the issue.
Instead of using
(Get-ADDefaultDomainPasswordPolicy).PasswordComplexity
Which may return a blank.
Using the following
(Get-ADDefaultDomainPasswordPolicy).ComplexityEnabled
Returns “True” as expected.
Thanks for a great tool.
Hello
Thank you for the work done with this script, would it be possible to have a single result file in HTML format for example
Thank you
Hi,
Your site is down and I cannot find any other way to contact you. I'd like to share some simple code I think will be useful to you
function Get-UserWithJoinPermissions{#Looks for groups that have domain join permissions assigned
$AllowedJoin = @();
$AllGPOs = Get-GPO -All | sort DisplayName;
foreach ($GPO in $AllGPOs){
$GPOreport = Get-GPOReport -Guid $GPO.id -ReportType Xml;
$permissionindex = $GPOreport.IndexOf('<q1:Name>SeMachineAccountPrivilege</q1:Name>');
if($permissionindex -gt 0){
$xmlreport = [xml]$GPOreport;
foreach ($member in (($xmlreport.GPO.Computer.ExtensionData.Extension.UserRightsAssignment | ? name -eq 'SeMachineAccountPrivilege').member) ){
$obj = New-Object -TypeName psobject;
$obj | Add-Member -MemberType NoteProperty -Name GPO -Value $GPO.DisplayName;
$obj | Add-Member -MemberType NoteProperty -Name SID -Value $member.sid.'#text';
$obj | Add-Member -MemberType NoteProperty -Name Name -Value $member.name.'#text';
$AllowedJoin += $obj;
}
}
}
foreach($record in $AllowedJoin){
Write-Both " [+] GPO [$($record.GPO)] allows object [$($record.Name)] with SID [$($record.SID)] to join computers to domain"
}
}
function Get-PrivelegedGroupMembership{#List Domain Admins, Enterprise Admins and Schema Admins members
$SchemaMemebers = Get-ADGroup 'Schema Admins' | Get-ADGroupMember;
$EnterpriseMemebers = Get-ADGroup 'Enterprise Admins' | Get-ADGroupMember;
$DomainAdminsMemebers = Get-ADGroup 'Domain Admins' | Get-ADGroupMember;
if($SchemaMemebers.count -ne 0){
Write-Both " [!] Schema Admins not empty!!!"
foreach($member in $SchemaMemebers){
Write-Both " [-] $($member.objectClass) $($member.name)"
}
}
if($EnterpriseMemebers.count -ne 0){
Write-Both " [!] Enterprise Admins not empty!!!"
foreach($member in $EnterpriseMemebers){
Write-Both " [-] $($member.objectClass) $($member.name)"
}
}
Write-Both " [+] Domain Admins members"
foreach($member in $DomainAdminsMemebers){
Write-Both " [-] $($member.objectClass) $($member.name)"
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.