Public/Set-PSUADOVariableGroup.ps1
|
function Set-PSUADOVariableGroup { <# .SYNOPSIS Updates an existing Azure DevOps Variable Group. .DESCRIPTION Updates the properties of an existing variable group in an Azure DevOps project. Allows modification of the variable group name, description, and variables. Use this function to rename a variable group or update its description. .PARAMETER VariableGroupId (Mandatory) The ID of the variable group to update. .PARAMETER VariableGroupName (Optional) The new name for the variable group. .PARAMETER Description (Optional) The new description for the variable group. .PARAMETER Project (Mandatory) The Azure DevOps project name containing the variable group. .PARAMETER Organization (Optional) The Azure DevOps organization name under which the project resides. Default value is $env:ORGANIZATION. Set using: Set-PSUUserEnvironmentVariable -Name "ORGANIZATION" -Value "your_org_name" .PARAMETER PAT (Optional) Personal Access Token for Azure DevOps authentication with Variable Groups (read, create, & manage) permissions. Default value is $env:PAT. Set using: Set-PSUUserEnvironmentVariable -Name "PAT" -Value "your_pat_token" .EXAMPLE Set-PSUADOVariableGroup -Organization "omg" -Project "psutilities" -VariableGroupId 123 -VariableGroupName "UpdatedVarGroup" Renames the variable group with ID 123 to "UpdatedVarGroup". .EXAMPLE Set-PSUADOVariableGroup -Organization "omg" -Project "psutilities" -VariableGroupId 456 -Description "Updated production variables" Updates the description of variable group with ID 456. .EXAMPLE Set-PSUADOVariableGroup -Organization "omg" -Project "psutilities" -VariableGroupId 789 -VariableGroupName "ProdVars" -Description "Production environment variables" Updates both the name and description of the variable group. .OUTPUTS [PSCustomObject] .NOTES Author: Lakshmanachari Panuganti Date: 15th October 2025 .LINK https://github.com/lakshmanachari-panuganti/OMG.PSUtilities/tree/main/OMG.PSUtilities.AzureDevOps https://www.linkedin.com/in/lakshmanachari-panuganti/ https://www.powershellgallery.com/packages/OMG.PSUtilities.AzureDevOps https://learn.microsoft.com/en-us/rest/api/azure/devops/distributedtask/variablegroups #> [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateRange(1, [int]::MaxValue)] [int]$VariableGroupId, [Parameter()] [ValidateNotNullOrEmpty()] [string]$VariableGroupName, [Parameter()] [string]$Description, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Project, [Parameter()] [ValidateNotNullOrEmpty()] [string]$Organization = $env:ORGANIZATION, [Parameter()] [ValidateNotNullOrEmpty()] [string]$PAT = $env:PAT ) begin { # Display parameters Write-Verbose "[$($MyInvocation.MyCommand.Name)] Parameters:" foreach ($param in $PSBoundParameters.GetEnumerator()) { if ($param.Key -eq 'PAT') { $maskedPAT = if ($param.Value -and $param.Value.Length -ge 3) { $param.Value.Substring(0, 3) + "********" } else { "***" } Write-Verbose " $($param.Key): $maskedPAT" } else { Write-Verbose " $($param.Key): $($param.Value)" } } # Validate Organization (required because ValidateNotNullOrEmpty doesn't check default values from environment variables) if (-not $Organization) { throw "The default value for the 'ORGANIZATION' environment variable is not set.`nSet it using: Set-PSUUserEnvironmentVariable -Name 'ORGANIZATION' -Value '<org>' or provide via -Organization parameter." } # Validate PAT (required because ValidateNotNullOrEmpty doesn't check default values from environment variables) if (-not $PAT) { throw "The default value for the 'PAT' environment variable is not set.`nSet it using: Set-PSUUserEnvironmentVariable -Name 'PAT' -Value '<pat>' or provide via -PAT parameter." } $headers = Get-PSUAdoAuthHeader -PAT $PAT } process { try { # First, get the existing variable group to preserve existing data $escapedProject = if ($Project -match '%[0-9A-Fa-f]{2}') { $Project } else { [uri]::EscapeDataString($Project) } $getUri = "https://dev.azure.com/$Organization/$escapedProject/_apis/distributedtask/variablegroups/$($VariableGroupId)?api-version=7.1-preview.2" Write-Verbose "Retrieving existing variable group from: $getUri" $existingGroup = Invoke-RestMethod -Uri $getUri -Headers $headers -Method Get -ErrorAction Stop # Build the update body with existing data $updateBody = @{ id = $existingGroup.id type = $existingGroup.type name = if ($VariableGroupName) { $VariableGroupName } else { $existingGroup.name } description = if ($PSBoundParameters.ContainsKey('Description')) { $Description } else { $existingGroup.description } variables = $existingGroup.variables } # Include variableGroupProjectReferences (required for update) if ($existingGroup.variableGroupProjectReferences) { # Update the name and description in the project references $updatedRefs = @() foreach ($ref in $existingGroup.variableGroupProjectReferences) { $updatedRefs += @{ projectReference = $ref.projectReference name = if ($VariableGroupName) { $VariableGroupName } else { $ref.name } description = if ($PSBoundParameters.ContainsKey('Description')) { $Description } else { $ref.description } } } $updateBody.variableGroupProjectReferences = $updatedRefs } # Include providerData if it exists (for Azure Key Vault linked variable groups) if ($existingGroup.providerData) { $updateBody.providerData = $existingGroup.providerData } $bodyJson = $updateBody | ConvertTo-Json -Depth 10 Write-Verbose "Update payload:" Write-Verbose $bodyJson $updateUri = "https://dev.azure.com/$Organization/$escapedProject/_apis/distributedtask/variablegroups/$($VariableGroupId)?api-version=7.1-preview.2" Write-Verbose "Updating variable group at: $updateUri" $response = Invoke-RestMethod -Uri $updateUri -Headers $headers -Method Put -Body $bodyJson -ContentType "application/json" -ErrorAction Stop Write-Verbose "Successfully updated variable group ID: $($response.id)" Write-Verbose "Response name: $($response.name)" Write-Verbose "Response description: $($response.description)" [PSCustomObject]@{ Id = $response.id Name = $response.name Description = $response.description Type = $response.type Variables = $response.variables CreatedBy = $response.createdBy.displayName CreatedOn = $response.createdOn ModifiedBy = $response.modifiedBy.displayName ModifiedOn = $response.modifiedOn PSTypeName = 'PSU.ADO.VariableGroup' } } catch { $PSCmdlet.ThrowTerminatingError($_) } } } |