やりたいこと
sharepoint online上にあるドキュメントライブラリに格納されたファイルに対して、
サーバからプログラムでファイル操作する、という実装を作ったんですが、
人によって書いてあることがまちまちで結構嵌ったので出来上がった結果をメモしておきます。
処理内容は以下の通りです。
・sharepoint上に特定のファイルがあるかどうかを判定する
・sharepoint上の特定のファイルをサーバにダウンロードする
・サーバ上の特定のファイルをsharepoint上に名前を変えてアップロードする
・sharepoint上の特定のファイルを削除する
事前準備
sharepoint用のAPIが必要になるので、MSのサイトからCSOMをダウンロードし、サーバにインストールします。
参考:https://blogs.technet.microsoft.com/sharepoint_support/2017/12/20/tips-for-csom-on-powershell/
今回の作業ではNuget版のMicrosoft.SharepointOnline.CSOMをインストールしています。
作業環境
sharepointのサイトurl: http://hogehoge.com/sites/FUGA
ドキュメントライブラリ名: DocLib
ドキュメントライブラリ内のフォルダ: Folder1
サーバ側のフォルダ: D:\FUGA\Folder1
対象ファイル: File1.txt
共通手順:CSOMのロードとsharepointへの認証
インストールしたCSOMのロードとSharepointへの認証はどの処理でも共通の手順になります。
処理完了後は$Context.Dispose()
で〆るようにしましょう
# SharepointOnline用のCSOMをロードする
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client") > $null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime") > $null
$UserName = "<SharepointUser>"
$Password = ConvertTo-SecureString "<SharepointPassword>" -AsPlainText -Force
$SiteURL = "http://hogehoge.com/sites/FUGA"
# 認証
$credential = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $Password)
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Context.Credentials = $credential
$objWeb = $Context.Web
$Context.Load($objWeb)
$Context.ExecuteQuery()
SharepointPasswordは実際のパスワードではなく暗号化された文字列(SecureStirng)です。
ConvertTo-SecureStringを使ってプログラム内で復号しています。
以下の記事に手順は詳しいのでそちらを参照して頂ければ。
参考:https://qiita.com/Takeru/items/c8c769f88e8ccb06ffe3
上記処理を流した後に用途に応じて以下の処理を流します。
sharepoint上に特定のファイルがあるかどうかを判定する
sharepointのドキュメントライブラリDocLib上にFolder1/File1.txtが存在しているかを確認します。
$SPOLib = "DocLib"
$SPOPath = "Folder1"
$FileName = "File1.txt"
# sharepoint上のファイルは以下のような形で表す事ができる
$SPOFile = $objWeb.ServerRelativeUrl + "/" + $SPOLib + "/" + $SPOPath + "/" + $FileName
Try {
$Check = $Context.Web.GetFileByServerRelativeUrl($SPOFile)
$Context.Load($Check)
$Context.ExecuteQuery()
}
Catch {
Write-Output "File NOT exist on Sharepoint.: $FileName"
$Context.Dispose()
exit 0
}
Write-Output "File exists on Sharepoint.: $FileName"
$Context.Dispose()
exit 0
sharepoint上の特定のファイルをサーバにダウンロードする
sharepoint上のFolder1/File1.txtをサーバのE:\FUGA\Folder1にダウンロードします。
[System.IO.FileMode]::Create
は既存のファイルを消して再作成するモードなので
必要に応じて適切なモードなり事前チェックなりが必要です
# sharepointとローカルそれぞれのファイル格納先を指定
$SPOLib = "DocLib"
$SPOPath = "Folder1"
$Path = "E:\FUGA\Folder1"
$FileName = "File1.txt"
$SPOFile = $objWeb.ServerRelativeUrl + "/" + $SPOLib + "/" + $SPOPath + "/" + $FileName
$TargetFile = Join-Path $Path $FileName
# sharepoint上のファイルを開いてからローカルファイルの書き込みストリームを開き、データコピーを行う
$OpenFile = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($Context, $SPOFile)
$WriteStream = [System.IO.File]::Open($TargetFile,[System.IO.FileMode]::Create)
$OpenFile.Stream.CopyTo($WriteStream)
$WriteStream.Close()
$Context.Dispose()
exit 0
サーバ上の特定のファイルをsharepoint上に名前を変えてアップロードする
サーバ上のFile1.txtをDocLib上のFolder1/backupにFile1_Backup.txtとしてアップロードします。
対象フォルダやファイル名を変えて処理したい場合は以下のような形にすれば可能です。
# ドキュメントライブラリ上のアップロード先フォルダをロードする
$SPOLib = "DocLib"
$SPOPath = "Folder1"
$UploadFolder = $SPOLib + "/" + $SPOPath + "/backup"
$Ufolder = $objWeb.GetFolderByServerRelativeUrl($objWeb.ServerRelativeUrl + $UploadFolder)
$Context.Load($Ufolder)
$Context.ExecuteQuery()
# ローカルサーバ側のアップロード元ファイルを定義
$Path = "E:\FUGA\Folder1"
$FileName = "File1.txt"
$TargetFile = Join-Path $Path $FileName
$LocalFile = Get-ChildItem $TargetFile
# sharepoint側のファイルストリームを開いてファイルをアップロード(Overwriteは必要に応じて変更)
$FileStream = New-Object System.IO.FileStream($LocalFile,[System.IO.FileMode]::Open)
$FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
$FileCreationInfo.Overwrite = $true
$FileCreationInfo.ContentStream = $FileStream
$BackupName = (Get-ChildItem $TargetFile).BaseName + "_" + (Get-ChildItem $TargetFile).Extension
$FileCreationInfo.Url = $BackupName
$UpLoad = $UFolder.Files.Add($FileCreationInfo)
$Context.Load($UpLoad)
$Context.ExecuteQuery()
$FileStream.Close()
$Context.Dispose()
exit 0
sharepoint上の特定のファイルを削除する
DocLib上のFolder1/File1.txtを削除します。ファイルのみ削除し、フォルダは削除しません。
$SPOLib = "DocLib"
$SPOPath = "Folder1"
$FileName = "File1.txt"
$DelFilePath = $SPOLib + "/" + $SPOPath
$DelFile = $objWeb.GetFolderByServerRelativeUrl($objWeb.ServerRelativeUrl + $DelFilePath + "/" + $FileName)
# Delete File
$DelFile.DeleteObject()
$Context.ExecuteQuery()
exit 0
ごちゃっとした記事ですが初投稿ということで多めに見ていただければ。