【问题标题】:Extracting data from AD with users from multiple groups and show those groups in Export-CSV使用来自多个组的用户从 AD 中提取数据并在 Export-CSV 中显示这些组
【发布时间】:2021-09-10 21:41:08
【问题描述】:

目标:创建一个带有数据格式的 Export-CSV 文件,以便可以将其导入另一个程序。 数据文件包括 UIDNumber、GivenName、SurName、Record Type、Custom Field 1、Custom Value 1、End。 “自定义字段 1”和“结束”是我部门特有的填充文本。

“自定义值 1”是我遇到问题的地方。我需要让用户确定他们所在的组并将这些组名分配给以“自定义值 1”分隔的管道。输出应该是这样的:

Employee ID,  First Name,  Last Name, Record Type, Custom Field 1, Custom Value 1, End

123456,       John, Doe, employee, ADGroup-MSelectionList, REF_USERS | PC_USERS,   End

我意识到我的代码已经完成并且速度很慢,但我正在学习。对于如何从每个组中获取用户关联并构建所需的字段,我有很多想法,只是不知道如何到达那里。

这是我的代码:

# Var
$LocalVar1 = 'USERGroup1'    
$LocalVar2 = 'USERGroup2'    
$LocalVar3 = 'USERGroup3'

$Field1 = 'ADGroup-MSelectionList'

$Field2 = 'END'

# Getting the members of each group into one container

$Allusers1 = Get-ADGroupMember -Identity $LocalVar1 | ? {$_.objectclass -eq "user" } | Foreach-Object ({ Get-ADUser $($_.samaccountname) -Properties * }) | ? {$_.enabled -eq $True} | Select @{Name="Employee ID";Expression={$_.UIDNumber}}    

$Allusers2 = Get-ADGroupMember -Identity $LocalVar2 | ? {$_.objectclass -eq "user" } | Foreach-Object ({ Get-ADUser $($_.samaccountname) -properties * }) | ? {$_.enabled -eq $True} | Select @{Name="Employee ID";Expression={$_.UIDNumber}}    

$Allusers3 = Get-ADGroupMember -Identity $LocalVar3 | ? {$_.objectclass -eq "user" } | Foreach-Object ({ Get-ADUser $($_.samaccountname) -properties * }) | ? {$_.enabled -eq $True} | Select @{Name="Employee ID";Expression={$_.UIDNumber}}

# Putting all the users in one basket
$Allusers = $AllUsers1 + $Allusers2 + $Allusers3

# Removing all of the duplicate users
$Allusers | Sort "Employee_ID" -unique

# Getting the individual users out of each group with required data

$users1 = Get-ADGroupMember -Identity $LocalVar1 | ? {$_.objectclass -eq "user" } | Foreach-Object ({ Get-ADUser $($_.samaccountname) -properties * }) | ? {$_.enabled -eq $True} | Select @{Name="Employee ID";Expression={$_.UIDNumber}},@{Name="First Name";Expression={$_.GivenName}},@{Name="Last Name";Expression={$_.SurName}},@{Name="Record Type";Expression={"Employee"}},
@{Name="Custom Field 1";Expression={$Field1}},@{Name="Custom Value 1";Expression={$LocalVar1}},@{Name="END";Expression={$Field2}}

$users2 = Get-ADGroupMember -Identity $LocalVar2 | ? {$_.objectclass -eq "user" } | Foreach-Object ({ Get-ADUser $($_.samaccountname) -properties * }) | ? {$_.enabled -eq $True} | Select @{Name="Employee ID";Expression={$_.UIDNumber}},@{Name="First Name";Expression={$_.GivenName}},@{Name="Last Name";Expression={$_.SurName}},@{Name="Record Type";Expression={"Employee"}},
@{Name="Custom Field 1";Expression={$Field1}},@{Name="Custom Value 1";Expression={$LocalVar2}},@{Name="END";Expression={$Field2}}

$users3 = Get-ADGroupMember -Identity $LocalVar3 | ? {$_.objectclass -eq "user" } | Foreach-Object ({ Get-ADUser $($_.samaccountname) -properties * }) | ? {$_.enabled -eq $True} | Select @{Name="Employee ID";Expression={$_.UIDNumber}},@{Name="First Name";Expression={$_.GivenName}},@{Name="Last Name";Expression={$_.SurName}},@{Name="Record Type";Expression={"Employee"}},
@{Name="Custom Field 1";Expression={$Field1}},@{Name="Custom Value 1";Expression={$LocalVar3}},@{Name="END";Expression={$Field2}}

# This is my started attempt to get what I want, but had no luck.
Foreach ($Employee_ID in $Allusers) {    
              Where-Object($User1 -eq $Allusers) 
       } 

【问题讨论】:

    标签: powershell nested


    【解决方案1】:

    这是我更新的代码。我仍在进行改进,并使用 EmployeeType 的 IF 语句削减了大约一半的原始编程。我在单独的脚本中创建了一个小的 -replace 代码来放置“|”每组之间。我还在查看您提供的所有链接,它们对我很有帮助。

    # Local Variables
    $LocalVar1 = 'Group_1_USERS'
    $LocalVar2 = 'Group_2_USERS'
    $LocalVar3 = 'Group_3_USERS'
    
    $Field1 = 'ADGroup-MSelectionList'
    $Field2 = 'END'
    
    # Going through each group to get extract users
    $users1 = Get-ADGroupMember -Identity $LocalVar1 | 
        ? {$_.objectclass -eq "user"} | 
            Foreach-Object ({ Get-ADUser $($_.samaccountname) -properties SamAccountName, Enabled }) | 
                ? {$_.enabled -eq $True} | 
                Select @{Name="SamAccountName";Expression={$_.SamAccountName}}
    
    $users2 = Get-ADGroupMember -Identity $LocalVar2 | 
        ? {$_.objectclass -eq "user"} | 
            Foreach-Object ({ Get-ADUser $($_.samaccountname) -properties SamAccountName, Enabled }) | 
                ? {$_.enabled -eq $True} | 
                Select @{Name="SamAccountName";Expression={$_.SamAccountName}}
    
    $users3 = Get-ADGroupMember -Identity $LocalVar3 | 
        ? {$_.objectclass -eq "user"} | 
            Foreach-Object ({ Get-ADUser $($_.samaccountname) -properties SamAccountName, Enabled }) | 
                ? {$_.enabled -eq $True} | 
                Select @{Name="SamAccountName";Expression={$_.SamAccountName}}
                
    # Putting all the users in one basket, Sort the users and remove
    $Data = $Users1 + $users2 + $users3 | Sort "SamAccountName" -Unique
    
    # Extracting, Formatting and Output
    $Data | Foreach ({ Get-ADUser $($_.samaccountname) -properties EmployeeType, UIDNumber, GivenName, SurName, SamAccountName }) | 
        Select-Object @{Name="Employee ID";Expression={$_.UIDNumber}},
            @{Name="First Name";Expression={$_.GivenName}},
            @{Name="Last Name";Expression={$_.SurName}},
            @{Name="Record Type";Expression={ If ($_.EmployeeType -eq "E") {"Employee"} else {"Contractor"}}},
            @{Name="Custom Field 1";Expression={$Field1}},
            @{Name="Custom Value 1";Expression={ ( (Get-ADPrincipalGroupMembership $_.samAccountName).Name | 
                Where-Object {$_ -Like "Group_*_USERS"})}},
            @{Name="END";Expression={$Field2}}|
    
    Export-CSV -Path "W:\$((Get-Date).ToString("yyyyMMdd_hh"))_File.csv" -NoTypeInformation
    

    【讨论】:

      【解决方案2】:

      除了所说的之外,您几乎肯定会遇到问题,因为您错误地使用了ForEach-Object。您应该阅读ForEachForEach-Object 之间的区别,因为您在管道中使用了前者的语法,这是不正确的。

      Docs ForEach-Object

      About_ForEach

      我会指出在这种情况下不需要 ForEach-Object 循环。 Get-ADUser can take the output from Get-ADGroupMember` 直接通过管道。例如,重构的代码段:

      $Allusers1 = Get-ADGroupMember -Identity $LocalVar1 | 
      Where-Object { $_.objectclass -eq "user" } | 
      Get-ADUser -Properties *  | 
      Where-Object { $_.Enabled } | 
      Select-Object @{Name = "Employee ID"; Expression = { $_.UIDNumber }} 
      

      顺便说一句:注意格式差异...

      注意:您只选择了您定义的自定义/计算属性。 $AllUsers1 将是一个对象数组,只有一个属性“Employee ID”。

      注意:尽量避免-Properties * 这通常是矫枉过正。而是给 -Properties 一个数组参数,其中包含您感兴趣的其他属性,在您的情况下可能类似于 -Properties "UIDNumber"

      就核心问题而言,我认为这是如何获取给定用户组的管道分隔字段。我无法修改您发布的内容,但我可以提供一个概念示例:

      $users1 = Get-ADGroupMember -Identity $LocalVar1 | 
      Where-Object { $_.objectclass -eq "user" } |  
      Get-ADUser $($_.samaccountname) -properties * | 
      Where-Object {$_.enabled -eq $True} | 
      Select-Object @{Name = "Employee ID"; Expression = { $_.UIDNumber }},
          @{Name = "First Name"; Expression = { $_.GivenName }},
          @{Name = "Last Name"; Expression = { $_.SurName }},
          @{Name = "Record Type"; Expression = { "Employee" }},
          @{Name = "Custom Field 1"; Expression = { $Field1 }},
          @{Name = "Custom Value 1"; Expression = { ( (Get-ADPrincipalGroupMembership $_.samAccountName).Name -join "|" ) }},
          @{Name = "END"; Expression = { $Field2 }}
      

      同样,这不值得生产。它旨在展示一个概念。关键是您要获取用户的组成员身份,实际上是这些 Name 属性的数组,并将它们连接到管道字符上。

      完成后,您仍需要将数据发送到 CSV 文件。继续这个例子:

      $users1 | Export-Csv C:\Temp\Users1.csv -NoTypeInformation
      

      顺便说一句:您确实应该更好地格式化您的代码。至少,您应该在管道字符上换行。对于计算的属性,我要么预先编写它们并将它们存储在一个数组中,要么将它们放在一个新行中,就像我在示例中所做的那样。有很多资源可以用于指导。例如,PowerShell 社区维护"The PowerShell Best Practices and Style Guide"

      【讨论】:

      • 史蒂文,感谢您的反馈和帮助。有很多关于 Powershell 的信息和很多关于如何完成最终结果的不同意见。我只按照呈现的方式编写代码。我喜欢更有条理,感谢您的指点。
      • 我一直在你的位置,我也在学习。如果我有时间,我会尝试添加一个更完整的示例。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多