/// <summary> /// サイトを削除 /// </summary> /// <param name="siteConnectionInfo">サイト接続情報(削除対象の親を指定すること)</param> /// <param name="webUrl">サイトURL(削除対象を指定すること)</param> /// <param name="progress">進捗報告オブジェクト</param> public static async Task <bool> DeleteSiteAsync(SiteConnectionInfo siteConnectionInfo, string webUrl, IProgress <string> progress = null) { bool ret = false; progress?.Report("サイト接続開始"); using (var ctx = new ClientContext(siteConnectionInfo.WebAbsoluteUrl)) { // 認証 ctx.Credentials = new SharePointOnlineCredentials(siteConnectionInfo.UserAccount, siteConnectionInfo.UserSecurePassword); ctx.RequestTimeout = Timeout.Infinite; // サイト取得 Web web = ctx.Web; progress?.Report("サイト削除"); // サイト削除 ret = web.DeleteWeb(webUrl); ctx.Load(web); await ctx.ExecuteQueryRetryAsync(); } progress?.Report("サイト接続終了"); return(ret); }
/// <summary> /// サイトを作成 /// </summary> /// <param name="siteConnectionInfo">サイト接続情報</param> /// <param name="siteInfo">サイト作成情報</param> /// <param name="progress">進捗報告オブジェクト</param> /// <returns>サイト情報</returns> public static async Task <SiteInfo> CreateSiteAsync(SiteConnectionInfo siteConnectionInfo, SiteInfo siteInfo, IProgress <string> progress = null) { SiteInfo ret; progress?.Report("サイト接続開始"); using (var ctx = new ClientContext(siteConnectionInfo.WebAbsoluteUrl)) { // 認証 ctx.Credentials = new SharePointOnlineCredentials(siteConnectionInfo.UserAccount, siteConnectionInfo.UserSecurePassword); ctx.RequestTimeout = Timeout.Infinite; // サイト取得 Web web = ctx.Web; // サイト作成 progress?.Report("サイト作成"); var createdWeb = web.CreateWeb( new SiteEntity() { Title = siteInfo.Title, Url = siteInfo.Url, SiteOwnerLogin = siteInfo.SiteOwnerLogin, Template = siteInfo.Template, StorageMaximumLevel = siteInfo.StorageMaximumLevel, UserCodeMaximumLevel = 0, Lcid = siteInfo.Lcid, TimeZoneId = siteInfo.TimeZoneId }, true, true ); ctx.Load(web); ctx.Load(createdWeb); ctx.Load(createdWeb.RegionalSettings); ctx.Load(createdWeb.RegionalSettings.TimeZone); await ctx.ExecuteQueryRetryAsync(); // 詰め替え ret = new SiteInfo() { Title = createdWeb.Title, Url = createdWeb.Url, Template = createdWeb.WebTemplate, Lcid = createdWeb.RegionalSettings.CollationLCID, TimeZoneId = createdWeb.RegionalSettings.TimeZone.Id }; } progress?.Report("サイト接続終了"); return(ret); }
/// <summary> /// サイトを取得 /// </summary> /// <param name="siteConnectionInfo">サイト接続情報</param> /// <param name="recursive">サブサイトを再帰的に取得するか否か(既定値:false)</param> /// <param name="progress">進捗報告オブジェクト</param> /// <returns>サイト情報</returns> public static async Task <SiteInfo> GetSiteAsync(SiteConnectionInfo siteConnectionInfo, bool recursive = false, IProgress <string> progress = null) { SiteInfo ret; progress?.Report("サイト接続開始"); using (var ctx = new ClientContext(siteConnectionInfo.WebAbsoluteUrl)) { // 認証 ctx.Credentials = new SharePointOnlineCredentials(siteConnectionInfo.UserAccount, siteConnectionInfo.UserSecurePassword); ctx.RequestTimeout = Timeout.Infinite; // サイト取得 progress?.Report("サイト取得"); Site site = ctx.Site; Web web = ctx.Web; ctx.Load(site); ctx.Load(site.Owner); ctx.Load(web); ctx.Load(web.RegionalSettings); ctx.Load(web.RegionalSettings.TimeZone); await ctx.ExecuteQueryRetryAsync().ConfigureAwait(false); // 詰め替え ret = new SiteInfo() { Id = web.Id, Title = web.Title, Url = web.Url, SiteOwnerLogin = site.Owner.Email, Template = web.WebTemplate, StorageMaximumLevel = 0, Lcid = web.Language, TimeZoneId = web.RegionalSettings.TimeZone.Id }; // サブサイト取得 if (recursive) { ret.subSites = await GetSubSitesRecursiveAsync(ctx, web, recursive, progress).ConfigureAwait(false); } } progress?.Report("サイト接続終了"); return(ret); }
/// <summary> /// エンドポイント /// </summary> /// <param name="args">引数</param> static void Main(string[] args) { // ログ出力用メソッド名 string methodName = MethodBase.GetCurrentMethod().Name; // 開始ログ Log.Write(methodName, "PnPバッチ開始"); try { // 引数解析 AppArgs appArgs = new AppArgs(args); Log.Write(methodName, appArgs.LogMsg.ToArray()); // 処理 if (appArgs.Retrived) { // サイト情報 var site = new SiteConnectionInfo(appArgs.SiteUrl, appArgs.Account, appArgs.Password); // 保存先 var template = new FileSystemConnectionInfo(appArgs.FolderPath, appArgs.FileName); // 進捗報告 var progress = new Progress <string>((log) => { Log.Write(methodName, log); }); // 実行 var task = (appArgs.Mode == AppArgs.MODE.GET)? PnPUtility.SaveSiteAsProvisioningTemplateAsync(site, template, progress) : PnPUtility.ApplyProvisioningTemplateAsync(site, template, progress); task.ConfigureAwait(false); task.Wait(); } } catch (Exception ex) { var message = (ex.InnerException != null) ? ex.InnerException : ex; Log.Write(methodName, message); } // 終了ログ Log.Write(methodName, "PnPバッチ終了"); }
/// <summary> /// サブサイトを取得 /// </summary> /// <param name="siteConnectionInfo">サイト接続情報</param> /// <param name="recursive">サブ-サブサイトを再帰的に取得するか否か(既定値:false)</param> /// <param name="progress">進捗報告オブジェクト</param> /// <returns>サイト情報一覧</returns> public static async Task <List <SiteInfo> > GetSubSitesAsync(SiteConnectionInfo siteConnectionInfo, bool recursive = false, IProgress <string> progress = null) { List <SiteInfo> ret; progress?.Report("サイト接続開始"); using (var ctx = new ClientContext(siteConnectionInfo.WebAbsoluteUrl)) { // 認証 ctx.Credentials = new SharePointOnlineCredentials(siteConnectionInfo.UserAccount, siteConnectionInfo.UserSecurePassword); ctx.RequestTimeout = Timeout.Infinite; // サブサイト取得 progress?.Report("サブサイト取得"); Web web = ctx.Web; ctx.Load(web); ret = await GetSubSitesRecursiveAsync(ctx, web, recursive, progress); } progress?.Report("サイト接続終了"); return(ret); }
/// <summary> /// 既存サイトの定義をテンプレートとして取得 /// </summary> /// <param name="siteConnectionInfo">SharePointサイト接続情報</param> /// <param name="templateSaveInfo">テンプレート保管場所情報</param> /// <param name="progress">進捗報告オブジェクト</param> /// <returns>サイト定義(XML)</returns> public static async Task <string> SaveSiteAsProvisioningTemplateAsync(SiteConnectionInfo siteConnectionInfo, IConnectionInfo templateSaveInfo, IProgress <string> progress = null) { // 戻り値 string ret; progress?.Report("テンプレート取得開始"); using (var ctx = new ClientContext(siteConnectionInfo.WebAbsoluteUrl)) { #region SharePointサイトに接続 progress?.Report($"1/3 SharePointサイトに接続"); ctx.Credentials = new SharePointOnlineCredentials(siteConnectionInfo.UserAccount, siteConnectionInfo.UserSecurePassword); ctx.RequestTimeout = Timeout.Infinite; var web = ctx.Web; ctx.Load(web, w => w.Title); await ctx.ExecuteQueryRetryAsync().ConfigureAwait(false); #endregion #region テンプレートを取得 // テンプレート取得オプション var creationInfo = new ProvisioningTemplateCreationInformation(ctx.Web) { // 進捗報告 ProgressDelegate = delegate(String pnpMessage, Int32 pnpProgress, Int32 pnpTotal) { progress?.Report($"2/3 テンプレートを取得 - {pnpProgress}/{pnpTotal} {pnpMessage}"); }, // ロゴ等のファイル依存ファイル出力先 FileConnector = templateSaveInfo.GetConnector(persistFilesPath), // ブランディング用ファイルを含める(テーマ/ロゴ/代替CSSなど) PersistBrandingFiles = true, // マスターページ/ページレイアウトを含む IncludeNativePublishingFiles = true, // 検索設定を含む IncludeSearchConfiguration = true, // 用語ストアを含む IncludeSiteCollectionTermGroup = true, // SharePointグループを含む IncludeSiteGroups = true, // 用語セットを含める IncludeAllTermGroups = true, // 用語セットの権限を含める IncludeTermGroupsSecurity = true, // 隠しリストを含める IncludeHiddenLists = true, // 「ページ」ライブラリ内の全ページを含める IncludeAllClientSidePages = true, // 発行ファイル(マスターページ/ページレイアウトなど)を含む PersistPublishingFiles = true }; // テンプレート取得 var template = ctx.Web.GetProvisioningTemplate(creationInfo); progress?.Report($"2/3 テンプレートを取得 - 完了"); ret = template.ToXML(); // テンプレート保存 progress?.Report($"3/3 テンプレートを保存:{ templateSaveInfo.FileIdentifer }"); templateSaveInfo.GetConnector().SaveFileStream(templateSaveInfo.FileIdentifer, new MemoryStream(Encoding.UTF8.GetBytes(ret))); #endregion } progress?.Report("テンプレート取得終了"); // 返却 return(ret); }
/// <summary> /// 保管済テンプレートを既存サイトに適用 /// </summary> /// <param name="siteConnectionInfo">SharePointサイト接続情報</param> /// <param name="templateGetInfo">テンプレート保管場所情報</param> /// <param name="progress">進捗報告オブジェクト</param> /// <returns>無し</returns> public static async Task ApplyProvisioningTemplateAsync(SiteConnectionInfo siteConnectionInfo, IConnectionInfo templateGetInfo, IProgress <string> progress = null) { progress?.Report("テンプレート適用開始"); using (var ctx = new ClientContext(siteConnectionInfo.WebAbsoluteUrl)) { #region SharePointサイトに接続 progress?.Report($"1/3 SharePointサイトに接続"); ctx.Credentials = new SharePointOnlineCredentials(siteConnectionInfo.UserAccount, siteConnectionInfo.UserSecurePassword); ctx.RequestTimeout = Timeout.Infinite; var web = ctx.Web; ctx.Load(web, w => w.Title); await ctx.ExecuteQueryRetryAsync(); #endregion #region テンプレートを取得 ProvisioningTemplate template = GetProvisioningTemplate(templateGetInfo); progress?.Report($"2/3 テンプレートを取得:{ templateGetInfo.FileIdentifer }"); #endregion #region テンプレートを適用 // テンプレート適用オプション var applyingInfo = new ProvisioningTemplateApplyingInformation() { // 進捗報告 ProgressDelegate = delegate(String pnpMessage, Int32 pnpProgress, Int32 pnpTotal) { progress?.Report($"3/3 テンプレートを適用 - {pnpProgress}/{pnpTotal} {pnpMessage}"); }, // 詳細な報告 MessagesDelegate = (string msg, ProvisioningMessageType type) => { switch (type) { case ProvisioningMessageType.Warning: progress?.Report($"[Warning] {msg}"); break; case ProvisioningMessageType.Error: progress?.Report($"[Error] {msg}"); throw new Exception(msg); case ProvisioningMessageType.EasterEgg: progress?.Report($"[EasterEgg] {msg}"); throw new Exception(msg); case ProvisioningMessageType.Progress: var msgs = msg?.Split('|'); if (msgs?.Length == 4) { progress?.Report($"[Progress] {msgs[0]} {msgs[2]}/{msgs[3]} {msgs[1]}"); } else { progress?.Report($"[Progress] {msg}"); } break; case ProvisioningMessageType.Completed: progress?.Report($"[Completed] {msg}"); break; default: break; } }, // 既存ナビゲーションをクリアする ClearNavigation = true, // テンプレート情報を維持する PersistTemplateInfo = true }; // テンプレート適用 ctx.Web.ApplyProvisioningTemplate( template, applyingInfo); progress?.Report($"3/3 テンプレートを適用 - 完了"); #endregion } progress?.Report("テンプレート適用終了"); }
/// <summary> /// テンプレート取得実行 /// </summary> private async Task DoGet(Dispatcher d) { try { // 保存先を選択 var fileName = $"Template_{ DateTime.Now.ToString("yyyyMMddHHmmss") }.xml"; var dialog = new SaveFileDialog() { Title = "保存先の選択", Filter = $"XML(*.xml)|*.xml", FileName = fileName, OverwritePrompt = true }; // 取得を実行 if (dialog.ShowDialog() == true) { // ログタブに切り替え await d.Execute(() => { _vm.LogTabSelected = true; }, true).ConfigureAwait(false); // サイト情報 var site = new SiteConnectionInfo(_vm.SelectedSite.URL, _vm.Tenant.UserAccount, _vm.Tenant.UserPassword); // 保存先 var template = new FileSystemConnectionInfo(Path.GetDirectoryName(dialog.FileName), Path.GetFileName(dialog.FileName)); // ログ var progress = new Progress <string>(WriteLog); // テンプレート取得 var task = PnPUtility.SaveSiteAsProvisioningTemplateAsync(site, template, progress); await task; if (task.Exception == null) { // テンプレート取得終了 await d.Execute(() => { _vm.IsGetting = false; }, true).ConfigureAwait(false); } else { // テンプレート取得終了 await d.Execute(() => { _vm.IsGetting = false; }, true).ConfigureAwait(false); MessageBox.Show($"テンプレート取得に失敗しました。\r\n{ task.Exception.InnerException?.Message?.ToString() }"); } } else { // テンプレート取得終了 await d.Execute(() => { _vm.IsGetting = false; }, true).ConfigureAwait(false); } } catch (Exception ex) { // テンプレート取得終了 await d.Execute(() => { _vm.IsGetting = false; }, true).ConfigureAwait(false); var message = (ex.InnerException != null) ? ex.InnerException.Message : ex.Message; MessageBox.Show($"テンプレート取得に失敗しました。\r\n{ message }"); } }
/// <summary> /// 検索実行 /// </summary> private async Task DoSearch(Dispatcher d) { try { // テンプレートを選択 var dialog = new OpenFileDialog() { Title = "テンプレートファイルの選択", Multiselect = false, Filter = $"XML(*.xml)|*.xml" }; // 取得を実行 if (dialog.ShowDialog() == true) { // ログタブに切り替え await d.Execute(() => { _vm.LogTabSelected = true; }, true).ConfigureAwait(false); // サイト情報 var site = new SiteConnectionInfo(_vm.SelectedSite.URL, _vm.Tenant.UserAccount, _vm.Tenant.UserPassword); // テンプレート var template = new FileSystemConnectionInfo(Path.GetDirectoryName(dialog.FileName), Path.GetFileName(dialog.FileName)); // ログ var progress = new Progress <string>(WriteLog); // テンプレート適用 var task = PnPUtility.ApplyProvisioningTemplateAsync(site, template, progress); await task; if (task.Exception == null) { // テンプレート取得終了 await d.Execute(() => { _vm.IsApplying = false; }, true).ConfigureAwait(false); } else { // テンプレート取得終了 await d.Execute(() => { _vm.IsApplying = false; }, true).ConfigureAwait(false); MessageBox.Show($"テンプレート取得に失敗しました。\r\n{ task.Exception.InnerException?.Message?.ToString() }"); } } else { // テンプレート取得終了 await d.Execute(() => { _vm.IsApplying = false; }, true).ConfigureAwait(false); } } catch (Exception ex) { // テンプレート取得終了 await d.Execute(() => { _vm.IsApplying = false; }, true).ConfigureAwait(false); var message = (ex.InnerException != null) ? ex.InnerException.Message : ex.Message; MessageBox.Show($"テンプレート取得に失敗しました。\r\n{ message }"); } }