如何获取特定用户组内的无效账户?

简介:

时候,IT管理员可能会想清除某些服务器/计算机内置管理员组里面的一些已失效的用户,这些用户可能曾经被加入管理员组,但是由于离职或是其他原因,账号已从AD注销,而在这些用户组内,他们的SID信息却得以保留,就像是这样:

 

 

像图中的最后两个用户,S-1-5-21-1004336348-1220945662-1801674531-10174 和 6866,就是由于信息从AD获取不到,而显示为SID的。如何批量从服务器抓这样的SID用户出来呢?我们可以使用 PowerShell 脚本。

 

以下就是一个代码示例,我将其做成了一个函数 QueryNonExistentUsers, 大家可以用在很多实际的工作之中,而且稍加修改,可以完成多种多样的任务:

 

#Query Non-existent Users PowerShell Script Function by Eric Sheh

#Version 1.2 Build 20120626

 

Function QueryNonExistentUsers

{

    Param

    (

        [Parameter(Mandatory=$true,Position=0)][String]$Server,

        [Parameter(Mandatory=$true,Position=1)][String]$UserGroup,

        [Parameter(Mandatory=$false,Position=2)][Bool]$CountInstead = $False

        # Example: QueryNonExistentUsers "hostname" "Administrators" $True OR QueryNonExistentUsers -Server "hostname" -UserGroup "Administrators" -CountInstead $True

        # OR QueryNonExistentUsers "hostname" "Administrators" OR QueryNonExistentUsers -Server "hostname" -UserGroup "Administrators"

    )

    Begin

    {

        $members=@()

    }

    Process

       {

        [adsi]$computer = "WinNT://" + $Server

        $group = $computer.psbase.children | ?{$_.psbase.schemaclassname -eq 'group'| ?{$_.Path -match $UserGroup}

       

        foreach ($user in $group.Members())

        {

            $usr_obj = New-Object PSObject

            $usr_obj | Add-Member -MemberType NoteProperty -Name 'aDSPath' -Value $user.GetType().InvokeMember('aDSPath','GetProperty', $null, $user, $null)

            $usr_obj | Add-Member -MemberType NoteProperty -Name 'Name' -Value $user.GetType().InvokeMember('Name', 'GetProperty', $null, $user, $null)

            $path = $usr_obj.aDSPath.split('/')

 

            if ($path.Count -eq 4)

            {

                $usr_obj | Add-Member -MemberType NoteProperty -Name 'Domain' -Value $path[2]

            }

            elseif ($path.Count -eq 5)

            {

                $usr_obj | Add-Member -MemberType NoteProperty -Name 'Domain' -Value $path[3]

            }

            else

            {

                $usr_obj | Add-Member -MemberType NoteProperty -Name 'Domain' -Value 'Unknown'

            }

            $members += $usr_obj

        }

     

        $members = @($members | Sort-Object -Property Domain, Name)

        $members = $members | Where-Object {$_.Domain -eq "Unknown"}       

       }

       End

       {

        If ($CountInstead)

        {

            return $members.count

        }

        else

        {

            return $members

        }

       }

}

 

我们可以写两行code来调用这个函数进行测试(例如连接到 TestServer,查询其上的内建 Administrators 组里面有没有无效用户):

 

#Test:

$Result = QueryNonExistentUsers "TestServer" "Administrators"

Write-Output $Result

 

可以看见执行结果与上面的第一张 UI 查询结果图是一致的:

 

最后我解释一下几个要点:

1. 使用 ADSI 比使用 WMI 的运行效率高;

2. 使用 ADSI 时,操作本地对象用"WinNT://",而操作AD对象,请使用"LDAP://";

3. 获得代码中定义的 $user 对象后,为何要用"/"符号分段呢?有时怎么确定 Domain 的呢?其实是利用了 Members 对象里 aDSPath 属性值的一些特性的: 
例如对于本地用户,aDSPath 的值是这样: 

 

即"WinNT://DomainName/HostName/LocalUserName"的形式,所以依"/"拆分后,形成了一个一维数组,共有5个元素,其中第二元素为空。因此要取第四个元素"HostName"作为该账户的"域"(因为这是个本地账户)。 
而对于域账户,aDSPath 的值是这样的: 

 

即"WinNT://DomainName/DomainUserName"的形式。因此拆分后形成一维数组只有四个元素,因此要取第三个元素作为该账户的域名称。 

而对于已失效的用户,结果是这样的: 

 

所以我们人为处理他的 Domain 值为"Unknown"并写入结果中。

 

对了,这个函数的参数和使用方法在以上的代码中其实已有说明,这里再单独列举一下:

QueryNonExistentUsers "hostname" "groupname" $true/$false

第一个参数 hostname 自然是你要查询的那台机器的名称了,第二个参数是你要查询的用户组,而第三个参数可以省略,默认是为 $false 的,返回具体的组内全部用户,而如果你指定为 $true, 那么返回的只是一个计数值。例如上面的例子中,如果执行"$Result = QueryNonExistentUsers "TestServer" "Administrators" $true",那么返回结果是数字2.

如果您要得到返回的完整组内用户列表,请将代码中的"$members = $members | Where-Object {$_.Domain -eq "Unknown"}"去掉(在第46行),这里有这一句就是为了在结果中筛出失效账户。




本文转自 hbycscc 51CTO博客,原文链接:http://blog.51cto.com/mvperic/959637

相关文章
|
1天前
|
Shell 数据库
学习笔记应用——创建用户账户并且拥有自己的信息
学习笔记应用——创建用户账户并且拥有自己的信息
|
6月前
|
弹性计算 对象存储
阿里云新账户和老账号如何区分?怎么判定?
阿里云新账户和老账号如何区分?怎么判定?阿里云账号分为云新账户、老账户、同人账号和同一用户有什么区别?阿里云官方推出的活动很多是限制账号类型的,常见的如阿里云新用户,什么是阿里云新用户?是指从未在阿里云官网购买过云产品的账号。下面阿小云来详细说下什么是阿里云新账户、老账户、同人账号、同一用户
159 0
阿里云新账户和老账号如何区分?怎么判定?
|
Linux Shell 编译器
Linux:关机&重启操作+用户登录和注销+添加用户+指定/修改密码+删除用户+查询用户信息+切换用户+查询当前用户/登录用户+用户组+修改用户的组+用户组和相关文件
Linux:关机&重启操作+用户登录和注销+添加用户+指定/修改密码+删除用户+查询用户信息+切换用户+查询当前用户/登录用户+用户组+修改用户的组+用户组和相关文件
287 0
Linux:关机&重启操作+用户登录和注销+添加用户+指定/修改密码+删除用户+查询用户信息+切换用户+查询当前用户/登录用户+用户组+修改用户的组+用户组和相关文件
|
数据安全/隐私保护
设置 CloudAMQP 账号
CloudAMQP 有多种账号级别,请参考下面的链接的内容访问你可以注册的级别:https://www.cloudamqp.com/plans.html 作为测试来说,你可以注册免费的的消息。 你可以选择免费的账号。
1148 0
|
数据安全/隐私保护
9、获取用户的详细信息接口,如果用户没有登录,我们提示用户登录
controller: //获取用户详细信息接口,当用户没有登录,我们强制让其登录 @RequestMapping(value = "get_information.
1096 0
|
数据安全/隐私保护 Shell