Updating names of AD groups

Hi,
I am scripting with powershell to update AD group names in each space.
I will have to get every space and them all the AD groups per space.
I will be updating the names of members in teams or can I directly update the AD teams names?
Or is there an external groups API call?

Kind Regards,
Micheal Power

Hi Micheal,

Thank you for reaching out to us with your query.

One of the best ways to automate this sort of task is to take the same actions in our web interface and to use the browser tools to watch the API calls that are being made. The web interface is built using exactly the same API so this can help to find the right endpoints and so on.

I’m not completely clear on what you’re trying to achieve, but if you’d like to provide screenshots showing the changes you’d make if doing this manually I’d be happy to look into what options are available and advise on the best approach to take.

In the meantime, you might find our API documentation to be helpful and there are also many examples available in our GitHub repository which could be a useful starting point.

I hope this is helpful. Please let me know if you have any questions.

Best Regards,

Charles

Hi @charles.hague,
So what I am trying to do is get all the External Security Groups. I am doing this by using the Octopus.Client.

#Get all the teams
$teams = $repository.Teams.GetAll()
Write-Output $team.ExternalSecurityGroups
This lists all the External Security Groups, I then need to rename each of the External Security group names.

Rename !BE01_EnvironmentReleaseDeployment to ES-AREA1!BE01_EnvironmentReleaseDeployment

Kind Regards,
Micheal Power

Hi Micheal,

Thank you for the clarification.

It is my understanding that Octopus stores the unique identifier for external security groups rather than the name and so renaming the group from within Octopus is likely to be unnecessary.

If the external security groups that exist in Active Directory are the same ones that were there before but have just been renamed it may be sufficient to just run the “Synchronize External Security Groups” task again for the new names to be picked up. If however they are entirely new groups intended to replace old groups then it’s likely that the most viable route would be to remove the old groups and add new ones.

Can you please advise which of these scenarios matches your situation?

Best Regards,

Charles

Hi @charles.hague,
It will be easier to update this on the database level.
Thanks for your help.

Kind Regards,
Micheal Power

Hi Mike,

Generally, I discourage editing the database directly. The Support Team would prefer the opportunity to discover exactly what you are trying to achieve and then seeing if it hasn’t been solved already for another customer or perhaps there is already a solution built into Octopus Deploy.

Often, database entries are referenced in numerous places within the Octopus database, so a single change that may seem innocuous, can ultimately end up causing other unintended issues.

As far as updating AD details, we do have some scripts floating around that use our API and Octopus Client. If these don’t meet your needs or cannot be altered to meet your needs, then we also have a development team that may be able to help you achieve your desired outcome.

If you still decide to go down the route of altering the SQL database, please make sure you have a backup of your database as well as your Master Key securely backed up. I would also recommend testing out the changes on a replica environment.

We have details regarding setting up a Test Instance over here: Creating a test instance - Octopus Deploy

Please, let me know what you choose to do and if we can help at all.

Regards,

Hi @dane.falvo,
Yes after some testing updating the database will not be an option.
So we are migrating Octopus to Azure and we have seen a little issue with AD Groups.

When an individual logs in to Ocotpus89 (Octopus instance in Azure) using the Okta button, the list of AD groups to which they belong is returned to Octopus. To be considered a member of an Octopus team, the name of the AD Group linked to a team must match one returned during login. These groups will be returned in the form ES-AREA1<group name>. In this case, the team has only been set up with the Active Directory group name which doesn’t require the domain to be included. When a search is executed against the groups returned during login, no match is found (due to missing ES-AREA1).

So, to resolve the problem we must add an External Group as follows:

If your Octopus team contains an AD Group, you will need to add this as an External Group by selecting the ADD EXTERNAL GROUP/ROLE button on the Configuration/Teams page for your team.

Specify the full name of the group in the form ES-AREA1\My_AD_Group.

Is there a way to script this function?

Kind Regards,
Micheal Power

Hi Micheal,

Thank you for getting back to us.

It’s certainly possible to script the process of adding an external security group, but it may not be the best approach to take depending on what you’re trying to achieve. I’ve reached out to our customer solutions team to check if they’ve seen this before as they may be able to advise on a better alternative.

I’ll let you know as soon as I have an update.

Best Regards,

Charles

Hi Michael,

It sounds to me like you’re looking for a way to script the rename of the External Security Group/Role ID? In our testing, we weren’t seeing the domain being included during the login process, but I realize our setup most likely doesn’t match yours. You can verify what groups are coming across by decoding the JWT token sent back during login and looking at the groups field. The External Group/Role Id field in Octopus should match this group.

You can use a script similar to this to update an existing Group/Role Id.

function Get-OctopusItems
{
	# Define parameters
    param(
    	$OctopusUri,
        $ApiKey,
        $SkipCount = 0
    )
    
    # Define working variables
    $items = @()
    $skipQueryString = ""
    $headers = @{"X-Octopus-ApiKey"="$ApiKey"}

    # Check to see if there there is already a querystring
    if ($octopusUri.Contains("?"))
    {
        $skipQueryString = "&skip="
    }
    else
    {
        $skipQueryString = "?skip="
    }

    $skipQueryString += $SkipCount
    
    # Get intial set
    $resultSet = Invoke-RestMethod -Uri "$($OctopusUri)$skipQueryString" -Method GET -Headers $headers

    # Check to see if it returned an item collection
    if ($resultSet.Items)
    {
        # Store call results
        $items += $resultSet.Items
    
        # Check to see if resultset is bigger than page amount
        if (($resultSet.Items.Count -gt 0) -and ($resultSet.Items.Count -eq $resultSet.ItemsPerPage))
        {
            # Increment skip count
            $SkipCount += $resultSet.ItemsPerPage

            # Recurse
            $items += Get-OctopusItems -OctopusUri $OctopusUri -ApiKey $ApiKey -SkipCount $SkipCount
        }
    }
    else
    {
        return $resultSet
    }
    

    # Return results
    return $items
}


# Set these variables for your environment
$octopusURL = "https://your.octopus.app"
$octopusAPIKey = "API-"
$header = @{ "X-Octopus-ApiKey" = $octopusAPIKey }
$spaceName = "Default"
$teamName = "MyTeam"
$newExternalGroupId = "ES-AREA1\My_AD_Group"

# Get the space
$space = (Get-OctopusItems -OctopusUri "$octopusURL/api/spaces" -ApiKey $octopusAPIKey | Where-Object {$_.Name -eq $spaceName})

# Get the team by name in the space
$team = (Get-OctopusItems -OctopusUri "$octopusURL/api/$($space.Id)/teams" -ApiKey $octopusAPIKey | Where-Object {$_.Name -eq $teamName})

# Update the external security group/role id
$team.ExternalSecurityGroups[0].Id = $newExternalGroupId

# Save
Invoke-RestMethod -Method Put -Uri "$octopusURL/api/$($space.Id)/teams/$($team.Id)" -Body ($team | ConvertTo-Json -Depth 10) -Headers $header

I hope this helps!
Mark

Hi @mark.reeder,
Thanks for the feedback, much appreciated.

Please find my attempt below:

I am getting all spaces and searching through each space. I am then getting a list of teams per space. If the ExternalSecurityGroup in that space is not null then update the ExternalSecurityGroup with ES-AREA1\ at the start of the ExternalSecurityGroup name. We dont know how many ExternalSecurityGroups there are so we have to search each space and then rename them. For example when I search through the first space there are 3 ExternalSecurityGroups and I will need to update all 3 and then move on to the next space. Can this be done?

$spaceList = Invoke-RestMethod "$OctopusUrl/api/Spaces?skip=0&take=100000" -Headers $header
    foreach ($space in $spaceList.Items){
    $spaceId = $space.Id
    
   $team = Invoke-RestMethod "$OctopusUrl/api/$($space.Id)/teams" -Headers $header
        if($team.Items.ExternalSecurityGroups -ne $null){
        # Update the external security group/role name
        $ExternalGroupName = $team.Items.ExternalSecurityGroups.DisplayName
        $newExternalGroupName = "ES-AREA1\ + $ExternalGroupName"
        $ExternalGroupName = $newExternalGroupName

 # Save
Invoke-RestMethod -Method Put -Uri "$octopusURL/api/$($space.Id)/teams/$($team.Id)" -Body 
($team | ConvertTo-Json -Depth 10) -Headers $header

Kind Regards,
Micheal Power

Hi Michael,
Give this script a try. I changed a few things around. This is going straight to get all teams which will ensure it grabs system teams as well. So it’s not looping through spaces, though you generally want to define your spaces in API calls, it doesn’t match your requirements in this case.

There is also an externalGroupSkipList which you can set if you want to leave any External Groups alone and not have them renamed. Otherwise, you can ignore this.

I will also give the warning that you will want to take database backups before running this just in case and to make your life easier. You can also comment out the Save section if you want to see what would happen without actually doing anything damaging.

$ErrorActionPreference = "Stop"
Write-Host ""

# Set these variables for your environment
$octopusURL = "https://your.octopus.app"
$octopusAPIKey = "API-KEY"
$header = @{ "X-Octopus-ApiKey" = $octopusAPIKey }
$newExternalGroupIdPrefix = "ES-AREA1\"
# List of External Security Group ID's you don't want renamed ie. $externalGroupSkipList = @("ignoreme", "leavemealone")
$externalGroupSkipList = @()


$hasUpdates = $false
# Get all teams
$teams = Invoke-RestMethod "$octopusURL/api/teams/all" -Headers $header
foreach ($team in $teams) {
    if ($team.SpaceId) {
        $spaceName = (Invoke-RestMethod "$octopusURL/api/spaces/$($team.SpaceId)" -Headers $header).Name
        Write-Host "Space: $($spaceName), Team: $($team.Name) - ($($octopusURL)/api/teams/$($team.Id))"
    } else {
        Write-Host "System Team: $($team.Name) - ($($octopusURL)/api/teams/$($team.Id))"
    }

    foreach ($externalSecurityGroup in $team.ExternalSecurityGroups) {
        # if our external group hasn't already been renamed and is not in our list to ignore, rename it
        if ($externalSecurityGroup.Id -notlike "ES-AREA1\*" -and $externalSecurityGroup.Id -notin $externalGroupSkipList) {
            $newExternalGroupId = $newExternalGroupIdPrefix + $externalSecurityGroup.Id
            Write-Host "    - Renaming External Security Group '$($externalSecurityGroup.Id)' to '$($newExternalGroupId)'"
            $externalSecurityGroup.Id = $newExternalGroupId
            $hasUpdates = $true
        }
    }

    # Save
    if ($hasUpdates) {
        $result = Invoke-RestMethod -Method Put -Uri "$octopusURL/api/teams/$($team.Id)" -Body ($team | ConvertTo-Json -Depth 10) -Headers $header
        $hasUpdates = $false
    }
}

Let me know how things go.

Thanks,
Mark

Hi @mark.reeder,
Thanks for your reply. Script works great, thank you.

Kind Regards,
Micheal Power

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.