‘Sup PSHomies,
The project manager is on to me! π
PM: “PowerShell is awesome!!!”
Me: “You know it!!!”
PM: “Glad you agree! So here’s what I need, We need a weekly update of all users, groups in the source domain based on their creation date…”
Me: “Wait, what just happened?
PM: “You were agreeing that PowerShell is awesome? (Grinning)”
Me: “Well played… I ain’t even mad mad at ya…”
And so begins another PowerShell journey π
The idea here is to be proactive in our migration. Instead of asking for a list of newly created users/groups we’ll gather the information ourselves. All the customer has to do now is validate our list as to who is relevant. Which got me thinking, why stop at user/groups?
Remember I needed to recreate the DFS Structure? The data that I used was from February. What if there were newly created DFS links in the mean time? Turns out my hunch paid off!
Now curiosity got the better of me… “What about accounts that were deleted?” We’re migrating in batches. My first action is always to verify that the accounts in the batch exist. Having a list of deleted objects helps verifying it wasn’t a typo and that this object isn’t relevant anymore…
Here’s what I came up with:
<# | |
Author: I. Strachan | |
Version: | |
Version History: | |
Purpose: Export DSA Objects | |
#> | |
[CmdletBinding()] | |
param( | |
$domain = 'pshirwin.local' | |
) | |
#region Initiate HashTables & variables | |
$exportDate = Get-Date -Format ddMMyyyy | |
$xlsxFile = ".\export\dsa\source\$domain - DSAObjects - $exportDate.xlsx" | |
$xmlFile = ".\export\dsa\source\$domain - DSAObjects - $exportDate.xml " | |
$DSAObjects = @{} | |
$Select = @{} | |
#endregion | |
#region Main | |
$DSAObjects.DFSLinks = Get-ADObject -LDAPFilter '(objectClass=msDFS-LInkv2)'-Properties msDFS-LinkPathv2,msDFS-Propertiesv2,whenChanged,whenCreated | | |
ForEach-Object{ | |
[PSCustomObject]@{ | |
DFSLink = '\\pshirwin{0}' -f ($_.'msDFS-LinkPathv2').Replace('/','\') | |
State = $_.'msDFS-Propertiesv2' -join ',' | |
Changed = $_.whenChanged | |
Created = $_.whenCreated | |
CreatedDate = Get-Date (Get-Date $_.whenCreated).Date -format yyyyMMdd | |
} | |
} | |
$DSAObjects.PrintQueues = Get-ADObject -LDAPFilter '(objectClass=printQueue)' -Properties printerName,portName,printShareName,uNCName,serverName,whenChanged,whenCreated | | |
ForEach-Object{ | |
[PSCustomObject]@{ | |
PrinterName = $_.printerName | |
PortName = $_.portName -join ',' | |
PrintShareName = $_.printShareName -join ',' | |
ServerName = $_.serverName | |
UNCName = $_.uNCName | |
Changed = $_.whenChanged | |
Created = $_.whenCreated | |
CreatedDate = Get-Date (Get-Date $_.whenCreated).Date -format yyyyMMdd | |
} | |
} | |
$DSAObjects.Contacts = Get-ADObject -LDAPFilter '(objectClass=contact)' -Properties DisplayName,givenName,sn,DistinguishedName,mail,whenChanged,whenCreated | | |
Foreach-Object { | |
[PSCustomObject]@{ | |
GivenName = $_.givenName | |
SurName = $_.sn | |
DistinguishedName = $_.DistinguishedName | |
DisplayName = $_.DisplayName | |
EmailAddress = $_.mail | |
Changed = $_.whenChanged | |
Created = $_.whenCreated | |
CreatedDate = Get-Date (Get-Date $_.whenCreated).Date -format yyyyMMdd | |
} | |
} | |
$DSAObjects.Users = Get-ADUser -LDAPFilter '(objectClass=user)' -Properties accountExpirationDate,LastLogonDate,Initials,Description,EmailAddress,Enabled,DisplayName,OfficePhone,MobilePhone,Department,whenChanged,whenCreated,DistinguishedName,canonicalname | | |
Foreach-Object { | |
[PSCustomObject]@{ | |
SamAccountName = $_.SamAccountName | |
DistinguishedName = $_.DistinguishedName | |
CanonicalName = $_.CanonicalName | |
Enabled = $_.Enabled | |
GivenName = $_.GivenName | |
Initials = $_.Initials | |
SurName = $_.SurName | |
EmailAddress = $_.EmailAddress | |
Description = $_.Description | |
Displayname = $_.DisplayName | |
OfficePhone = $_.OfficePhone | |
MobilePhone = $_.MobilePhone | |
Department = $_.Department | |
LastLogonDate = $_.LastLogonDate | |
AccountExpiresOn = $_.accountExpirationDate | |
Changed = $_.whenChanged | |
Created = $_.whenCreated | |
CreatedDate = Get-Date (Get-Date $_.whenCreated).Date -format yyyyMMdd | |
} | |
} | |
$DSAObjects.Groups = Get-ADGroup -LDAPFilter '(objectClass=group)' -Properties Member,MemberOf,whenChanged,whenCreated | | |
Foreach-Object { | |
[PSCustomObject]@{ | |
DistinguishedName = $_.DistinguishedName | |
SamAccountName = $_.SamAccountName | |
Name = $_.Name | |
Changed = $_.whenChanged | |
Created = $_.whenCreated | |
CreatedDate = Get-Date (Get-Date $_.whenCreated).Date -format yyyyMMdd | |
Member = $_.Member | |
MemberOf = $_.MemberOf | |
} | |
} | |
$DSAObjects.Deleted = Get-ADObject -Filter * -IncludeDeletedObjects -Properties CN,SamAccountName,LastKnownParent | Where-Object{$_.Deleted -eq $true} | | |
ForEach-Object{ | |
[PSCustomObject]@{ | |
CN = $(($_.CN -split "`n") -join '; ') | |
SamAccountName = $_.SamAccountName | |
Deleted = $_.Deleted | |
ObjectClass = $_.ObjectClass | |
LastKnownParent = $_.LastKnownParent | |
} | |
} | |
#endregion | |
#region Export Object and to Excel | |
$Select.DFSLinks = '*' | |
$Select.Users = '*' | |
$Select.Contacts = '*' | |
$Select.Groups = @('ObjectClass', 'DistinguishedName', 'Name', 'Changed', 'Created') | |
$Select.PrintQueue = @('ObjectClass', 'PrinterName','PortName','PrintShareName','ServerName','UNCName','Changed','Created') | |
$Select.Deleted = @('CN','SamAccountName','Deleted','ObjectClass','LastKnownParent') | |
#XML File | |
$DSAObjects | | |
Export-Clixml -Path $xmlFile -Encoding UTF8 | |
#Excel File | |
$DSAObjects.Keys | | |
ForEach-Object{ | |
if($DSAObjects.$_){ | |
$DSAObjects.$_ | | |
Select-Object $Select.$_ | | |
Export-Excel -Path $xlsxFile -WorkSheetname $_ -AutoSize -BoldTopRow -FreezeTopRow | |
} | |
} | |
#endregion |
I added Contact and PrintQueues as a bonus π
For reporting it’s ImportExcel to the rescue!
At first I added a extra property in order to lookup the creation date using yyyyMMddΒ date format. Turns out it wasn’t necessary. You can just a easily use a filter on Created
The PM is quite pleased… PowerShell is Awesome!!! But you already knew that… π
Hope itβs worth something to you
Ttyl,
Urv
Cool post Irwin. I have to say, that Export-Excel Is quite a game changer when it comes to give reports back to non technical people (read management). Can’t live without it ever since ^^
LikeLiked by 1 person
I know right? π
LikeLiked by 1 person