获取AD安全组的嵌套成员

时间:2014-02-04 14:03:14

标签: powershell active-directory

我正在尝试获取AD安全组的成员并列出他们的帐户名,名字,姓氏和上次登录日期。

这是我目前的脚本

# 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

如何修改它以获取名字,姓氏和上次登录日期?目前,它仅列出帐户名称(sAMAccountName)。

非常感谢您的帮助。

修改

这个脚本适合我。只需使用要扫描的组的LDAP地址编辑第26行。

# 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

输出如下:

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}

2 个答案:

答案 0 :(得分:1)

名字和姓氏是微不足道的。您似乎已经获得了该对象,因此您只需添加

即可
$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.

更新:回答您的问题...... 在同一行上打印它们很简单,只需将它们放在引号中

即可
"$($de.givenName) $($de.sn) $LastLogon"

如果您注意到,最后一个没有$(),这意味着在字符串中“评估”。如果您只是将变量名称放在双引号“”中,它将被展开。但是当你想要做更多的事情时,你想要使用那个$(把这里的东西放在这里执行)方法。

现在你遇到的问题是LastLogon属性可能没有值,所以在阅读它时,你必须确保有一个值。你可以做一些像这样的事情

if ($de.lastlogon) {
  $LastLogon=[datetime]::FromFileTime($de.lastlogon)
}

顺便说一下,lastlogon属性......并不是很理想。看一下这篇文章:https://blogs.technet.com/b/askds/archive/2009/04/15/the-lastlogontimestamp-attribute-what-it-was-designed-for-and-how-it-works.aspx

希望这有帮助。

答案 1 :(得分:1)

看看这是如何影响你的想法...

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

格式化魔术是最后一行中的FT以及一些即兴散列表,以便于阅读。为了获得LastLogonTimestamp powershell,你可以跳过篮球。您正在使用的对象类型将其存储为LargeInteger,它只是报告为System .__ ComObject或其他类型。幸运的是,该对象还包含一种将其转换为可用值的方法,我在最后一行调用该值。

为了能够单独访问该值,您需要将其真正转换为Int64类型,并从中提取DateTime值,这就是我们需要的原因:

[datetime]::FromFileTime($_.ConvertLargeIntegerToInt64($_.lastLogonTimestamp[0]))