Powershell 查找不包括禁用用户的组的成员

Powershell 查找不包括禁用用户的组的成员,powershell,Powershell,我有10个安全组,全部称为“'companyname'RDS Users” 我正在尝试创建一个脚本,它可以执行以下操作:列出所有组,然后列出所有成员(不包括残疾成员),然后让它通过电子邮件发送csv。我已完成以下操作,但无法排除禁用的用户 下面的脚本显示了我取得了多大的进步,但是禁用的用户显示在那里,这基本上意味着脚本是没有意义的 $mailServer = "" $mailFrom = "" $mailTo = "" $mailSubject = "" $file = "

我有10个安全组,全部称为“'companyname'RDS Users”

我正在尝试创建一个脚本,它可以执行以下操作:列出所有组,然后列出所有成员(不包括残疾成员),然后让它通过电子邮件发送csv。我已完成以下操作,但无法排除禁用的用户

下面的脚本显示了我取得了多大的进步,但是禁用的用户显示在那里,这基本上意味着脚本是没有意义的

$mailServer = ""
$mailFrom = ""   
$mailTo = ""    
$mailSubject = ""    
$file = "somepath\RDSUsers.csv"      

Import-Module ActiveDirectory   

$US = Get-ADUser -Filter * -Property Enabled |where {$_.Enabled -eq "True"}| FT Name, Enabled -Autosize

$Groups = (Get-AdGroup -filter * | Where {$_.name -like "*RDS Users" -and $_.name -ne "RDS Users"}| select name -expandproperty name)

$Table = @()

$Record = [ordered]@{
    "Group Name" = ""
    "Name" = ""
    "Username" = ""
} 

Foreach ($Group in $Groups)
{
    $Arrayofmembers = Get-ADGroupMember -identity $Group |select name,samaccountname
    foreach ($Member in $Arrayofmembers)
    {
        $Record."Group Name" = $Group
        $Record."Name" = $Member.name
        $Record."UserName" = $Member.samaccountname
        $objRecord = New-Object PSObject -property $Record
        $Table += $objrecord 
    }
}

if ($Table -eq "RDS Users") {}
$Table

这里通常有一行代码发送带有excel附件的电子邮件,下面应该在
$Table
变量中生成所需的输出。然后,您可以通过管道将
$Table
传输到
格式-*
命令之一

Import-Module ActiveDirectory
$US = Get-ADUser -Filter "Enabled -eq '$true'" -Property Enabled
$Groups = Get-ADGroup -Filter "Name -like '*RDS Users' -and Name -ne 'RDS Users'" |
             Select-Object -ExpandProperty Name
$Table = Foreach ($Group in $Groups)
{
    try
    {
        $Arrayofmembers = Get-ADGroupMember -Identity $Group -ErrorAction Stop | Select-Object Name, SamAccountName
        $compare = Compare-Object -ReferenceObject $US -DifferenceObject $Arrayofmembers -ExcludeDifferent -IncludeEqual -PassThru -Property SamAccountName -ErrorAction Stop |
        Select-Object Name, SamAccountName
        $compare | ForEach-Object {
            [pscustomobject]@{
                "Group Name" = $Group
                "Name"       = $_.Name
                "UserName"   = $_.SamAccountName
            }
        }
    }
    catch
    {
        [pscustomobject]@{
            "Group Name" = $Group
            "Name" = $null
            "UserName" = $null
        }
        Continue
    }
}
$Table
说明:

Get-ADGroupMember
命令不会提供其返回对象的
Enabled
属性。对于该数据,您需要将其输出输入另一个命令,如
Get ADUser
。由于您已将所有已启用的用户存储在
$US
中,因此我们只需将
$US
集合与每个
获取ADGroupMember
输出的结果进行比较即可

我删除了大多数
Where Object
命令,以支持在AD命令上使用
-Filter
参数。几乎总是,
-Filter
参数会更快,尤其是在比较广告索引属性时,如
Name
Enabled

不需要将每个输出对象存储在变量中,除非要进一步操作它。这就是删除
$Record
的原因。相反,所有返回的对象都存储在数组
$Table
中。我删除了
+=
操作符,主要是因为它在重复构建阵列时效率低下。此外,您可以简单地将变量设置为
foreach
循环的输出,这将生成所需的数组。由于我们在每个循环迭代中创建了一个自定义对象,并在声明时提供了属性,
[ordered]
不是必需的。但是,如果先创建哈希表,然后创建相应的对象,则可能需要使用
[ordered]
。在创建循环中涉及的自定义对象时,通常最好每次创建一个新对象。否则,您可能会无意中更新错误对象上的值。仅仅因为将对象添加到数组中,您仍然可以在添加后更新其属性


Compare Object
命令将所有内容绑定在一起。
-ExcludeDifferent-IncludeEqual
参数组合将仅输出具有匹配属性值的对象。因为我们正在比较
$Arrayofmembers
$US
,这是理想的。
-PassThru
开关允许返回对象以及传递到命令中的所有属性。然后,您可以使用
选择对象
命令来选择对您来说重要的属性。

您使用了
FT-Name,Enabled-Autosize
Format-*
cmdlet不应用于屏幕或纯文本文件的最终输出之外的任何其他用途。它会分割你的对象,将它们包装在格式化代码中,然后将它们吐出。使用
选择对象
,因为这是它的设计目的。[咧嘴笑]这太好了,非常感谢你,我真的很感谢你的努力……不幸的是,它不起作用:-(我得到..比较对象:无法将参数绑定到参数'DifferenceObject',因为它为空。我希望的输出是RDS用户组和这些成员的列表,不包括禁用的用户。很抱歉,在powershell不太好这比我通常编写的更高级,这就是我们如何变得更好的原因!是
$Groups
输出
$null
?这是我的确切错误…………比较对象:无法将参数绑定到参数“DifferenceObject”,因为它为null。在C:RDS_Users.ps1:16字符:70+…对象-引用对象$US-DifferenceObject$Arrayofmembers-Exclud…+~~~~~~~~~~~~~~~+CategoryInfo:InvalidData:(:)[比较对象],ParameterBindingValidationException+FullyQualifiedErrorId:ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CompareObjectCommands脚本是否在出现错误时停止,还是只是将错误输出到控制台并继续处理?这意味着您的
$ErrorActionPreference
不会继续。因此,我们将需要将其添加到命令中。