Azure Blob Storage へのフォルダ・ファイルアップロード

ローカルPCに置いてあるファイルを Azure Blob Storage へアップする方法はたくさんあります。
安全にデータをアップロードする方法の１つに REST を使ったものがあります。
https://docs.microsoft.com/ja-jp/azure/databox/data-box-deploy-copy-data-via-rest

なのですが、これは手数が多すぎると思い Azcopy を使うPowerhellスクリプトを構築してみました。
対象マシンが複数ある場合、スクリプトの配布+α で済むかと思います。

前提としては、上記Azcopyコマンドのインストール済み、Azure Storage Account を持っている状態とします。
また、アップロード確認用に Azure Storage Explorer をインストールしておきましょう。
上記ツール等の設定は他を参照してください。
・Azcopy インストール
・Azure Storage Account
・Azure Storage Explorer

# １. Blog Container 作成

   ストレージアカウントの画面で上の[+コンテナー]をクリックし、Blobコンテナーを作成します。

|![02.2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/36af2822-c3e2-c385-6d71-fe65d06db553.jpeg)|
|:--|

# ２. Blob の Shared Access Signature(SAS) 取得

   Blob を表示し、左にある[共有アクセストークン]をクリックします。

|![02.3.1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/4aadc606-a2ac-e0ae-2165-8185b5de3f6b.jpeg)|
|:--|

ここで、お好みに合わせてアクセス許可を変更します。(ここでは「書き込み」Onlyで設定)
その後、[SASトークンおよびURLを生成]ボタンをクリックし、[BLOB SAS URL]をコピーします。
![02.6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/89ea3199-5024-2eca-7db8-37f649718f1b.jpeg)

:four_leaf_clover:ここで Azcopy を使って適当なファイルをがアップロードできるか、Azure Storage Explorer にて確認しておきましょう。

まだ、Blob には何もアップロードされていません。
|![02.6.1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/93efae95-2e69-129a-1bb5-89f0c7737ae4.png)|
|:--|

PowerShell ウィンドウを開き、Azcopy にて hoge.log ファイルをアップロードします。
|![02.6.2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/e2849780-514b-d3b1-f66d-20d7ea09db41.png)|
|:--|


その結果、Storage Explorer に hoge.log ファイルがアップロードされました。
|![02.6.3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/ac99112c-1d1b-4381-9ff1-950cd3349f08.png)|
|:--|


# ３. psスクリプト作成   

   ファイルがどんな名称のPCから送られたのか分かるように、また日付単位でフォルダを切りたいと思います。
   サンプルスクリプト
```
# 処理対象のフォルダ
$str_copy_from = '.\srcDir'  # オリジナルディレクトリ
$str_copy_to = '.\tempDir'   # 一時保存用ディレクトリ

# フォルダコピー  (オリジナルディレクトリから一時保存ディレクトリへコピー)
Copy-Item $str_copy_from -destination $str_copy_to -recurse
 
# 一時保存ディレクトリ内のファイル・フォルダのリストを取得する。
$itemList = Get-ChildItem $str_copy_to;
foreach($item in $itemList)
{
    if($item.PSIsContainer)
    {
        # フォルダの場合の処理
        # 今回はなにもしない
    }
    else
    {
        # ファイルの場合の処理
        # ユーザー名取得
        $user = whoami
                
        # 一時保存ディレクトリにユーザー名＋日付でフォルダを作成
        $newFolder = $str_copy_to + '\' + $user + '\' + (Get-Date).ToString("yyyyMMdd")
        mkdir $newFolder

        # 一時保存ディレクトリにコピー用ファイルを持っていきアップロード用フォルダ作成
        $temp = $str_copy_to + '\' + $item
        Move-Item $temp $newFolder -Force
        
        # フォルダごとアップロード  (フォルダアップロードの場合は末尾に[--recursive=true]を入れる)
        azcopy copy $str_copy_to "https://*********************vA%3D" --recursive=true
        
    }
} 

# 後片付け
Remove-Item -Path $str_copy_to -Recurse
```


:four_leaf_clover:
スクリプトの実行権限に要注意
Windowsのデフォルト設定だと ps スクリプトを実行する権限が備わっていません。そのため、次のコマンドを使って ps スクリプトを実行する権限を付けておきます。

```
PS> Set-ExecutionPolicy RemoteSigned
```


# ４. タスクスケジューラによる定期実行

   [タスクの作成]をクリックし、
![03.0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/071184b6-5f60-41b7-566e-76d2757cf376.jpeg)

   [全般]タブでタスクに名前をつけます。この時、「最上位の特権で実行する(I)」にチェック。
![03.1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/d9ef5df4-ad48-d62a-6b9b-50426de73de9.jpeg)

   [トリガー]タブでジョブの開始時間、繰り返し間隔、継続時間等を変更
   (以下の設定では、５分間隔に設定してます)
![03.2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/042be42b-aa69-584d-d0ae-b5a01813e1da.jpeg)

   [操作]タブで実行プログラムを設定
   この時、「プログラム/スクリプト(P):」にはPowerShell.exeを指定します。
   (%Systemroot%\System32\WindowsPowerShell\v1.0\powershell.exe)
   「引数の追加(オプション)(A):」には実行するスクリプトを次のように指定「-Command ".\blobtest.ps1"」
   「開始(オプション)(T):」には実行するスクリプトのパスを指定
![03.3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/78eba222-c01f-09c2-3d1a-d9ffb7ec3d50.jpeg)

   
  [設定]タブで「タスクを停止するまでの時間(K):」が設定されているので、これをオフ
![03.4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/738e3e86-8c11-4222-e83d-46a09efc9883.jpeg)


# おまけ
直近変更のあったファイルだけを対象にアップロードしたい場合には、PowerShell スクリプトの中でLastwritetime コマンドレットを使って対象ファイルを抽出＆アップロードを実行すれば良さそうですね。