Wouldn’t it be cool to learn all the changes made to Active Directory recently? All the accounts added and removed, all the ones modified including the old and the new values for each modified property? Below is a script that does exactly that: creates snapshots of your AD and allows to compare your live environments against them.
Yeah, I know that there are commercial products doing that (and even allowing rollbacks) and that AD auditing in Windows 2008 is now almost there natively but hey this is a PowerShell blog.
The basic idea behind the script below is:
- We have a set of properties which we want to track.
- Let’s retrieve them and export to an XML file. That will be our snapshot.
- At any time we can then load the snapshot and compare it against what is currently in the AD.
Here’s the code. Not perfect – feel free to improve it at the code repository – but works for me!
############################################################################### # Compare-AD - a set of functions (and sample code using them) to create # snapshots of user accounts in the current Active Directory domain # save them in an xml file, and then compare live AD environment # against that XML # # (C) Dmitry Sotnikov # http://dmitrysotnikov.wordpress.com/2008/10/14/compare-ad-against-snapshotscompare-ad-against-snapshots # ############################################################################### # Requires QAD cmdlets if ((Get-PSSnapin "Quest.ActiveRoles.ADManagement" ` -ErrorAction SilentlyContinue) -eq $null) { Add-PSSnapin "Quest.ActiveRoles.ADManagement" } ############################################################################### # Functions ############################################################################### # Retrives all AD users from the current domain and stores the selected # set of properties (passed as an array of strings in the $properties parameter) # as an xml file by the path passed as $path # See sample use below function New-Snapshot { param($path, $properties) Get-QADUser -SizeLimit 0 -DontUseDefaultIncludedProperties ` -IncludedProperties $properties | Select $properties | Export-Clixml $path } # Load the snapshot and compare it against current AD domain function Compare-ActiveDirectory { param($path, $properties) # $old is the snapshot, $new is the current environment data $old = Import-Clixml $path $new = Get-QADUser -SizeLimit 0 -DontUseDefaultIncludedProperties ` -IncludedProperties $properties | Select $properties # First lets report the ones which got created or deleted $diff = Compare-Object $old $new -Property Name $created = , ($diff | where { $_.SideIndicator -eq "=>" }) $deleted = , ($diff | where { $_.SideIndicator -eq "<=" }) if ( $created.Count -gt 0 ) { "New accounts:" $created | Format-Table Name } if ( $deleted.Count -gt 0 ) { "Deleted accounts:" $deleted | Format-Table Name } # Now let's load the accounts in a hash-table so it is easier to locate them $hash = @{} $new | ForEach-Object { $hash[$_.DistinguishedName] = $_ } # Let's enumerate the accounts and their properties and report any changes "Modified objects:" foreach ( $snapshot in $old ) { $current = $hash[$snapshot.DistinguishedName] if ( $current -and ($current.ModificationDate -ne $snapshot.ModificationDate )) { @" Object $($snapshot.distinguishedname) Modified at $($current.ModificationDate) Property`tOld Value`tNew Value ========`t=========`t========= "@ foreach ($property in $properties) { if ( ($property -ne "ModificationDate") -and ($snapshot.$property -ne $current.$property )) { "$property`t$($snapshot.$property)`t$($current.$property)" } } } } } ############################################################################### # Common parameters ############################################################################### # These are the properties to be compared # Make sure they include Name, DistinguishedName, and ModificationDate # Remove the TS attributes if your system requirements for retrieving those # are not met: # http://dmitrysotnikov.wordpress.com/2008/07/23/system-requirements-for-powershell-terminal-services-management/ $Members_to_Compare = @( "Name", "DistinguishedName", "ModificationDate", "AccountIsDisabled", "AccountIsLockedOut", "AccountName", "CanonicalName", "City", "Company", "Department", "Description", "DisplayName", "Email", "Fax", "FirstName", "HomeDirectory", "HomeDrive", "HomePhone", "Initials", "LastName", "LdapDisplayName", "LogonName", "LogonScript", "Manager", "MobilePhone", "Notes", "Office", "Pager", "ParentContainerDN", "PasswordNeverExpires", "PhoneNumber", "PostalCode", "PostOfficeBox", "ProfilePath", "SamAccountName", "StateOrProvince", "StreetAddress", "Title", "TsAllowLogon", "TsBrokenConnectionAction", "TsConnectClientDrives", "TsConnectPrinterDrives", "TsDefaultToMainPrinter", "TsHomeDirectory", "TsHomeDrive", "TsInitialProgram", "TsMaxConnectionTime", "TsMaxDisconnectionTime", "TsMaxIdleTime", "TsProfilePath", "TsReconnectionAction", "TsRemoteControl", "TsWorkDirectory", "UserPrincipalName", "WebPage" ) # Path to the snapshot file $SnapshotPath = "c:\snapshot.xml" ############################################################################### # Sample usage ############################################################################### # Create a snapshot New-Snapshot -Path $SnapshotPath -Properties $Members_to_Compare # Make some changes New-QADUser -Name "Lawrence Alford" -ParentContainer mydomain.local/test Set-QADUser "Jennifer Clarke" -PhoneNumber "(249) 111-22-33" Set-QADUser "Ernest Cantrell" -City "San Francisco" Remove-QADObject "Andreas Bold" -Force # Let's see if we find them Compare-ActiveDirectory -Path $SnapshotPath -Properties $Members_to_Compare
Tags: AD, AD cmdlets, Active Directory, Examples, PowerShell, cmdlets
Subscribe by email

0 Responses to “Compare AD against snapshots”