本文假設已經存在了一個 Azure Storage Account,需要進行文件的上傳,下載,復制,刪除等操作。
為了方便查看 PowerShell 代碼執行的結果,本文使用了 MS 發布的一個 Azure Storage 客戶端工具:Microsoft Azure Storage Explorer,文中簡稱為 Storage Explorer。
安裝 PowerShell Azure 模塊
操作 Azure 的模塊是不隨 PowerShell 一起安裝的,使用前需要單獨的安裝。
PowerShellGet 模塊
如果要從 PowerShell Gallery 安裝 Azure 模塊,需要確保已經安裝了 PowerShellGet 模塊。下面的命令檢查已安裝 PowerShellGet 模塊的版本:
Get-Module PowerShellGet -list | Select-Object Name,Version,Path
安裝 Azure PowerShell 模塊
下面的命令安裝 Azure Resource Manager 模塊:
Install-Module AzureRM -AllowClobber
注意,安裝過程中有確認安裝的交互過程。
載入 Azure 模塊
在使用 Azure 相關的命令前需要通過 Import-Module 命令加載 Azure 模塊:
Import-Module AzureRM
創建 Azure Storage 上下文
如果我們要對一個 Storage Account 中的文件進行操作,需要提供訪問 Storage Account 的認證信息。我們的方式是直接通過 New-AzureStorageContext 命令創建一個 AzureStorageContext 類型的對象,這個對象中包含了認證信息,所以接下來所有對 storage 的訪問操作都需要使用它:
$ctx = New-AzureStorageContext -ConnectionString "DefaultEndpointsProtocol=https;AccountName=youraccountname;AccountKey=youraccesskey;"
除了使用 -ConnectionString 選項,還可以把參數分開來寫:
$StorageAccountName = "youraccountname" $StorageAccountKey = "youraccesskey" $ctx = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey -Protocol Https
注意,在上面的命令中除了添加必要的認證選項外,我們還顯式的指定了通信協議。指定 https 是非常重要的,因為以 https 協議上傳下載的數據默認會進行數據的完整性校驗。也就是說在進行文件的上傳或者下載時,我們不需要再做額外的數據完整性校驗了。
除了 New-AzureStorageContext 命令,還有其他的方式可以獲得 AzureStorageContext 對象。比如可以先通過 Login-AzureRmAccount 登錄,然后找到某個(或者是創建一個) Storage Account,並獲取其 Context 屬性。
創建 Container
任何的 blob 對象都必須被包含在一個 Container 中,所以在進行 blob 文件的操作前,我們需要先創建一個 Container:
$ContainerName = "containertest" New-AzureStorageContainer -Name $ContainerName -Permission Off -Context $ctx
為 Container 設置的權限會控制 Container 中的所有文件,當前一共有三個權限類型:
Container:匿名用戶可以訪問文件內容,並且可以枚舉 Container 中的所有文件。
Blob:匿名用戶可以訪問文件內容,但是不能枚舉 container 中的文件。
Off:匿名用戶不能訪問文件。
-Permission 選項用來設置 Container 的權限,默認值是 Off(筆者喜歡總是顯式的指定這個選項以提高腳本的可讀性)。
-Context 選項指定該命令的執行上下文,主要是認證信息,這里我們使用前面生成的對象 $ctx。
上傳文件
我們可以通過 Set-AzureStorageBlobContent 命令來上傳文件,需要指定文件存放的 Container 和 訪問 Storage Account 的上下文:
Set-AzureStorageBlobContent -Container $ContainerName -File ".\cortana.jpg" -Blob "cortana.jpg" -Context $ctx
上傳成功后我們可以通過 Storage Explorer 直觀的檢查一下:
這樣上傳的文件都是直接放在 Container 的根目錄下的,如果要對文件存放的目錄進行管理,需要在上傳時指定包含目錄名稱的文件名:
Set-AzureStorageBlobContent -Container $ContainerName -File ".\cortana.jpg" -Blob "images/cortana.jpg" -Context $ctx
這樣上傳后,文件 cortana.jpg 會存放在 images 目錄下。
上傳目錄下的多個文件
我們還可以通過一個命令一次上傳某個目錄下的所有文件:
Get-ChildItem -Path "D:\ConsoleApplication1" -File -Recurse | Set-AzureStorageBlobContent -Container $ContainerName -Context $ctx
D:\ConsoleApplication1 目錄中是一個簡單的 C# 控制台應用,通過管道組合 Get-ChildItem 命令,可以完成多個文件的上傳,並且這些文件的目錄結構和原來都是一樣的。
覆蓋已經存在的 blob
如果我們要上傳一個文件,並指定了一個已經存在的 blob 名稱,此時會與用戶交互以確定是否覆蓋已經存在的 blob。對於各種自動化的任務,我們不希望交互的行為,所以可以加上 -Force 選項強制覆蓋已有文件:
Set-AzureStorageBlobContent -Container $ContainerName -File ".\cortana.jpg" -Blob "cortana.jpg" -Context $ctx -Force
下載文件
Get-AzureStorageBlobContent 命令用來下載文件。下載文件的前提是你知道某個 blob 對象的名稱:
$localFileDirectory = "D:\" Get-AzureStorageBlobContent -Destination $localFileDirectory -Container $ContainerName -Blob "images/cortana.jpg" -Context $ctx -Force
注意,下載到本地的文件路徑為:"D:\images\cortana.jpg"。
其實在很多的情況下我們都沒有這么明確的 blob 名稱,我們需要下載滿足某些情況的 blob,比如下載 images 目錄下的所有文件。這里的問題是我們不知道 images 究竟是哪級目錄,所以可能的做法是遍歷 Container 下的所有文件,然后檢查文件名稱中包含 images 目錄的文件並下載它。為了遍歷 Container 中的文件,需要使用 Get-AzureStorageBlob 命令:
$localFileDirectory = "D:\" $blobs = Get-AzureStorageBlob -Container $ContainerName -Context $ctx foreach($blob in $blobs) { if($blob.Name.Contains("images/")) { Get-AzureStorageBlobContent -Destination $localFileDirectory -Container $ContainerName -Blob $blob.Name -Context $ctx -Force } }
這段代碼中我們用 Get-AzureStorageBlob 命令拿到 Container 下的所有文件信息,然后檢查文件的路徑中有沒有包含 "images/" 字符串,如果包含,就下載這個文件。
復制文件
自動化的腳本操作可以輕松愉快的備份各種數據,當然也包含存儲在 Storage Account 中的文件。Start-AzureStorageBlobCopy 命令用於 blob 文件的復制操作。單從名字上看這應該是個異步方法,但是真實的情況稍微復雜一些。因為這個命令既可以用於同步操作也可以用於異步操作,關鍵在於調用這個命令的方式!下面的命令在同一個 Container 中執行文件復制操作:
Start-AzureStorageBlobCopy -SrcBlob "cortana.jpg" ` -SrcContainer $ContainerName ` -DestContainer $ContainerName ` -DestBlob "myimages/cortana.jpg" ` -Context $ctx
這個操作是同步執行的,它把 Container 根目錄下的 cortana.jpg 文件拷貝到同一個 Container 的 myimages 目錄下。
如果你要跨地域的在不同的 Storage Account 中復制大量的文件,建議你通過異步的方式進行:
# 把 Start-AzureStorageBlobCopy 命令的返回值存儲到變量中會讓復制過程以異步的方式進行。 $blobResult = Start-AzureStorageBlobCopy -SrcBlob $blobName ` -SrcContainer $containerName ` -DestContainer $containerName2 ` -DestBlob $blobName ` -Context $ctx ` -DestContext $ctx2 # 然后通過檢查返回值的方式確定復制操作是否完成。 $status = $blobResult | Get-AzureStorageBlobCopyState # 通過循環,當檢查到結果的狀態不為 "Pending" 時,表示復制操作已經完成。 while ($status.Status -eq "Pending") { $status = $blobResult | Get-AzureStorageBlobCopyState $status Start-Sleep 10 }
刪除文件
Remove-AzureStorageBlob 命令刪除指定的 blob 文件:
Remove-AzureStorageBlob -Container $ContainerName -Blob "myimages/cortana.jpg" -Context $ctx
要是有復雜點的要求,就得通過遍歷 Contaner 中的文件來完成。
權限管理
在創建 Container 時我們已經提到,可以給 Container 設置三種不同的訪問控制權限:Container,Blob,Off。我們也可以在創建 Container 之后通過 Set-AzureStorageContainerAcl 命令改變它的訪問控制權限。下面的命令把 Container 的訪問控制權限設置為 Blob:
Set-AzureStorageContainerAcl -Name $containerName -Context $ctx -Permission Blob