Private/Configure-Azure.ps1


#
# Configure-Azure.ps1
#

function Set-AzureKeyVault() {
    [array]$options = "[Go Back]", "Connect to Existing KeyVault", "Create New KeyVault"
    do {
        $sel = Invoke-Menu -MenuTitle "---- Configure Azure KeyVault ------" -MenuOptions $options  
        $akvSelection = $sel         
    } until ($akvSelection -ge 0)
    switch ($akvSelection) {
        '0' { Show-ConfigMenu }
        '1' {
            Write-Host "Connecting to Existing KeyVault"
            #if (!$global:devops_selectedSubscription) {
            Get-AzureAccounts("Azure KeyVault")
            #}

            az account set --subscription $global:devops_selectedSubscription
            [array]$kvList = az keyvault list --subscription $global:devops_selectedSubscription --query [].name --output json | ConvertFrom-Json | Sort-Object
            if (!$kvList) {
                Write-Host "No KeyVaults exist for the Current Subscription, please create one"
                pause
            }
            else {
                do {
                    $sel = Invoke-Menu -MenuTitle "---- Select Azure KeyVault ------" -MenuOptions $kvlist  
                    $akvToUse = $sel         
                } until ($akvToUse -ge 0)
                $global:devops_AzureKeyVault = $kvList[$sel]
                $clientKeySS = ($global:devops_configFile.Projects[$global:devops_projectConfigID].ClientSecret) | ConvertTo-SecureString -ErrorAction SilentlyContinue
                $global:clientSecret = (New-Object PSCredential "user", $clientKeySS).GetNetworkCredential().Password
                if ($global:clientSecret) {
                    Add-ClientSecrettoKeyVault
                }
                $global:devops_projectFile.selectedSubscription = $global:devops_selectedSubscription
                $global:devops_projectFile.selectedSubscriptionName = $global:devops_selectedSubscriptionName
                $global:devops_projectFile.AzureKeyVaultName = $global:devops_AzureKeyVault
                $global:devops_projectFile | ConvertTo-Json | Set-Content ("$global:devops_projectLocation\$global:devops_gitRepo.json")                      
            }            
            Show-ConfigMenu
        }
        '2' {
            Write-Host "Create New KeyVault"
            # if (!$global:devops_selectedSubscription) {
            Get-AzureAccounts("Azure KeyVault")
            # }
            Write-Host ""
            $subconfirm = Read-Host "A New Azure KeyVault will be created in the $global:devops_selectedSubscriptionName [Press Enter to Continue or [Q] to quit]"
            if ($subconfirm -eq 'Q') {
                Show-ConfigMenu
            }
            try {
                az account set --subscription $global:devops_selectedSubscription
                [array]$locationlist = az account list-locations --query [].name --output table | Sort-Object 
                do {
                    $sel = Invoke-Menu -MenuTitle "---- Select location for the KeyVault ------" -MenuOptions $locationlist  
                    $locToUse = $sel         
                } until ($locToUse -ge 0)
                $location = $locationlist[$sel]
                $resourcegroup = Read-Host "Enter the Resource Group to add the KeyVault to"
                $kvName = Read-Host "Enter the name for the KeyVault"
                $rgExists = az group list --query "[?name=='$resourcegroup']" | ConvertFrom-Json
                if (!$rgExists) {
                    Write-Host "Resource group does not Exist... Creating"
                    $rg = az group create --location $location --name $resourcegroup
                    if (!$rg) {
                        Write-Host "Failed to create Resource Group, please try again" -ForegroundColor Red
                        pause
                        return
                    }
                }
                $createdKV = az keyvault create --location $location --resource-group $resourcegroup --name $kvName
                if (!$createdKV) {
                    Write-Host "Failed to create KayVault, please try again" -ForegroundColor Red
                    pause
                    return
                }
                $global:devops_AzureKeyVault = $kvName
                $clientKeySS = ($global:devops_configFile.Projects[$global:devops_projectConfigID].ClientSecret) | ConvertTo-SecureString
                $global:clientSecret = (New-Object PSCredential "user", $clientKeySS).GetNetworkCredential().Password
                if ($global:clientSecret) {
                    Add-ClientSecrettoKeyVault
                }
                $global:devops_projectFile.selectedSubscription = $global:devops_selectedSubscription
                $global:devops_projectFile.selectedSubscriptionName = $global:devops_selectedSubscriptionName
                $global:devops_projectFile.AzureKeyVaultName = $global:devops_AzureKeyVault
                $global:devops_projectFile | ConvertTo-Json | Set-Content ("$global:devops_projectLocation\$global:devops_gitRepo.json")  
        
            }
            catch {
                Write-Host $_
                pause
            }            
            Show-ConfigMenu
        }
        Default {}
    }
}

function Set-ServicePrincipal() {
    [array]$options = "[Go Back]", "Select Existing Service Principal", "Create New Service Principal", "Manual Setup of Service Principal"
    do {
        $sel = Invoke-Menu -MenuTitle "---- Configure Service Principal ------" -MenuOptions $options  
        $spSelection = $sel         
    } until ($spSelection -ge 0)
    switch ($spSelection) {
        '0' { Show-ConfigMenu }
        '1' {
            Write-Host "Select Existing Service Principal"
            # if (!$global:devops_selectedSubscription) {
            Get-AzureAccounts("Service Principal")
            # }
            Write-Host "Retrieving available Service Principals.... please wait"
            az account set --subscription $global:devops_selectedSubscription
            [array]$spList = az ad sp list --all --query "[?signInAudience=='AzureADMyOrg'].{Name:displayName, ID:appId, Tenant:appOwnerTenantId} " --output json | ConvertFrom-Json | Sort-Object
            if (!$spList) {
                Write-Host "No Service Principals exist for the Current Subscription, please create one"
                pause
            }
            else {
                [array]$spmenu = $spList | ForEach-Object { $_.Name }
                do {
                    $sel = Invoke-Menu -MenuTitle "---- Select Service Principal ------" -MenuOptions $spmenu  
                    $spToUse = $sel         
                } until ($spToUse -ge 0)
                $global:devops_ClientID = $spList[$sel].ID
                $global:devops_TenantID = $spList[$sel].Tenant
                $global:devops_projectFile.ClientID = $global:devops_ClientID
                $global:devops_projectFile.TenantID = $global:devops_TenantID
                $CSecret = Read-Host "Enter the Client Secret for $global:devops_ClientID (or leave blank to create a new one)"
                if (!$CSecret) {
                    Write-Host "No Secret provided .... creating new one"
                    $newCreds = az ad sp credential reset --name $global:devops_ClientID --append --credential-description "Devops" | ConvertFrom-Json
                    $SS = ConvertTo-SecureString -AsPlainText -String $newCreds.password -Force | ConvertFrom-SecureString
                    $updatedProject = [ordered]@{ID = $global:devops_configFile.Projects[$global:devops_projectConfigID].ID; Name = $global:devops_configFile.Projects[$global:devops_projectConfigID].Name; ProjectLocation = $global:devops_projectLocation; ClientSecret = $SS; Tenant = $newCred.tenant }
                    $global:devops_configFile.Projects[$global:devops_projectConfigID] = $updatedProject
                    $global:clientSecret = $newCreds.password
                    if ($global:devops_AzureKeyVault) {                        
                        Add-ClientSecrettoKeyVault
                    }
                    $global:devops_configFile | ConvertTo-Json | Set-Content ("$env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json")        
                }
                else {
                    $SS = ConvertTo-SecureString -AsPlainText -String $CSecret -Force | ConvertFrom-SecureString
                    $updatedProject = [ordered]@{ID = $global:devops_configFile.Projects[$global:devops_projectConfigID].ID; Name = $global:devops_configFile.Projects[$global:devops_projectConfigID].Name; ProjectLocation = $global:devops_projectLocation; ClientSecret = $SS }
                    $global:devops_configFile.Projects[$global:devops_projectConfigID] = $updatedProject
                    $global:clientSecret = $CSecret
                    if ($global:devops_AzureKeyVault) {                        
                        Add-ClientSecrettoKeyVault
                    }
                    $global:devops_configFile | ConvertTo-Json | Set-Content ("$env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json")        
 
                }
                $global:devops_projectFile | ConvertTo-Json | Set-Content ("$global:devops_projectLocation\$global:devops_gitRepo.json")                      
            }            
            Show-ConfigMenu
        }
        '2' {
            Write-Host "Create New Service Principal"
            # if (!$global:devops_selectedSubscription) {
            Get-AzureAccounts("Service Principal")
            # }
            Write-Host ""
            $spconfirm = Read-Host "Enter the Display Name for the New Service Principal [or [Q] to quit]"
            if ($spconfirm.ToUpper() -eq 'Q') {
                Show-ConfigMenu
            }
            try {
                $spdetails = az ad sp create-for-rbac --name $spconfirm | ConvertFrom-Json
                $global:devops_ClientID = $spdetails.appId
                $global:devops_TenantID = $spdetails.tenant
                $global:devops_projectFile.ClientID = $global:devops_ClientID
                $global:devops_projectFile.TenantID = $global:devops_TenantID
                $CSecret = $spdetails.password

                $SS = ConvertTo-SecureString -AsPlainText -String $CSecret -Force | ConvertFrom-SecureString
                $updatedProject = [ordered]@{ID = $global:devops_configFile.Projects[$global:devops_projectConfigID].ID; Name = $global:devops_configFile.Projects[$global:devops_projectConfigID].Name; ProjectLocation = $global:devops_projectLocation; ClientSecret = $SS }
                $global:devops_configFile.Projects[$global:devops_projectConfigID] = $updatedProject
                if ($global:devops_AzureKeyVault) {
                    $global:clientSecret = $CSecret
                    Add-ClientSecrettoKeyVault
                }
                $global:devops_configFile | ConvertTo-Json | Set-Content ("$env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json")       
                $global:devops_projectFile | ConvertTo-Json | Set-Content ("$global:devops_projectLocation\$global:devops_gitRepo.json")                      
           
            }
            catch {
                Write-Host $_
                pause
            }
            pause
            Show-ConfigMenu
        }
        '3' {
            Write-Host "Manual Setup of Service Principal"
            Write-Host ""
           
            $action = Read-Host "[C] Continue to setup Service Principal [or [Q] to quit]"

            if ($action.ToUpper() -eq 'Q') {
                Show-ConfigMenu
            }
            else {
                $appId = Read-Host "Enter the Client ID of the existing Service Principal"
                $tenant = Read-Host "Enter the Tenant ID"
                $secret = Read-Host "Enter the Secret value the existing Service Principal"
                
                $global:devops_ClientID = $appId
                $global:devops_TenantID = $tenant
                $CSecret = $secret

                $SS = ConvertTo-SecureString -AsPlainText -String $CSecret -Force | ConvertFrom-SecureString

                $global:devops_projectFile.ClientID = $global:devops_ClientID
                $global:devops_projectFile.TenantID = $global:devops_TenantID

                $updatedProject = [ordered]@{ID = $global:devops_configFile.Projects[$global:devops_projectConfigID].ID; Name = $global:devops_configFile.Projects[$global:devops_projectConfigID].Name; ProjectLocation = $global:devops_projectLocation; ClientSecret = $SS }
                $global:devops_configFile.Projects[$global:devops_projectConfigID] = $updatedProject
                if ($global:devops_AzureKeyVault) {
                    $global:clientSecret = $CSecret
                    Add-ClientSecrettoKeyVault
                }
                $global:devops_configFile | ConvertTo-Json | Set-Content ("$env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json")       
                $global:devops_projectFile | ConvertTo-Json | Set-Content ("$global:devops_projectLocation\$global:devops_gitRepo.json")    
            }                  
        }
        Default {}
    }
}

function Add-ClientSecrettoKeyVault() {    
    $keyName = "$($global:devops_gitRepo)-clientsecret"
    Write-Host "Adding Client Secret to KeyVault with name $keyName"
    $global:devops_projectFile.ClientSecretAKVName = $keyName
    $kvsuccess = az keyvault secret set --name $keyName --vault-name $global:devops_AzureKeyVault --value $global:clientSecret --subscription $global:devops_selectedSubscription 
    Write-Host "Removing Client Secret from Local Store"
    $global:devops_configFile.Projects[$global:devops_projectConfigID].ClientSecret = $null
    $global:devops_configFile | ConvertTo-Json | Set-Content ("$env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json")        
    pause    
}