<# .SYNOPSIS Generate graphed report for all Active Directory objects. .DESCRIPTION Generate graphed report for all Active Directory objects. .PARAMETER CompanyLogo Enter URL or UNC path to your desired Company Logo for generated report. -CompanyLogo "\\Server01\Admin\Files\CompanyLogo.png" .PARAMETER RightLogo Enter URL or UNC path to your desired right-side logo for generated report. -RightLogo "https://www.psmpartners.com/wp-content/uploads/2017/10/porcaro-stolarek-mete.png" .PARAMETER ReportTitle Enter desired title for generated report. -ReportTitle "Active Directory Report" .PARAMETER Days Users that have not logged in [X] amount of days or more. -Days "30" .PARAMETER UserCreatedDays Users that have been created within [X] amount of days. -UserCreatedDays "7" .PARAMETER DaysUntilPWExpireINT Users password expires within [X] amount of days -DaysUntilPWExpireINT "7" .PARAMETER ADModNumber Active Directory Objects that have been modified within [X] amount of days. -ADModNumber "3" .NOTES Version: 1.0.3 Author: Bradley Wyatt Date: 12/4/2018 Modified: JBear 12/5/2018 Bradley Wyatt 12/8/2018 jporgand 12/6/2018 #> param ( #Company logo that will be displayed on the left, can be URL or UNC [Parameter(ValueFromPipeline = $true, HelpMessage = "Enter URL or UNC path to Company Logo")] [String]$CompanyLogo = "http://thelazyadministrator.com/wp-content/uploads/2018/06/logo-2-e1529684959389.png", #Logo that will be on the right side, UNC or URL [Parameter(ValueFromPipeline = $true, HelpMessage = "Enter URL or UNC path for Side Logo")] [String]$RightLogo = "http://thelazyadministrator.com/wp-content/uploads/2018/06/amd.png", #Title of generated report [Parameter(ValueFromPipeline = $true, HelpMessage = "Enter desired title for report")] [String]$ReportTitle = "Active Directory Report", #Location the report will be saved to [Parameter(ValueFromPipeline = $true, HelpMessage = "Enter desired directory path to save; Default: C:\Automation\")] [String]$ReportSavePath = "C:\Lab\", #Find users that have not logged in X Amount of days, this sets the days [Parameter(ValueFromPipeline = $true, HelpMessage = "Users that have not logged on in more than [X] days. amount of days; Default: 30")] $Days = 30, #Get users who have been created in X amount of days and less [Parameter(ValueFromPipeline = $true, HelpMessage = "Users that have been created within [X] amount of days; Default: 7")] $UserCreatedDays = 7, #Get users whos passwords expire in less than X amount of days [Parameter(ValueFromPipeline = $true, HelpMessage = "Users password expires within [X] amount of days; Default: 7")] $DaysUntilPWExpireINT = 7, #Get AD Objects that have been modified in X days and newer [Parameter(ValueFromPipeline = $true, HelpMessage = "AD Objects that have been modified within [X] amount of days; Default: 3")] $ADModNumber = 3 #CSS template located C:\Program Files\WindowsPowerShell\Modules\ReportHTML\1.4.1.1\ #Default template is orange and named "Sample" ) $DomainAdmin = "Admins du domaine" $EntrepriseAdmin = "Administrateurs de l`'entreprise" Write-Host "Gathering Report Customization..." -ForegroundColor White Write-Host "__________________________________" -ForegroundColor White (Write-Host -NoNewline "Company Logo (left): " -ForegroundColor Yellow), (Write-Host $CompanyLogo -ForegroundColor White) (Write-Host -NoNewline "Company Logo (right): " -ForegroundColor Yellow), (Write-Host $RightLogo -ForegroundColor White) (Write-Host -NoNewline "Report Title: " -ForegroundColor Yellow), (Write-Host $ReportTitle -ForegroundColor White) (Write-Host -NoNewline "Report Save Path: " -ForegroundColor Yellow), (Write-Host $ReportSavePath -ForegroundColor White) (Write-Host -NoNewline "Amount of Days from Last User Logon Report: " -ForegroundColor Yellow), (Write-Host $Days -ForegroundColor White) (Write-Host -NoNewline "Amount of Days for New User Creation Report: " -ForegroundColor Yellow), (Write-Host $UserCreatedDays -ForegroundColor White) (Write-Host -NoNewline "Amount of Days for User Password Expiration Report: " -ForegroundColor Yellow), (Write-Host $DaysUntilPWExpireINT -ForegroundColor White) (Write-Host -NoNewline "Amount of Days for Newly Modified AD Objects Report: " -ForegroundColor Yellow), (Write-Host $ADModNumber -ForegroundColor White) Write-Host "__________________________________" -ForegroundColor White function LastLogonConvert ($ftDate) { $Date = [DateTime]::FromFileTime($ftDate) if ($Date -lt (Get-Date '1/1/1900') -or $date -eq 0 -or $date -eq $null) { "Never" } else { $Date } } #End function LastLogonConvert #Check for ReportHTML Module $Mod = Get-Module -ListAvailable -Name "ReportHTML" If ($null -eq $Mod) { Write-Host "ReportHTML Module is not present, attempting to install it" Install-Module -Name ReportHTML -Force Import-Module ReportHTML -ErrorAction SilentlyContinue } #Array of default Security Groups $DefaultSGs = @( "Access Control Assistance Operators" "Account Operators" "Administrators" "Allowed RODC Password Replication Group" "Backup Operators" "Certificate Service DCOM Access" "Cert Publishers" "Cloneable Domain Controllers" "Cryptographic Operators" "Denied RODC Password Replication Group" "Distributed COM Users" "DnsUpdateProxy" "DnsAdmins" "Domain Admins" "Domain Computers" "Domain Controllers" "Domain Guests" "Domain Users" "Enterprise Admins" "Enterprise Key Admins" "Enterprise Read-only Domain Controllers" "Event Log Readers" "Group Policy Creator Owners" "Guests" "Hyper-V Administrators" "IIS_IUSRS" "Incoming Forest Trust Builders" "Key Admins" "Network Configuration Operators" "Performance Log Users" "Performance Monitor Users" "Print Operators" "Pre-Windows 2000 Compatible Access" "Protected Users" "RAS and IAS Servers" "RDS Endpoint Servers" "RDS Management Servers" "RDS Remote Access Servers" "Read-only Domain Controllers" "Remote Desktop Users" "Remote Management Users" "Replicator" "Schema Admins" "Server Operators" "Storage Replica Administrators" "System Managed Accounts Group" "Terminal Server License Servers" "Users" "Windows Authorization Access Group" "WinRMRemoteWMIUsers" ) $Table = New-Object 'System.Collections.Generic.List[System.Object]' $OUTable = New-Object 'System.Collections.Generic.List[System.Object]' $UserTable = New-Object 'System.Collections.Generic.List[System.Object]' $GroupTypetable = New-Object 'System.Collections.Generic.List[System.Object]' $DefaultGrouptable = New-Object 'System.Collections.Generic.List[System.Object]' $EnabledDisabledUsersTable = New-Object 'System.Collections.Generic.List[System.Object]' $DomainAdminTable = New-Object 'System.Collections.Generic.List[System.Object]' $ExpiringAccountsTable = New-Object 'System.Collections.Generic.List[System.Object]' $CompanyInfoTable = New-Object 'System.Collections.Generic.List[System.Object]' $securityeventtable = New-Object 'System.Collections.Generic.List[System.Object]' $DomainTable = New-Object 'System.Collections.Generic.List[System.Object]' $OUGPOTable = New-Object 'System.Collections.Generic.List[System.Object]' $GroupMembershipTable = New-Object 'System.Collections.Generic.List[System.Object]' $PasswordExpirationTable = New-Object 'System.Collections.Generic.List[System.Object]' $PasswordExpireSoonTable = New-Object 'System.Collections.Generic.List[System.Object]' $userphaventloggedonrecentlytable = New-Object 'System.Collections.Generic.List[System.Object]' $EnterpriseAdminTable = New-Object 'System.Collections.Generic.List[System.Object]' $NewCreatedUsersTable = New-Object 'System.Collections.Generic.List[System.Object]' $GroupProtectionTable = New-Object 'System.Collections.Generic.List[System.Object]' $OUProtectionTable = New-Object 'System.Collections.Generic.List[System.Object]' $GPOTable = New-Object 'System.Collections.Generic.List[System.Object]' $ADObjectTable = New-Object 'System.Collections.Generic.List[System.Object]' $ProtectedUsersTable = New-Object 'System.Collections.Generic.List[System.Object]' $ComputersTable = New-Object 'System.Collections.Generic.List[System.Object]' $ComputerProtectedTable = New-Object 'System.Collections.Generic.List[System.Object]' $ComputersEnabledTable = New-Object 'System.Collections.Generic.List[System.Object]' $DefaultComputersinDefaultOUTable = New-Object 'System.Collections.Generic.List[System.Object]' $DefaultUsersinDefaultOUTable = New-Object 'System.Collections.Generic.List[System.Object]' $TOPUserTable = New-Object 'System.Collections.Generic.List[System.Object]' $TOPGroupsTable = New-Object 'System.Collections.Generic.List[System.Object]' $TOPComputersTable = New-Object 'System.Collections.Generic.List[System.Object]' $GraphComputerOS = New-Object 'System.Collections.Generic.List[System.Object]' #Get all users right away. Instead of doing several lookups, we will use this object to look up all the information needed. $AllUsers = Get-ADUser -Filter * -Properties * $GPOs = Get-GPO -All | Select-Object DisplayName, GPOStatus, ModificationTime, @{ Label = "ComputerVersion"; Expression = { $_.computer.dsversion } }, @{ Label = "UserVersion"; Expression = { $_.user.dsversion } } <########################### Dashboard ############################> Write-Host "Working on Dashboard Report..." -ForegroundColor Green $dte = (Get-Date).AddDays(- $ADModNumber) $ADObjs = Get-ADObject -Filter { whenchanged -gt $dte -and ObjectClass -ne "domainDNS" -and ObjectClass -ne "rIDManager" -and ObjectClass -ne "rIDSet" } -Properties * foreach ($ADObj in $ADObjs) { if ($ADObj.ObjectClass -eq "GroupPolicyContainer") { $Name = $ADObj.DisplayName } else { $Name = $ADObj.Name } $obj = [PSCustomObject]@{ 'Name' = $Name 'Object Type' = $ADObj.ObjectClass 'When Changed' = $ADObj.WhenChanged } $ADObjectTable.Add($obj) } if (($ADObjectTable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: No AD Objects have been modified recently' } $ADObjectTable.Add($obj) } $ADRecycleBinStatus = (Get-ADOptionalFeature -Filter 'name -like "Recycle Bin Feature"').EnabledScopes if ($ADRecycleBinStatus.Count -lt 1) { $ADRecycleBin = "Disabled" } else { $ADRecycleBin = "Enabled" } #Company Information $ADInfo = Get-ADDomain $ForestObj = Get-ADForest $DomainControllerobj = Get-ADDomain $Forest = $ADInfo.Forest $InfrastructureMaster = $DomainControllerobj.InfrastructureMaster $RIDMaster = $DomainControllerobj.RIDMaster $PDCEmulator = $DomainControllerobj.PDCEmulator $DomainNamingMaster = $ForestObj.DomainNamingMaster $SchemaMaster = $ForestObj.SchemaMaster $obj = [PSCustomObject]@{ 'Domain' = $Forest 'AD Recycle Bin' = $ADRecycleBin 'Infrastructure Master' = $InfrastructureMaster 'RID Master' = $RIDMaster 'PDC Emulator' = $PDCEmulator 'Domain Naming Master' = $DomainNamingMaster 'Schema Master' = $SchemaMaster } $CompanyInfoTable.Add($obj) if (($CompanyInfoTable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: Could not get items for table' } $CompanyInfoTable.Add($obj) } #Get newly created users $When = ((Get-Date).AddDays(- $UserCreatedDays)).Date $NewUsers = $AllUsers | Where-Object { $_.whenCreated -ge $When } foreach ($Newuser in $Newusers) { $obj = [PSCustomObject]@{ 'Name' = $Newuser.Name 'Enabled' = $Newuser.Enabled 'Creation Date' = $Newuser.whenCreated } $NewCreatedUsersTable.Add($obj) } if (($NewCreatedUsersTable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: No new users have been recently created' } $NewCreatedUsersTable.Add($obj) } #Get Domain Admins $DomainAdminMembers = Get-ADGroupMember $DomainAdmin foreach ($DomainAdminMember in $DomainAdminMembers) { $Name = $DomainAdminMember.Name $Type = $DomainAdminMember.ObjectClass $Enabled = ($AllUsers | Where-Object { $_.Name -eq $Name }).Enabled $obj = [PSCustomObject]@{ 'Name' = $Name 'Enabled' = $Enabled 'Type' = $Type } $DomainAdminTable.Add($obj) } if (($DomainAdminTable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: No Domain Admin Members were found' } $DomainAdminTable.Add($obj) } #Get Enterprise Admins $EnterpriseAdminsMembers = Get-ADGroupMember $EntrepriseAdmin -Server $SchemaMaster foreach ($EnterpriseAdminsMember in $EnterpriseAdminsMembers) { $Name = $EnterpriseAdminsMember.Name $Type = $EnterpriseAdminsMember.ObjectClass $Enabled = ($AllUsers | Where-Object { $_.Name -eq $Name }).Enabled $obj = [PSCustomObject]@{ 'Name' = $Name 'Enabled' = $Enabled 'Type' = $Type } $EnterpriseAdminTable.Add($obj) } if (($EnterpriseAdminTable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: Enterprise Admin members were found' } $EnterpriseAdminTable.Add($obj) } $DefaultComputersOU = (Get-ADDomain).computerscontainer $DefaultComputers = Get-ADComputer -Filter * -Properties * -SearchBase "$DefaultComputersOU" foreach ($DefaultComputer in $DefaultComputers) { $obj = [PSCustomObject]@{ 'Name' = $DefaultComputer.Name 'Enabled' = $DefaultComputer.Enabled 'Operating System' = $DefaultComputer.OperatingSystem 'Modified Date' = $DefaultComputer.Modified 'Password Last Set' = $DefaultComputer.PasswordLastSet 'Protect from Deletion' = $DefaultComputer.ProtectedFromAccidentalDeletion } $DefaultComputersinDefaultOUTable.Add($obj) } if (($DefaultComputersinDefaultOUTable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: No computers were found in the Default OU' } $DefaultComputersinDefaultOUTable.Add($obj) } $DefaultUsersOU = (Get-ADDomain).UsersContainer $DefaultUsers = $Allusers | Where-Object { $_.DistinguishedName -like "*$($DefaultUsersOU)" } | Select-Object Name, UserPrincipalName, Enabled, ProtectedFromAccidentalDeletion, EmailAddress, @{ Name = 'lastlogon'; Expression = { LastLogonConvert $_.lastlogon } }, DistinguishedName foreach ($DefaultUser in $DefaultUsers) { $obj = [PSCustomObject]@{ 'Name' = $DefaultUser.Name 'UserPrincipalName' = $DefaultUser.UserPrincipalName 'Enabled' = $DefaultUser.Enabled 'Protected from Deletion' = $DefaultUser.ProtectedFromAccidentalDeletion 'Last Logon' = $DefaultUser.LastLogon 'Email Address' = $DefaultUser.EmailAddress } $DefaultUsersinDefaultOUTable.Add($obj) } if (($DefaultUsersinDefaultOUTable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: No Users were found in the default OU' } $DefaultUsersinDefaultOUTable.Add($obj) } #Expiring Accounts $LooseUsers = Search-ADAccount -AccountExpiring -UsersOnly foreach ($LooseUser in $LooseUsers) { $NameLoose = $LooseUser.Name $UPNLoose = $LooseUser.UserPrincipalName $ExpirationDate = $LooseUser.AccountExpirationDate $enabled = $LooseUser.Enabled $obj = [PSCustomObject]@{ 'Name' = $NameLoose 'UserPrincipalName' = $UPNLoose 'Expiration Date' = $ExpirationDate 'Enabled' = $enabled } $ExpiringAccountsTable.Add($obj) } if (($ExpiringAccountsTable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: No Users were found to expire soon' } $ExpiringAccountsTable.Add($obj) } #Security Logs $SecurityLogs = Get-EventLog -Newest 7 -LogName "Security" | Where-Object { $_.Message -like "*An account*" } foreach ($SecurityLog in $SecurityLogs) { $TimeGenerated = $SecurityLog.TimeGenerated $EntryType = $SecurityLog.EntryType $Recipient = $SecurityLog.Message $obj = [PSCustomObject]@{ 'Time' = $TimeGenerated 'Type' = $EntryType 'Message' = $Recipient } $SecurityEventTable.Add($obj) } if (($SecurityEventTable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: No logon security events were found' } $SecurityEventTable.Add($obj) } #Tenant Domain $Domains = Get-ADForest | Select-Object -ExpandProperty upnsuffixes | ForEach-Object { $obj = [PSCustomObject]@{ 'UPN Suffixes' = $_ Valid = "True" } $DomainTable.Add($obj) } if (($DomainTable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: No UPN Suffixes were found' } $DomainTable.Add($obj) } Write-Host "Done!" -ForegroundColor White <########################### Groups ############################> Write-Host "Working on Groups Report..." -ForegroundColor Green #Get groups and sort in alphabetical order $Groups = Get-ADGroup -Filter * -Properties * $SecurityCount = 0 $MailSecurityCount = 0 $CustomGroup = 0 $DefaultGroup = 0 $Groupswithmemebrship = 0 $Groupswithnomembership = 0 $GroupsProtected = 0 $GroupsNotProtected = 0 foreach ($Group in $Groups) { $DefaultADGroup = 'False' $Type = New-Object 'System.Collections.Generic.List[System.Object]' $Gemail = (Get-ADGroup $Group -Properties mail).mail if (($group.GroupCategory -eq "Security") -and ($Gemail -ne $Null)) { $MailSecurityCount++ } if (($group.GroupCategory -eq "Security") -and (($Gemail) -eq $Null)) { $SecurityCount++ } if ($Group.ProtectedFromAccidentalDeletion -eq $True) { $GroupsProtected++ } else { $GroupsNotProtected++ } if ($DefaultSGs -contains $Group.Name) { $DefaultADGroup = "True" $DefaultGroup++ } else { $CustomGroup++ } if ($group.GroupCategory -eq "Distribution") { $Type = "Distribution Group" } if (($group.GroupCategory -eq "Security") -and (($Gemail) -eq $Null)) { $Type = "Security Group" } if (($group.GroupCategory -eq "Security") -and (($Gemail) -ne $Null)) { $Type = "Mail-Enabled Security Group" } if ($Group.Name -ne "Domain Users") { $Users = (Get-ADGroupMember -Identity $Group | Sort-Object DisplayName | Select-Object -ExpandProperty Name) -join ", " if (!($Users)) { $Groupswithnomembership++ } else { $Groupswithmemebrship++ } } else { $Users = "Skipped Domain Users Membership" } $OwnerDN = Get-ADGroup -Filter { name -eq $Group.Name } -Properties managedBy | Select-Object -ExpandProperty ManagedBy Try { $Manager = Get-ADUser -Filter { distinguishedname -like $OwnerDN } | Select-Object -ExpandProperty Name } Catch { write-host -ForegroundColor Yellow "Cannot resolve the manager, " $Manager " on the group " $group.name } #$Manager = $AllUsers | Where-Object { $_.distinguishedname -eq $OwnerDN } | Select-Object -ExpandProperty Name $obj = [PSCustomObject]@{ 'Name' = $Group.name 'Type' = $Type 'Members' = $users 'Managed By' = $Manager 'E-mail Address' = $GEmail 'Protected from Deletion' = $Group.ProtectedFromAccidentalDeletion 'Default AD Group' = $DefaultADGroup } $table.Add($obj) } if (($table).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: No Groups were found' } $table.Add($obj) } #TOP groups table $obj1 = [PSCustomObject]@{ 'Total Groups' = $Groups.Count 'Mail-Enabled Security Groups' = $MailSecurityCount 'Security Groups' = $SecurityCount 'Distribution Groups' = $DistroCount } $TOPGroupsTable.Add($obj1) $obj1 = [PSCustomObject]@{ 'Name' = 'Mail-Enabled Security Groups' 'Count' = $MailSecurityCount } $GroupTypetable.Add($obj1) $obj1 = [PSCustomObject]@{ 'Name' = 'Security Groups' 'Count' = $SecurityCount } $GroupTypetable.Add($obj1) $DistroCount = ($Groups | Where-Object { $_.GroupCategory -eq "Distribution" }).Count $obj1 = [PSCustomObject]@{ 'Name' = 'Distribution Groups' 'Count' = $DistroCount } $GroupTypetable.Add($obj1) #Default Group Pie Chart $obj1 = [PSCustomObject]@{ 'Name' = 'Default Groups' 'Count' = $DefaultGroup } $DefaultGrouptable.Add($obj1) $obj1 = [PSCustomObject]@{ 'Name' = 'Custom Groups' 'Count' = $CustomGroup } $DefaultGrouptable.Add($obj1) #Group Protection Pie Chart $obj1 = [PSCustomObject]@{ 'Name' = 'Protected' 'Count' = $GroupsProtected } $GroupProtectionTable.Add($obj1) $obj1 = [PSCustomObject]@{ 'Name' = 'Not Protected' 'Count' = $GroupsNotProtected } $GroupProtectionTable.Add($obj1) #Groups with membership vs no membership pie chart $objmem = [PSCustomObject]@{ 'Name' = 'With Members' 'Count' = $Groupswithmemebrship } $GroupMembershipTable.Add($objmem) $objmem = [PSCustomObject]@{ 'Name' = 'No Members' 'Count' = $Groupswithnomembership } $GroupMembershipTable.Add($objmem) Write-Host "Done!" -ForegroundColor White <########################### Organizational Units ############################> Write-Host "Working on Organizational Units Report..." -ForegroundColor Green #Get all OUs' $OUs = Get-ADOrganizationalUnit -Filter * -Properties * $OUwithLinked = 0 $OUwithnoLink = 0 $OUProtected = 0 $OUNotProtected = 0 foreach ($OU in $OUs) { $LinkedGPOs = New-Object 'System.Collections.Generic.List[System.Object]' if (($OU.linkedgrouppolicyobjects).length -lt 1) { $LinkedGPOs = "None" $OUwithnoLink++ } else { $OUwithLinked++ $GPOslinks = $OU.linkedgrouppolicyobjects foreach ($GPOlink in $GPOslinks) { $Split1 = $GPOlink -split "{" | Select-Object -Last 1 $Split2 = $Split1 -split "}" | Select-Object -First 1 $LinkedGPOs.Add((Get-GPO -Guid $Split2 -ErrorAction SilentlyContinue).DisplayName) } } if ($OU.ProtectedFromAccidentalDeletion -eq $True) { $OUProtected++ } else { $OUNotProtected++ } $LinkedGPOs = $LinkedGPOs -join ", " $obj = [PSCustomObject]@{ 'Name' = $OU.Name 'Linked GPOs' = $LinkedGPOs 'Modified Date' = $OU.WhenChanged 'Protected from Deletion' = $OU.ProtectedFromAccidentalDeletion } $OUTable.Add($obj) } if (($OUTable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: No OUs were found' } $OUTable.Add($obj) } #OUs with no GPO Linked $obj1 = [PSCustomObject]@{ 'Name' = "OUs with no GPO's linked" 'Count' = $OUwithnoLink } $OUGPOTable.Add($obj1) $obj2 = [PSCustomObject]@{ 'Name' = "OUs with GPO's linked" 'Count' = $OUwithLinked } $OUGPOTable.Add($obj2) #OUs Protected Pie Chart $obj1 = [PSCustomObject]@{ 'Name' = "Protected" 'Count' = $OUProtected } $OUProtectionTable.Add($obj1) $obj2 = [PSCustomObject]@{ 'Name' = "Not Protected" 'Count' = $OUNotProtected } $OUProtectionTable.Add($obj2) Write-Host "Done!" -ForegroundColor White <########################### USERS ############################> Write-Host "Working on Users Report..." -ForegroundColor Green $UserEnabled = 0 $UserDisabled = 0 $UserPasswordExpires = 0 $UserPasswordNeverExpires = 0 $ProtectedUsers = 0 $NonProtectedUsers = 0 $UsersWIthPasswordsExpiringInUnderAWeek = 0 $UsersNotLoggedInOver30Days = 0 $AccountsExpiringSoon = 0 #Get users that haven't logged on in X amount of days, var is set at start of script $userphaventloggedonrecentlytable = New-Object 'System.Collections.Generic.List[System.Object]' foreach ($User in $AllUsers) { $AttVar = $User | Select-Object Enabled, PasswordExpired, PasswordLastSet, PasswordNeverExpires, PasswordNotRequired, Name, SamAccountName, EmailAddress, AccountExpirationDate, @{ Name = 'lastlogon'; Expression = { LastLogonConvert $_.lastlogon } }, DistinguishedName $maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge.Days if ((($AttVar.PasswordNeverExpires) -eq $False) -and (($AttVar.Enabled) -ne $false)) { #Get Password last set date $passwordSetDate = ($User | ForEach-Object { $_.PasswordLastSet }) if ($null -eq $passwordSetDate) { $daystoexpire = "User has never logged on" } else { #Check for Fine Grained Passwords $PasswordPol = (Get-ADUserResultantPasswordPolicy $user) if (($PasswordPol) -ne $null) { $maxPasswordAge = ($PasswordPol).MaxPasswordAge } $expireson = $passwordsetdate.AddDays($maxPasswordAge) $today = (Get-Date) #Gets the count on how many days until the password expires and stores it in the $daystoexpire var $daystoexpire = (New-TimeSpan -Start $today -End $Expireson).Days } } else { $daystoexpire = "N/A" } if (($User.Enabled -eq $True) -and ($AttVar.LastLogon -lt ((Get-Date).AddDays(- $Days))) -and ($User.LastLogon -ne $NULL)) { $obj = [PSCustomObject]@{ 'Name' = $User.Name 'UserPrincipalName' = $User.UserPrincipalName 'Enabled' = $AttVar.Enabled 'Protected from Deletion' = $User.ProtectedFromAccidentalDeletion 'Last Logon' = $AttVar.lastlogon 'Password Never Expires' = $AttVar.PasswordNeverExpires 'Days Until Password Expires' = $daystoexpire } $userphaventloggedonrecentlytable.Add($obj) } #Items for protected vs non protected users if ($User.ProtectedFromAccidentalDeletion -eq $False) { $NonProtectedUsers++ } else { $ProtectedUsers++ } #Items for the enabled vs disabled users pie chart if (($AttVar.PasswordNeverExpires) -ne $false) { $UserPasswordNeverExpires++ } else { $UserPasswordExpires++ } #Items for password expiration pie chart if (($AttVar.Enabled) -ne $false) { $UserEnabled++ } else { $UserDisabled++ } $Name = $User.Name $UPN = $User.UserPrincipalName $Enabled = $AttVar.Enabled $EmailAddress = $AttVar.EmailAddress $AccountExpiration = $AttVar.AccountExpirationDate $PasswordExpired = $AttVar.PasswordExpired $PasswordLastSet = $AttVar.PasswordLastSet $PasswordNeverExpires = $AttVar.PasswordNeverExpires $daysUntilPWExpire = $daystoexpire $obj = [PSCustomObject]@{ 'Name' = $Name 'UserPrincipalName' = $UPN 'Enabled' = $Enabled 'Protected from Deletion' = $User.ProtectedFromAccidentalDeletion 'Last Logon' = $LastLogon 'Email Address' = $EmailAddress 'Account Expiration' = $AccountExpiration 'Change Password Next Logon' = $PasswordExpired 'Password Last Set' = $PasswordLastSet 'Password Never Expires' = $PasswordNeverExpires 'Days Until Password Expires' = $daystoexpire } $usertable.Add($obj) if ($daystoexpire -lt $DaysUntilPWExpireINT) { $obj = [PSCustomObject]@{ 'Name' = $Name 'Days Until Password Expires' = $daystoexpire } $PasswordExpireSoonTable.Add($obj) } } if (($userphaventloggedonrecentlytable).Count -eq 0) { $userphaventloggedonrecentlytable = [PSCustomObject]@{ Information = "Information: No Users were found to have not logged on in $Days days or more" } } if (($PasswordExpireSoonTable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: No users were found to have passwords expiring soon' } $PasswordExpireSoonTable.Add($obj) } if (($usertable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: No users were found' } $usertable.Add($obj) } #Data for users enabled vs disabled pie graph $objULic = [PSCustomObject]@{ 'Name' = 'Enabled' 'Count' = $UserEnabled } $EnabledDisabledUsersTable.Add($objULic) $objULic = [PSCustomObject]@{ 'Name' = 'Disabled' 'Count' = $UserDisabled } $EnabledDisabledUsersTable.Add($objULic) #Data for users password expires pie graph $objULic = [PSCustomObject]@{ 'Name' = 'Password Expires' 'Count' = $UserPasswordExpires } $PasswordExpirationTable.Add($objULic) $objULic = [PSCustomObject]@{ 'Name' = 'Password Never Expires' 'Count' = $UserPasswordNeverExpires } $PasswordExpirationTable.Add($objULic) #Data for protected users pie graph $objULic = [PSCustomObject]@{ 'Name' = 'Protected' 'Count' = $ProtectedUsers } $ProtectedUsersTable.Add($objULic) $objULic = [PSCustomObject]@{ 'Name' = 'Not Protected' 'Count' = $NonProtectedUsers } $ProtectedUsersTable.Add($objULic) if ($null -ne (($userphaventloggedonrecentlytable).Information)) { $UHLONXD = "0" } Else { $UHLONXD = $userphaventloggedonrecentlytable.Count } #TOP User table If ($null -eq (($ExpiringAccountsTable).Information)) { $objULic = [PSCustomObject]@{ 'Total Users' = $AllUsers.Count "Users with Passwords Expiring in less than $DaysUntilPWExpireINT days" = $PasswordExpireSoonTable.Count 'Expiring Accounts' = $ExpiringAccountsTable.Count "Users Haven't Logged on in $Days Days or more" = $UHLONXD } $TOPUserTable.Add($objULic) } Else { $objULic = [PSCustomObject]@{ 'Total Users' = $AllUsers.Count "Users with Passwords Expiring in less than $DaysUntilPWExpireINT days" = $PasswordExpireSoonTable.Count 'Expiring Accounts' = "0" "Users Haven't Logged on in $Days Days or more" = $UHLONXD } $TOPUserTable.Add($objULic) } Write-Host "Done!" -ForegroundColor White <########################### Group Policy ############################> Write-Host "Working on Group Policy Report..." -ForegroundColor Green $GPOTable = New-Object 'System.Collections.Generic.List[System.Object]' foreach ($GPO in $GPOs) { $obj = [PSCustomObject]@{ 'Name' = $GPO.DisplayName 'Status' = $GPO.GpoStatus 'Modified Date' = $GPO.ModificationTime 'User Version' = $GPO.UserVersion 'Computer Version' = $GPO.ComputerVersion } $GPOTable.Add($obj) } if (($GPOTable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: No Group Policy Obejects were found' } $GPOTable.Add($obj) } Write-Host "Done!" -ForegroundColor White <########################### Computers ############################> Write-Host "Working on Computers Report..." -ForegroundColor Green $Computers = Get-ADComputer -Filter * -Properties * $ComputersProtected = 0 $ComputersNotProtected = 0 $ComputerEnabled = 0 $ComputerDisabled = 0 #Only search for versions of windows that exist in the Environment $WindowsRegex = "(Windows (Server )?(\d+|XP)?( R2)?).*" $OsVersions = $Computers | Select-Object OperatingSystem -unique | ForEach-Object { if ($_.OperatingSystem -match $WindowsRegex ) { return $matches[1] } elseif ($_.OperatingSystem -ne $null) { return $_.OperatingSystem } } | Select-Object -unique | Sort-Object $OsObj = [PSCustomObject]@{} $OsVersions | ForEach-Object { $OsObj | Add-Member -Name $_ -Value 0 -Type NoteProperty } foreach ($Computer in $Computers) { if ($Computer.ProtectedFromAccidentalDeletion -eq $True) { $ComputersProtected++ } else { $ComputersNotProtected++ } if ($Computer.Enabled -eq $True) { $ComputerEnabled++ } else { $ComputerDisabled++ } $obj = [PSCustomObject]@{ 'Name' = $Computer.Name 'Enabled' = $Computer.Enabled 'Operating System' = $Computer.OperatingSystem 'Modified Date' = $Computer.Modified 'Password Last Set' = $Computer.PasswordLastSet 'Protect from Deletion' = $Computer.ProtectedFromAccidentalDeletion } $ComputersTable.Add($obj) if ($Computer.OperatingSystem -match $WindowsRegex) { $OsObj."$($matches[1])"++ } } if (($ComputersTable).Count -eq 0) { $Obj = [PSCustomObject]@{ Information = 'Information: No computers were found' } $ComputersTable.Add($obj) } #Pie chart breaking down OS for computer obj $OsObj.PSObject.Properties | ForEach-Object { $GraphComputerOS.Add([PSCustomObject]@{'Name' = $_.Name; "Count" = $_.Value }) } #Data for TOP Computers data table $OsObj | Add-Member -Name 'Total Computers' -Value $Computers.Count -Type NoteProperty $TOPComputersTable.Add($OsObj) #Data for protected Computers pie graph $objULic = [PSCustomObject]@{ 'Name' = 'Protected' 'Count' = $ComputerProtected } $ComputerProtectedTable.Add($objULic) $objULic = [PSCustomObject]@{ 'Name' = 'Not Protected' 'Count' = $ComputersNotProtected } $ComputerProtectedTable.Add($objULic) #Data for enabled/vs Computers pie graph $objULic = [PSCustomObject]@{ 'Name' = 'Enabled' 'Count' = $ComputerEnabled } $ComputersEnabledTable.Add($objULic) $objULic = [PSCustomObject]@{ 'Name' = 'Disabled' 'Count' = $ComputerDisabled } $ComputersEnabledTable.Add($objULic) Write-Host "Done!" -ForegroundColor White $tabarray = @('Dashboard', 'Groups', 'Organizational Units', 'Users', 'Group Policy', 'Computers') Write-Host "Compiling Report..." -ForegroundColor Green ##--OU Protection PIE CHART--## #Basic Properties $PO12 = Get-HTMLPieChartObject $PO12.Title = "Organizational Units Protected from Deletion" $PO12.Size.Height = 250 $PO12.Size.width = 250 $PO12.ChartStyle.ChartType = 'doughnut' #These file exist in the module directoy, There are 4 schemes by default $PO12.ChartStyle.ColorSchemeName = "ColorScheme3" #There are 8 generated schemes, randomly generated at runtime $PO12.ChartStyle.ColorSchemeName = "Generated3" #you can also ask for a random scheme. Which also happens ifyou have too many records for the scheme $PO12.ChartStyle.ColorSchemeName = 'Random' #Data defintion you can reference any column from name and value from the dataset. #Name and Count are the default to work with the Group function. $PO12.DataDefinition.DataNameColumnName = 'Name' $PO12.DataDefinition.DataValueColumnName = 'Count' ##--Computer OS Breakdown PIE CHART--## $PieObjectComputerObjOS = Get-HTMLPieChartObject $PieObjectComputerObjOS.Title = "Computer Operating Systems" #These file exist in the module directoy, There are 4 schemes by default $PieObjectComputerObjOS.ChartStyle.ColorSchemeName = "ColorScheme3" #There are 8 generated schemes, randomly generated at runtime $PieObjectComputerObjOS.ChartStyle.ColorSchemeName = "Generated3" #you can also ask for a random scheme. Which also happens ifyou have too many records for the scheme $PieObjectComputerObjOS.ChartStyle.ColorSchemeName = 'Random' ##--Computers Protection PIE CHART--## #Basic Properties $PieObjectComputersProtected = Get-HTMLPieChartObject $PieObjectComputersProtected.Title = "Computers Protected from Deletion" $PieObjectComputersProtected.Size.Height = 250 $PieObjectComputersProtected.Size.width = 250 $PieObjectComputersProtected.ChartStyle.ChartType = 'doughnut' #These file exist in the module directoy, There are 4 schemes by default $PieObjectComputersProtected.ChartStyle.ColorSchemeName = "ColorScheme3" #There are 8 generated schemes, randomly generated at runtime $PieObjectComputersProtected.ChartStyle.ColorSchemeName = "Generated3" #you can also ask for a random scheme. Which also happens ifyou have too many records for the scheme $PieObjectComputersProtected.ChartStyle.ColorSchemeName = 'Random' #Data defintion you can reference any column from name and value from the dataset. #Name and Count are the default to work with the Group function. $PieObjectComputersProtected.DataDefinition.DataNameColumnName = 'Name' $PieObjectComputersProtected.DataDefinition.DataValueColumnName = 'Count' ##--Computers Enabled PIE CHART--## #Basic Properties $PieObjectComputersEnabled = Get-HTMLPieChartObject $PieObjectComputersEnabled.Title = "Computers Enabled vs Disabled" $PieObjectComputersEnabled.Size.Height = 250 $PieObjectComputersEnabled.Size.width = 250 $PieObjectComputersEnabled.ChartStyle.ChartType = 'doughnut' #These file exist in the module directoy, There are 4 schemes by default $PieObjectComputersEnabled.ChartStyle.ColorSchemeName = "ColorScheme3" #There are 8 generated schemes, randomly generated at runtime $PieObjectComputersEnabled.ChartStyle.ColorSchemeName = "Generated3" #you can also ask for a random scheme. Which also happens ifyou have too many records for the scheme $PieObjectComputersEnabled.ChartStyle.ColorSchemeName = 'Random' #Data defintion you can reference any column from name and value from the dataset. #Name and Count are the default to work with the Group function. $PieObjectComputersEnabled.DataDefinition.DataNameColumnName = 'Name' $PieObjectComputersEnabled.DataDefinition.DataValueColumnName = 'Count' ##--USERS Protection PIE CHART--## #Basic Properties $PieObjectProtectedUsers = Get-HTMLPieChartObject $PieObjectProtectedUsers.Title = "Users Protected from Deletion" $PieObjectProtectedUsers.Size.Height = 250 $PieObjectProtectedUsers.Size.width = 250 $PieObjectProtectedUsers.ChartStyle.ChartType = 'doughnut' #These file exist in the module directoy, There are 4 schemes by default $PieObjectProtectedUsers.ChartStyle.ColorSchemeName = "ColorScheme3" #There are 8 generated schemes, randomly generated at runtime $PieObjectProtectedUsers.ChartStyle.ColorSchemeName = "Generated3" #you can also ask for a random scheme. Which also happens ifyou have too many records for the scheme $PieObjectProtectedUsers.ChartStyle.ColorSchemeName = 'Random' #Data defintion you can reference any column from name and value from the dataset. #Name and Count are the default to work with the Group function. $PieObjectProtectedUsers.DataDefinition.DataNameColumnName = 'Name' $PieObjectProtectedUsers.DataDefinition.DataValueColumnName = 'Count' #Basic Properties $PieObjectOUGPOLinks = Get-HTMLPieChartObject $PieObjectOUGPOLinks.Title = "OU GPO Links" $PieObjectOUGPOLinks.Size.Height = 250 $PieObjectOUGPOLinks.Size.width = 250 $PieObjectOUGPOLinks.ChartStyle.ChartType = 'doughnut' #These file exist in the module directoy, There are 4 schemes by default $PieObjectOUGPOLinks.ChartStyle.ColorSchemeName = "ColorScheme4" #There are 8 generated schemes, randomly generated at runtime $PieObjectOUGPOLinks.ChartStyle.ColorSchemeName = "Generated5" #you can also ask for a random scheme. Which also happens ifyou have too many records for the scheme $PieObjectOUGPOLinks.ChartStyle.ColorSchemeName = 'Random' #Data defintion you can reference any column from name and value from the dataset. #Name and Count are the default to work with the Group function. $PieObjectOUGPOLinks.DataDefinition.DataNameColumnName = 'Name' $PieObjectOUGPOLinks.DataDefinition.DataValueColumnName = 'Count' #Basic Properties $PieObject4 = Get-HTMLPieChartObject $PieObject4.Title = "Office 365 Unassigned Licenses" $PieObject4.Size.Height = 250 $PieObject4.Size.width = 250 $PieObject4.ChartStyle.ChartType = 'doughnut' #These file exist in the module directoy, There are 4 schemes by default $PieObject4.ChartStyle.ColorSchemeName = "ColorScheme4" #There are 8 generated schemes, randomly generated at runtime $PieObject4.ChartStyle.ColorSchemeName = "Generated4" #you can also ask for a random scheme. Which also happens ifyou have too many records for the scheme $PieObject4.ChartStyle.ColorSchemeName = 'Random' #Data defintion you can reference any column from name and value from the dataset. #Name and Count are the default to work with the Group function. $PieObject4.DataDefinition.DataNameColumnName = 'Name' $PieObject4.DataDefinition.DataValueColumnName = 'Unassigned Licenses' #Basic Properties $PieObjectGroupType = Get-HTMLPieChartObject $PieObjectGroupType.Title = "Group Types" $PieObjectGroupType.Size.Height = 250 $PieObjectGroupType.Size.width = 250 $PieObjectGroupType.ChartStyle.ChartType = 'doughnut' #Pie Chart Groups with members vs no members $PieObjectGroupMembersType = Get-HTMLPieChartObject $PieObjectGroupMembersType.Title = "Group Membership" $PieObjectGroupMembersType.Size.Height = 250 $PieObjectGroupMembersType.Size.width = 250 $PieObjectGroupMembersType.ChartStyle.ChartType = 'doughnut' $PieObjectGroupMembersType.ChartStyle.ColorSchemeName = "ColorScheme4" $PieObjectGroupMembersType.ChartStyle.ColorSchemeName = "Generated8" $PieObjectGroupMembersType.ChartStyle.ColorSchemeName = 'Random' $PieObjectGroupMembersType.DataDefinition.DataNameColumnName = 'Name' $PieObjectGroupMembersType.DataDefinition.DataValueColumnName = 'Count' #Basic Properties $PieObjectGroupType2 = Get-HTMLPieChartObject $PieObjectGroupType2.Title = "Custom vs Default Groups" $PieObjectGroupType2.Size.Height = 250 $PieObjectGroupType2.Size.width = 250 $PieObjectGroupType2.ChartStyle.ChartType = 'doughnut' #These file exist in the module directoy, There are 4 schemes by default $PieObjectGroupType.ChartStyle.ColorSchemeName = "ColorScheme4" #There are 8 generated schemes, randomly generated at runtime $PieObjectGroupType.ChartStyle.ColorSchemeName = "Generated8" #you can also ask for a random scheme. Which also happens ifyou have too many records for the scheme $PieObjectGroupType.ChartStyle.ColorSchemeName = 'Random' #Data defintion you can reference any column from name and value from the dataset. #Name and Count are the default to work with the Group function. $PieObjectGroupType.DataDefinition.DataNameColumnName = 'Name' $PieObjectGroupType.DataDefinition.DataValueColumnName = 'Count' ##--Enabled users vs Disabled Users PIE CHART--## #Basic Properties $EnabledDisabledUsersPieObject = Get-HTMLPieChartObject $EnabledDisabledUsersPieObject.Title = "Enabled vs Disabled Users" $EnabledDisabledUsersPieObject.Size.Height = 250 $EnabledDisabledUsersPieObject.Size.width = 250 $EnabledDisabledUsersPieObject.ChartStyle.ChartType = 'doughnut' #These file exist in the module directoy, There are 4 schemes by default $EnabledDisabledUsersPieObject.ChartStyle.ColorSchemeName = "ColorScheme3" #There are 8 generated schemes, randomly generated at runtime $EnabledDisabledUsersPieObject.ChartStyle.ColorSchemeName = "Generated3" #you can also ask for a random scheme. Which also happens ifyou have too many records for the scheme $EnabledDisabledUsersPieObject.ChartStyle.ColorSchemeName = 'Random' #Data defintion you can reference any column from name and value from the dataset. #Name and Count are the default to work with the Group function. $EnabledDisabledUsersPieObject.DataDefinition.DataNameColumnName = 'Name' $EnabledDisabledUsersPieObject.DataDefinition.DataValueColumnName = 'Count' ##--PasswordNeverExpires PIE CHART--## #Basic Properties $PWExpiresUsersTable = Get-HTMLPieChartObject $PWExpiresUsersTable.Title = "Password Expiration" $PWExpiresUsersTable.Size.Height = 250 $PWExpiresUsersTable.Size.Width = 250 $PWExpiresUsersTable.ChartStyle.ChartType = 'doughnut' #These file exist in the module directoy, There are 4 schemes by default $PWExpiresUsersTable.ChartStyle.ColorSchemeName = "ColorScheme3" #There are 8 generated schemes, randomly generated at runtime $PWExpiresUsersTable.ChartStyle.ColorSchemeName = "Generated3" #you can also ask for a random scheme. Which also happens ifyou have too many records for the scheme $PWExpiresUsersTable.ChartStyle.ColorSchemeName = 'Random' #Data defintion you can reference any column from name and value from the dataset. #Name and Count are the default to work with the Group function. $PWExpiresUsersTable.DataDefinition.DataNameColumnName = 'Name' $PWExpiresUsersTable.DataDefinition.DataValueColumnName = 'Count' ##--Group Protection PIE CHART--## #Basic Properties $PieObjectGroupProtection = Get-HTMLPieChartObject $PieObjectGroupProtection.Title = "Groups Protected from Deletion" $PieObjectGroupProtection.Size.Height = 250 $PieObjectGroupProtection.Size.width = 250 $PieObjectGroupProtection.ChartStyle.ChartType = 'doughnut' #These file exist in the module directoy, There are 4 schemes by default $PieObjectGroupProtection.ChartStyle.ColorSchemeName = "ColorScheme3" #There are 8 generated schemes, randomly generated at runtime $PieObjectGroupProtection.ChartStyle.ColorSchemeName = "Generated3" #you can also ask for a random scheme. Which also happens ifyou have too many records for the scheme $PieObjectGroupProtection.ChartStyle.ColorSchemeName = 'Random' #Data defintion you can reference any column from name and value from the dataset. #Name and Count are the default to work with the Group function. $PieObjectGroupProtection.DataDefinition.DataNameColumnName = 'Name' $PieObjectGroupProtection.DataDefinition.DataValueColumnName = 'Count' #Dashboard Report $FinalReport = New-Object 'System.Collections.Generic.List[System.Object]' $FinalReport.Add($(Get-HTMLOpenPage -TitleText $ReportTitle -LeftLogoString $CompanyLogo -RightLogoString $RightLogo)) $FinalReport.Add($(Get-HTMLTabHeader -TabNames $tabarray)) $FinalReport.Add($(Get-HTMLTabContentopen -TabName $tabarray[0] -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy)))) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Company Information")) $FinalReport.Add($(Get-HTMLContentTable $CompanyInfoTable)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Groups")) $FinalReport.Add($(Get-HTMLColumn1of2)) $FinalReport.Add($(Get-HTMLContentOpen -BackgroundShade 1 -HeaderText 'Domain Administrators')) $FinalReport.Add($(Get-HTMLContentDataTable $DomainAdminTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLColumn2of2)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText 'Enterprise Administrators')) $FinalReport.Add($(Get-HTMLContentDataTable $EnterpriseAdminTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Objects in Default OUs")) $FinalReport.Add($(Get-HTMLColumn1of2)) $FinalReport.Add($(Get-HTMLContentOpen -BackgroundShade 1 -HeaderText 'Computers')) $FinalReport.Add($(Get-HTMLContentDataTable $DefaultComputersinDefaultOUTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLColumn2of2)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText 'Users')) $FinalReport.Add($(Get-HTMLContentDataTable $DefaultUsersinDefaultOUTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "AD Objects Modified in Last $ADModNumber Days")) $FinalReport.Add($(Get-HTMLContentDataTable $ADObjectTable)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Expiring Items")) $FinalReport.Add($(Get-HTMLColumn1of2)) $FinalReport.Add($(Get-HTMLContentOpen -BackgroundShade 1 -HeaderText "Users with Passwords Expiring in less than $DaysUntilPWExpireINT days")) $FinalReport.Add($(Get-HTMLContentDataTable $PasswordExpireSoonTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLColumn2of2)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText 'Accounts Expiring Soon')) $FinalReport.Add($(Get-HTMLContentDataTable $ExpiringAccountsTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Accounts")) $FinalReport.Add($(Get-HTMLColumn1of2)) $FinalReport.Add($(Get-HTMLContentOpen -BackgroundShade 1 -HeaderText "Users Haven't Logged on in $Days Days or more")) $FinalReport.Add($(Get-HTMLContentDataTable $userphaventloggedonrecentlytable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLColumn2of2)) $FinalReport.Add($(Get-HTMLContentOpen -BackgroundShade 1 -HeaderText "Accounts Created in $UserCreatedDays Days or Less")) $FinalReport.Add($(Get-HTMLContentDataTable $NewCreatedUsersTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Security Logs")) $FinalReport.Add($(Get-HTMLContentDataTable $securityeventtable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "UPN Suffixes")) $FinalReport.Add($(Get-HTMLContentTable $DomainTable)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLTabContentClose)) #Groups Report $FinalReport.Add($(Get-HTMLTabContentopen -TabName $tabarray[1] -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy)))) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Groups Overivew")) $FinalReport.Add($(Get-HTMLContentTable $TOPGroupsTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Active Directory Groups")) $FinalReport.Add($(Get-HTMLContentDataTable $Table -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumn1of2)) $FinalReport.Add($(Get-HTMLContentOpen -BackgroundShade 1 -HeaderText 'Domain Administrators')) $FinalReport.Add($(Get-HTMLContentDataTable $DomainAdminTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLColumn2of2)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText 'Enterprise Administrators')) $FinalReport.Add($(Get-HTMLContentDataTable $EnterpriseAdminTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Active Directory Groups Chart")) $FinalReport.Add($(Get-HTMLColumnOpen -ColumnNumber 1 -ColumnCount 4)) $FinalReport.Add($(Get-HTMLPieChart -ChartObject $PieObjectGroupType -DataSet $GroupTypetable)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLColumnOpen -ColumnNumber 2 -ColumnCount 4)) $FinalReport.Add($(Get-HTMLPieChart -ChartObject $PieObjectGroupType2 -DataSet $DefaultGrouptable)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLColumnOpen -ColumnNumber 3 -ColumnCount 4)) $FinalReport.Add($(Get-HTMLPieChart -ChartObject $PieObjectGroupMembersType -DataSet $GroupMembershipTable)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLColumnOpen -ColumnNumber 4 -ColumnCount 4)) $FinalReport.Add($(Get-HTMLPieChart -ChartObject $PieObjectGroupProtection -DataSet $GroupProtectionTable)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLTabContentClose)) #Organizational Unit Report $FinalReport.Add($(Get-HTMLTabContentopen -TabName $tabarray[2] -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy)))) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Organizational Units")) $FinalReport.Add($(Get-HTMLContentDataTable $OUTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Organizational Units Charts")) $FinalReport.Add($(Get-HTMLColumnOpen -ColumnNumber 1 -ColumnCount 2)) $FinalReport.Add($(Get-HTMLPieChart -ChartObject $PieObjectOUGPOLinks -DataSet $OUGPOTable)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLColumnOpen -ColumnNumber 2 -ColumnCount 2)) $FinalReport.Add($(Get-HTMLPieChart -ChartObject $PO12 -DataSet $OUProtectionTable)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLContentclose)) $FinalReport.Add($(Get-HTMLTabContentClose)) #Users Report $FinalReport.Add($(Get-HTMLTabContentopen -TabName $tabarray[3] -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy)))) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Users Overivew")) $FinalReport.Add($(Get-HTMLContentTable $TOPUserTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Active Directory Users")) $FinalReport.Add($(Get-HTMLContentDataTable $UserTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Expiring Items")) $FinalReport.Add($(Get-HTMLColumn1of2)) $FinalReport.Add($(Get-HTMLContentOpen -BackgroundShade 1 -HeaderText "Users with Passwords Expiring in less than $DaysUntilPWExpireINT days")) $FinalReport.Add($(Get-HTMLContentDataTable $PasswordExpireSoonTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLColumn2of2)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText 'Accounts Expiring Soon')) $FinalReport.Add($(Get-HTMLContentDataTable $ExpiringAccountsTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Accounts")) $FinalReport.Add($(Get-HTMLColumn1of2)) $FinalReport.Add($(Get-HTMLContentOpen -BackgroundShade 1 -HeaderText "Users Haven't Logged on in $Days Days or more")) $FinalReport.Add($(Get-HTMLContentDataTable $userphaventloggedonrecentlytable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLColumn2of2)) $FinalReport.Add($(Get-HTMLContentOpen -BackgroundShade 1 -HeaderText "Accounts Created in $UserCreatedDays Days or Less")) $FinalReport.Add($(Get-HTMLContentDataTable $NewCreatedUsersTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Users Charts")) $FinalReport.Add($(Get-HTMLColumnOpen -ColumnNumber 1 -ColumnCount 3)) $FinalReport.Add($(Get-HTMLPieChart -ChartObject $EnabledDisabledUsersPieObject -DataSet $EnabledDisabledUsersTable)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLColumnOpen -ColumnNumber 2 -ColumnCount 3)) $FinalReport.Add($(Get-HTMLPieChart -ChartObject $PWExpiresUsersTable -DataSet $PasswordExpirationTable)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLColumnOpen -ColumnNumber 3 -ColumnCount 3)) $FinalReport.Add($(Get-HTMLPieChart -ChartObject $PieObjectProtectedUsers -DataSet $ProtectedUsersTable)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLTabContentClose)) #GPO Report $FinalReport.Add($(Get-HTMLTabContentopen -TabName $tabarray[4] -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy)))) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Group Policies")) $FinalReport.Add($(Get-HTMLContentDataTable $GPOTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLTabContentClose)) #Computers Report $FinalReport.Add($(Get-HTMLTabContentopen -TabName $tabarray[5] -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy)))) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Computers Overivew")) $FinalReport.Add($(Get-HTMLContentTable $TOPComputersTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Computers")) $FinalReport.Add($(Get-HTMLContentDataTable $ComputersTable -HideFooter)) $FinalReport.Add($(Get-HTMLContentClose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Computers Charts")) $FinalReport.Add($(Get-HTMLColumnOpen -ColumnNumber 1 -ColumnCount 2)) $FinalReport.Add($(Get-HTMLPieChart -ChartObject $PieObjectComputersProtected -DataSet $ComputerProtectedTable)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLColumnOpen -ColumnNumber 2 -ColumnCount 2)) $FinalReport.Add($(Get-HTMLPieChart -ChartObject $PieObjectComputersEnabled -DataSet $ComputersEnabledTable)) $FinalReport.Add($(Get-HTMLColumnClose)) $FinalReport.Add($(Get-HTMLContentclose)) $FinalReport.Add($(Get-HTMLContentOpen -HeaderText "Computers Operating System Breakdown")) $FinalReport.Add($(Get-HTMLPieChart -ChartObject $PieObjectComputerObjOS -DataSet $GraphComputerOS)) $FinalReport.Add($(Get-HTMLContentclose)) $FinalReport.Add($(Get-HTMLTabContentClose)) $FinalReport.Add($(Get-HTMLClosePage)) $Day = (Get-Date).Day $Month = (Get-Date).Month $Year = (Get-Date).Year $ReportName = ("$Day - $Month - $Year - AD Report") Save-HTMLReport -ReportContent $FinalReport -ShowReport -ReportName $ReportName -ReportPath $ReportSavePath