You don't have to stay up until the wee hours of the morning looking for an amazing tool that slices and dices like the famed Ginsu Knife. Are you looking for a way to speed up your work? Are you tired of the same old routine? Would you be surprised that your answer is already at your fingertips? Windows PowerShell is the amazing tool that can slice, dice, mince, sort, group and more all of your data. But wait...there's more.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
I've been working on a question in the PowerShell forum at ScriptingAnswers.com. The admin wanted to report on all the user accounts that had been assigned the change user password permission. He wanted to see the user account and then what accounts they had permission to modify. His original thought was that he needed to get the permission from every user account and then go through every account again to see if they were in the list. Oh, and we're talking about 5000+ user accounts.
This is a great example I think of the object paradigm shift in PowerShell. If I have an object for a user account that shows the permissions, I can analyze, sort, group, filter and more that data. I only need to make a single query to Active Directory. Note: my examples are meant to illustrate a concept. They are not necessarily production-ready commands.
We suggested he use the Get-QADPermission from the free Quest AD cmdlets. We can use this cmdlet to find a particular permission.
[cc lang="Powershell"]
PS R:\> Get-QADPermission "w.flash" -Allow -ExtendedRight "User-Change-Password" -Inherited |
>> Select Account,Rights,Source
>>
Permissions for: jdhlab.local/Employees/William Flash
Account Rights Source
------- ------ ------
Everyone ExtendedRight NotInherited
JDHLAB\Jeff ExtendedRight NotInherited
JDHLAB\Exchange Servers ExtendedRight Inherited
[/cc]
That's cool. So I'll get these permissions for all accounts in Employees organizational unit filtering out Everyone and all the Exchange related objects, and save the results to a variable.
[cc lang="PowerShell"]
$all=get-qaduser -size 0 -searchroot "OU=Employees,DC=jdhlab,DC=local" |
Get-QADPermission -Allow -ExtendedRight "User-Change-Password" -Inherited |
where {$_.account -notmatch "everyone|exchange"}
[/cc]
Hmmm...how many accounts am I talking about?
[cc lang="PowerShell"]
PS R:\> $all.count
172
[/cc]
Now for the slicing and dicing. What accounts are affected? I'll use Select-Object to return unique values for the TargetObject property.
[cc lang="PowerShell"]
#these accounts have additional permissions
PS R:\> $all | select targetobject -unique
[/cc]
When I have data like this, I also like to group information.
[cc lang="Powershell"]
#group permissions by target object
PS R:\> $grouping=$all | Group-Object -Property TargetObject
[/cc]
With this, I can find out how many people have the permission for a given count. Remember, Group-Object creates a new type of object.
[cc lang="Powershell"]
PS R:\> $grouping | sort count| select Name,Count | format-table -autosize
Name Count
---- -----
JDHLAB\W.Flash 1
JDHLAB\rbiv 2
JDHLAB\sapple 2
JDHLAB\jshortz 2
JDHLAB\M.Decree 3
JDHLAB\S.Kahele 3
JDHLAB\G.Twersky 3
JDHLAB\M.Manger 3
...
[/cc]
I wonder who these people are?
[cc lang="PowerShell"]
PS R:\> $grouping | select Name, @{name="Accounts";Expression={$_.group | select AccountName}}
Name Accounts
---- --------
JDHLAB\jshortz {@{AccountName=JDHLAB\Jeff}, @{AccountName=JDHLAB\W.Flash}}
JDHLAB\L.Pittenger {@{AccountName=JDHLAB\Jeff}, @{AccountName=JDHLAB\HelpDesk}, @{AccountName=JDHLAB\jshortz}}
JDHLAB\L.Ngov {@{AccountName=JDHLAB\Jeff}, @{AccountName=JDHLAB\HelpDesk}, @{AccountName=JDHLAB\jshortz}}
...
[/cc]
I'm sure there are better ways to display this information, but I hope you get the point. There's so much you can do with this information. Ultimately, I think this is the expression the original poster was looking for to create the management report.
[cc lang="PowerShell"]
PS C:\> $all | sort Accountname | Format-table -groupby AccountName -Property TargetObject,RightsDisplay -HideTableHeaders
AccountName: JDHLAB\HelpDesk
JDHLAB\B.Relihan Change Password
JDHLAB\J.Pingrey Change Password
JDHLAB\W.Fredricksen Change Password
JDHLAB\I.Alberda Change Password
JDHLAB\E.Cresto Change Password
...
AccountName: JDHLAB\Jeff
JDHLAB\C.Medin Change Password
JDHLAB\J.Norlander Change Password
JDHLAB\I.Alberda Change Password
...
[/cc]
The longest part of this entire process was querying Active Directory, but I only had to do it once.
The biggest challenge many admins still face is thinking "object-ively" but once grasped look at how much you can accomplish. Plus free shipping and handling to boot!
That works extremely well.
It’s odd that using the ‘Inherited’ switch allows the individual changes to be displayed. Using the ‘SchemaDefault’ allows both to be displayed.
This:
get-qaduser | Get-QADPermission -Allow -ExtendedRight “User-Change-Password” -schema | where {$_.account -notmatch “everyone|exchange|self”}
Allows all accounts to be disaplyed a the console even if they contain no records. (as an alternative to your more completre version)