diff --git a/CHANGELOG.md b/CHANGELOG.md index 6733f2bf..d9d66dd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,11 @@ -0.5.6: +0.5.7: +--- +* Fixing issue with setting branch permissions (#136) +* Get/Set-ADOPermission: Support for ServiceEndpoints (#137) +* Set-ADOPermission: Exposing specialized parameter sets (#138) +* PSDevOps.WorkProcess objects now return .ProcessName and .ProcessID as alias properties + +0.5.6: --- ### Azure DevOps Improvements * Get-ADOPermission : Can now get permissions related to Dashboards, Analytics, AreaPaths, and IterationPaths diff --git a/Get-ADOPermission.ps1 b/Get-ADOPermission.ps1 index a2a6b06c..55816a56 100644 --- a/Get-ADOPermission.ps1 +++ b/Get-ADOPermission.ps1 @@ -48,9 +48,10 @@ $SecurityToken, # The Project ID. - # If this is provided without anything else, will get permissions for the projectID + # If this is provided without anything else, will get permissions for the projectID [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='Project')] [Parameter(ValueFromPipelineByPropertyName,ParameterSetName='Analytics')] + [Parameter(ValueFromPipelineByPropertyName,ParameterSetName='EndpointID')] [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='AreaPath')] [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='Dashboard')] [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='Tagging')] @@ -58,9 +59,9 @@ [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='BuildDefinition')] [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='BuildPermission')] [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='IterationPath')] - [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='RepositoryID')] + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='RepositoryID')] [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='ProjectRepository')] - [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='ProjectOverview')] + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='ProjectOverview')] [Alias('Project')] [string] $ProjectID, @@ -121,6 +122,18 @@ [switch] $Dashboard, + + # If set, will get all service endpoints permissions. + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='ServiceEndpoint')] + [Alias('ServiceEndpoints')] + [switch] + $ServiceEndpoint, + + # If set, will get endpoint permissions related to a particular endpoint. + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='EndpointID')] + [string] + $EndpointID, + # The Build Definition ID [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='BuildDefinition')] [string] @@ -137,12 +150,12 @@ $BuildPermission, # If provided, will get build and release permissions for a given project's repositoryID - [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='RepositoryID')] + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='RepositoryID')] [string] $RepositoryID, - # If provided, will get permissions for a given branch within a repository - [Parameter(ValueFromPipelineByPropertyName,ParameterSetName='RepositoryBranch')] + # If provided, will get permissions for a given branch within a repository + [Parameter(ValueFromPipelineByPropertyName,ParameterSetName='RepositoryID')] [Parameter(ValueFromPipelineByPropertyName,ParameterSetName='AllRepositories')] [string] $BranchName, @@ -216,10 +229,10 @@ if (-not $ProjectID) { return } } $psBoundParameters["ParameterSet"] ='accesscontrollists/{NamespaceId}' - switch -Regex ($psCmdlet.ParameterSetName) { + switch -Regex ($psCmdlet.ParameterSetName) { Project { $null = $PSBoundParameters.Remove('ProjectID') - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = '52d39943-cb85-4d7f-8fa8-c6baac873819' SecurityToken = "`$PROJECT:vstfs:///Classification/TeamProject/$ProjectID" } + $PSBoundParameters) @@ -232,7 +245,7 @@ } else { Get-ADOIterationPath -Organization $Organization -Project $ProjectID -IterationPath $iterationPath } - + if (-not $gotPath) { continue } @@ -247,15 +260,15 @@ ) [Array]::Reverse($PathIdList) - + $null = $PSBoundParameters.Remove('ProjectID') - - $q.Enqueue(@{ - NamespaceID = - if ($psCmdlet.ParameterSetName -eq 'AreaPath') { + + $q.Enqueue(@{ + NamespaceID = + if ($psCmdlet.ParameterSetName -eq 'AreaPath') { '83e28ad4-2d72-4ceb-97b0-c7726d5502c3' } else { - 'bf7bfa03-b2b7-47db-8113-fa2e002cc5b1' + 'bf7bfa03-b2b7-47db-8113-fa2e002cc5b1' } SecurityToken = @(foreach($PathId in $PathIdList) { "vstfs:///Classification/Node/$PathId" @@ -264,89 +277,105 @@ } Analytics { $null = $PSBoundParameters.Remove('ProjectID') - $q.Enqueue(@{ - NamespaceID = if ($ProjectID) { '58450c49-b02d-465a-ab12-59ae512d6531' } else { 'd34d3680-dfe5-4cc6-a949-7d9c68f73cba'} + $q.Enqueue(@{ + NamespaceID = if ($ProjectID) { '58450c49-b02d-465a-ab12-59ae512d6531' } else { 'd34d3680-dfe5-4cc6-a949-7d9c68f73cba'} SecurityToken = "`$/$(if ($ProjectID) { $ProjectID } else { 'Shared' })" } + $PSBoundParameters) } Dashboard { $null = $PSBoundParameters.Remove('ProjectID') - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = '8adf73b7-389a-4276-b638-fe1653f7efc7' SecurityToken = "$/$(if ($ProjectID) { $ProjectID })/$(if ($teamID) { $teamid } else { [guid]::Empty } )" } + $PSBoundParameters) } ProjectOverview { $null = $psboundParameters.Remove('Recurse') - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = '52d39943-cb85-4d7f-8fa8-c6baac873819' # Project permissions SecurityToken = "`$PROJECT:vstfs:///Classification/TeamProject/$ProjectID" } + $PSBoundParameters) - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = '2e9eb7ed-3c0a-47d4-87c1-0ffdd275fd87' # Repositories SecurityToken = "reposV2/$projectId" Recurse = $true } + $PSBoundParameters) - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = '33344d9c-fc72-4d6f-aba5-fa317101a7e9' # Build definitions SecurityToken = "$ProjectID/" Recurse = $true } + $PSBoundParameters) - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = 'c788c23e-1b46-4162-8f5e-d7585343b5de' # Releases SecurityToken = "$ProjectID/" Recurse = $true } + $PSBoundParameters) - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = '8adf73b7-389a-4276-b638-fe1653f7efc7' # Dashboards SecurityToken = "`$/$ProjectID/" Recurse = $true } + $PSBoundParameters) - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = '49b48001-ca20-4adc-8111-5b60c903a50c' # Service Endpoints SecurityToken = "endpoints/$ProjectID" Recurse = $true } + $PSBoundParameters) - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = 'cb594ebe-87dd-4fc9-ac2c-6a10a4c92046' # Service Hooks SecurityToken = "PublisherSecurity/$ProjectID" Recurse = $true } + $PSBoundParameters) } Plan { - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = 'bed337f8-e5f3-4fb9-80da-81e17d06e7a8' SecurityToken = "Plan" } + $PSBoundParameters) } + 'ServiceEndpoint|EndpointID' { + if ($psCmdlet.ParameterSetName -eq 'ServiceEndpoint') { + $PSBoundParameters['Recurse'] = $true + } + + if ($EndpointID) { + $q.Enqueue(@{ + NamespaceID = '49b48001-ca20-4adc-8111-5b60c903a50c' + SecurityToken = "endpoints/Collection/$(if ($EndpointID) {$EndpointID})" + } + $PSBoundParameters) + } + $q.Enqueue(@{ + NamespaceID = '49b48001-ca20-4adc-8111-5b60c903a50c' + SecurityToken = "endpoints/$(if ($ProjectID) {"$ProjectID/"})$(if ($EndpointID) {$EndpointID})" + } + $PSBoundParameters) + } Tagging { - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = 'bb50f182-8e5e-40b8-bc21-e8752a1e7ae2' SecurityToken = "/$ProjectID" } + $PSBoundParameters) } ManageTFVC { - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = 'a39371cf-0841-4c16-bbd3-276e341bc052' SecurityToken = "/$ProjectID" } + $PSBoundParameters) } 'BuildDefinition|BuildPermission' { - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = 'a39371cf-0841-4c16-bbd3-276e341bc052' SecurityToken = "$ProjectID$(($buildpath -replace '\\','/').TrimEnd('/'))/$DefinitionID" } + $PSBoundParameters) - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = 'c788c23e-1b46-4162-8f5e-d7585343b5de' SecurityToken = "$ProjectID$(($buildpath -replace '\\','/').TrimEnd('/'))/$DefinitionID" } + $PSBoundParameters) } 'RepositoryID|AllRepositories|ProjectRepository' { - $q.Enqueue(@{ + $q.Enqueue(@{ NamespaceID = '2e9eb7ed-3c0a-47d4-87c1-0ffdd275fd87' SecurityToken = "repo$( if ($psCmdlet.ParameterSetName -eq 'AllRepositories') {'s'})V2$( @@ -368,23 +397,6 @@ if ($BranchName) { end { $c, $t, $progId = 0, $q.Count, [Random]::new().Next() - if ($ExpandACL) { - - $resolveIdentity = { - param([Parameter(Mandatory,ValueFromPipelineByPropertyName)][string]$Descriptor) - begin { - if (-not $script:ResolvedIdentities) { $script:ResolvedIdentities= @{} } - } - process { - if (-not $script:ResolvedIdentities[$Descriptor]) { - $script:ResolvedIdentities[$Descriptor] = - Invoke-ADORestAPI "https://vssps.dev.azure.com/$Organization/_apis/identities?api-version=6.0&descriptors=$Descriptor&queryMembership=Direct" - } - return $script:ResolvedIdentities[$Descriptor] - } - } - } - if ($Overview -and $inputObject) { $projectRepositories = $inputObject | Get-ADORepository $projectServiceEndpoints = $inputObject | Get-ADOServiceEndpoint @@ -508,7 +520,7 @@ if ($BranchName) { switch ($namespace.Name) { Project { $inputObject } 'Git Repositories' { - foreach ($repo in $ProjectRepository) { + foreach ($repo in $projectRepositories) { if ($aclOut.Token -like "*/$($repo.id)*") { $repo;break } diff --git a/Get-ADOServiceEndpoint.ps1 b/Get-ADOServiceEndpoint.ps1 index c42ca6c4..56d01060 100644 --- a/Get-ADOServiceEndpoint.ps1 +++ b/Get-ADOServiceEndpoint.ps1 @@ -103,7 +103,8 @@ '.Type' } else { '' - } + } + Invoke-ADORestAPI @invokeParams -Uri $uri -PSTypeName @( # Prepare a list of typenames so we can customize formatting: "$Organization.$Project.ServiceEndpoint$subTypeName" # * $Organization.$Project.ServiceEndpoint "$Organization.ServiceEndpoint$subTypeName" # * $Organization.ServiceEndpoint diff --git a/PSDevOps.psd1 b/PSDevOps.psd1 index 9ca76be3..bc671d87 100644 --- a/PSDevOps.psd1 +++ b/PSDevOps.psd1 @@ -1,5 +1,5 @@ @{ - ModuleVersion = '0.5.6' + ModuleVersion = '0.5.7' RootModule = 'PSDevOps.psm1' Description = 'PowerShell Tools for DevOps' Guid = 'e6b56c5f-41ac-4ba4-8b88-2c063f683176' @@ -9,6 +9,13 @@ ProjectURI = 'https://github.com/StartAutomating/PSDevOps' LicenseURI = 'https://github.com/StartAutomating/PSDevOps/blob/master/LICENSE' ReleaseNotes = @' +0.5.7: +--- +* Fixing issue with setting branch permissions (#136) +* Get/Set-ADOPermission: Support for ServiceEndpoints (#137) +* Set-ADOPermission: Exposing specialized parameter sets (#138) +* PSDevOps.WorkProcess objects now return .ProcessName and .ProcessID as alias properties + 0.5.6: --- ### Azure DevOps Improvements diff --git a/PSDevOps.types.ps1xml b/PSDevOps.types.ps1xml index 55c20646..35dc249e 100644 --- a/PSDevOps.types.ps1xml +++ b/PSDevOps.types.ps1xml @@ -1691,4 +1691,30 @@ Invoke-ADORestAPI -Uri "$($this.Url)/comments" -QueryParameter @{"api-version"=" + + PSDevOps.WorkProcess + + + ProcessID + TypeID + + + ProcessName + Name + + + + + Deserialized.PSDevOps.WorkProcess + + + ProcessID + TypeID + + + ProcessName + Name + + + diff --git a/Set-ADOPermission.ps1 b/Set-ADOPermission.ps1 index af12ad13..68da958e 100644 --- a/Set-ADOPermission.ps1 +++ b/Set-ADOPermission.ps1 @@ -26,6 +26,7 @@ # If this is provided without anything else, will get permissions for the projectID [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='Project')] [Parameter(ValueFromPipelineByPropertyName,ParameterSetName='Analytics')] + [Parameter(ValueFromPipelineByPropertyName,ParameterSetName='EndpointID')] [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='AreaPath')] [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='Dashboard')] [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='IterationPath')] @@ -97,11 +98,28 @@ [switch] $Tagging, + # If set, will set permissions for Team Foundation Version Control related to the current project. [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='ManageTFVC')] [switch] $ManageTFVC, + # If set, will set permissions for Delivery Plans. + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='Plan')] + [switch] + $Plan, + + # If set, will set dashboard permissions related to the current project. + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='Dashboard')] + [Alias('Dashboards')] + [switch] + $Dashboard, + + # If set, will set endpoint permissions related to a particular endpoint. + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='EndpointID')] + [string] + $EndpointID, + # If set, will list the type of permisssions. [Parameter(ParameterSetName='securitynamespaces')] [Alias('SecurityNamespace', 'ListPermissionType','ListSecurityNamespace')] @@ -271,6 +289,16 @@ SecurityToken = "Plan" } + $PSBoundParameters) } + EndpointID { + $q.Enqueue(@{ + NamespaceID = '49b48001-ca20-4adc-8111-5b60c903a50c' + SecurityToken = "endpoints/$( + if ($ProjectID) {"$ProjectID/"} else { "Collection/"} + )$( + if ($EndpointID) {$EndpointID} + )" + } + $PSBoundParameters) + } Tagging { $q.Enqueue(@{ NamespaceID = 'bb50f182-8e5e-40b8-bc21-e8752a1e7ae2' @@ -403,7 +431,6 @@ $($cachedNamespaces.$namespaceID.actions | Format-Table -Property Name, DisplayN $c++ Write-Progress "Setting Permissions for $Identity" " (Allowing: $friendlyAllow Denying: $friendlyDeny) on $SecurityToken " -Id $progId -PercentComplete ($c * 100/$t) - if (-not $Descriptors) { Write-Error "No -Descriptor or -Identity provided" return diff --git a/Types/PSDevOps.WorkProcess/Alias.psd1 b/Types/PSDevOps.WorkProcess/Alias.psd1 new file mode 100644 index 00000000..1f5789b5 --- /dev/null +++ b/Types/PSDevOps.WorkProcess/Alias.psd1 @@ -0,0 +1,4 @@ +@{ + ProcessName = 'Name' + ProcessID = 'TypeID' +}