mirror of
https://github.com/microsoft/vcpkg.git
synced 2024-12-12 02:19:03 +08:00
166 lines
4.2 KiB
PowerShell
166 lines
4.2 KiB
PowerShell
|
# Copyright (c) Microsoft Corporation.
|
||
|
# SPDX-License-Identifier: MIT
|
||
|
|
||
|
<#
|
||
|
.SYNOPSIS
|
||
|
Returns whether there's a name collision in the resource group.
|
||
|
|
||
|
.DESCRIPTION
|
||
|
Find-ResourceGroupNameCollision takes a list of resources, and checks if $Test
|
||
|
collides names with any of the resources.
|
||
|
|
||
|
.PARAMETER Test
|
||
|
The name to test.
|
||
|
|
||
|
.PARAMETER Resources
|
||
|
The list of resources.
|
||
|
#>
|
||
|
function Find-ResourceGroupNameCollision {
|
||
|
[CmdletBinding()]
|
||
|
Param([string]$Test, $Resources)
|
||
|
|
||
|
foreach ($resource in $Resources) {
|
||
|
if ($resource.ResourceGroupName -eq $Test) {
|
||
|
return $true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $false
|
||
|
}
|
||
|
|
||
|
<#
|
||
|
.SYNOPSIS
|
||
|
Attempts to find a name that does not collide with any resources in the resource group.
|
||
|
|
||
|
.DESCRIPTION
|
||
|
Find-ResourceGroupName takes a set of resources from Get-AzResourceGroup, and finds the
|
||
|
first name in {$Prefix, $Prefix-1, $Prefix-2, ...} such that the name doesn't collide with
|
||
|
any of the resources in the resource group.
|
||
|
|
||
|
.PARAMETER Prefix
|
||
|
The prefix of the final name; the returned name will be of the form "$Prefix(-[1-9][0-9]*)?"
|
||
|
#>
|
||
|
function Find-ResourceGroupName {
|
||
|
[CmdletBinding()]
|
||
|
Param([string] $Prefix)
|
||
|
|
||
|
$resources = Get-AzResourceGroup
|
||
|
$result = $Prefix
|
||
|
$suffix = 0
|
||
|
while (Find-ResourceGroupNameCollision -Test $result -Resources $resources) {
|
||
|
$suffix++
|
||
|
$result = "$Prefix-$suffix"
|
||
|
}
|
||
|
|
||
|
return $result
|
||
|
}
|
||
|
|
||
|
<#
|
||
|
.SYNOPSIS
|
||
|
Generates a random password.
|
||
|
|
||
|
.DESCRIPTION
|
||
|
New-Password generates a password, randomly, of length $Length, containing
|
||
|
only alphanumeric characters, underscore, and dash.
|
||
|
|
||
|
.PARAMETER Length
|
||
|
The length of the returned password.
|
||
|
#>
|
||
|
function New-Password {
|
||
|
Param ([int] $Length = 32)
|
||
|
|
||
|
# This 64-character alphabet generates 6 bits of entropy per character.
|
||
|
# The power-of-2 alphabet size allows us to select a character by masking a random Byte with bitwise-AND.
|
||
|
$alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"
|
||
|
$mask = 63
|
||
|
if ($alphabet.Length -ne 64) {
|
||
|
throw 'Bad alphabet length'
|
||
|
}
|
||
|
|
||
|
[Byte[]]$randomData = [Byte[]]::new($Length)
|
||
|
$rng = $null
|
||
|
try {
|
||
|
$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
|
||
|
$rng.GetBytes($randomData)
|
||
|
}
|
||
|
finally {
|
||
|
if ($null -ne $rng) {
|
||
|
$rng.Dispose()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$result = ''
|
||
|
for ($idx = 0; $idx -lt $Length; $idx++) {
|
||
|
$result += $alphabet[$randomData[$idx] -band $mask]
|
||
|
}
|
||
|
|
||
|
return $result
|
||
|
}
|
||
|
|
||
|
<#
|
||
|
.SYNOPSIS
|
||
|
Waits for the shutdown of the specified resource.
|
||
|
|
||
|
.DESCRIPTION
|
||
|
Wait-Shutdown takes a VM, and checks if there's a 'PowerState/stopped'
|
||
|
code; if there is, it returns. If there isn't, it waits ten seconds and
|
||
|
tries again.
|
||
|
|
||
|
.PARAMETER ResourceGroupName
|
||
|
The name of the resource group to look up the VM in.
|
||
|
|
||
|
.PARAMETER Name
|
||
|
The name of the virtual machine to wait on.
|
||
|
#>
|
||
|
function Wait-Shutdown {
|
||
|
[CmdletBinding()]
|
||
|
Param([string]$ResourceGroupName, [string]$Name)
|
||
|
|
||
|
Write-Host "Waiting for $Name to stop..."
|
||
|
while ($true) {
|
||
|
$Vm = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $Name -Status
|
||
|
$highestStatus = $Vm.Statuses.Count
|
||
|
for ($idx = 0; $idx -lt $highestStatus; $idx++) {
|
||
|
if ($Vm.Statuses[$idx].Code -eq 'PowerState/stopped') {
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Write-Host "... not stopped yet, sleeping for 10 seconds"
|
||
|
Start-Sleep -Seconds 10
|
||
|
}
|
||
|
}
|
||
|
|
||
|
<#
|
||
|
.SYNOPSIS
|
||
|
Sanitizes a name to be used in a storage account.
|
||
|
|
||
|
.DESCRIPTION
|
||
|
Sanitize-Name takes a string, and removes all of the '-'s and
|
||
|
lowercases the string, since storage account names must have no
|
||
|
'-'s and must be completely lowercase alphanumeric. It then makes
|
||
|
certain that the length of the string is not greater than 24,
|
||
|
since that is invalid.
|
||
|
|
||
|
.PARAMETER RawName
|
||
|
The name to sanitize.
|
||
|
#>
|
||
|
function Sanitize-Name {
|
||
|
[CmdletBinding()]
|
||
|
Param(
|
||
|
[string]$RawName
|
||
|
)
|
||
|
|
||
|
$result = $RawName.Replace('-', '').ToLowerInvariant()
|
||
|
if ($result.Length -gt 24) {
|
||
|
Write-Error 'Sanitized name for storage account $result was too long.'
|
||
|
}
|
||
|
|
||
|
return $result
|
||
|
}
|
||
|
|
||
|
Export-ModuleMember -Function Find-ResourceGroupName
|
||
|
Export-ModuleMember -Function New-Password
|
||
|
Export-ModuleMember -Function Wait-Shutdown
|
||
|
Export-ModuleMember -Function Sanitize-Name
|