用于创建快照并将其存储到另一个位置的存储帐户的 Powershell 脚本

Powershell script to create a snapshot and store it into a storage account in another location

使用 powershell 脚本,我需要创建 VM 的快照并将快照保存在不同区域的存储帐户中。快照名称还应包含拍摄日期,以便在 30 天后自动删除。请让我知道如何实现这一目标。 我面临的另一个主要问题是如何在不直接在脚本中使用密钥的情况下将快照存储在存储帐户中。

这是我正在使用的旧脚本,它在快照名称功能中没有日期,并且直接在脚本中使用存储帐户密钥,这是不安全的。

 #powershell script to create a snapshot

Select-AzSubscription -SubscriptionName 'subs name'

$subscriptionId = 'xxxxxx'

$resourceGroupName = "Rgname"

$vmName="VMname"

$Location = "East US"

#how to get-date in the name of the snap
$snapshotName = "snapname"


$vmOSDisk=(Get-AzVM -ResourceGroupName $resourceGroupName -Name $vmName).StorageProfile.OsDisk.Name

$Disk = Get-AzDisk -ResourceGroupName $resourceGroupName -DiskName $vmOSDisk

$SnapshotConfig = New-AzSnapshotConfig -SourceUri $Disk.Id -CreateOption Copy -Location $Location

$Snapshot=New-AzSnapshot -Snapshot $snapshotConfig -SnapshotName `
      $snapshotName -ResourceGroupName $resourceGroupName






#powershell script to convert snapshot into managed disks
      
$diskName = 'ManagedDiskname'

#Provide the size of the disks in GB. It should be greater than the VHD file size.
$diskSize = '128'


$storageType = 'Premium_LRS'

Select-AzSubscription -SubscriptionId $SubscriptionId

$snapshot = Get-AzSnapshot -ResourceGroupName $resourceGroupName -SnapshotName $snapshotName 

$diskConfig = New-AzDiskConfig -SkuName $storageType -Location $location -CreateOption Copy -SourceResourceId $snapshot.Id

New-AzDisk -Disk $diskConfig -ResourceGroupName $resourceGroupName -DiskName $diskName






#powershell script to save managed disk into a storage account which is in a different location

$sasExpiryDuration = "3600"

$storageAccountName = "storageacctname"

$storageContainerName = "containername"

$storageAccountKey = '(Get-AzStorageAccountKey -ResourceGroupName "Snapshot-Powershell" -AccountName "storageforsnap")'

#Provide the key of the storage account where you want to copy the VHD of the managed disk. 
$storageAccountKey = 'xxxxxx'


$destinationVHDFileName = "vhdfilename"

. 
$useAzCopy = 1 


Select-AzSubscription -SubscriptionId $SubscriptionId


$sas = Grant-AzDiskAccess -ResourceGroupName $ResourceGroupName -DiskName $diskName -DurationInSecond $sasExpiryDuration -Access Read 


$destinationContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey

#Copy the VHD of the managed disk to the storage account
if($useAzCopy -eq 1)
{
    $containerSASURI = New-AzStorageContainerSASToken -Context $destinationContext -ExpiryTime(get-date).AddSeconds($sasExpiryDuration) -FullUri -Name $storageContainerName -Permission rw
    azcopy copy $sas.AccessSAS $containerSASURI

}else{

    Start-AzStorageBlobCopy -AbsoluteUri $sas.AccessSAS -DestContainer $storageContainerName -DestContext $destinationContext -DestBlob $destinationVHDFileName
}

1. Azure snapshot can be auto deleted after 30 days

据我所知,Azure 不提供该功能。但是我们可以通过定时任务来实现。

例如

  1. Enable Run As account in Azure automation account

  2. 在自动化帐户中安装模块 Az.Automation Az.AccountsAz.Compute。关于如何安装,请参考here

  3. 在自动化帐户中使用以下脚本创建 Azure Powershell runbook。详情请参考here.


#get the snpshots created before 30 days
Get-AzSnapshot| Where-Object{($_.TimeCreated -lt ([datetime]::UtcNow.AddDays(-30)))}
foreach($snp in $snps){
  $snp| Remove-AzSnapshot -Force
}
  1. Create a schedule for the Azure runbook.

2. How to securely connect Azure blob

如果你想安全连接Azure blob,我们可以用Azure AD auth来实现。详情请参考here.

例如

  1. 分配 Storage Blob Data Contributor 角色给用户或 sp
New-AzRoleAssignment -SignInName <email> `
    -RoleDefinitionName "Storage Blob Data Contributor" `
    -Scope  "/subscriptions/<subscription>/resourceGroups/sample-resource-group/providers/Microsoft.Storage/storageAccounts/<storage-account>"
  1. 脚本
Connect-AzAccount
$ResourceGroupName=""
$snapshotName=""
$sasExpiryDuration=3600

$sas =Grant-AzSnapshotAccess  -SnapshotName $snapshotName -ResourceGroupName $ResourceGroupName  -DurationInSecond $sasExpiryDuration -Access Read 

$storageAccountName=""
$destinationContext = New-AzStorageContext -StorageAccountName $storageAccountName -UseConnectedAccount

$storageContainerName="image"
$destinationVHDFileName="test.vhd"
Start-AzStorageBlobCopy -AbsoluteUri $sas.AccessSAS -DestContainer $storageContainerName -DestContext $destinationContext -DestBlob $destinationVHDFileName

#check copy state
Get-AzStorageBlobCopyState -Container $storageContainerName -Blob $destinationVHDFileName -Context $destinationContext