我的目標是轉儲我們的 AD 組及其成員的 CSV 檔案,以及這些成員物件是否已啟用,但我遇到了一個奇怪的(可能是自己造成的)問題,其中 Foreach-Object 回圈的行為例外。
輸出幾乎有效。它轉儲一個 CSV 檔案。該檔案包含每個組的行,填充了正確的組相關資料,以及正確的行數,跟隨組成員的數量。但是,這些行上的組成員屬性會重復,為每個組成員結果一遍又一遍地顯示相同的用戶資料,顯然遵循從 Get-ADGroupMember 回傳的最后一個物件的屬性。
為了嘗試診斷問題,我添加了行Write-Host $GroupMember.Name -ForegroundColor Gray. 這就是我如何知道 CSV 中的條目是每個組最后回傳的結果。令人困惑的是,控制臺正確地回顯了每個組成員的顯示名稱。
我假設這里存在某種邏輯錯誤,但我沒有找到它。任何幫助,將不勝感激!
clear
Import-Module ActiveDirectory
# CONFIG ========================================
# Plant Number OU to scan. Used in $CSV and in Get-ADComputer's search base.
$PlantNumber = "1234"
# FQDN of DC you want to query against. Used by the Get-AD* commands.
$ServerName = "server.com"
# Output directory for the CSV. Default is [Environment]::GetFolderPath("Desktop"). Used in $CSV. NOTE: If setting up as an automated task, change this to a more sensible place!
$OutputDir = [Environment]::GetFolderPath("Desktop")
# CSV Output string. Default is "$OutputDir\$PlantNumber" "-ComputersByOS_" "$(get-date -f yyyy-MM-dd).csv" ( 's used due to underscores in name)
$CSV = "$OutputDir\$PlantNumber" "GroupMembers_" "$(get-date -f yyyy-MM-dd).csv"
# Create empty array for storing collated results
$collectionTable = @()
# Get AD groups, return limited properties
Get-AdGroup -filter * -Property Name, SamAccountName, Description, GroupScope -SearchBase "OU=Security Groups,OU=$PlantNumber,OU=Plants,DC=SERVER,DC=COM" -server $ServerName | Select SamAccountName, Description, GroupScope | Foreach-Object {
Write-Host "Querying" $_.SamAccountName "..."
#Initialize $collectionRow, providing the columns we want to collate
$collectionRow = "" | Select GroupName, GroupScope, GroupDesc, MemberObjectClass, MemberName, MemberDisplayName, Enabled
# Populate Group-level collectionRow properties
$collectionRow.GroupName = $_.SamAccountName
$collectionRow.GroupDesc = $_.Description
$collectionRow.GroupScope = $_.GroupScope
# Process group members
Get-ADGroupMember -Identity ($collectionRow.GroupName) -Server $ServerName -Recursive | ForEach-Object {
$GroupMember = $_
# Echo member name to console
Write-Host $GroupMember.Name -ForegroundColor Gray
$collectionRow.MemberName = $GroupMember.SamAccountName
$collectionRow.MemberDisplayName = $GroupMember.name
$collectionRow.MemberObjectClass = $GroupMember.ObjectClass
# If the member object is a user, collect some additional data
If ($collectionRow.MemberObjectClass -eq "user") {
Try {
$collectionRow.Enabled = (Get-ADUser $GroupMember.SamAccountName -Property Enabled -ErrorAction Stop).Enabled
If ($collectionRow.Enabled -eq "TRUE") {$collectionTable = $collectionRow}
}
Catch {
$collectionRow.Enabled = "ERROR"
$collectionTable = $collectionRow
}
}
}
}
Write-Host "`n"
# Attempt to save results to CSV. If an error occurs, alert the user and try again.
$ExportSuccess = 'false'
while ($ExportSuccess -eq 'false') {
Try
{
# Export results to $CSV
$collectionTable| Export-csv $CSV -NoTypeInformation -ErrorAction Stop
# If the above command is successful, the rest of the Try section will execute. If not, Catch is triggered instead.
$ExportSuccess = 'true'
Write-Host "`nProcessing complete. Results output to"$CSV
}
Catch
{
Write-Host "Error writing to"$CSV"!" -ForegroundColor Yellow
Read-Host -Prompt "Ensure the file is not open, then press any key to try again"
}
}
uj5u.com熱心網友回復:
你的代碼中有很多東西需要修復,我只指出最重要的:
- 不要使用
@()和= - 您繼續使用
'True'and'False'which 是字串,PowerShell布林值是$trueand$false。
還有太多的冗余代碼。也ForEach-Object很慢,如果您的組有很多成員,并且由于您正在使用-Recursive,最好使用快速回圈。
$PlantNumber = "1234"
$ServerName = "server.com"
$OutputDir = [Environment]::GetFolderPath("Desktop")
$fileName = "${PlantNumber}GroupMembers_$(Get-Date -f yyyy-MM-dd).csv"
$CSV = Join-Path $OutputDir -ChildPath $fileName
# $collectionTable = @() => Don't do this to collect results, ever
$adGroupParams = @{
# Name and SAM are default, no need to add them
Properties = 'Description', 'GroupScope'
SearchBase = "OU=Security Groups,OU=$PlantNumber,OU=Plants,DC=SERVER,DC=COM"
Server = $ServerName
Filter = '*'
}
# Get AD groups, return limited properties
$collectionTable = foreach($group in Get-AdGroup @adGroupParams)
{
Write-Host "Querying $($group.samAccountName)..."
foreach($member in Get-ADGroupMember $group -Server $ServerName -Recursive)
{
# if this member is 'user' the Enabled property
# will be a bool ($true / $false) else it will be $null
$enabled = if($member.ObjectClass -eq 'User')
{
(Get-ADUser $member).Enabled
}
[pscustomobject]@{
GroupName = $group.SamAccountName
GroupDesc = $group.Description
GroupScope = $group.GroupScope
MemberName = $member.SamAccountName
MemberDisplayName = $member.Name
MemberObjectClass = $member.ObjectClass
Enabled = $enabled
}
}
}
uj5u.com熱心網友回復:
據我了解,您需要將包含成員的組串列匯出到 csv 檔案,并知道成員帳戶是否已啟用,如果您想要,您可以查看以下代碼
$output = @()
Import-Module ActiveDirectory
$ServerName = "server.com"
$PlantNumber = "1234"
$OutputDir = [Environment]::GetFolderPath("Desktop")
$CSV = "$OutputDir\$PlantNumber" "GroupMembers_" "$(get-date -f yyyy-MM-dd).csv"
$groups = Get-AdGroup -filter * -Property Description -SearchBase "OU=Security Groups,OU=$PlantNumber,OU=Plants,DC=SERVER,DC=COM" -server $ServerName
foreach ($group in $groups){
$members = Get-ADGroupMember -Identity $group.SamAccountName -Recursive
foreach ($member in $members){
$output = [pscustomobject]@{
GroupName = $group.SamAccountName
GroupDesc = $group.Description
GroupScope = $group.GroupScope
MemberName = $member.samaccountname
MemberDisplayName = $member.Name
MemberObjectClass = $member.ObjectClass
Enabled = $(Get-ADUser -Identity $member.samaccountname).enabled
}
}
}
$output | Export-Csv $CSV -NoTypeInformation
uj5u.com熱心網友回復:
我明確沒有參考您的代碼。我只想展示我將如何處理這項任務。我希望它無論如何都會幫助你。
$Server = 'Server01.contoso.com'
$SearchBase = 'OU=BaseOU,DC=contoso,DC=com'
$CSVOutputPath = '... CSV path '
$ADGroupList = Get-ADGroup -Filter * -Properties Description -SearchBase $SearchBase -Server $Server
$ADUserList = Get-ADUser -Filter * -Properties Description -SearchBase $SearchBase -Server $Server
$Result =
foreach ($ADGroup in $ADGroupList) {
$ADGroupMemberList = Get-ADGroupMember -Identity $ADGroup.sAMAccountName -Recursive
foreach ($ADGroupmember in $ADGroupMemberList) {
$ADUser = $ADUserList | Where-Object -Property sAMAccountName -EQ -Value $ADGroupmember.sAMAccountName
[PSCustomObject]@{
ADGroupName = $ADGroup.Name
ADGroupDescription = $ADGroup.Description
ADGroupMemberName = $ADUser.Name
ADGroupMemberSamAccountName = $ADUser.sAMAccountName
ADGroupMemberDescription = $ADUser.Description
ADGroupMemberStatus = if ($ADUser.Enabled) { 'enabled' }else { 'diabled' }
}
}
}
$Result |
Export-Csv -Path $CSVOutputPath -NoTypeInformation -Delimiter ',' -Encoding utf8
它只會輸出幾個屬性,但我希望你能明白。
BTW:屬性 DistinguishedName、Enabled、GivenName、Name、ObjectClass、ObjectGUID、SamAccountName、SID、Surname、UserPrincipalName 包含在默認回傳集中,Get-ADUser屬性 DistinguishedName、GroupCategory、GroupScope、Name、ObjectClass、ObjectGUID、SamAccountName、SID 是包含在 的默認回傳集中Get-ADGroup。您不需要使用引數顯式查詢它們-Properties。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/397998.html
