Skip to content

Commit

Permalink
Merge pull request #12 from santisq/11-add-exclude-parameter
Browse files Browse the repository at this point in the history
Adds `-Exclude` parameter to both cmdlets
  • Loading branch information
santisq authored Sep 3, 2024
2 parents 1916a19 + 5cdffc8 commit 8cf28c3
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 16 deletions.
35 changes: 30 additions & 5 deletions docs/en-US/Get-ADTreeGroupMember.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Get-ADTreeGroupMember
[-Server <String>]
[-Depth <Int32>]
[-ShowAll]
[-Exclude <String[]>]
[<CommonParameters>]
```

Expand All @@ -34,6 +35,7 @@ Get-ADTreeGroupMember
[-Server <String>]
[-Recursive]
[-ShowAll]
[-Exclude <String[]>]
[<CommonParameters>]
```

Expand Down Expand Up @@ -88,7 +90,7 @@ PS ..\PSADTree\> Get-ADTreeGroupMember TestGroup001 -Server otherDomain
PS ..\PSADTree\> Get-ADTreeGroupMember TestGroup001 -ShowAll
```

By default, previously processed groups will be marked as _"Processed Group"_ and their hierarchy will not be displayed.
By default, previously processed groups will be marked as _"Processed Group"_ and their hierarchy will not be displayed.
The `-ShowAll` switch indicates that the cmdlet should display the hierarchy of all previously processed groups.

> [!NOTE]
Expand All @@ -99,7 +101,7 @@ The `-ShowAll` switch indicates that the cmdlet should display the hierarchy of

### -Depth

Determines the number of nested groups and their members included in the recursion.
Determines the number of nested groups and their members included in the recursion.
By default, only 3 levels of recursion are included.

```yaml
Expand Down Expand Up @@ -199,13 +201,13 @@ Accept wildcard characters: False

### -ShowAll

By default, previously processed groups will be marked as _"Processed Group"_ and their hierarchy will not be displayed.
By default, previously processed groups will be marked as _"Processed Group"_ and their hierarchy will not be displayed.
This switch forces the cmdlet to display the full hierarchy including previously processed groups.

> [!NOTE]
>
> This cmdlet uses a caching mechanism to ensure that Active Directory Groups are only queried once per Identity.
> This caching mechanism is also used to reconstruct the pre-processed group's hierarchy when the `-ShowAll` switch is used, thus not incurring a performance cost.
> This cmdlet uses a caching mechanism to ensure that Active Directory Groups are only queried once per Identity.
> This caching mechanism is also used to reconstruct the pre-processed group's hierarchy when the `-ShowAll` switch is used, thus not incurring a performance cost.
> The intent behind this switch is to not clutter the cmdlet's output by default.

```yaml
Expand All @@ -220,6 +222,29 @@ Accept pipeline input: False
Accept wildcard characters: False
```

### -Exclude

Specifies an array of one or more string patterns to be matched as the cmdlet enumerates child principals.
Any matching principal is excluded from the output.
Wildcard characters are accepted.

> [!NOTE]
>
> - Patterns are tested against the principal's `.SamAccountName` property.
> - When the matched principal is of type `group`, all child principals are also excluded from the output.

```yaml
Type: String[]
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: True
```

### CommonParameters

This cmdlet supports the common parameters. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
Expand Down
34 changes: 29 additions & 5 deletions docs/en-US/Get-ADTreePrincipalGroupMembership.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Get-ADTreePrincipalGroupMembership
[-Server <String>]
[-Depth <Int32>]
[-ShowAll]
[-Exclude <String[]>]
[<CommonParameters>]
```

Expand All @@ -32,6 +33,7 @@ Get-ADTreePrincipalGroupMembership
[-Server <String>]
[-Recursive]
[-ShowAll]
[-Exclude <String[]>]
[<CommonParameters>]
```

Expand Down Expand Up @@ -84,7 +86,7 @@ PS ..\PSADTree\> Get-ADTreePrincipalGroupMembership john.doe -Server otherDomain
PS ..\PSADTree\> Get-ADTreePrincipalGroupMembership john.doe -ShowAll
```

By default, previously processed groups will be marked as _"Processed Group"_ and their hierarchy will not be displayed.
By default, previously processed groups will be marked as _"Processed Group"_ and their hierarchy will not be displayed.
The `-ShowAll` switch indicates that the cmdlet should display the hierarchy of all previously processed groups.

> [!NOTE]
Expand All @@ -95,7 +97,7 @@ The `-ShowAll` switch indicates that the cmdlet should display the hierarchy of

### -Depth

Determines the number of nested group memberships included in the recursion.
Determines the number of nested group memberships included in the recursion.
By default, only 3 levels of recursion are included.

```yaml
Expand Down Expand Up @@ -179,13 +181,13 @@ Accept wildcard characters: False

### -ShowAll

By default, previously processed groups will be marked as _"Processed Group"_ and their hierarchy will not be displayed.
By default, previously processed groups will be marked as _"Processed Group"_ and their hierarchy will not be displayed.
This switch forces the cmdlet to display the full hierarchy including previously processed groups.

> [!NOTE]
>
> This cmdlet uses a caching mechanism to ensure that Active Directory Groups are only queried once per Identity.
> This caching mechanism is also used to reconstruct the pre-processed group's hierarchy when the `-ShowAll` switch is used, thus not incurring a performance cost.
> This cmdlet uses a caching mechanism to ensure that Active Directory Groups are only queried once per Identity.
> This caching mechanism is also used to reconstruct the pre-processed group's hierarchy when the `-ShowAll` switch is used, thus not incurring a performance cost.
> The intent behind this switch is to not clutter the cmdlet's output by default.

```yaml
Expand All @@ -200,6 +202,28 @@ Accept pipeline input: False
Accept wildcard characters: False
```

### -Exclude

Specifies an array of one or more string patterns to be matched as the cmdlet enumerates child principals.
Any matching principal is excluded from the output.
Wildcard characters are accepted.

> [!NOTE]
>
> Patterns are tested against the principal's `.SamAccountName` property.

```yaml
Type: String[]
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: True
```

### CommonParameters

This cmdlet supports the common parameters. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
Expand Down
5 changes: 5 additions & 0 deletions src/PSADTree/Commands/GetADTreeGroupMemberCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ private void EnumerateMembers(
}
}

if (ShouldExclude(member, _exclusionPatterns))
{
continue;
}

TreeObjectBase treeObject = ProcessPrincipal(
principal: member,
parent: parent,
Expand Down
14 changes: 12 additions & 2 deletions src/PSADTree/Commands/GetADTreePrincipalGroupMembershipCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,13 @@ protected override void ProcessRecord()
try
{
using PrincipalSearchResult<Principal> search = principal.GetGroups();
foreach (Principal parent in search)
foreach (Principal parent in search.GetSortedEnumerable(_comparer))
{
if (ShouldExclude(parent, _exclusionPatterns))
{
continue;
}

GroupPrincipal groupPrincipal = (GroupPrincipal)parent;
TreeGroup treeGroup = new(source, null, groupPrincipal, 1);
Push(groupPrincipal, treeGroup);
Expand Down Expand Up @@ -162,8 +167,13 @@ private void EnumerateMembership(
string source,
int depth)
{
foreach (Principal group in searchResult)
foreach (Principal group in searchResult.GetSortedEnumerable(_comparer))
{
if (ShouldExclude(group, _exclusionPatterns))
{
continue;
}

TreeGroup treeGroup = ProcessGroup((GroupPrincipal)group);
if (ShowAll.IsPresent)
{
Expand Down
54 changes: 50 additions & 4 deletions src/PSADTree/PSADTreeCmdletBase.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.DirectoryServices.AccountManagement;
using System.Linq;
using System.Management.Automation;

namespace PSADTree;
Expand All @@ -23,11 +24,18 @@ public abstract class PSADTreeCmdletBase : PSCmdlet, IDisposable

internal PSADTreeComparer _comparer = new();

protected WildcardPattern[]? _exclusionPatterns;

private const WildcardOptions _wpoptions = WildcardOptions.Compiled
| WildcardOptions.CultureInvariant
| WildcardOptions.IgnoreCase;


[Parameter(
Position = 0,
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true)]
Position = 0,
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true)]
[Alias("DistinguishedName")]
public string? Identity { get; set; }

Expand All @@ -44,10 +52,21 @@ public abstract class PSADTreeCmdletBase : PSCmdlet, IDisposable
[Parameter]
public SwitchParameter ShowAll { get; set; }

[Parameter]
[SupportsWildcards]
public string[]? Exclude { get; set; }

protected override void BeginProcessing()
{
try
{
if (Exclude is not null)
{
_exclusionPatterns = Exclude
.Select(e => new WildcardPattern(e, _wpoptions))
.ToArray();
}

if (Server is null)
{
_context = new PrincipalContext(ContextType.Domain);
Expand All @@ -70,6 +89,33 @@ protected void Push(GroupPrincipal? groupPrincipal, TreeGroup treeGroup)
}
}

private static bool MatchAny(
Principal principal,
WildcardPattern[] patterns)
{
foreach (WildcardPattern pattern in patterns)
{
if (pattern.IsMatch(principal.SamAccountName))
{
return true;
}
}

return false;
}

protected static bool ShouldExclude(
Principal principal,
WildcardPattern[]? patterns)
{
if (patterns is null)
{
return false;
}

return MatchAny(principal, patterns);
}

protected virtual void Dispose(bool disposing)
{
if (disposing && !_disposed)
Expand Down

0 comments on commit 8cf28c3

Please sign in to comment.