OctopusTenants.psm1

Import-Module PowershellOctopusClientPS
(Get-Module -ListAvailable PowershellOctopusClientPS).ModuleBase

Import-Module OctopusMachines

try
{
    $octoclientpath = Join-Path -Path (Get-Module -ListAvailable PowershellOctopusClientPS).ModuleBase -ChildPath "lib\Octopus.Client.dll"
    $newtonsoftPath = Join-Path -Path (Get-Module -ListAvailable PowershellOctopusClientPS).ModuleBase -ChildPath "lib\Newtonsoft.Json.dll"
    Add-Type -Path $newtonsoftPath
    Add-Type -Path $octoclientpath
}
catch [System.Reflection.ReflectionTypeLoadException]
{    #system.attonations always throws
    #Write-Host "Message: $($_.Exception.Message)"
    #Write-Host "StackTrace: $($_.Exception.StackTrace)"
    #Write-Host "LoaderExceptions: $($_.Exception.LoaderExceptions)"
}
<#
    .SYNOPSIS
    return a setup client
#>

function LoadOctopusClientAndDependancies {
[OutputType([Octopus.Client.OctopusClient])]
    Param(
        [parameter(Mandatory=$true)][String] $url,
        [parameter(Mandatory=$true)][String] $apiKey
    )
    
    $client = [Octopus.Client.OctopusClient]::new([Octopus.Client.OctopusServerEndpoint]::new($url, $apiKey))
    $client
}

function RemoveTenantFromEnvironment {
    Param(
        [parameter(Mandatory=$true)] [String]$octopusURL,
        [parameter(Mandatory=$true)] [String]$octopusAPIKey,
        #Name of the enviroment to destroy.
        [parameter(Mandatory=$true)] [String]$enviromentName,
        #Octopus space to destroy enviroment in, if empty/null will add to all spaces.
        [parameter(Mandatory=$true)][String]$inSpace = '',
        [parameter(Mandatory=$false)][String]$tenantName = '',
        [parameter(Mandatory=$false)][String]$orgCode = ''
    )

    if([string]::IsNullOrEmpty($orgCode) -and [string]::IsNullOrEmpty($tenantName)) {
        throw "Either the orgCode or tenantName parameter is required."
    }

    $client = LoadOctopusClientAndDependancies -url $octopusURL -apiKey $octopusAPIKey   
    $repository = $client.ForSystem()
    $spaces = $repository.Spaces.FindByName($inSpace)       
    $spaces | foreach { 
        try {      
            $currSpace = $repository.Spaces.FindByName($_.Name)
            $repositoryForSpace = $client.ForSpace($currSpace)
            $theEnviromentResource = $repositoryForSpace.Environments.FindByName($enviromentName)
            $projects = $repositoryForSpace.Projects.GetAll()     
            
            if(-not [string]::IsNullOrEmpty($tenantName))
            {
                $tenants = $repositoryForSpace.Tenants.FindByName($tenantName)                                       
            } elseif(-not [string]::IsNullOrEmpty($orgCode)) {
                $tenants = $repositoryForSpace.Tenants.FindAll("$orgCode-",$null,1000)    
            }

            $tenants | foreach {
                $currTenant = $_  

                #remove machines if client space
                if($currSpace.Id -eq 'Spaces-3') {
                    RemoveAllTenantMachines -octopusURL $octopusURL -octopusAPIKey $octopusAPIKey -tenantName $currTenant.Name -Enviroment $theEnviromentResource.Name -Space $currSpace.Name
                }
                #remove project environment connections
                $projects | foreach {
                    $currProject = $_ 
                    if($currTenant.ProjectEnvironments.ContainsKey($currProject.Id) -and ($currTenant.ProjectEnvironments[$currProject.Id] -eq $theEnviromentResource.Id)) {                        
                        $currTenant.ProjectEnvironments[$currProject.Id].Remove($theEnviromentResource.Id) 
                        if($currTenant.ProjectEnvironments[$currProject.Id].Count -eq 0) {
                            $currTenant.ProjectEnvironments.Remove($currProject.Id)
                        }                   
                    }                    
                }
                if($currTenant.ProjectEnvironments.Count -eq 0) {
                    Write-Output "Deleting Tenant $($currTenant.Name)"
                    $repositoryForSpace.Tenants.Delete($currTenant)
                }else {
                    Write-Output "Saving Tenant $($currTenant.Name)"
                    $repositoryForSpace.Tenants.Modify($currTenant)
                }
            }
        }catch {
            Write-Error "RemoveTenantFromEnvironment -> $($_)"
        }
    }
}