public static Guid AddSiteCollectionTenant(this Web web, SiteEntity properties) { Tenant tenant = new Tenant(web.Context); SiteCreationProperties newsite = new SiteCreationProperties(); newsite.Url = properties.Url; newsite.Owner = properties.SiteOwnerLogin; newsite.Template = properties.Template; newsite.Title = properties.Title; newsite.StorageMaximumLevel = properties.StorageMaximumLevel; newsite.StorageWarningLevel = properties.StorageWarningLevel; newsite.TimeZoneId = properties.TimeZoneId; newsite.UserCodeMaximumLevel = properties.UserCodeMaximumLevel; newsite.UserCodeWarningLevel = properties.UserCodeWarningLevel; newsite.Lcid = properties.Lcid; try { SpoOperation op = tenant.CreateSite(newsite); web.Context.Load(tenant); web.Context.Load(op, i => i.IsComplete, i => i.PollingInterval); web.Context.ExecuteQuery(); //check if site creation operation is complete while (!op.IsComplete) { System.Threading.Thread.Sleep(op.PollingInterval); op.RefreshLoad(); if (!op.IsComplete) { try { web.Context.ExecuteQuery(); } catch (WebException webEx) { // Context connection gets closed after action completed. // Calling ExecuteQuery again returns an error which can be ignored LoggingUtility.LogWarning(MSG_CONTEXT_CLOSED, webEx, EventCategory.Site); } } } } catch(Exception ex) { // Eat the siteSubscription exception to make the same code work for MT as on-prem april 2014 CU+ if (ex.Message.IndexOf("Parameter name: siteSubscription") == -1) { throw ex; } } // Get site guid and return var siteGuid = web.GetSiteGuidByUrlTenant(new Uri(properties.Url)); return siteGuid; }
/// <summary> /// Adds a SiteEntity by launching site collection creation and waits for the creation to finish /// </summary> /// <param name="tenant">A tenant object pointing to the context of a Tenant Administration site</param> /// <param name="properties">Describes the site collection to be created</param> /// <param name="removeFromRecycleBin">It true and site is present in recycle bin, it will be removed first from the recycle bin</param> /// <param name="wait">If true, processing will halt until the site collection has been created</param> /// <returns>Guid of the created site collection and Guid.Empty is the wait parameter is specified as false</returns> public static Guid CreateSiteCollection(this Tenant tenant, SiteEntity properties, bool removeFromRecycleBin = false, bool wait = true) { if (removeFromRecycleBin) { if (tenant.CheckIfSiteExists(properties.Url, SITE_STATUS_RECYCLED)) { tenant.DeleteSiteCollectionFromRecycleBin(properties.Url); } } SiteCreationProperties newsite = new SiteCreationProperties(); newsite.Url = properties.Url; newsite.Owner = properties.SiteOwnerLogin; newsite.Template = properties.Template; newsite.Title = properties.Title; newsite.StorageMaximumLevel = properties.StorageMaximumLevel; newsite.StorageWarningLevel = properties.StorageWarningLevel; newsite.TimeZoneId = properties.TimeZoneId; newsite.UserCodeMaximumLevel = properties.UserCodeMaximumLevel; newsite.UserCodeWarningLevel = properties.UserCodeWarningLevel; newsite.Lcid = properties.Lcid; try { SpoOperation op = tenant.CreateSite(newsite); tenant.Context.Load(tenant); tenant.Context.Load(op, i => i.IsComplete, i => i.PollingInterval); tenant.Context.ExecuteQuery(); if (wait) { WaitForIsComplete(tenant, op); } } catch (Exception ex) { // Eat the siteSubscription exception to make the same code work for MT as on-prem April 2014 CU+ if (ex.Message.IndexOf("Parameter name: siteSubscription") == -1) { throw; } } // Get site guid and return. If we create the site asynchronously, return an empty guid as we cannot retrieve the site by URL yet. Guid siteGuid = Guid.Empty; if (wait) { siteGuid = tenant.GetSiteGuidByUrl(new Uri(properties.Url)); } return siteGuid; }
/// <summary> /// Adds a SiteEntity by launching site collection creation and waits for the creation to finish /// </summary> /// <param name="tenant">A tenant object pointing to the context of a Tenant Administration site</param> /// <param name="properties">Describes the site collection to be created</param> /// <param name="removeFromRecycleBin">It true and site is present in recycle bin, it will be removed first from the recycle bin</param> /// <param name="wait">If true, processing will halt until the site collection has been created</param> /// <returns>Guid of the created site collection and Guid.Empty is the wait parameter is specified as false</returns> public static Guid CreateSiteCollection(this Tenant tenant, SiteEntity properties, bool removeFromRecycleBin = false, bool wait = true) { if (removeFromRecycleBin) { if (tenant.CheckIfSiteExists(properties.Url, SITE_STATUS_RECYCLED)) { tenant.DeleteSiteCollectionFromRecycleBin(properties.Url); } } SiteCreationProperties newsite = new SiteCreationProperties(); newsite.Url = properties.Url; newsite.Owner = properties.SiteOwnerLogin; newsite.Template = properties.Template; newsite.Title = properties.Title; newsite.StorageMaximumLevel = properties.StorageMaximumLevel; newsite.StorageWarningLevel = properties.StorageWarningLevel; newsite.TimeZoneId = properties.TimeZoneId; newsite.UserCodeMaximumLevel = properties.UserCodeMaximumLevel; newsite.UserCodeWarningLevel = properties.UserCodeWarningLevel; newsite.Lcid = properties.Lcid; SpoOperation op = tenant.CreateSite(newsite); tenant.Context.Load(tenant); tenant.Context.Load(op, i => i.IsComplete, i => i.PollingInterval); tenant.Context.ExecuteQueryRetry(); // Get site guid and return. If we create the site asynchronously, return an empty guid as we cannot retrieve the site by URL yet. Guid siteGuid = Guid.Empty; if (wait) { // Let's poll for site collection creation completion WaitForIsComplete(tenant, op); // Add delay to avoid race conditions Thread.Sleep(30 * 1000); // Return site guid of created site collection siteGuid = tenant.GetSiteGuidByUrl(new Uri(properties.Url)); } return siteGuid; }
protected override void ExecuteCmdlet() { #if ONPREMISES var entity = new SiteEntity(); entity.Url = Url; entity.Title = Title; entity.SiteOwnerLogin = Owner; entity.Template = Template; entity.StorageMaximumLevel = StorageQuota; entity.StorageWarningLevel = StorageQuotaWarningLevel; entity.TimeZoneId = TimeZone; entity.UserCodeMaximumLevel = ResourceQuota; entity.UserCodeWarningLevel = ResourceQuotaWarningLevel; entity.Lcid = Lcid; Tenant.CreateSiteCollection(entity); #else Tenant.CreateSiteCollection(Url, Title, Owner, Template, (int)StorageQuota, (int)StorageQuotaWarningLevel, TimeZone, (int)ResourceQuota, (int)ResourceQuotaWarningLevel, Lcid, RemoveDeletedSite, Wait); #endif }
public static Guid AddSiteCollection(this Tenant tenant, string siteFullUrl, string title, string siteOwnerLogin, string template, int storageMaximumLevel, int storageWarningLevel, int timeZoneId, int userCodeMaximumLevel, int userCodeWarningLevel, uint lcid, bool removeFromRecycleBin = false, bool wait = true) { SiteEntity siteCol = new SiteEntity() { Url = siteFullUrl, Title = title, SiteOwnerLogin = siteOwnerLogin, Template = template, StorageMaximumLevel = storageMaximumLevel, StorageWarningLevel = storageWarningLevel, TimeZoneId = timeZoneId, UserCodeMaximumLevel = userCodeMaximumLevel, UserCodeWarningLevel = userCodeWarningLevel, Lcid = lcid }; return tenant.CreateSiteCollection(siteCol, removeFromRecycleBin, wait); }
public static void CreateSubTeamSite(ClientContext ctx, string sitename, string siteurl) { var site = new OfficeDevPnP.Core.Entities.SiteEntity() { Title = sitename, Url = siteurl, Description = "Site creating for testing purpose", Template = "STS#0", Lcid = 1033 }; if (!ctx.Web.WebExistsByTitle(sitename)) { ctx.Web.CreateWeb(site, true, true); Console.WriteLine("Creating New Subsite"); } else { Console.WriteLine("Site Already exists"); } }
/// <summary> /// Adds a SiteEntity by launching site collection creation and waits for the creation to finish /// </summary> /// <param name="tenant">A tenant object pointing to the context of a Tenant Administration site</param> /// <param name="properties">Describes the site collection to be created</param> /// <param name="removeSiteFromRecycleBin">It true and site is present in recycle bin, it will be removed first from the recycle bin</param> /// <param name="wait">If true, processing will halt until the site collection has been created</param> /// <returns>Guid of the created site collection</returns> public static Guid CreateSiteCollection(this Tenant tenant, SiteEntity properties, bool removeFromRecycleBin = false, bool wait = true) { if (removeFromRecycleBin) { if (tenant.CheckIfSiteExists(properties.Url, SITE_STATUS_RECYCLED)) { tenant.DeleteSiteCollectionFromRecycleBin(properties.Url); } } SiteCreationProperties newsite = new SiteCreationProperties(); newsite.Url = properties.Url; newsite.Owner = properties.SiteOwnerLogin; newsite.Template = properties.Template; newsite.Title = properties.Title; newsite.StorageMaximumLevel = properties.StorageMaximumLevel; newsite.StorageWarningLevel = properties.StorageWarningLevel; newsite.TimeZoneId = properties.TimeZoneId; newsite.UserCodeMaximumLevel = properties.UserCodeMaximumLevel; newsite.UserCodeWarningLevel = properties.UserCodeWarningLevel; newsite.Lcid = properties.Lcid; try { SpoOperation op = tenant.CreateSite(newsite); tenant.Context.Load(tenant); tenant.Context.Load(op, i => i.IsComplete, i => i.PollingInterval); tenant.Context.ExecuteQuery(); if (wait) { //check if site creation operation is complete while (!op.IsComplete) { System.Threading.Thread.Sleep(op.PollingInterval); op.RefreshLoad(); if (!op.IsComplete) { try { tenant.Context.ExecuteQuery(); } catch (WebException webEx) { // Context connection gets closed after action completed. // Calling ExecuteQuery again returns an error which can be ignored LoggingUtility.Internal.TraceWarning((int)EventId.ClosedContextWarning, webEx, CoreResources.TenantExtensions_ClosedContextWarning); } } } } } catch (Exception ex) { // Eat the siteSubscription exception to make the same code work for MT as on-prem April 2014 CU+ if (ex.Message.IndexOf("Parameter name: siteSubscription") == -1) { throw; } } // Get site guid and return var siteGuid = tenant.GetSiteGuidByUrl(new Uri(properties.Url)); return siteGuid; }
private string CreateTestSiteCollection(Tenant tenant, string sitecollectionName) { string devSiteUrl = ConfigurationManager.AppSettings["SPODevSiteUrl"]; string siteToCreateUrl = GetTestSiteCollectionName(devSiteUrl, sitecollectionName); SiteEntity siteToCreate = new SiteEntity() { Url = siteToCreateUrl, Template = "STS#0", Title = "Test", Description = "Test site collection", SiteOwnerLogin = ConfigurationManager.AppSettings["SPOUserName"], }; tenant.CreateSiteCollection(siteToCreate, false, true); return siteToCreateUrl; }
/// <summary> /// Adds a SiteEntity by launching site collection creation and waits for the creation to finish /// </summary> /// <param name="tenant">A tenant object pointing to the context of a Tenant Administration site</param> /// <param name="properties">Describes the site collection to be created</param> public static void CreateSiteCollection(this Tenant tenant, SiteEntity properties) { SiteCreationProperties newsite = new SiteCreationProperties(); newsite.Url = properties.Url; newsite.Owner = properties.SiteOwnerLogin; newsite.Template = properties.Template; newsite.Title = properties.Title; newsite.StorageMaximumLevel = properties.StorageMaximumLevel; newsite.StorageWarningLevel = properties.StorageWarningLevel; newsite.TimeZoneId = properties.TimeZoneId; newsite.UserCodeMaximumLevel = properties.UserCodeMaximumLevel; newsite.UserCodeWarningLevel = properties.UserCodeWarningLevel; newsite.Lcid = properties.Lcid; try { tenant.CreateSite(newsite); tenant.Context.ExecuteQueryRetry(); } catch (Exception ex) { // Eat the siteSubscription exception to make the same code work for MT as on-prem April 2014 CU+ if (ex.Message.IndexOf("Parameter name: siteSubscription") == -1) { throw; } } }
/// <summary> /// Returns all site collections in the current Tenant /// </summary> /// <param name="tenant"></param> /// <returns></returns> public static IList<SiteEntity> GetSiteCollections(this Tenant tenant) { var sites = new List<SiteEntity>(); var props = tenant.GetSiteProperties(0, true); tenant.Context.Load(props); tenant.Context.ExecuteQuery(); foreach (var prop in props) { var siteEntity = new SiteEntity(); siteEntity.Lcid = prop.Lcid; siteEntity.SiteOwnerLogin = prop.Owner; siteEntity.StorageMaximumLevel = prop.StorageMaximumLevel; siteEntity.StorageWarningLevel = prop.StorageWarningLevel; siteEntity.Template = prop.Template; siteEntity.TimeZoneId = prop.TimeZoneId; siteEntity.Title = prop.Title; siteEntity.Url = prop.Url; siteEntity.UserCodeMaximumLevel = prop.UserCodeMaximumLevel; siteEntity.UserCodeWarningLevel = prop.UserCodeWarningLevel; siteEntity.CurrentResourceUsage = prop.CurrentResourceUsage; siteEntity.LastContentModifiedDate = prop.LastContentModifiedDate; siteEntity.StorageUsage = prop.StorageUsage; siteEntity.WebsCount = prop.WebsCount; sites.Add(siteEntity); } return sites; }
public static Web CreateSite(this Web web, SiteEntity subsite, bool inheritPermissions = true, bool inheritNavigation = true) { // Call actual implementation return CreateWeb(web, subsite.Title, subsite.Url, subsite.Description, subsite.Template, (int)subsite.Lcid, inheritPermissions, inheritNavigation); }
/// <summary> /// Get OneDrive site collections by iterating through all user profiles. /// </summary> /// <param name="tenant"></param> /// <returns>List of <see cref="SiteEntity"/> objects containing site collection info.</returns> public static IList<SiteEntity> GetOneDriveSiteCollections(this Tenant tenant) { var sites = new List<SiteEntity>(); var svcClient = GetUserProfileServiceClient(tenant); // get all user profiles var userProfileResult = svcClient.GetUserProfileByIndex(-1); var profileCount = svcClient.GetUserProfileCount(); while (int.Parse(userProfileResult.NextValue) != -1) { var personalSpaceProperty = userProfileResult.UserProfile.FirstOrDefault(p => p.Name == "PersonalSpace"); if (personalSpaceProperty != null) { if (personalSpaceProperty.Values.Any()) { var usernameProperty = userProfileResult.UserProfile.FirstOrDefault(p => p.Name == "UserName"); var nameProperty = userProfileResult.UserProfile.FirstOrDefault(p => p.Name == "PreferredName"); var url = personalSpaceProperty.Values[0].Value as string; var name = nameProperty.Values[0].Value as string; SiteEntity siteEntity = new SiteEntity(); siteEntity.Url = url; siteEntity.Title = name; siteEntity.SiteOwnerLogin = usernameProperty.Values[0].Value as string; sites.Add(siteEntity); } } userProfileResult = svcClient.GetUserProfileByIndex(int.Parse(userProfileResult.NextValue)); } return sites; }
private string CreateTestSiteCollection(Tenant tenant, string sitecollectionName) { string devSiteUrl = ConfigurationManager.AppSettings["SPODevSiteUrl"]; string siteOwnerLogin = string.Format("{0}\\{1}", ConfigurationManager.AppSettings["OnPremDomain"], ConfigurationManager.AppSettings["OnPremUserName"]); if (TestCommon.AppOnlyTesting()) { using (var clientContext = TestCommon.CreateClientContext()) { List<UserEntity> admins = clientContext.Web.GetAdministrators(); siteOwnerLogin = admins[0].LoginName.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries)[1]; } } string siteToCreateUrl = GetTestSiteCollectionName(devSiteUrl, sitecollectionName); SiteEntity siteToCreate = new SiteEntity() { Url = siteToCreateUrl, Template = "STS#0", Title = "Test", Description = "Test site collection", SiteOwnerLogin = siteOwnerLogin, }; tenant.CreateSiteCollection(siteToCreate); return siteToCreateUrl; }
/// <summary> /// Adds a SiteEntity by launching site collection creation and waits for the creation to finish /// </summary> /// <param name="tenant">A tenant object pointing to the context of a Tenant Administration site</param> /// <param name="properties">Describes the site collection to be created</param> /// <param name="removeFromRecycleBin">It true and site is present in recycle bin, it will be removed first from the recycle bin</param> /// <param name="wait">If true, processing will halt until the site collection has been created</param> /// <returns>Guid of the created site collection and Guid.Empty is the wait parameter is specified as false</returns> public static Guid CreateSiteCollection(this Tenant tenant, SiteEntity properties, bool removeFromRecycleBin = false, bool wait = true) { if (removeFromRecycleBin) { if (tenant.CheckIfSiteExists(properties.Url, SITE_STATUS_RECYCLED)) { tenant.DeleteSiteCollectionFromRecycleBin(properties.Url); } } SiteCreationProperties newsite = new SiteCreationProperties(); newsite.Url = properties.Url; newsite.Owner = properties.SiteOwnerLogin; newsite.Template = properties.Template; newsite.Title = properties.Title; newsite.StorageMaximumLevel = properties.StorageMaximumLevel; newsite.StorageWarningLevel = properties.StorageWarningLevel; newsite.TimeZoneId = properties.TimeZoneId; newsite.UserCodeMaximumLevel = properties.UserCodeMaximumLevel; newsite.UserCodeWarningLevel = properties.UserCodeWarningLevel; newsite.Lcid = properties.Lcid; SpoOperation op = tenant.CreateSite(newsite); tenant.Context.Load(tenant); tenant.Context.Load(op, i => i.IsComplete, i => i.PollingInterval); tenant.Context.ExecuteQueryRetry(); // Get site guid and return. If we create the site asynchronously, return an empty guid as we cannot retrieve the site by URL yet. Guid siteGuid = Guid.Empty; if (wait) { // Let's poll for site collection creation completion WaitForIsComplete(tenant, op); // Add delay to avoid race conditions Thread.Sleep(30 * 1000); // Return site guid of created site collection try { siteGuid = tenant.GetSiteGuidByUrl(new Uri(properties.Url)); } catch(Exception ex) { // Eat all exceptions cause there's currently (December 16) an issue in the service that can make this call fail in combination with app-only usage Log.Error("Temp eating exception to issue in service (December 2016). Exception is {0}.", ex.ToDetailedString()); } } return siteGuid; }
public void SubSiteExistsTest() { using (var tenantContext = TestCommon.CreateTenantClientContext()) { var tenant = new Tenant(tenantContext); string devSiteUrl = ConfigurationManager.AppSettings["SPODevSiteUrl"]; Console.WriteLine("SubSiteExistsTest: step 1"); string siteToCreateUrl = CreateTestSiteCollection(tenant, sitecollectionName); Console.WriteLine("SubSiteExistsTest: step 1.1"); string subSiteUrlGood = ""; string subSiteUrlWrong = ""; Site site = tenant.GetSiteByUrl(siteToCreateUrl); tenant.Context.Load(site); tenant.Context.ExecuteQueryRetry(); Web web = site.RootWeb; web.Context.Load(web); web.Context.ExecuteQueryRetry(); Console.WriteLine("SubSiteExistsTest: step 1.2"); //Create sub site SiteEntity sub = new SiteEntity() { Title = "Test Sub", Url = "sub", Description = "Test" }; web.CreateWeb(sub); siteToCreateUrl = UrlUtility.EnsureTrailingSlash(siteToCreateUrl); subSiteUrlGood = String.Format("{0}{1}", siteToCreateUrl, sub.Url); subSiteUrlWrong = String.Format("{0}{1}", siteToCreateUrl, "8988980"); // Check real sub site Console.WriteLine("SubSiteExistsTest: step 2"); bool subSiteExists = tenant.SubSiteExists(subSiteUrlGood); Console.WriteLine("SubSiteExistsTest: step 2.1"); Assert.IsTrue(subSiteExists); // check non existing sub site Console.WriteLine("SubSiteExistsTest: step 3"); bool subSiteExists2 = tenant.SubSiteExists(subSiteUrlWrong); Console.WriteLine("SubSiteExistsTest: step 3.1"); Assert.IsFalse(subSiteExists2); // check root site (= site collection). Will return true when existing Console.WriteLine("SubSiteExistsTest: step 4"); bool subSiteExists3 = tenant.SubSiteExists(siteToCreateUrl); Console.WriteLine("SubSiteExistsTest: step 4.1"); Assert.IsTrue(subSiteExists3); // check root site (= site collection) that does not exist. Will return false when non-existant Console.WriteLine("SubSiteExistsTest: step 5"); bool subSiteExists4 = tenant.SubSiteExists(siteToCreateUrl + "8808809808"); Console.WriteLine("SubSiteExistsTest: step 5.1"); Assert.IsFalse(subSiteExists4); } }
/// <summary> /// Launches a site collection creation and waits for the creation to finish /// </summary> /// <param name="web">Context to admin site</param> /// <param name="url">The SPO url</param> /// <param name="title">The site title</param> /// <param name="siteOwnerLogin">Owner account</param> /// <param name="template">Site template being used</param> /// <param name="storageMaximumLevel">Site quota in MB</param> /// <param name="storageWarningLevel">Site quota warning level in MB</param> /// <param name="timeZoneId">TimeZoneID for the site. "(UTC+01:00) Brussels, Copenhagen, Madrid, Paris" = 3 </param> /// <param name="userCodeMaximumLevel">The user code quota in points</param> /// <param name="userCodeWarningLevel">The user code quota warning level in points</param> /// <param name="lcid">The site locale. See http://technet.microsoft.com/en-us/library/ff463597.aspx for a complete list of Lcid's</param> /// <returns></returns> public static Guid CreateSiteCollectionTenant(this Web web, string url, string title, string siteOwnerLogin, string template, int storageMaximumLevel, int storageWarningLevel, int timeZoneId, int userCodeMaximumLevel, int userCodeWarningLevel, uint lcid) { SiteEntity siteCol = new SiteEntity() { Url = url, Title = title, SiteOwnerLogin = siteOwnerLogin, Template = template, StorageMaximumLevel = storageMaximumLevel, StorageWarningLevel = storageWarningLevel, TimeZoneId = timeZoneId, UserCodeMaximumLevel = userCodeMaximumLevel, UserCodeWarningLevel = userCodeWarningLevel, Lcid = lcid }; return AddSiteCollectionTenant(web, siteCol); }
/// <summary> /// Adds a sub site to an existing site /// </summary> /// <param name="web">Site to be processed - can be root web or sub site</param> /// <param name="parent">Information about the parent site</param> /// <param name="subsite">Information describing the sub site to be added</param> /// <param name="inheritPermissions">Does the sub site inherit the permissions of the parent site</param> /// <param name="inheritNavigation">Does the sub site inherit the navigation of the parent site</param> public static void AddSite(this Web web, SiteEntity parent, SiteEntity subsite, bool inheritPermissions, bool inheritNavigation) { // Call actual implementation CreateSite(web, subsite, inheritPermissions, inheritNavigation); }
private string CreateTestSiteCollection(Tenant tenant, string sitecollectionName) { try { string devSiteUrl = ConfigurationManager.AppSettings["SPODevSiteUrl"]; string siteToCreateUrl = GetTestSiteCollectionName(devSiteUrl, sitecollectionName); string siteOwnerLogin = ConfigurationManager.AppSettings["SPOUserName"]; if (TestCommon.AppOnlyTesting()) { using (var clientContext = TestCommon.CreateClientContext()) { List<UserEntity> admins = clientContext.Web.GetAdministrators(); siteOwnerLogin = admins[0].LoginName.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries)[2]; } } SiteEntity siteToCreate = new SiteEntity() { Url = siteToCreateUrl, Template = "STS#0", Title = "Test", Description = "Test site collection", SiteOwnerLogin = siteOwnerLogin, }; Console.WriteLine(String.Format("!!Before creating site collection {0}", siteToCreateUrl)); tenant.CreateSiteCollection(siteToCreate, false, true); Console.WriteLine(String.Format("!!Site collection created {0}", siteToCreateUrl)); return siteToCreateUrl; } catch (Exception ex) { Console.WriteLine(ex.ToString()); throw; } }
public static Guid AddSiteCollection(this Tenant tenant, SiteEntity properties, bool removeFromRecycleBin = false, bool wait = true) { return tenant.CreateSiteCollection(properties, removeFromRecycleBin, wait); }
/// <summary> /// Returns all site collections in the current Tenant based on a startIndex. IncludeDetail adds additional properties to the SPSite object. /// </summary> /// <param name="tenant">Tenant object to operate against</param> /// <param name="startIndex">Not relevant anymore</param> /// <param name="endIndex">Not relevant anymore</param> /// <param name="includeDetail">Option to return a limited set of data</param> /// <returns>An IList of SiteEntity objects</returns> public static IList<SiteEntity> GetSiteCollections(this Tenant tenant, int startIndex = 0, int endIndex = 500000, bool includeDetail = true, bool includeOD4BSites = false) { var sites = new List<SiteEntity>(); SPOSitePropertiesEnumerable props = null; while (props == null || props.NextStartIndexFromSharePoint != null) //while (props == null || props.NextStartIndex > -1) { SPOSitePropertiesEnumerableFilter filter = new SPOSitePropertiesEnumerableFilter() { IncludePersonalSite = includeOD4BSites ? PersonalSiteFilter.Include : PersonalSiteFilter.UseServerDefault, StartIndex = props == null ? null : props.NextStartIndexFromSharePoint, IncludeDetail = includeDetail }; //props = tenant.GetSitePropertiesFromSharePointByFilters(filter); props = tenant.GetSitePropertiesFromSharePoint(props == null?null:props.NextStartIndexFromSharePoint, includeDetail); //props = tenant.GetSiteProperties(props == null ? 0 : props.NextStartIndex, includeDetail); tenant.Context.Load(props); tenant.Context.ExecuteQueryRetry(); foreach (var prop in props) { var siteEntity = new SiteEntity(); siteEntity.Lcid = prop.Lcid; siteEntity.SiteOwnerLogin = prop.Owner; siteEntity.StorageMaximumLevel = prop.StorageMaximumLevel; siteEntity.StorageWarningLevel = prop.StorageWarningLevel; siteEntity.Template = prop.Template; siteEntity.TimeZoneId = prop.TimeZoneId; siteEntity.Title = prop.Title; siteEntity.Url = prop.Url; siteEntity.UserCodeMaximumLevel = prop.UserCodeMaximumLevel; siteEntity.UserCodeWarningLevel = prop.UserCodeWarningLevel; siteEntity.CurrentResourceUsage = prop.CurrentResourceUsage; siteEntity.LastContentModifiedDate = prop.LastContentModifiedDate; siteEntity.StorageUsage = prop.StorageUsage; siteEntity.WebsCount = prop.WebsCount; var lockState = SiteLockState.Unlock; if (Enum.TryParse(prop.LockState, out lockState)) { siteEntity.LockState = lockState; } sites.Add(siteEntity); } } return sites; }
internal static string CreateTestSiteCollection(Tenant tenant, string sitecollectionName, bool isNoScriptSite = false) { try { string devSiteUrl = ConfigurationManager.AppSettings["SPODevSiteUrl"]; string siteToCreateUrl = GetTestSiteCollectionName(devSiteUrl, sitecollectionName); string siteOwnerLogin = ConfigurationManager.AppSettings["SPOUserName"]; if (TestCommon.AppOnlyTesting()) { using (var clientContext = TestCommon.CreateClientContext()) { List<UserEntity> admins = clientContext.Web.GetAdministrators(); siteOwnerLogin = admins[0].LoginName.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries)[2]; } } SiteEntity siteToCreate = new SiteEntity() { Url = siteToCreateUrl, Template = "STS#0", Title = "Test", Description = "Test site collection", SiteOwnerLogin = siteOwnerLogin, Lcid = 1033, StorageMaximumLevel = 100, UserCodeMaximumLevel = 0 }; tenant.CreateSiteCollection(siteToCreate, false, true); if (isNoScriptSite) { tenant.SetSiteProperties(siteToCreateUrl, noScriptSite: true); } return siteToCreateUrl; } catch (Exception ex) { Console.WriteLine(ex.ToDetailedString()); throw; } }
public static void AddSite(this Web web, SiteEntity parent, SiteEntity subsite, bool inheritPermissions, bool inheritNavigation) { // Call actual implementation CreateWeb(web, subsite.Title, subsite.Url, subsite.Description, subsite.Template, (int)subsite.Lcid, inheritPermissions, inheritNavigation); }
internal static string CreateTestSubSite(Tenant tenant, string sitecollectionUrl, string subSiteName) { try { // Create a sub site in the central site collection using (var cc = TestCommon.CreateClientContext(sitecollectionUrl)) { //Create sub site SiteEntity sub = new SiteEntity() { Title = "Sub site for engine testing", Url = subSiteName, Description = "" }; var subWeb = cc.Web.CreateWeb(sub); subWeb.EnsureProperty(t => t.Url); return subWeb.Url; } } catch(Exception ex) { Console.WriteLine(ex.ToDetailedString()); throw; } // Below approach is not working on edog...to be investigated //// create a sub site in the central site collection //Site site = tenant.GetSiteByUrl(sitecollectionUrl); //tenant.Context.Load(site); //tenant.Context.ExecuteQueryRetry(); //Web web = site.RootWeb; //web.Context.Load(web); //web.Context.ExecuteQueryRetry(); ////Create sub site //SiteEntity sub = new SiteEntity() { Title = "Sub site for engine testing", Url = subSiteName, Description = "" }; //var subWeb = web.CreateWeb(sub); //subWeb.EnsureProperty(t => t.Url); //return subWeb.Url; }
public static Guid AddSiteCollectionTenant(this Web web, SiteEntity properties, bool removeFromRecycleBin = false, bool wait = true) { Tenant tenant = new Tenant(web.Context); return tenant.AddSiteCollection(properties, removeFromRecycleBin, wait); }
private static string CreateTestSiteCollection(Tenant tenant, string sitecollectionName, bool isNoScriptSite = false) { string devSiteUrl = ConfigurationManager.AppSettings["SPODevSiteUrl"]; string siteOwnerLogin = string.Format("{0}\\{1}", ConfigurationManager.AppSettings["OnPremDomain"], ConfigurationManager.AppSettings["OnPremUserName"]); if (TestCommon.AppOnlyTesting()) { using (var clientContext = TestCommon.CreateClientContext()) { List<UserEntity> admins = clientContext.Web.GetAdministrators(); siteOwnerLogin = admins[0].LoginName.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries)[1]; } } string siteToCreateUrl = GetTestSiteCollectionName(devSiteUrl, sitecollectionName); SiteEntity siteToCreate = new SiteEntity() { Url = siteToCreateUrl, Template = "STS#0", Title = "Test", Description = "Test site collection", SiteOwnerLogin = siteOwnerLogin, Lcid = 1033, }; tenant.CreateSiteCollection(siteToCreate); // Create the default groups using (ClientContext cc = new ClientContext(siteToCreateUrl)) { var owners = cc.Web.AddGroup("Test Owners", "", true, false); var members = cc.Web.AddGroup("Test Members", "", true, false); var visitors = cc.Web.AddGroup("Test Visitors", "", true, true); cc.Web.AssociateDefaultGroups(owners, members, visitors); } return siteToCreateUrl; }
/// <summary> /// Returns all site collections in the current Tenant based on a startIndex. IncludeDetail adds additional properties to the SPSite object. EndIndex is the maximum number based on chunkcs of 300. /// </summary> /// <param name="tenant">Tenant object to operate against</param> /// <param name="startIndex">Start getting site collections from this index. Defaults to 0</param> /// <param name="endIndex">The index of the last site. Defaults to 100.000</param> /// <param name="includeDetail">Option to return a limited set of data</param> /// <returns>An IList of SiteEntity objects</returns> public static IList<SiteEntity> GetSiteCollections(this Tenant tenant, int startIndex = 0, int endIndex = 100000, bool includeDetail = true) { var sites = new List<SiteEntity>(); // O365 Tenant Site Collection limit is 500.000 (https://support.office.com/en-us/article/SharePoint-Online-software-boundaries-and-limits-8f34ff47-b749-408b-abc0-b605e1f6d498?CTT=1&CorrelationId=1928c530-fc12-4134-ada5-8ed2c2ec01fc&ui=en-US&rs=en-US&ad=US), // but let's limit to 100.000. Note that GetSiteProperties returns 300 per request. for (int i = startIndex; i < endIndex; i += 300) { var props = tenant.GetSiteProperties(i, includeDetail); tenant.Context.Load(props); tenant.Context.ExecuteQueryRetry(); foreach (var prop in props) { var siteEntity = new SiteEntity(); siteEntity.Lcid = prop.Lcid; siteEntity.SiteOwnerLogin = prop.Owner; siteEntity.StorageMaximumLevel = prop.StorageMaximumLevel; siteEntity.StorageWarningLevel = prop.StorageWarningLevel; siteEntity.Template = prop.Template; siteEntity.TimeZoneId = prop.TimeZoneId; siteEntity.Title = prop.Title; siteEntity.Url = prop.Url; siteEntity.UserCodeMaximumLevel = prop.UserCodeMaximumLevel; siteEntity.UserCodeWarningLevel = prop.UserCodeWarningLevel; siteEntity.CurrentResourceUsage = prop.CurrentResourceUsage; siteEntity.LastContentModifiedDate = prop.LastContentModifiedDate; siteEntity.StorageUsage = prop.StorageUsage; siteEntity.WebsCount = prop.WebsCount; sites.Add(siteEntity); } if (props.Count < 300) break; //exit for loop if there are no more site collections } return sites; }
internal static string CreateTestSubSite(Tenant tenant, string sitecollectionUrl, string subSiteName) { using (ClientContext cc = new ClientContext(sitecollectionUrl)) { //Create sub site SiteEntity sub = new SiteEntity() { Title = "Sub site for engine testing", Url = subSiteName, Description = "" }; var subWeb = cc.Web.CreateWeb(sub); subWeb.EnsureProperty(t => t.Url); return subWeb.Url; } }
/// <summary> /// Processess the branding updates for the passed site /// </summary> /// <param name="cc">clientcontext of the site to operate on</param> /// <param name="site">Information about the site that will be processed</param> /// <param name="currentThemeName">Theme to be applied</param> /// <param name="currentBrandingVersion">Version of the theme that should be applied</param> /// <param name="forceBranding">Enforce branding when the branding was not yet set</param> private static void ProcessBrandingUpdate(ClientContext cc, SiteEntity site, string currentThemeName, int currentBrandingVersion, bool forceBranding) { // Check if we've a property bag entry string themeName = cc.Web.GetPropertyBagValueString(BRANDING_THEME, ""); if (!String.IsNullOrEmpty(themeName)) { // No theme property bag entry, assume no theme has been applied if (themeName.Equals(currentThemeName, StringComparison.InvariantCultureIgnoreCase)) { Console.WriteLine("Theme {0} is set for site {1}", themeName, site.Url); // the used theme matches to the theme we want to update int? brandingVersion = cc.Web.GetPropertyBagValueInt(BRANDING_VERSION, 0); if (brandingVersion < currentBrandingVersion || forceBranding) { Console.WriteLine("Theme {0} has version {1} while version {2} is needed. Theme will be updated", themeName, brandingVersion, currentBrandingVersion); // The used theme is having an older version or the branding version was property bag entry was removed DeployTheme(cc, currentThemeName); // Set the web propertybag entries cc.Web.SetPropertyBagValue(BRANDING_THEME, currentThemeName); cc.Web.SetPropertyBagValue(BRANDING_VERSION, currentBrandingVersion); } else { // We're good, no action needed Console.WriteLine("Theme {0} has latest version {1}. Theme will not be updated", themeName, brandingVersion); } } else { // Theme does not match what we've expected, don't change it Console.WriteLine("Theme {0} was applied. No update required", themeName); } } else { // No theme property bag entry, assume no theme has been applied, so this site should not be updated if (forceBranding) { Console.WriteLine("Web property bag {0} is not set for site {1}, but force branding is configured, so set theme {1} for site {2}", BRANDING_THEME, themeName, site.Url); // The used theme is having an older version or the branding version was property bag entry was removed DeployTheme(cc, currentThemeName); // Set the web propertybag entries cc.Web.SetPropertyBagValue(BRANDING_THEME, currentThemeName); cc.Web.SetPropertyBagValue(BRANDING_VERSION, currentBrandingVersion); } else { Console.WriteLine("Web property bag {0} is not set for site {1}...skip this site ", BRANDING_THEME, site.Url); } } }
private void CreateSiteCollection(SiteCollectionProvisioningJob job) { Console.WriteLine("Creating Site Collection \"{0}\".", job.RelativeUrl); // Define the full Site Collection URL String siteUrl = String.Format("{0}{1}", PnPPartnerPackSettings.InfrastructureSiteUrl.Substring(0, PnPPartnerPackSettings.InfrastructureSiteUrl.IndexOf("sharepoint.com/") + 14), job.RelativeUrl); using (var adminContext = PnPPartnerPackContextProvider.GetAppOnlyTenantLevelClientContext()) { // Configure the Site Collection properties SiteEntity newSite = new SiteEntity(); newSite.Description = job.Description; newSite.Lcid = (uint)job.Language; newSite.Title = job.SiteTitle; newSite.Url = siteUrl; newSite.SiteOwnerLogin = job.PrimarySiteCollectionAdmin; newSite.StorageMaximumLevel = job.StorageMaximumLevel; newSite.StorageWarningLevel = job.StorageWarningLevel; newSite.Template = PnPPartnerPackSettings.DefaultSiteTemplate; newSite.TimeZoneId = job.TimeZone; newSite.UserCodeMaximumLevel = job.UserCodeMaximumLevel; newSite.UserCodeWarningLevel = job.UserCodeWarningLevel; // Create the Site Collection and wait for its creation (we're asynchronous) var tenant = new Tenant(adminContext); tenant.CreateSiteCollection(newSite, true, true); // TODO: Do we want to empty Recycle Bin? Site site = tenant.GetSiteByUrl(siteUrl); Web web = site.RootWeb; adminContext.Load(site, s => s.Url); adminContext.Load(web, w => w.Url); adminContext.ExecuteQueryRetry(); // Enable Secondary Site Collection Administrator if (!String.IsNullOrEmpty(job.SecondarySiteCollectionAdmin)) { Microsoft.SharePoint.Client.User secondaryOwner = web.EnsureUser(job.SecondarySiteCollectionAdmin); secondaryOwner.IsSiteAdmin = true; secondaryOwner.Update(); web.SiteUsers.AddUser(secondaryOwner); adminContext.ExecuteQueryRetry(); } Console.WriteLine("Site \"{0}\" created.", site.Url); // Check if external sharing has to be enabled if (job.ExternalSharingEnabled) { EnableExternalSharing(tenant, site); // Enable External Sharing Console.WriteLine("Enabled External Sharing for site \"{0}\".", site.Url); } } // Move to the context of the created Site Collection using (ClientContext clientContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(siteUrl)) { Site site = clientContext.Site; Web web = site.RootWeb; clientContext.Load(site, s => s.Url); clientContext.Load(web, w => w.Url); clientContext.ExecuteQueryRetry(); // Check if we need to enable PnP Partner Pack overrides if (job.PartnerPackExtensionsEnabled) { // Enable Responsive Design PnPPartnerPackUtilities.EnablePartnerPackOnSite(site.Url); Console.WriteLine("Enabled PnP Partner Pack Overrides on site \"{0}\".", site.Url); } // Check if the site has to be responsive if (job.ResponsiveDesignEnabled) { // Enable Responsive Design PnPPartnerPackUtilities.EnableResponsiveDesignOnSite(site.Url); Console.WriteLine("Enabled Responsive Design Template to site \"{0}\".", site.Url); } // Apply the Provisioning Template Console.WriteLine("Applying Provisioning Template \"{0}\" to site.", job.ProvisioningTemplateUrl); // Determine the reference URLs and file names String templatesSiteUrl = PnPPartnerPackUtilities.GetSiteCollectionRootUrl(job.ProvisioningTemplateUrl); String templateFileName = job.ProvisioningTemplateUrl.Substring(job.ProvisioningTemplateUrl.LastIndexOf("/") + 1); using (ClientContext repositoryContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext(templatesSiteUrl)) { // Configure the XML file system provider XMLTemplateProvider provider = new XMLSharePointTemplateProvider( repositoryContext, templatesSiteUrl, PnPPartnerPackConstants.PnPProvisioningTemplates); // Load the template from the XML stored copy ProvisioningTemplate template = provider.GetTemplate(templateFileName); template.Connector = provider.Connector; // We do intentionally remove taxonomies, which are not supported // in the AppOnly Authorization model // For further details, see the PnP Partner Pack documentation ProvisioningTemplateApplyingInformation ptai = new ProvisioningTemplateApplyingInformation(); // Write provisioning steps on console log ptai.MessagesDelegate += delegate (string message, ProvisioningMessageType messageType) { Console.WriteLine("{0} - {1}", messageType, messageType); }; ptai.ProgressDelegate += delegate (string message, int step, int total) { Console.WriteLine("{0:00}/{1:00} - {2}", step, total, message); }; ptai.HandlersToProcess ^= OfficeDevPnP.Core.Framework.Provisioning.Model.Handlers.TermGroups; // Configure template parameters if (job.TemplateParameters != null) { foreach (var key in job.TemplateParameters.Keys) { if (job.TemplateParameters.ContainsKey(key)) { template.Parameters[key] = job.TemplateParameters[key]; } } } web.ApplyProvisioningTemplate(template, ptai); } Console.WriteLine("Applyed Provisioning Template \"{0}\" to site.", job.ProvisioningTemplateUrl); } }
/// <summary> /// Adds a new child Web (site) to a parent Web. /// </summary> /// <param name="parentWeb">The parent Web (site) to create under</param> /// <param name="subsite">Details of the Web (site) to add. Only Title, Url (as the leaf URL), Description, Template and Language are used.</param> /// <param name="inheritPermissions">Specifies whether the new site will inherit permissions from its parent site.</param> /// <param name="inheritNavigation">Specifies whether the site inherits navigation.</param> /// <returns></returns> public static Web CreateWeb(this Web parentWeb, SiteEntity subsite, bool inheritPermissions = true, bool inheritNavigation = true) { return CreateWeb(parentWeb, subsite.Title, subsite.Url, subsite.Description, subsite.Template, (int)subsite.Lcid, inheritPermissions, inheritNavigation); }
/// <summary> /// Launches a site collection creation and waits for the creation to finish /// </summary> /// <param name="properties">Describes the site collection to be created</param> public void AddSiteCollection(SharePointProvisioningData properties) { if (this.CreateOnPremises) { this.SiteProvisioningOnPremises.CreateSiteCollectionOnPremises(this.SharePointProvisioningData); this.createdSiteContext = this.SiteProvisioningOnPremises.SpOnPremiseAuthentication(this.SharePointProvisioningData.Url); } else { SiteEntity newSite = new SiteEntity { Description = properties.Description, Title = properties.Title, Url = properties.Url, Template = properties.Template, Lcid = properties.Lcid, SiteOwnerLogin = properties.SiteOwner.Login, StorageMaximumLevel = properties.StorageMaximumLevel, StorageWarningLevel = properties.StorageWarningLevel, TimeZoneId = properties.TimeZoneId, UserCodeMaximumLevel = properties.UserCodeMaximumLevel, UserCodeWarningLevel = properties.UserCodeWarningLevel, }; Tenant tenant = new Tenant(this.AppOnlyClientContext); tenant.CreateSiteCollection(newSite); InstantiateCreatedSiteClientContext(newSite.Url); } }