powershell - 使用快照复制 Azure Blob

标签 powershell azure azure-storage azure-blob-storage

我正在尝试备份一些 Blob 存储以防止意外删除容器,并且我可以使用 PowerShell 和 start-CopyAzurBlog 或从命令行使用 AZCopy 很好地复制 Blob,但是这些 Blob 有一个编号快照(用作版本控制过程的一部分),并且每当我复制时,它都不会附带快照。

我知道您可以将/snapshot 命令与 AZCopy 结合使用,但这会为每个快照创建一个全新的 blob,我需要它们成为单个 blob 的一部分。 有没有办法完整复制这些?理想情况下,这应该在 PowerShell 中,这样我就可以使用 Azure 自动化,但如果需要的话,我很乐意在 C# 中做一些事情。

最佳答案

这是符合赵兴路逻辑的代码。该方法是首先列出源 blob 的快照,从快照在目标中创建 blob,然后拍摄该 blob 的快照。最后,您可以将基本 blob 复制到目标 blob 中。

    static void CopyBlobAndSnapshots()
    {
        var sourceAccountName = "<source-account-name>";
        var sourceAccountKey = "<source-account-key>";
        var sourceContainerName = "<source-container-name>";
        var targetAccountName = "<target-account-name>";
        var targetAccountKey = "<target-account-key>";
        var targetContainerName = "<target-container-name>";
        var blobName = "<source-blob-name>";
        var sourceAccount = new CloudStorageAccount(new StorageCredentials(sourceAccountName, sourceAccountKey), true);
        var targetAccount = new CloudStorageAccount(new StorageCredentials(targetAccountName, targetAccountKey), true);
        var sourceBlobClient = sourceAccount.CreateCloudBlobClient();
        var sourceContainer = sourceBlobClient.GetContainerReference(sourceContainerName);
        var sourceBlob = sourceContainer.GetBlockBlobReference(blobName);
        var targetBlobClient = targetAccount.CreateCloudBlobClient();
        var targetContainer = targetBlobClient.GetContainerReference(targetContainerName);
        targetContainer.CreateIfNotExists();
        //Create a SAS Token on source blob with read permissions that is valid for 2 weeks.
        var sasToken = sourceBlob.GetSharedAccessSignature(new SharedAccessBlobPolicy()
            {
                Permissions = SharedAccessBlobPermissions.Read,
                SharedAccessExpiryTime = new DateTimeOffset(DateTime.UtcNow.AddDays(14))
            });
        //List blob snapshots first
        var baseBlobAndSnapshots = sourceContainer.ListBlobs(blobName, true, BlobListingDetails.Snapshots).ToList();
        //Since the list contains both base blob and snapshots, we should remove the base blob from this list.
        var blobSnapshots = baseBlobAndSnapshots.Where(b => ((CloudBlockBlob)b).SnapshotTime != null).ToList();
        //Now we should arrange them in reverse chronological order
        blobSnapshots.Reverse();
        CloudBlockBlob targetBlob = null;
        string sourceBlobUrl = string.Empty;
        foreach (var blob in blobSnapshots)
        {
            var blockBlob = (CloudBlockBlob) blob;
            Console.WriteLine("Copying blob snapshot. Snapshot date/time = " + blockBlob.SnapshotTime);
            sourceBlobUrl = string.Format("{0}&{1}", blockBlob.SnapshotQualifiedUri, sasToken.Substring(1));
            targetBlob = targetContainer.GetBlockBlobReference(blobName);
            targetBlob.StartCopy(new Uri(sourceBlobUrl));
            //Check the status;
            targetBlob.FetchAttributes();
            do
            {
                var copyState = targetBlob.CopyState;
                if (copyState.Status == CopyStatus.Pending)
                {
                    Thread.Sleep(1000);//Copy not completed. Wait for it to complete.
                    targetBlob.FetchAttributes();
                }
                else
                {
                    break;
                }
            } 
            while (true);
            Console.WriteLine("Copying blob snapshot complete. Snapshot date/time = " + blockBlob.SnapshotTime);
            Console.WriteLine("----------------------------");
            //Now take the blob snapshot
            Console.WriteLine("Taking blob snapshot....");
            targetBlob.Snapshot();
            Console.WriteLine("Blob snapshot taken....");
            Console.WriteLine("----------------------------");
        }
        Console.WriteLine("Copying base blob.");
        sourceBlobUrl = string.Format("{0}{1}", sourceBlob.Uri, sasToken);
        targetBlob = targetContainer.GetBlockBlobReference(blobName);
        targetBlob.StartCopy(new Uri(sourceBlobUrl));
        //Check the status;
        targetBlob.FetchAttributes();
        do
        {
            var copyState = targetBlob.CopyState;
            if (copyState.Status == CopyStatus.Pending)
            {
                Thread.Sleep(1000);//Copy not completed. Wait for it to complete.
                targetBlob.FetchAttributes();
            }
            else
            {
                break;
            }
        } 
        while (true);
        Console.WriteLine("Blob with snapshot copy completed!");
    }

关于powershell - 使用快照复制 Azure Blob,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33661169/

相关文章:

azure - 检查 Azure Functions 运行的环境

azure - 限制 Azure 存储容器的初始大小

azure - 为什么 Azure Functions 创建 V1 存储帐户?

azure - 在 Azure 媒体服务上存储实时视频

xml - 使用Powershell将嵌套的xml转换为csv时遇到问题

在 x86 上下文中运行时,PowerShell 返回已安装软件的不准确结果

Azure CLI 如何检查资源是否存在

node.js - 通过 GitHub 部署时,Express 4 应用程序无法在 Azure 中运行

json - Powershell JSON管道将多个值扩展为一列csv

regex - Powershell-替换给出奇怪的行为