framework/Resources/Scripts/remove_client_cache.ps1

Param(
    [Parameter(Mandatory)]
    [string]$EnvironmentName,
    [Parameter(Mandatory)]
    [string]$CacheName,
    [Parameter(Mandatory)]
    [string]$ClientCacheName,
    [int]$Port,
    [pscredential]$Credentials,

    [string]$ScriptsFolderPath = ".\Resources\Scripts"
)

. "$ScriptsFolderPath\dashboard_common.ps1"

function GetUploadedVmNames {
    param(
        [Parameter(Mandatory)][string]$ResourceGroup
    )
    return Get-AzVM -ResourceGroupName $ResourceGroup -ErrorAction Stop | Where-Object { $_.Tags.ContainsKey("InstallMode") -and $_.Tags["InstallMode"] -eq "server" } | Select-Object -ExpandProperty Name 
}

function GetClientVMs {
    param(
        [Parameter(Mandatory)][string]$ResourceGroup
    )
    return Get-AzVM -ResourceGroupName $ResourceGroup -ErrorAction Stop |
    Where-Object { $_.Tags.ContainsKey("InstallMode") -and $_.Tags["InstallMode"] -eq "client" }
}

function InvokeCommandOnServerWindows {
    param(
        [string]$ResourceGroupName,
        [string[]]$VmNames
    )

    $script = "Remove-ClientCache -CacheName $CacheName -ClientCacheName $ClientCacheName"
    if ($Port) {
        $script += " -Port $Port"
    }
    if ($Credentials) {
        $script += " -Credentials `"$($Credentials.GetNetworkCredential().UserName):$($Credentials.GetNetworkCredential().Password)`""
    }
    $jobs = @()
    foreach ($vm in $VmNames) {
        $jobs += Start-Job -ScriptBlock {
            param($ResourceGroupName, $vm, $script)
            $result = Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $vm -CommandId 'RunPowerShellScript' -ScriptString $script

            foreach ($val in $result.Value) {
                Write-Host $val.Message
            }
        } -ArgumentList $ResourceGroupName, $vm, $script

        # if server param is provided, exute on only one server
        if (![string]::IsNullOrWhiteSpace($Server)) {
            break
        }
    }

    $jobs | Wait-Job | Out-Null
    $jobs | Receive-Job
}

function InvokeCommandOnServerLinux {
    param(
        [string]$ResourceGroupName,
        [string[]]$VmNames
    )

    $script = "/opt/ncache/bin/tools/remove-clientcache -cachename $CacheName -clientcachename $ClientCacheName"
    if ($Port) {
        $script += " -port $Port"
    }
    if ($Credentials) {
        $script += " -credentials `"$($Credentials.GetNetworkCredential().UserName):$($Credentials.GetNetworkCredential().Password)`""
    }
    $jobs = @()
    foreach ($vm in $VmNames) {
        $jobs += Start-Job -ScriptBlock {
            param($ResourceGroupName, $vm, $script)
            $result = Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $vm -CommandId 'RunShellScript' -ScriptString $script

            foreach ($val in $result.Value) {
                Write-Host $val.Message
            }
        } -ArgumentList $ResourceGroupName, $vm, $script

        # if server param is provided, exute on only one server
        if (![string]::IsNullOrWhiteSpace($Server)) {
            break
        }
    }

    $jobs | Wait-Job | Out-Null
    $jobs | Receive-Job
}

function InvokeCommandOnVms {
    param(
        [object]$Resource,
        [string]$ResourceGroupName,
        [string[]]$VmNames
    )

    $os = $Resource.Tags['OsType']
    if ($os -eq "Windows") {
        InvokeCommandOnServerWindows -ResourceGroupName $ResourceGroupName -VmNames $VmNames
    }
    else {
        InvokeCommandOnServerLinux -ResourceGroupName $ResourceGroupName -VmNames $VmNames
    }
}

function Remove-CacheTagAndDashboards {
    param(
        [object]$Resource
    )

    $clientVMs = GetClientVMs -ResourceGroup $Resource.ResourceGroupName
    foreach ($vm in $clientVMs) {
        try {
            # Convert tags dictionary to hashtable
            $tags = @{}
            if ($vm.Tags) {
                foreach ($k in $vm.Tags.Keys) {
                    $tags[$k] = $vm.Tags[$k]
                }
            }

            if ($tags.ContainsKey("Caches")) {
                # Split the caches by comma, trim spaces
                $cacheList = $tags["Caches"] -split "," | ForEach-Object { $_.Trim() }

                # Remove the target cache
                $updatedList = $cacheList | Where-Object { $_ -ne $CacheName }

                if ($updatedList.Count -gt 0) {
                    $tags["Caches"] = $updatedList -join ","
                }
                else {
                    # If no caches left, drop the key
                    $tags.Remove("Caches")
                }

                # Apply updated tags
                Set-AzResource -ResourceId $vm.Id -Tag $tags -Force -ErrorAction Stop | Out-Null
            }
        }
        catch {
            Write-Output "Failed to update tags on $($vm.Name): $_"
        }
    }

    Update-NcAzDashboards -ScriptsFolderPath $ScriptsFolderPath -ResourceGroupName $Resource.ResourceGroupName -CacheName $CacheName -SkipServer
}

function ExecuteCommands {
    $resource = Get-AzResourceGroup -ErrorAction Stop | Where-Object { $_.Tags -and $_.Tags.Contains("EnvironmentName") -and $_.Tags["EnvironmentName"] -eq $EnvironmentName } 
    if (-not $resource) {
        throw "No such environment exists"
    }

    $resourceGroupName = $resource.ResourceGroupName
    $vmNames = GetUploadedVmNames -ResourceGroup $resourceGroupName

    InvokeCommandOnVms -Resource $resource -ResourceGroupName $resourceGroupName -VmNames $vmNames

    Remove-CacheTagAndDashboards -Resource $resource
}

try {
    if (-not (Get-AzContext)) {
        Connect-AzAccount
        if (Get-AzContext) {
            ExecuteCommands
        }
    }
    else {
        ExecuteCommands
    }
}
catch {
    Write-Error $($_.Exception.Message)
}