So for all those who still does not believe PowerShell is taking manageability to a new level π here’s a quick test: can you get basic statistics from your environment using “legacy” technologies such as VBScrip, WMI, ADSI, etc.? Here’s the list of “stuff” you might want to get: number of users, number of locations your company has (and their list), number of departments (and the list), titles, groups, etc. – the list can go on and on – I think you get the idea. Anyone?
With PowerShell you can do that with literally one line commands! And I’ve got an email from one of AD cmdlets team members – Andrei Polevoi – today with some cool examples of how he was using PowerShell to get the info.
Number of users:
PS C:\> (get-QADUser).count
List all departments:
PS C:\> get-qaduser -department * -sl 50000 | select Department | sort -property Department | Get-Unique -asstring
Get number of departments:
PS C:\> $dpts = get-qaduser -department * -sl 50000 | select Department | sort -property Department | Get-Unique -asstring
PS C:\> $dpts.count
Locations:
PS C:\> $all_cities = get-qaduser -city * -sl 50000 | select City | sort -property City | Get-Unique -asstring
PS C:\> $all_cities.count
Titles:
PS C:\> $all_titles = get-qaduser -Title * -sl 5000 | select Title | sort -property Title | Get-Unique -asstring
PS C:\> $all_titles.count
Groups:
PS C:\> (get-qadgroup).count
I bet your VBScripts were slightly more complex? π
PowerShell just brings AD manageability to the whole new level!
get-qaduser, get-aqdgroup …. where are those cmdlets ?
oh, nevermind, I found them – I posted the comment too quickly, my bad π
I’m trying to get a list of all groups and their members by displayname.
I came up with this, but I want to clean up the output by displayname:
$groups = get-qadgroup -sl 0
foreach ($group in $groups) {$group
($group).members
” ”
}
Ambers,
Could you provide an example of what you are trying to get?
Here’s how I understood the task:
Get-QADGroup | ForEach-Object {
“Group: ” + $_.DisplayName
Get-QADGroupMember $_ | Format-Table DisplayName
}
This gives output like this:
Group: DL1
DisplayName
———–
MailUser1
MailUser4
MailUser5
Group: DL2
DisplayName
———–
MailUser1
MailUser18
MailUser19
Is that what you had in mind?
That is exactly what I had in mind. I’ll change the DisplayName header to read Members and then I’ll be set. Thanks Dmitry.
Glad that I could help!
How about counting all the members of a list of groups? I have a large list of groups and I want to know how many users that represents. Just a count, no other information. Some groups may be nested.
Thanks!
Bruce,
So you have a certain set of groups and need to get a list (or just the number) of total unique users in them, correct?
This is the script which does the job for me:
# This function goes through the members of a given group,
# adds unique new users to the collection,
# and calls itself for nested groups
function GetUserMembers($group) {
# Go through the members of the group
$group.Members | ForEach-Object {
# Get the actual object from the DN
$subitem = Get-QADObject -Identity $_
# Check object type
if ($subitem.Type -eq “group”) {
# If group – call the function to process its members
GetUserMembers($subitem)
} elseif (($subitem.Type -eq “user”) -and ($h.Contains($_) -eq $false)) {
# If user and not yet in the collection – add it
$h.Add($_,$subitem)
}
}
}
# The actual script starts here
# Create a hash-table collection.
# Hash table is used so we can do the uniqueness check
$h = new-object Collections.HashTable
# Substitute this Get-QADGroup call with your way to get the groups you need.
# E.g. “Get-QADGroup” will return all groups in the domain,
# “Get-QADGroup QDL*” will get all starting with QDL, etc.
Get-QADGroup QDL.SPB.ProgramManagers | foreach {
GetUserMembers($_)
}
# Output the number of users:
write-Host (“These groups had ” + $h.Count + ” unique users.”)
# And the full list of members
“Here’s the full list of unique members:”
$h.Values
# Let’s clean up the hash-table now
$h.Clear()
Be careful with this script though. I just looked it over and unless I’m mistaken I don’t believe it properly supports circular group memberships (where group A contains group B and group B also contains group A). As a result, if you have a circular group membership and run this script you will get into an endless loop that will terminate once the maximum nested level has been reached. If you have circular group membership you’ll also need to store a hashtable that keeps track of the names of groups already processed, including the ones that you started with, and ensure that you don’t process a group more than once.
I’m very new to powershell. I found your post because of Ambers’s post. I don’t know where to get the cmdlet you mentioned. Sorry of this basic question, but can you please direct me a little bit?
thanks
Now I found it.
For everyone else
http://www.quest.com/activeroles-server/arms.aspx
what would be a good replacement for ADSystemInfo in vbscript in Powershell?
For example in vbscript….
‘Group Memebership Variables
Set ADSysInfo = CreateObject(“ADSystemInfo”)
Set CurrentUser = GetObject(“LDAP://” & ADSysInfo.UserName)
‘Get User Info & Group Membership
On Error Resume next
strGroups = LCase(Join(CurrentUser.MemberOf))
UsrFullName = currentUser.FullName
UsrName = ws.expandenvironmentstrings(“%username%”)
UsrEmail = CurrentUser.mail
UsrHomeDir = CurrentUser.homeDirectory
UsrScript = CurrentUser.scriptPath
Can any of the get-QAD provide this?
Thanks!
Matt,
I am not very familiar with VBScript programming for AD. I assume that your code is trying to get attributes of a particular user. In PowerShell, this can be done with:
Get-QADUser -Name “User’s Name” | Format-List FullName, homeDirectory
etc. for the list of attributes you want to see.
AD PowerShell discussion forum at: http://powergui.org/forum.jspa?forumID=173 – is a pretty good place for such howto questions.
Dmitry
I want to know how to get the list of members of a group, and the last change date and time.
The idea is if somehow I can store this info in a file and then check everyday thru cron to see if there is any change in the members, and as soon as there is a change, I want to update a new file and mail the file to the administrator.
Can someone help me on this?
Thanks
Rajdeep,
Sorry for not responding right away. A better way to get answers to AD/PowerShell related questions is posting them to the forums at: http://powergui.org/forum.jspa?forumID=173 – there are a lot of smart people there to answer them. π
If you want to know when a group was changed you can just look up its ModificationDate attribute:
(Get-QADGroup MyGroup).ModificationDate
or as a table for all groups:
Get-QADGroup | Format-Table Name, ModificationDate
This will obviously give you date of any last change – not necessarily in membership.
Dmitry