Archive for the 'AD cmdlets' Category

New cmdlets to manage AD computer accounts

Up to version 1.3, we used to have one cmdlet for computer accounts (namely Get-QADComputer) – now we have 6:

You can kind of guess what they do by their names, but let’s quickly go through them one by one and give a few quick examples.

Retrieves AD computer account objects based on the criteria you specify. E.g. (anyone still running Vista? ;) )

Get-QADComputer spb* -OSName 'Windows Vista*' | Format-Table Name, ManagedBy

Creates new computer account in AD (does not join the actual computer though) and sets the attributes you specify:

New-QADComputer -Name 'LAB-SRV3' -SamAccountName 'LAB-SRV3' -ParentContainer 'CN=Computers,DC=lab,DC=local' -Location 'AMS/HQ/Building A'

Modifies AD computer account properties (can work in bulk when you pipe Get-QADComputer output into this one).

Set-QADComputer 'quest.local/computers/Comp4' -ManagedBy 'QUEST\DSotnikov'

or

Get-QADComputer spb* | Set-QADComputer -Location 'St. Petersburg'

Enable or disable one or multiple computer accounts:

Enable-QADComputer 'CN=LAB-SRV1,CN=Computers,DC=dom,DC=local'

or

Get-QADComputer -SearchRoot 'dom.local/labComputers' | Disable-QADComputer

Reset a computer account in Active Directory. When resetting a computer account, you reset the secure channel between the computer that uses that account to join the domain and a domain controller in the domain.Resetting a computer account breaks that computer’s connection to the domain and requires it to rejoin the domain.

Reset-QADComputer 'CN=LAB-SRV1,CN=Computers,DC=dom,DC=local'

More information can be found in AD cmdlets online reference and PDF guideDownload the new AD cmdlets now and let us know what you think by posting to the AD PowerShell discussion forum!

AD Cmdlets 1.3 RTMed

Late last week we released to the web the latest version (1.3) of our free Active Directory cmdlets (also known as QAD-cmdlets, widely used by tens of thousands admins and compatible with more or less any version of Active Directory or ADAM/ADLDS).

You can read more about the cmdlets in this PDF guide, or online reference.

This is a significant update with some 14 new cmdlets, 24 new parameters, 43 enhanced ones, and a few bugs fixed (not that we had any really ;) )

Detailed What’s New information can be found on page 19 of the PDF guide and in my upcoming blog posts. Download the new AD cmdlets now and let us know what you think by posting to the AD PowerShell discussion forum!

Find users in too many groups

Large Kerberos tokens (caused by too many groups listed in them) can be an issue in some environments (I’ve just had a similar trouble myself in an ADFS deployment). Luckily PowerShell is here to help. This quick script will list all users who are members of more than 75 groups:

$limit = 75
Get-QADUser -SizeLimit 0 -DontUseDefaultIncludedProperties |
  ForEach-Object {
    $groups = Get-QADGroup -ContainsIndirectMember $_.DN -SizeLimit $limit `
      -DontUseDefaultIncludedProperties -WarningAction SilentlyContinue
    if ($groups.Count -ge $limit) { $_ }
  }

Here’s a quick overview of what the script is doing:

  1. I assign the limit (75) to a variable. This is just for my convenience of reuse. E.g. I could turn this line into param($limit = 75) – and save this as a parameterized script or turn it into a function.
  2. I user Get-QADUser to retrieve all (-SizeLimit 0) user accounts from my current domain and I make sure to not retrieve any attributes along – so I save memory and improve performance (-DontUseDefaultIncludedProperties)
  3. For each user in my domain, I retrieve the first 75 (-SizeLimit $limit) groups to which the user belongs directly or through nesting (-ContainsIndirectMember $_.DN). There’s obviously no need to retrieve all groups – we just need to know if the user reached the limit. Again, we do not need any attributes (-DontUseDefaultIncludedProperties). I also tell PowerShell to not warn me if there are more groups than the size limit I specified (-WarningAction SilentlyContinue).
  4. Finally, if indeed we reached the limit, I output that user object.

You can obviously then just see the list on the screen or output it to CSV or HTML report.

Tags: , , , , , , ,

Get a list of users’ email addresses

Here’s a one-liner to turn members of a group into a list of email addresses, separated by semicolon. I am using it every now and then when someone from our partners (which obviously do not have access to our address book) ask me for a list of folks to include in some discussions, or grant access to some resources, and so on.

Here’s the oneliner (for PowerShell v2):

(Get-QADGroupMember MyGroupName -Type user -Indirect |
    Select -expand Email) -join ';'

PowerShell v1 version has a slightly different syntax for join:

[string]::join(';',
  (Get-QADGroupMember MyGroupName -Type user -Indirect |
    Select -expand Email))

And here’s a quick explanation of what it does:

  • I use Get-QADGroupMember to retrieve all members of the group. Note that -Indirect parameter gives me all members of nested groups, and -Type user makes sure that nested groups themselves get excluded.
  • Then I am taking the collection of user objects and turn that into a collection of just one property of the objects (Email) using  Select -expand.
  • Finally I am using join to turn that collection into a string and using semicolon as separator.

Hope this is useful.

List all empty OUs

Here’s a one-liner you can use to quickly find empty organizational units in your Active Directory:

Get-QADObject -Type organizationalUnit -DontUseDefaultIncludedProperties |
  where {
    -not ( Get-QADObject -SearchRoot $_.DN -DontUseDefaultIncludedProperties `
    -SearchScope OneLevel -SizeLimit 1 -WarningAction SilentlyContinue )
  }

A quick explanation of what I am doing here:

  1. I am retrieving all organizationalUnit objects from my domain (and use the -DontUseDefaultIncludedProperties switch to save a few milliseconds ;) )
  2. Then for each of the OUs I am retrieving all AD objects that are in that OU by doing a Get-QADObject and limiting the search scope to the DN of the current OU.
  3. Note that (like we did when looking for large groups) I am using the -SizeLimit parameter to see if I can get 1 item in the call (all I need is to learn whether there is anything in the OU – I don’t need the whole list) – which obviously makes the whole script magnitudes of time faster. I use -SearchScope
  4. Based on Kirk’s recommendation I am using -SearchScope OneLevel to exclude the OU itself.
  5. I am using -not operator so I get only the OUs for which this Get-QADObject evaluates to $null (nothing found) and thus -not $null evaluates to $true.

P.S. This is the code I was using initially, which I then corrected based on Kirk’s comments below:

$emptyOUs = Get-QADObject -Type organizationalUnit -DontUseDefaultIncludedProperties | where {(Get-QADObject -SearchRoot $_.DN -SizeLimit 2 -DontUseDefaultIncludedProperties).Count -lt 2}

Tags: , , , , , ,

Microsoft’s AD cmdlets available for Win 2003 and later

Microsoft has just released to the web final bits of their Active Directory Web Services. This is the service you need to install on your domain controller or ADAM/AD LDS server to make them accessible for Microsoft’s AD cmdlets.

As you can see from the diagram above, unlike Quest AD cmdlets, Microsoft’s ones require Active Directory Web Services (ADWS) on the server/DC you manage. These web services ship with Windows Server 2008 R2. Now they are also available as a free download for Windows Server 2003 SP2 and later.

This means that as long as you are ready to install this additional software on your DCs, you can start using these new cmdlets from Microsoft. There is no need to upgrade DCs to 2008 R2 or change the forest functional level.

More choices for PowerShell management of AD – better for everyone. :)

Tags: , ,

Adding Direct Reports action

Here’s my quick addition to Kamran’s “How to export data from Active Directory using the free PowerGUI tool“:

If you might need to find users managed by someone more than once, there are a couple of ways you can make this simpler for your self:

A. Download and install free Org Chart powerpack, or

B. Follow these instructions to add a Direct Reports button to PowerGUI admin console:

1. Start PowerGUI admin console and browse to Active Directory / Users.

2. In the right-hand pane, right-click the category to which you want to add the action and pick New / Script Action from the shortcut menu.

new-script-action

3. In the New Action dialog box, type in the action name (e.g. Direct Reports), and script:

$input | ForEach-Object {
    Get-QADUser -Manager $_
}

(The script is quite trivial: for each user account currently selected in the PowerGUI grid, we get the list of AD users which have this object specified as Manager).

direct-reports

3. On that same dialog box, click the Display Configuration button, and then in the Display results group, select the Display the results in a nested view option.

This tells PowerGUI that your action outputs objects to the grid (which it does – we need to see the reports selected user has!)

nested-view

4. That’s it! Click OK on both dialog boxes, select the user account whose reports you need to see, and click your newly added Direct Reports action.

Big thanks to Kamran for posting his original tip and video.

Tags: , , , , , ,

Fastest way to retrieve AD objects

DontUseDefaultIncludedProperties is the AD cmdlets parameter you need when you want to get AD objects fast without extra properties you do not need. For example, I have just used it in my script to locate the largest groups in our Active Directory. Let’s talk about how effective it really is and how it works under the covers.

First, of all, let me prove that it is indeed very efficient. Here’s the same Get-QADUser run 100 times with and without the parameter:

[PS] C:\>Measure-Command { for ($i=0;$i -lt 100;$i++) { $a = Get-QADUser -SamAccountName dsotnikov -DontUseDefaultIncludedProperties } }

...
Seconds : 3
Milliseconds : 951
...


[PS] C:\>Measure-Command { for ($i=0;$i -lt 100;$i++) { $a = Get-QADUser -SamAccountName dsotnikov } }

...
Seconds : 7
Milliseconds : 526
...

That’s twice as fast with the parameter than it is without it!

Why? Because DontUseDefaultIncludedProperties makes the cmdlet only retrieve 2 attributes: distinguishedName и objectClass, whereas the cmdlet without it will go get quite a few other properties.

You can easily see which attributes got retrieved by running:
$a = Get-QADUser -SamAccountName dsotnikov -DontUseDefaultIncludedProperties
$a.Cache.AttributesInCache

The interesting thing is that the cmdlet is even smarter with subsequent use of the object. For most properties (to be specific, for all regular .NET properties of the object but not PowerShell dynamic NoteProperties), we will go and retrieve the property once you request it later on. E.g. this will actually work and give you the account description:

$a = Get-QADUser -SamAccountName dsotnikov -DontUseDefaultIncludedProperties
$a.Description

And this will retrieve a whole bunch of attributes:
Get-QADUser -SamAccountName dsotnikov -DontUseDefaultIncludedProperties | Format-List *

You can obviously keep using $a.Cache.AttributesInCache to check which ones we retrieve.

Pretty cool, isn’t it?

The only other thing I would note is the difference between:

Get-QADUser -SamAccountName dsotnikov -DontUseDefaultIncludedProperties

and

Get-QADUser dsotnikov -DontUseDefaultIncludedProperties

The former is way more efficient than the latter because the -SamAccountName parameter (or any other parameter besides the generic implied -Identity) lets us optimize the query specifically to search by that attribute rather than do the Ambiguous Name Resolution which we use otherwise. Be specific in your parameters and we will give you the fastest results!

Tags: , , , , , ,

Find large AD groups

Here’s a quick script which I wrote yesterday for one of our professional services engineers. Basically they wanted to give customer a report for large groups, i.e. groups with more than certain number of user accounts including the ones in nested groups.

This turned out to be very straight-forward with QAD cmdlets.

The script is below:

function Get-LargeADGroup {
param($limit = 75)

 Get-QADGroup | Foreach-Object {
   $members = $_ |
           Get-QADGroupMember -Indirect -Type 'user' `
              -DontUseDefaultIncludedProperties `
              -SizeLimit ($limit+1) -WarningAction SilentlyContinue
   if ( ($members -ne $null) -and
        ($members.gettype().Name -eq 'Object[]') -and
        ($members.Count -ge $limit)) {
     $_
   }
 }
}

#Usage
Get-LargeADGroup -limit 75 | Select Name, DN | Export-Csv c:\largegroups.csv

One trick worth pointing out is the use of -SizeLimit to not retrieve all members of the group – after all I just need to know if there is more than certain number of them.

Hope this helps! :)

What was that group again?

A simple one-liner can help. Just earlier today I could not remember the name of a particular distribution list but knew a couple of its members. The quick one-liner to help me out was:

Get-QADGroup -ContainsMember ('User A', 'User B')

And while we are on it, here’s an even better one-liner if you want to find a DL which has all direct reports of, say, your company’s VP:

Get-QADGroup -ContainsMember (Get-QADUser -Manager 'User C')

And obviously if such a DL does not exist, you should probably just go ahead and create it ;)

New-QADGroup -Name 'Top Managers' -Member (Get-QADUser -Manager 'User C')

I love PowerShell. :)

Tags: , , , , ,

Next Page »


View Dmitry Sotnikov's profile on LinkedIn

Follow Dmitry Sotnikov at Twitter

My Recent Tweets

Archives

See you at:

Legal

The posts on this blog are provided “as is” with no warranties and confer no rights. The opinions expressed on this site are mine and mine alone, and do not necessarily represent those of my employer Quest Software or anyone else for that matter. All trademarks acknowledged.

© 2007 Dmitry Sotnikov

Pages

 

December 2009
M T W T F S S
« Nov    
 123456
78910111213
14151617181920
21222324252627
28293031