utilities/tools/Test-NamePrefixAvailability.ps1 (183 lines of code) (raw):

<# .SYNOPSIS Test if a given name prefix token placeholder is already taken .DESCRIPTION Test if a given name prefix token placeholder is already taken. Tests resource names by their actual value in the parameter files .PARAMETER namePrefix Parameter description .PARAMETER Tokens Optional. A hashtable parameter that contains tokens to be replaced in the paramter files .EXAMPLE $inputObject = @{ NamePrefix = 'carml' Tokens = @{ Location = 'westeurope' ResourceGroupName = 'validation-rg' SubscriptionId = '00000000-0000-0000-0000-000000000000' ManagementGroupId = '00000000-0000-0000-0000-000000000000' RemoveDeployment = $false } } Test-NamePrefixAvailability @inputObject Test if namePrefix 'carml' is available. #> function Test-NamePrefixAvailability { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string] $namePrefix, [Parameter(Mandatory = $false)] [Psobject] $Tokens = @{} ) begin { Write-Debug ('{0} entered' -f $MyInvocation.MyCommand) # Load helper Scripts $repoRoot = (Get-Item $PSScriptRoot).Parent.Parent.FullName . (Join-Path $repoRoot 'utilities' 'pipelines' 'tokensReplacement' 'Convert-TokensInFileList.ps1') } process { $prefixAvailable = $true # Find Parameter Files # -------------------- $relevantResourceTypes = @( 'Microsoft.Storage/storageAccounts' 'Microsoft.ContainerRegistry/registries' 'Microsoft.KeyVault/vaults' ) $storageAccountNames = @() $containerRegistryNames = @() $keyVaultNames = @() $parameterFiles = (Get-ChildItem -Path $repoRoot -Recurse -Filter 'main.test.bicep').FullName | Where-Object { Test-Path (Join-Path (Split-Path $_ -Parent) 'dependencies.bicep') # Currently we only need to consider files that have ResourceGroup resources } | ForEach-Object { $_.Replace('\', '/') } foreach ($parameterFile in $parameterFiles) { $fileContent = Get-Content -Path $parameterFile foreach ($relevantResourceType in $relevantResourceTypes) { switch ($relevantResourceType) { 'Microsoft.Storage/storageAccounts' { $filter = 'storageAccountName:' } 'Microsoft.ContainerRegistry/registries' { $filter = 'registryName:' } 'Microsoft.KeyVault/vaults' { $filter = 'keyVaultName:' } Default { Write-Warning "The entered resource Type '$_' could not be matched." continue } } $temp = $null # determine if entry is of one of the resourceTypes using the filter variable $temp = $fileContent | ForEach-Object { if ($_ -match "$filter\s'") { $_ } } # determine serviceshort default value if no parameter has been supplied $serviceShort = $fileContent | Where-Object { $_ -Match "^param serviceShort string = '([a-z]+)'$" } | ForEach-Object { $matches[1] } if ($temp) { $temp = $temp.Split($filter) $temp = $temp | Where-Object { $_ -match '\S' } # replace empty lines in array # trim the entry and replace placeholder values $temp = $temp.Replace("'", '') # remove trailing quotes $temp = $temp.Replace('[[namePrefix]]', $namePrefix) $temp = $temp.Replace('${serviceShort}', $serviceShort) $temp = $temp.Replace(' ', '') # remove trailing whitespaces # drop entries which generate its name during runtime (e.g. via uniqueString function in bicep) if ($temp -match 'uniqueString') { continue } # add entry to resourcetype-specific list switch ($filter) { 'storageAccountName:' { $storageAccountNames += $temp } 'registryName:' { $containerRegistryNames += $temp } 'keyVaultName:' { $keyVaultNames += $temp } Default {} } } } } $storageAccountNames = $storageAccountNames | Select-Object -Unique $containerRegistryNames = $containerRegistryNames | Select-Object -Unique $keyVaultNames = $keyVaultNames | Select-Object -Unique # Extract Parameter Names # ----------------------- $subscriptionId = (Get-AzContext).Subscription.Id # Storage Write-Host "`nCheck Storage Accounts" -ForegroundColor 'Cyan' Write-Host '======================' -ForegroundColor 'Cyan' foreach ($storageAccountName in $storageAccountNames) { $path = '/subscriptions/{0}/providers/Microsoft.Storage/checkNameAvailability?api-version=2021-04-01' -f $subscriptionId $requestInputObject = @{ Method = 'POST' Path = $path Payload = @{ name = $storageAccountName type = 'Microsoft.Storage/storageAccounts' } | ConvertTo-Json } $response = ((Invoke-AzRestMethod @requestInputObject).Content | ConvertFrom-Json) if ($response.nameAvailable) { Write-Host "=> The storage account name [$storageAccountName] is currently available" -ForegroundColor 'Green' } else { Write-Warning "=> Warning: The storage account name [$storageAccountName] is not available. Please try a different prefix." $prefixAvailable = $false } } # Key Vault Write-Host "`nChecking Key Vaults" -ForegroundColor 'Cyan' Write-Host '===================' -ForegroundColor 'Cyan' foreach ($keyVaultName in $keyVaultNames) { $path = '/subscriptions/{0}/providers/Microsoft.KeyVault/checkNameAvailability?api-version=2021-10-01' -f $subscriptionId $requestInputObject = @{ Method = 'POST' Path = $path Payload = @{ name = $keyVaultName type = 'Microsoft.KeyVault/vaults' } | ConvertTo-Json } $response = ((Invoke-AzRestMethod @requestInputObject).Content | ConvertFrom-Json) if ($response.nameAvailable) { Write-Host "=> The key vault name [$keyVaultName] is currently available" -ForegroundColor 'Green' } else { Write-Warning "=> Warning: The key vault name [$keyVaultName] is not available. Please try a different prefix." $prefixAvailable = $false } } # Azure Container Registry Write-Host "`nCheck Azure Container Registries" -ForegroundColor 'Cyan' Write-Host '==============================' -ForegroundColor 'Cyan' foreach ($acrName in $acrNames) { $path = '/subscriptions/{0}/providers/Microsoft.ContainerRegistry/checkNameAvailability?api-version=2019-05-01' -f $subscriptionId $requestInputObject = @{ Method = 'POST' Path = $path Payload = @{ name = $acrName type = 'Microsoft.ContainerRegistry/registries' } | ConvertTo-Json } $response = ((Invoke-AzRestMethod @requestInputObject).Content | ConvertFrom-Json) if ($response.nameAvailable) { Write-Host "=> The Azure container registry name [$acrName] is currently available" -ForegroundColor 'Green' } else { Write-Warning "=> Warning: The Azure container registry name [$acrName] is not available. Please try a different prefix." $prefixAvailable = $false } } Write-Host "`nRESULT" -ForegroundColor 'Cyan' Write-Host '======' -ForegroundColor 'Cyan' if (-not $prefixAvailable) { Write-Error "=> Prefix [$namePrefix] is not available for all resources. Please try a different one." } else { Write-Host "=> Prefix [$namePrefix] is available for all resources." -ForegroundColor 'Green' } } end { Write-Debug ('{0} exited' -f $MyInvocation.MyCommand) } }