Reputation: 123
I'm trying to get members of AD security group and list their account name, first name, last name and last logon date.
This is the script I have currently
# Function get-NestedMembers
# List the members of a group including all nested members of subgroups
function get-NestedMembers ($group){
if ($group.objectclass[1] -eq 'group') {
write-verbose "Group $($group.cn)"
$Group.member |% {
$de = new-object directoryservices.directoryentry("LDAP://$_")
if ($de.objectclass[1] -eq 'group') {
get-NestedMembers $de
}
Else {
$de.sAMAccountName
}
}
}
Else {
Throw "$group is not a group"
}
}
# get-NestedMembers usage examples :
# get a group
$group = new-object directoryservices.directoryentry("LDAP://CN="group name",OU=folder,OU=Citrix,OU=Applications,DC=xx,DC=xx,DC=xx,DC=com")
# Get all nested members
get-NestedMembers $group
How do I modify it to get also First name, Last name and last logon date? Currently, it only lists account name (sAMAccountName).
Thanks a lot for any help.
This script works for me. Just edit line 26 with LDAP address of the group you want to scan.
# Function get-NestedMembers
# List the members of a group including all nested members of subgroups
Import-Module ActiveDirectory
function get-NestedMembers ($group){
if ($group.objectclass[1] -eq 'group') {
write-verbose "Group $($group.cn)"
$Group.member |% {
$de = new-object directoryservices.directoryentry("LDAP://$_")
if ($de.objectclass[1] -eq 'group') {
get-NestedMembers $de
}
Else {
$de
}
}
}
Else {
Throw "$group is not a group"
}
}
# get a group
$group = new-object directoryservices.directoryentry("LDAP://CN=GroupName,OU=Groups,OU=File Servers,OU=Applications,DC=contoso,DC=com")
# Get all nested members
get-NestedMembers $group|FT @{l="First Name";e={$_.givenName}},@{l="Last Name";e={$_.sn}},@{l="Last Logon";e={[datetime]::FromFileTime($_.ConvertLargeIntegerToInt64($_.lastLogonTimestamp[0]))}},sAMAccountName
Output looks like this:
First Name Last Name Last Logon sAMAccountName
---------- --------- ---------- --------------
Name Surname 10.11.2014 14:58:02 {accname}
Name Surname 17.11.2014 19:11:15 {accname}
Name Surname 07.11.2014 15:38:57 {accname}
Name Surname 14.11.2014 03:50:03 {accname}
Name Surname 16.11.2014 21:30:15 {accname}
Upvotes: 0
Views: 2101
Reputation: 6605
first name and last name are trivial. You seem to get the object already, so you can just add
$de.givenName ## to get first name
$de.sn ## to get last name
[datetime]::FromFileTime($de.lastlogon) ## however, this may not be exact. There are abundance of info on why.
Update: Responding to your questions... Printing them on the same line is easy simply put them in quotes
"$($de.givenName) $($de.sn) $LastLogon"
If you noticed, the last one does not have $(), which means "evaluate" within a string. If you simply put the variable name within doub-quotes "", it will be expanded. But when you want to do more, you want to use that $(put something here for execution) method.
Now the issue you are having is that LastLogon attribute may not have a value, so when reading it, you have to make sure there is a value. You could for example do something like this
if ($de.lastlogon) {
$LastLogon=[datetime]::FromFileTime($de.lastlogon)
}
By the way, lastlogon attribute..is not really ideal. Take a look at this post: https://blogs.technet.com/b/askds/archive/2009/04/15/the-lastlogontimestamp-attribute-what-it-was-designed-for-and-how-it-works.aspx
Hope this helps.
Upvotes: 1
Reputation: 36277
See how this strikes your fancy...
function get-NestedMembers ($group){
if ($group.objectclass[1] -eq 'group') {
write-verbose "Group $($group.cn)"
$Group.member |% {
$de = new-object directoryservices.directoryentry("LDAP://$_")
if ($de.objectclass[1] -eq 'group') {
"get-NestedMembers $de"
}
Else {
$de
}
}
}
Else {
Throw "$group is not a group"
}
}
# get-NestedMembers usage examples :
# get a group
$group = new-object directoryservices.directoryentry("LDAP://CN="group name",OU=folder,OU=Citrix,OU=Applications,DC=xx,DC=xx,DC=xx,DC=com")
# Get all nested members
get-NestedMembers $group|FT @{l="First Name";e={$_.givenName}},@{l="Last Name";e={$_.sn}},@{l="Last Logon";e={[datetime]::FromFileTime($_.ConvertLargeIntegerToInt64($_.lastLogonTimestamp[0]))}},sAMAccountName
The formatting magic is the FT in the last line there along with some impromptu hash tables to make it easier to read. To get the LastLogonTimestamp powershell makes you jump through hoops. The object type that you're using stores it as a LargeInteger that it just reports back as a System.__ComObject or some such. Fortunately the object also contains a way to convert that to a usable value which I call in that last line.
To be able to access that value alone you need to really convert it to a Int64 type, and from that extract the DateTime value, which is why we need:
[datetime]::FromFileTime($_.ConvertLargeIntegerToInt64($_.lastLogonTimestamp[0]))
Upvotes: 1