Power Automate DesktopでSharePoint ファイルをダウンロードする (ついでにアップロードも)
バイナリデータ ⇔ ファイル
はじめに
SharePointのファイルをダウンロードする方法は公式サイトのドキュメントにしっかりと説明されていました。ポイントは、バイナリデータを使うところですね。アクション一覧を見ても全然ピンと来なくて出来ないのかと勘違いしちゃいました。自分では思いつかなかったです。難しい。
手順自体はとても単純で、ファイルコンテンツを取得 → バイナリデータをファイルに変換
これだけ。
手順
- ファイル コンテンツを取得
- バイナリ データをファイルに変換
ということで、公式サイトで説明されている、ファイルをすべてダウンロードする方法と、取得したいファイルをダウンロードする方法(というか、こちらの方が利用頻度は高い気がします)の2つを作ってみます。
フォルダーのコンテンツをすべてダウンロードする
1つ目。まず初めに、公式サイトでアクションの使い方や説明をされているので、そちらを先にご覧になったほうが理解が深まると思います。
大まかな流れとしては、
- フォルダーのメタデータを取得
- フォルダーのリストを取得
- For eachでリストを反復処理
- アイテムのパスを使用してファイルコンテンツを取得
- 取得したコンテンツからバイナリデータをファイルに変換 (ローカルに保存)

パスによるフォルダー メタデータの取得
| パラメーター | 値 |
|---|---|
| サイトのアドレス | http://contoso.sharepoint.com/sites/sitename |
| フォルダーのパス | /Shared Documents/Reports |
| 生成された変数 | %GetFolderMetadataByPathResponse% |
フォルダーの一覧
| パラメーター | 値 |
|---|---|
| サイトのアドレス | %siteAddress% |
| フォルダーのパス | %GetFolderMetadataByPathResponse['Id']% |
| 生成された変数 | %ListFolderResponse% |
For each
| パラメーター | 値 |
|---|---|
| 反復処理を行う値 | %ListFolderResponse% |
| 保存先 | %CurrentItem% |
パスによるファイル コンテンツの取得
| パラメーター | 値 |
|---|---|
| サイトのアドレス | %siteAddress% |
| ファイル パス | %CurrentItem['Path']% |
| 生成された変数 | %GetFileContentByPathResponse% |
バイナリ データをファイルに変換
| パラメーター | 値 |
|---|---|
| バイナリ データ | %GetFileContentByPathResponse% |
| ファイル パス | %DownloadPath%\%CurrentItem['Name']% |
| ファイルが存在する場合 | 何もしない |
これで、フォルダー内のファイルが全部ダウンロードできました。
ただ、サブフォルダーがあった場合にエラーで止まってしまうので対処が必要です。
フォルダーにサブフォルダーが含まれている場合は
For eachで取り出したアイテムがフォルダーかどうか確認をして、フォルダーだったらダウンロード処理を行わないようにIf文で分岐をさせます。
ついでに、If文でフォルダーか確認した後でさらにIf文をネストしてサブフォルダー内のファイルもダウンロードするかどうか確認する。とか、この条件式を引数にするなどすると、いろいろ対応できるフローになって良いかな。と思います。

If
| パラメーター | 値 |
|---|---|
| 最初のオペランド | %CurrentItem['IsFolder']% |
| 演算子 | と等しい (=) |
| 2番目のオペランド | %True% |
パスによるフォルダー メタデータの取得
| パラメーター | 値 |
|---|---|
| サイトのアドレス | %siteAddress% |
| フォルダーのパス | %sitePath%/%CurrentItem['Name']% |
| 生成された変数 | %GetFolderMetadataByPathResponse% |
フォルダーの一覧
| パラメーター | 値 |
|---|---|
| サイトのアドレス | %siteAddress% |
| フォルダーのパス | %GetFolderMetadataByPathResponse['Id']% |
| 生成された変数 | %ListFolderResponse% |
For each
| パラメーター | 値 |
|---|---|
| 反復処理を行う値 | %ListFolderResponse% |
| 保存先 | %CurrentItem2% |
パスによるファイル コンテンツの取得
| パラメーター | 値 |
|---|---|
| サイトのアドレス | %siteAddress% |
| ファイル パス | %CurrentItem2['Path']% |
| 生成された変数 | %GetFileContentByPathResponse% |
バイナリ データをファイルに変換
| パラメーター | 値 |
|---|---|
| バイナリ データ | %GetFileContentByPathResponse% |
| ファイル パス | %DownloadPath%\%CurrentItem2['Name']% |
| ファイルが存在する場合 | 何もしない |
全体図
1つ目は完成です。

ファイルを指定してダウンロードする
2つ目。次は特定のアイテムだけダウンロードしたい場合です。ダウンロードしたいファイルのパスがわかっているなら、パスを使用してファイルコンテンツを取得 → バイナリデータをファイルに変換でOKです。
- パスを使用してファイル コンテンツを取得する
- バイナリデータをファイルに変換

ループ要らないですね。複数のファイルを取得したい場合は、同じフォルダー内だったらファイル名をリストで渡して、For each内に上の2つを配置するとか。別々のフォルダーだったらデータテーブルを使うとか。他にも、どこでループさせるかはいろいろあると思います。お好みで。
パスによるファイル コンテンツの取得
| パラメーター | 値 |
|---|---|
| サイトのアドレス | %siteAddress% |
| ファイル パス | %FilePath% |
| 生成された変数 | %GetFileContentByPathResponse% |
組み合わせた
ファイル名 なし → 全部ダウンロード。
ファイル名 あり → そのファイルだけダウンロード。
という感じにしてみました。

別々のフォルダーからダウンロードしたい場合は、このフローの呼び出し元でループを使って対応させるつもりです。
入出力変数はこんな風にしてみました
入力
| 変数名 | データの種類 | 外部名 | 説明 |
|---|---|---|---|
| DownloadPath | テキスト | in_DownloadPath | ファイルの保存先。 |
| isGetSubFolder | ブール値 | in_isGetSubFolder | サブフォルダーのファイルも取得するかどうか。 |
| FileNames | リスト | in_FileNames | ダウンロードするファイル名。リスト形式。 |
| SiteAddress | テキスト | in_SiteAddress | 例: https://contoso.sharepoint.com/sites/sitename |
| SitePath | テキスト | in_SitePath | 例: /Shared Documents/○○ |
これでダウンロード処理は完成です。
SharePoint にローカル ファイルをアップロードする方法
続いてアップロードです。SharePointにアップロードするときは逆に、ファイルをバイナリデータに変換すれば良いわけですね。ダウンロード処理が出来たらアップロードは特筆すべき点もなく完成させられると思います。


説明に関係しない部分ですが、「Windows環境変数を取得」で取得したOneDriveのルートパスと、ソースファイルのディレクトリを繋げたものを %OneDriveFullPath% に入れています。
入出力変数の例
入力
| 変数名 | データの種類 | 外部名 | 説明 |
|---|---|---|---|
| FileNames | リスト | in_FileNames | アップロードするファイル名。リスト形式。 |
| SiteAddress | テキスト | in_SiteAddress | 例: https://contoso.sharepoint.com/sites/sitename |
| SitePath | テキスト | in_SitePath | 例: /Shared Documents/○○ |
| UploadPath | テキスト | in_UploadPath | アップロードフォルダーのパス。 |
アップロード処理も出来ました。
感想
わかってしまえば、なるほど。。。という感想で。「保存」するのに「変換」アクションを使うなど誰が思いつくか。いやまあ…………そうなるのか。。。勉強になりました。
参考
Discussion