我在 PowerShell 中有这个代码,它会查看组和用户,并使用我想要的字段创建制表符分隔的txt文件。
然而,它只能找到一半的信息。我正在尝试替换生成相同报告的另一个流程,此报告收集大约580,000行数据,而此 PowerShell 报告仅生成大约300,000个。
我想我需要递归地查看群组,但我不知道该怎么做。
代码:
#requires -version 2
$ScriptName = $MyInvocation.MyCommand.Name
$ADS_GROUP_TYPE_SECURITY_ENABLED = 0x80000000
$PageSize = 250 # Adjust as needed
# Create the Pathname object and enable its EscapedMode property
$ADS_ESCAPEDMODE_ON = 2
$ADS_SETTYPE_DN = 4
$ADS_FORMAT_X500_DN = 7
$Pathname = new-object -comobject "Pathname"
[Void] $Pathname.GetType().InvokeMember("EscapedMode", "SetProperty", $NULL, $Pathname, $ADS_ESCAPEDMODE_ON)
# Returns correctly escaped DN using Pathname object
function Get-EscapedPath {
param(
[String] $distinguishedName
)
[Void] $Pathname.GetType().InvokeMember("Set", "InvokeMethod", $NULL, $Pathname, ($distinguishedName, $ADS_SETTYPE_DN))
$Pathname.GetType().InvokeMember("Retrieve", "InvokeMethod", $NULL, $Pathname, $ADS_FORMAT_X500_DN)
}
# Returns a property from a ResultPropertyCollection if it's defined
function Get-SearchResultProperty {
param(
[System.DirectoryServices.ResultPropertyCollection] $properties,
[String] $propertyName
)
if ( $properties[$propertyName] ) {
$properties[$propertyName][0]
}
else {
""
}
}
# Returns a property from a DirectoryEntry if it's defined
function Get-DirEntryProperty {
param(
[System.DirectoryServices.DirectoryEntry] $dirEntry,
[String] $propertyName
)
if ( $dirEntry.$propertyName ) {
$dirEntry.$propertyName[0]
}
else {
""
}
}
write-progress $ScriptName "Enumerating groups"
$domain = [ADSI] ""
$searcher = [ADSISearcher] "(objectClass=group)"
$searcher.SearchRoot = $domain
$searcher.PageSize = $PageSize
$searcher.SearchScope = "subtree";
$searcher.PropertiesToLoad.AddRange(@("name","grouptype","distinguishedname","description","managedby","member"))
$searchResults = $searcher.FindAll()
$groupCounter = 0
$groupCount = $searchResults.Count
foreach ( $searchResult in $searchResults ) {
$properties = $searchResult.Properties
$domainName = "domainname"
$groupName = Get-SearchResultProperty $properties "name"
$groupType = Get-SearchResultProperty $properties "grouptype"
if ( ($groupType -band $ADS_GROUP_TYPE_SECURITY_ENABLED) -ne 0 ) {
$groupTypeString = "Security"
}
else {
$groupTypeString = "Distribution"
}
$groupDescription = Get-SearchResultProperty $properties "description"
$groupDN = Get-SearchResultProperty $properties "distinguishedname"
$groupManagedBy = Get-SearchResultProperty $properties "managedby"
$member = $properties["member"]
if ( $member ) {
$memberCounter = 0
$memberCount = ($member | measure-object).Count
foreach ( $memberDN in $member ) {
$memberDirEntry = [ADSI] "LDAP://$(Get-EscapedPath $memberDN)"
"" | select-object `
@{Name = "Domain"; Expression = {$domainName}},
@{Name = "Group Name"; Expression = {$groupName}},
@{Name = "Type"; Expression = {$groupTypeString}},
@{Name = "Description"; Expression = {$groupDescription}},
@{Name = "Distinguished Name"; Expression = {$groupDN}},
@{Name = "Managed By"; Expression = {$groupManagedBy}},
@{Name = "Members"; Expression = {$memberDN}},
@{Name = "Full Name"; Expression = {Get-DirEntryProperty $memberDirEntry "name"}},
@{Name = "User Name"; Expression = {Get-DirEntryProperty $memberDirEntry "samaccountname"}},
@{Name = "Display Name"; Expression = {Get-DirEntryProperty $memberDirEntry "displayname"}}
$memberCounter++
$memberPercent = ($memberCounter / $memberCount) * 100 -as [Int]
$params = @{
"Activity" = $ScriptName
"Completed" = $memberPercent -eq 100
"CurrentOperation" = "Enumerating '$groupDN'"
"PercentComplete" = $memberPercent
"Status" = "Groups: {0}/{1} [{2:P2}] - Members: {3}/{4} [{5:P2}]" -f
$groupCounter,
$groupCount,
($groupCounter / $groupCount),
$memberCounter,
$memberCount,
($memberCounter / $memberCount)
}
write-progress @params
}
}
else {
# Group contains no members
"" | select-object `
@{Name = "Domain"; Expression = {$domainName}},
@{Name = "Group Name"; Expression = {$groupName}},
@{Name = "Type"; Expression = {$groupTypeString}},
@{Name = "Description"; Expression = {$groupDescription}},
@{Name = "Distinguished Name"; Expression = {$groupDN}},
@{Name = "Managed By"; Expression = {$groupManagedBy}},
@{Name = "Members"; Expression = {""}},
@{Name = "Full Name"; Expression = {""}},
@{Name = "User Name"; Expression = {""}},
@{Name = "Display Name"; Expression = {""}}
}
$groupCounter++
$groupPercent = ($groupCounter / $groupCount) * 100 -as [Int]
$params = @{
"Activity" = $ScriptName
"Completed" = $groupPercent -eq 100
"CurrentOperation" = "Enumerating '$groupDN'"
"PercentComplete" = $groupPercent
"Status" = "Groups: {0}/{1} [{2:P2}]" -f
$groupCounter,
$groupCount,
($groupCounter / $groupCount)
}
write-progress @params
# Periodically force garbage collection to reduce memory usage
if ( ($groupCounter % $PageSize) -eq 0 ) {
[GC]::Collect()
[GC]::WaitForPendingFinalizers()
}
}
$searchResults.Dispose()
编辑: 我尝试使用这一行,就在包含"子树":
的行之前$searcher.Filter = "(member:1.2.840.113556.1.4.1941:=*)"
并尝试编辑此行:
$searcher = [ADSISearcher] "(objectClass=group)"
到这个
$searcher = [ADSISearcher] "(&(objectClass=group)(memberof:1.2.840.113556.1.4.1941L:=*))"
既不工作,也只是立即返回,没有输出,大概是因为过滤器没有拾取任何东西。之前我没有过滤器,因为我想要一切