PowerShell: The Ultimate Ginsu Knife

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.

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.

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

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.

$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"}

Hmmm…how many accounts am I talking about?

PS R:\> $all.count
172

Now for the slicing and dicing. What accounts are affected? I’ll use Select-Object to return unique values for the TargetObject property.

#these accounts have additional permissions
PS R:\> $all | select targetobject -unique

When I have data like this, I also like to group information.

#group permissions by target object
PS R:\> $grouping=$all | Group-Object -Property TargetObject

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.

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
...

I wonder who these people are?

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}}
...

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.

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
...

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!

Post to Twitter Post to Plurk Post to Yahoo Buzz Post to Delicious Post to Digg Post to Facebook Post to FriendFeed Post to Google Buzz Post to Ping.fm Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati

This entry was posted in Active Directory, PowerShell, Quest Software, Scripting and tagged , , . Bookmark the permalink.

One Response to PowerShell: The Ultimate Ginsu Knife

  1. jv says:

    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)