我在PowerShell中查看組和用戶並使用我想要的字段創建制表符分隔的txt文件。PowerShell中的ADSI報表 - 遞歸組
但它只能找到一半的信息。我試圖替換生成相同報告的另一個進程,並且此報告收集大約580,000行數據,因爲此報告僅生成大約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:=*))"
既不工作,它只是立即返回沒有輸出,大概是因爲過濾器沒有拿起任何東西。我以前沒有一個過濾器,因爲我想要的一切
我在回答一個類似的問題:用戶清單在廣告組中遞歸地使用PowerShell腳本而無CmdLets](http://stackoverflow.com/a/8055996/608772) – JPBlanc 2014-09-26 11:43:08