Get-TfsPermssion–Missing command from Team Foundation Power Tools PowerShell Snapin

The TFPT PowerShell snapin is a nice start but it is missing a key cmdlet IMO and that is Get-TfsPermission.  Since TFS allows you to add individual users all over your directory structure, it can be quite hard rationalizing exactly who has access to what without traversing a bunch of directories in the Team Foundation client’s Source Control window, opening the Properties dialog and inspecting the Security settings.  Fortunately there is also a command line way to do this via TFS’s tf.exe utility.  Unfortunately the output of this command is just text and what’s worse is that this text is a pain to query over using PowerShell’s built-in querying cmdlets.  So I wrote the following function to convert this text into objects which enables easier querying:

<#
.SYNOPSIS
    Gets the Team Foundation server permissions for items based on the specified paths.
.DESCRIPTION
    Gets the Team Foundation server permissions for items based on the specified paths and outputs rich
    objects as opposed to text.
.PARAMETER Path
    The path to the Team Foundation server item.
.PARAMETER LiteralPath
    Specifies a path to one or more locations. Unlike Path, the value of LiteralPath is used exactly as it
    is typed. No characters are interpreted as wildcards. If the path includes escape characters, enclose
    it in single quotation marks. Single quotation marks tell Windows PowerShell not to interpret any
    characters as escape sequences.
.PARAMETER Recurse
    Gets permissions for the items at the specified location and in all child locations.
.EXAMPLE
    C:\PS> Get-TfsPermission C:\Tfs\Acme\Branches\Release\3.7 | Select ServerItem -exp Identities
    Get the permissions for the specified folder and expands the Identities array to show each identity.
    The server item corresponding to each identity object is tagged onto the object.
.EXAMPLE
    C:\PS> Get-TfsPermission C:\Tfs\Acme | Select ServerItem -expand Identities | Where {$_.Allow -match ‘Checkin’ } | Format-List ServerItem,Identity,Allow,Deny   
    This command looks for items where the ‘checkin’ privilege has been granted locally.
.NOTES
    Author: Keith Hill
    Date:   June 28, 2010   
#>
function Get-TfsPermission
{
    [CmdletBinding(DefaultParameterSetName="Path")]
    param(
        [Parameter(Mandatory=$true, Position=0, ParameterSetName="Path",
                   ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true,
                   HelpMessage="Path to workspace item")]
        [ValidateNotNullOrEmpty()]
        [string[]]
        $Path,
       
        [Alias("PSPath")]
        [Parameter(Mandatory=$true, Position=0, ParameterSetName="LiteralPath",
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage="Path to workspace item")]
        [ValidateNotNullOrEmpty()]
        [string[]]
        $LiteralPath,
       
        [Parameter()]
        [switch]
        $Recurse
    )

    Begin
    {
        Set-StrictMode -Version Latest
        $item = $null
    }

    Process
    {
        if ($psCmdlet.ParameterSetName -eq "Path")
        {
            # In the -Path (non-literal) case we may need to resolve a wildcarded path
            $resolvedPaths = @($Path | Resolve-Path | Convert-Path)
        }
        else
        {
            # Must be -LiteralPath
            $resolvedPaths = @($LiteralPath | Convert-Path)
        }
    
        foreach ($rpath in $resolvedPaths)
        {
            Write-Verbose "Processing $rpath"
           
            $tfargs = ”
            $tfargs += if ($Recurse) { ‘/r’ }
           
            # Look at each line of TF PERMISSION output and use a regex to determine
            # what the data for the line is.
            switch -regex (tf permission $rpath $tfargs)
            {
                ‘^Server item:\s+(\S+)\s+\(Inherit:\s+(\w+)\)’
                {
                    # If previous object exists, output it before creating a new one
                    if ($item) { $item }
                    $item = new-object psobject  -property @{
                        ServerItem = $matches[1]
                        Inherits   = $matches[2] -eq ‘yes’
                        Identities = @()
                    }
                    $item.psobject.TypeNames[0] = "TfsTools.VersionControl.ItemPermissions"  
                }
               
                ‘\bIdentity:\s+(.*)$’  
                {
                    $identityName = $matches[1]
                    $currentIdentity = new-object psobject -property @{
                        Identity = $identityName
                        Allow = ”
                        Deny = ”
                        InheritedAllow = ”
                        InheritedDeny = ”
                    }
                    $item.Identities += $currentIdentity
                }
               
                ‘\bAllow:\s*(.*)$’     
                {
                    $currentIdentity.Allow = $matches[1]
                }
               
                ‘\bDeny:\s*(.*)$’      
                {
                    $currentIdentity.Deny = $matches[1]
                }
               
                ‘\bAllow\s+\(Inherited\)\s*:\s*(.*)$’     
                {
                    $currentIdentity.InheritedAllow = $matches[1]
                }
               
                ‘\bDeny\s+\(Inherited\)\s*:\s*(.*)$’      
                {
                    $currentIdentity.InheritedDeny = $matches[1]
                }           
            }
        }
    }

    End
    {
        # Output the very last object
        if ($item) { $item }
    }
}

The output of this function isn’t great for viewing since it is primarily intended to enable querying of the permission info on each server item.  Note to the Team Foundation Power Tools devs, it sure would be nice to get this functionality into a future TFPT drop.

Advertisements
This entry was posted in PowerShell 2.0. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s