Grundlagen: Azure Storage: Dateien (BLOBs) per PowerShell kopieren

Speicherdienste in der Cloud sind die Basis für viele Anwendungszwecke. Und der Trend zeigt klar in eine Richtung: Die Speichermengen in Azure wachsen aufgrund der hohen Verfügbarkeit an Speicherplatz schnell an.

Eine der häufigsten Aktivitäten in den Speicherdiensten ist ganz klar das Kopieren von Daten. Nur welche Varianten gibt es? Die Daten erst von einem Speicherkonto lokal herunterzuladen und dann wieder nach Azure hochzuladen ist für große Speichermengen kein gangbarer Weg, da er meist zu viel Zeit beansprucht. In Azure ist es allerdings auch möglich, Kopieroperation asynchron auf direktem Weg von Quelle zu Ziel ablaufen zu lassen. Das heißt, man startet einen Kopiervorgang und prüft später nach, dass dieser abgeschlossen wurde. Eine ständige Verbindung eines Clients zur Azure Service Management API ist nicht notwendig.

Für diesen Artikel habe ich für die Skriptbeispiele folgende Testumgebung aufgebaut: zwei Speicherkonten mit dem Namen “storagesource” und “storagedestination”. storagesource enthält die Container source1 und source2, storagedestination den Container destination1.

SNAGHTMLbad255f

Im aktuellen Speicherkonto

Die ersten beiden Beispiele gehen davon aus, dass wir Dateien nur im aktuellen Speicherkonto kopieren. Das heißt, wir brauchen nur die Container angeben. Hierbei müssen wir nur sicherstellen, dass das aktuelle Speicherkonto festgelegt wurde. Dafür wird der PowerShell-Befehl Set-AzureSubscription und der Parameter CurrentStorageAccount verwendet.

Im folgenden Beispiel kopieren wir einzelne Dateien (BLOBs, binary large objects) in einen anderen Container im aktuellen Speicherkonto. Vor dem Kopieren lassen wir den Inhalt vom Quell-und Ziel-Container ausgeben und hinterher noch einmal vom Ziel-Container. Für den Kopiervorgang verwenden wir den PowerShell-Befehl Start-AzureStorageBlobCopy und mit dem PowerShell-Befehl Get-AzureStorageBlob lassen wir die BLOBs in einem Container ausgeben.

Im folgenden Beispiel kopieren wir nicht vordefinierte Dateien, sondern alle Dateien im Quell-Container in den Ziel-Container. Dazu verwenden wir den Parameter Blob vom PowerShell-Befehl Get-AzureStorageBlob, um die Eingabeliste zu filtern. Wenn man in diesem Beispiel den Filter weglässt, wird der ganze Container kopiert, da dann keine Filterung stattfindet.

Unterschiedliche Speicherkonten

Möchte man Daten kopieren, die nicht im gleichen Speicherkonto liegen, muss man mit Speicherkontexten arbeiten. Einen Speicherkontext erstellt man mit dem Befehl New-AzureStorageContext. Das folgende Beispiel zeigt zuerst, wie wir für die zwei Speicherkonten storagesource und storagedestination einen Speicherkontext erstellen. New-AzureStorageContext benötigt den Namen des Speicherkontos und einen Zugriffsschlüssel.

Nachdem wir die Speicherkontexte erstellt haben, können wir zwischen allen Speicherkonten hin und her kopieren. Bei den meisten Storage-Befehlen ist es möglich, einen Speicherkontext anzugeben. Die Verwendung des aktuellen Speicherkontos ist nur eine vereinfachte Variante.

Das folgende Skriptbeispiel enthält drei Kopiervorgänge: Zuerst folgt ein einfaches Beispiel, das eine einzelne Datei zwischen zwei Speicherkonten mithilfe von Speicherkontexten kopiert. Danach folgt ein erweitertes Beispiel, das alle Textdateien aus dem aktuellen Speicherkonto in das Speicherkonto storagedestination kopiert und dann von dort wieder zurück in das Speicherkonto storagesource.

Es ist wichtig zu beachten, dass dies ein vereinfachtes Beispiel ist. Der Kopiervorgang ist asynchron und kann länger dauern, wenn die Dateien größer sind. Zu diesem Zweck gibt es den PowerShell-Befehl Get-AzureStorageBlobCopyState, um zu überprüfen, ob ein Kopiervorgang noch andauert oder schon abgeschlossen wurde.

Der Befehl wird auf den Ziel-BLOB angewandt. Wenn wir also zum Beispiel eine Zieldatei mit dem Namen copy2.vhd im Container destination erstellen, dann sieht die Statusabfrage für den Kopiervorgang beispielsweise wie folgt aus.

Hier ein Auszug eines “echten” Skripts, wie wir es bei den IT Camps für Hybrid IT verwenden. Das folgende Skript startet Kopiervorgänge und geht danach in eine Schleife über, die regelmäßig prüft, ob die Kopiervorgänge abgeschlossen wurden. Das Skript prüft in immer größeren Abständen nach dem aktuellen Status. Zusätzlich lasse ich über den Befehl Format-Table die Ausgabe übersichtlich als Tabelle ausgeben.

Weitere Informationen

PowerShell: Azure-Automatisierung für Einsteiger (Microsoft Virtual Academy)

Grundlagen: Speicherkonten in Azure per PowerShell erstellen (MSDN Blogs)

Skripte

Für den Fall, dass die eingebetteten Skripte auf GitHub Gist nicht aufrufbar sind, sind diese hier noch einmal unformatiert aufgeführt. (Es kann durch das Layout der Blog-Webseite sein, dass die Code-Zeilen abgeschnitten sind. Dann bitte einfach im Quelltext der Seite nachschauen.)

Beispiel 1

 "--> Set current storage account."
Set-AzureSubscription -SubscriptionName "MSFT MVA Stage" -CurrentStorageAccountName "storagesource"

"--> Get blobs from containers 'source1' and 'source2' from current storage account (storagesource)."
Get-AzureStorageBlob -Container source1
Get-AzureStorageBlob -Container source2

"--> Copy BLOBs from container 'source1' into 'source2'. Each copy command shows the copied BLOBs."
"--> Copy BLOB 'Test1.txt'."
Start-AzureStorageBlobCopy -SrcBlob "Test1.txt" -SrcContainer source1 -DestContainer source2
"--> Copy BLOB 'Test2.txt'."
Start-AzureStorageBlobCopy -SrcBlob "Test2.txt" -SrcContainer source1 -DestContainer source2

"--> Display BLOBs in 'source2'."
Get-AzureStorageBlob -Container source2

<# Output

--> Set current storage account.
--> Get blobs from containers 'source1' and 'source2' from current storage account (storagesource).


   Container Uri: https://storagesource.blob.core.windows.net/source1

Name      BlobType  Length ContentType LastModified               SnapshotTime
----      --------  ------ ----------- ------------               ------------
Test1.txt BlockBlob 18     text/plain  02.04.2015 16:02:07 +00:00             
Test2.txt BlockBlob 18     text/plain  02.04.2015 16:02:06 +00:00             
Test3.txt BlockBlob 18     text/plain  02.04.2015 16:02:06 +00:00             
--> Copy BLOBs from container 'source1' into 'source2'. Each copy command shows the copied BLOBs.
--> Copy BLOB 'Test1.txt'.


   Container Uri: https://storagesource.blob.core.windows.net/source2

Name      BlobType  Length ContentType LastModified               SnapshotTime
----      --------  ------ ----------- ------------               ------------
Test1.txt BlockBlob 18     text/plain  02.04.2015 16:12:06 +00:00             
--> Copy BLOB 'Test2.txt'.
Test2.txt BlockBlob 18     text/plain  02.04.2015 16:12:08 +00:00             
--> Display BLOBs in 'source2'.
Test1.txt BlockBlob 18     text/plain  02.04.2015 16:12:06 +00:00             
Test2.txt BlockBlob 18     text/plain  02.04.2015 16:12:08 +00:00             

#>

Beispiel 2

 "--> Set current storage account."
Set-AzureSubscription -SubscriptionName "MSFT MVA Stage" -CurrentStorageAccountName "storagesource"

"--> Get blobs from containers 'source1' and 'source2' from current storage account (storagesource)."
Get-AzureStorageBlob -Container source1
Get-AzureStorageBlob -Container source2

"--> Copy all BLOBs with pattern '*.txt' from container 'source1' into 'source2'. The copy command shows processed BLOBs."
Get-AzureStorageBlob -Blob "*.txt" -Container source1 | Start-AzureStorageBlobCopy -DestContainer source2

<# Output

--> Set current storage account.
--> Get blobs from containers 'source1' and 'source2' from current storage account (storagesource).


   Container Uri: https://storagesource.blob.core.windows.net/source1

Name      BlobType  Length ContentType LastModified               SnapshotTime
----      --------  ------ ----------- ------------               ------------
Test1.txt BlockBlob 18     text/plain  02.04.2015 16:02:07 +00:00             
Test2.txt BlockBlob 18     text/plain  02.04.2015 16:02:06 +00:00             
Test3.txt BlockBlob 18     text/plain  02.04.2015 16:02:06 +00:00             
--> Copy all BLOBs with pattern '*.txt' from container 'source1' into 'source2'. The copy command shows processed BLOBs.


   Container Uri: https://storagesource.blob.core.windows.net/source2

Name      BlobType  Length ContentType LastModified               SnapshotTime
----      --------  ------ ----------- ------------               ------------
Test1.txt BlockBlob 18     text/plain  02.04.2015 16:25:42 +00:00             
Test2.txt BlockBlob 18     text/plain  02.04.2015 16:25:42 +00:00             
Test3.txt BlockBlob 18     text/plain  02.04.2015 16:25:42 +00:00             

#>

Beispiel 3

 "--> Set current storage account."
Set-AzureSubscription -SubscriptionName "MSFT MVA Stage" -CurrentStorageAccountName "storagesource"

"--> Get blobs from containers 'source1' and 'source2' from current storage account (storagesource)."
Get-AzureStorageBlob -Container source1
Get-AzureStorageBlob -Container source2

"--> Copy all BLOBs with pattern '*.txt' from container 'source1' into 'source2'. The copy command shows processed BLOBs."
Get-AzureStorageBlob -Blob "*.txt" -Container source1 | Start-AzureStorageBlobCopy -DestContainer source2

<# Output

--> Set current storage account.
--> Get blobs from containers 'source1' and 'source2' from current storage account (storagesource).


   Container Uri: https://storagesource.blob.core.windows.net/source1

Name      BlobType  Length ContentType LastModified               SnapshotTime
----      --------  ------ ----------- ------------               ------------
Test1.txt BlockBlob 18     text/plain  02.04.2015 16:02:07 +00:00             
Test2.txt BlockBlob 18     text/plain  02.04.2015 16:02:06 +00:00             
Test3.txt BlockBlob 18     text/plain  02.04.2015 16:02:06 +00:00             
--> Copy all BLOBs with pattern '*.txt' from container 'source1' into 'source2'. The copy command shows processed BLOBs.


   Container Uri: https://storagesource.blob.core.windows.net/source2

Name      BlobType  Length ContentType LastModified               SnapshotTime
----      --------  ------ ----------- ------------               ------------
Test1.txt BlockBlob 18     text/plain  02.04.2015 16:25:42 +00:00             
Test2.txt BlockBlob 18     text/plain  02.04.2015 16:25:42 +00:00             
Test3.txt BlockBlob 18     text/plain  02.04.2015 16:25:42 +00:00             

#>

Beispiel 4

 Get-AzureStorageBlobCopyState -Blob copy2.vhd -Container destination

<# Output

CopyId            : 0c61d2d2-5cc8-4936-8800-1690b17d71f3
CompletionTime    : 05.01.2015 15:53:08 +00:00
Status            : Success
Source            : https://pkdestination.blob.core.windows.net/backup/fixedvhd2.vhd
BytesCopied       : 20972032
TotalBytes        : 20972032
StatusDescription : 

#>

Beispiel 5

 # Get all BLOBs from source container and start copy operation asynchronously for all files based on $fileFilter.
Get-AzureStorageBlob -Context $sourceStorageContext -Container $sourceStorageContainer -Blob $fileFilter | 
    Start-AzureStorageBlobCopy -DestContext $destinationStorageContext -DestContainer $destinationStorageContainer

# Check copy state in destination container.
$waitTime = 5 # Initial wait time.
do {
    # Wait some time before refresh of copy state, except on first iteration.
    if ($copyState) { 
        Write-Host "Refresh in $waitTime seconds."
        # After each iteration wait some more time.
        Start-Sleep -Seconds ($waitTime++)
    }

    # Get all BLOBs in destination container and get copy state for all of them.
    $copyState = Get-AzureStorageBlob -Context $destinationStorageContext -Container $destinationStorageContainer -Blob $fileFilter | 
                    Get-AzureStorageBlobCopyState

    # Print formatted output.
    $copyState | Format-Table -Property CopyId, Status, TotalBytes, BytesCopied, @{Name = "Progress"; Expression = {$_.BytesCopied / $_.TotalBytes * 100}; FormatString = "0.00" }, CompletionTime -AutoSize
} while ($copyState.Status -contains "Pending")