PowerShell 操作 Azure Blob Storage


本文假設已經存在了一個 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM