简体   繁体   中英

Powershell - How to remove trailing spaces from a list of groups a user is in

I've copied/created a script to get all the members of a group that a user is part of, including nested groups. However, my output isn't quite the way I want it.

It goes in one of two ways. Either it outputs as one big string, which looks nice, but has trailing spaces on each line so I cannot simply copy and paste it into AD. Or if I change the Out-String to use -stream, it comes out as a garbled mess, but may allow me to trim the spaces.

I currently have the output going into a TextBox in a simple GUI.

Function Get-ADUserNestedGroups {
Param
(
    [string]$DistinguishedName,
    [array]$Groups = @()
)

#Get the AD object, and get group membership.
$ADObject = Get-ADObject -Filter "DistinguishedName -eq '$DistinguishedName'" -Properties memberOf, DistinguishedName;

#If object exists.
If($ADObject)
{
    #Enummurate through each of the groups.
    Foreach($GroupDistinguishedName in $ADObject.memberOf)
    {
        #Get member of groups from the enummerated group.
        $CurrentGroup = Get-ADObject -Filter "DistinguishedName -eq '$GroupDistinguishedName'" -Properties memberOf, DistinguishedName;
   
        #Check if the group is already in the array.
        If(($Groups | Where-Object {$_.DistinguishedName -eq $GroupDistinguishedName}).Count -eq 0)
        {
            #Add group to array.
            $Groups +=  $CurrentGroup;

            #Get recursive groups.      
            $Groups = Get-ADUserNestedGroups -DistinguishedName $GroupDistinguishedName -Groups $Groups;
        }
    }
}

#Return groups.
Return $Groups;
}

 Function Display-UserGroups {

#Get all groups.
$Groups = Get-ADUserNestedGroups -DistinguishedName (Get-ADUser -Identity $userSAM).DistinguishedName;

$ResultsTextBox.Text = $Groups | Select-Object Name| Sort-Object name | Out-String

The output with the first way looks like:

Group Name1(Eight Spaces Here)

Group Name2(Eight Spaces Here)

The output with the second way looks like:

Group Name1GroupName2GroupName3

Thanks for your help!

You need to trim your output, which can easily be done with String.Trim method. However, it can only be applied against strings. $Groups will be an array of ADObject types. You will need to return the Name values of those objects and apply the Trim() method to the values.

($Groups | Select -Expand Name | Sort).Trim() -join "`r`n"

You can use $Groups += $CurrentGroup.trimEnd() to add the value with the trailing spaces trimmed.

A few other methods you might want to research

.trim()      # Trim leading and trailing
.trimEnd()   # Trim trailing
.trimStart() # Trim leading

The padding is being caused by PowerShell's formatting system. Select-Object is returning single property (Name) objects. PowerShell outputs that as a table, which may have some padding. Out-String is keeping that padding which is why it was reflecting in your final output...

The name property of the group is already a string. There's no need to use Out-String if you unroll the Name property from your $Groups variable/collection.

With some other adjustments for readability & testing. Below will emit a single string with each group on a new line. That should be paste-able into AD, by which I think you meant Active Directory User & Computers.

Function Get-ADUserNestedGroups
{
    Param
    (
        [string]$DistinguishedName,
        [array]$Groups = @()
    )
    
    # Get the AD object, and get group membership.
    $ADObject = Get-ADObject $DistinguishedName -Properties memberOf, DistinguishedName
    
    # If object exists.
    If( $ADObject )
    {
        # Enummurate through each of the groups.
        Foreach( $GroupDistinguishedName in $ADObject.memberOf )
        {
            # Get member of groups from the enummerated group.
            $CurrentGroup = Get-ADObject $GroupDistinguishedName -Properties memberOf, DistinguishedName
       
            # Check if the group is already in the array.
            If( $Groups.DistinguishedName -notcontains $GroupDistinguishedName )
            {
                # Add group to array.
                $Groups +=  $CurrentGroup
    
                # Get recursive groups.      
                $Groups = Get-ADUserNestedGroups -DistinguishedName $GroupDistinguishedName -Groups $Groups
            }
        }
    }
    
    # Return groups.
    Return $Groups
    }
    
$userSAM = 'UserName'

# Get all groups.
$Groups = Get-ADUserNestedGroups -DistinguishedName (Get-ADUser -Identity $userSAM).DistinguishedName
($Groups.Name | Sort-Object) -join [System.Environment]::NewLine

Among the secondary changes you'll see I removed the -Filter parameter in a few places. The DistinguishedName can be used as the -Identity parameter so no need to filter.

Also, where you were checking if the $Groups collection already had the current group I used the -notContains operator instead. That should be faster then repeatedly iterating the collection with |Where{...} The code is also shorter and more readable.

Note: if we reverse the operands we could use -notin which may look nicer still

An aside; You should avoid appending arrays with += . Doing so can causes performance problems because it creates a new array any copies the contents over. The best way to deal with this is to allow PowerShell to accumulate the results for you. If you must do the append directly, look into using Array Lists. There's a lot information on this, just google it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM