private void GetExternalUsers(Office365Tenant tenant)
        {
            GetExternalUsersResults results = null;

            if (!string.IsNullOrEmpty(SiteUrl))
            {
                results = tenant.GetExternalUsersForSite(SiteUrl, Position, PageSize, Filter, SortOrder);
            }
            else
            {
                results = tenant.GetExternalUsers(Position, PageSize, Filter, SortOrder);
            }
            ClientContext.Load(results, r => r.TotalUserCount, r => r.UserCollectionPosition, r => r.ExternalUserCollection.Include(u => u.DisplayName, u => u.InvitedAs, u => u.UniqueId, u => u.AcceptedAs, u => u.WhenCreated, u => u.InvitedBy));
            ClientContext.ExecuteQueryRetry();
            foreach (var externalUser in results.ExternalUserCollection)
            {
                if (!ShowOnlyUsersWithAcceptingAccountNotMatchInvitedAccount)
                {
                    WriteObject(externalUser);
                }
                else if (!string.Equals(externalUser.InvitedAs, externalUser.AcceptedAs, System.StringComparison.OrdinalIgnoreCase))
                {
                    WriteObject(externalUser);
                }
            }
        }
Example #2
0
        public ActionResult CreateDefaultOrigins()
        {
            try
            {
                IList <string> publicCdnOrigins = new List <string>();

                using (var clientContext = GetClientContext())
                {
                    var tenant = new Office365Tenant(clientContext);

                    tenant.CreateTenantCdnDefaultOrigins(SPOTenantCdnType.Public);

                    publicCdnOrigins = tenant.GetTenantCdnOrigins(SPOTenantCdnType.Public);

                    clientContext.ExecuteQuery();
                }

                return(Json(publicCdnOrigins));
            }
            catch (Exception ex)
            {
                Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                return(Json(ex.Message));
            }
        }
Example #3
0
        public ActionResult SetCDN(bool value)
        {
            bool CDNEnabled = false;

            try
            {
                using (var clientContext = GetClientContext())
                {
                    var tenant = new Office365Tenant(clientContext);

                    tenant.SetTenantCdnEnabled(SPOTenantCdnType.Public, value);

                    var publicCDNEnabled = tenant.GetTenantCdnEnabled(SPOTenantCdnType.Public);

                    clientContext.ExecuteQuery();

                    CDNEnabled = publicCDNEnabled.Value;

                    return(Json(CDNEnabled));
                }
            }
            catch (Exception ex)
            {
                Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                return(Json(ex.Message));
            }
        }
Example #4
0
        public ActionResult SetFiletypes(List <string> filetypes)
        {
            try
            {
                string cdnFileTypes;

                using (var clientContext = GetClientContext())
                {
                    var tenant = new Office365Tenant(clientContext);

                    var newFileTypes = string.Join(",", filetypes);

                    tenant.SetTenantCdnPolicy(SPOTenantCdnType.Public, SPOTenantCdnPolicyType.IncludeFileExtensions, newFileTypes);

                    var publicCDNPolicies = tenant.GetTenantCdnPolicies(SPOTenantCdnType.Public);

                    clientContext.ExecuteQuery();

                    cdnFileTypes = publicCDNPolicies.Where(s => s.StartsWith(SPOTenantCdnPolicyType.IncludeFileExtensions.ToString())).First();
                }

                return(Json(ConvertToList(cdnFileTypes)));
            }
            catch (Exception ex)
            {
                Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                return(Json(ex.Message));
            }
        }
Example #5
0
        /// <summary>
        /// Demonstrates how to check status for specific submission or for all submissions
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="workItemId"></param>
        private static void CheckStatusOfRequestedProcess(ClientContext ctx, Guid workItemId)
        {
            ///
            /// CHECK STATUS of the property job with GUID - notice that there's additional logs in the folder as well
            ///

            // Check status of specific request based on received GUID
            Office365Tenant tenant = new Office365Tenant(ctx);
            var             job    = tenant.GetImportProfilePropertyJob(workItemId);

            ctx.Load(job);
            ctx.ExecuteQuery();
            Console.Write("\n--\n");
            Console.WriteLine(string.Format("ID: {0} - Request status: {1} - Error status: {2}",
                                            job.JobId, job.State.ToString(), job.Error.ToString()));
            Console.Write("\n--\n");

            ///
            /// Get list of all jobs in the tenant
            ///
            var jobs = tenant.GetImportProfilePropertyJobs();

            ctx.Load(jobs);
            ctx.ExecuteQuery();
            foreach (var item in jobs)
            {
                Console.WriteLine(string.Format("ID: {0} - Request status: {1} - Error status: {2}",
                                                item.JobId, item.State.ToString(), item.Error.ToString()));
            }
        }
Example #6
0
        // from https://msdn.microsoft.com/en-us/library/office/microsoft.online.sharepoint.tenantmanagement.aspx
        public override EventResult <ClientResult <Guid> > Execute()
        {
            EventResult <ClientResult <Guid> > result = new EventResult <ClientResult <Guid> >();
            string          filePath         = CreatetImportValueFile();
            Office365Tenant tenant           = new Office365Tenant(Param.Util.ProjContext);
            IDictionary <string, string> dic = new Dictionary <string, string>();

            dic.Add("BirthPlace", "brthPlace");
            dic.Add("GraduateDate", "grdDate");
            string sourceDataIdProperty = "IdName";
            string sourceUri            = UploadJsonFile(Param, filePath);

            // 先行リリーステナントでないとつかえない?https://github.com/SharePoint/PnP/issues/1400

            Param.Util.ProjContext.Load(tenant);
            Param.Util.ProjContext.ExecuteQuery();
            result.Result = tenant.QueueImportProfileProperties(ImportProfilePropertiesUserIdType.Email, sourceDataIdProperty, dic, sourceUri);
            Param.Util.ProjContext.ExecuteQuery();
            if (result.Result.Value.Equals(Guid.Empty))
            {
                MessageBox.Show("先行リリースではないので使えないみたいです。");
            }
            System.IO.File.Delete(filePath);
            return(result);
        }
        protected override void ExecuteCmdlet()
        {
            var o365 = new Office365Tenant(ClientContext);

            if (ParameterSpecified(nameof(JobId)))
            {
                var job = o365.GetImportProfilePropertyJob(JobId.Id);
                ClientContext.Load(job);
                ClientContext.ExecuteQueryRetry();

                GetErrorInfo(job);
                WriteObject(job);
            }
            else
            {
                ImportProfilePropertiesJobStatusCollection jobs = o365.GetImportProfilePropertyJobs();
                ClientContext.Load(jobs);
                ClientContext.ExecuteQueryRetry();
                foreach (var job in jobs)
                {
                    GetErrorInfo(job);
                }
                WriteObject(jobs);
            }
        }
        protected override void ExecuteCmdlet()
        {
            var office365Tenant = new Office365Tenant(ClientContext);

            ClientContext.Load(office365Tenant);
            ClientContext.ExecuteQueryRetry();
            GetExternalUsers(office365Tenant);
        }
Example #9
0
        /// <summary>
        /// Returns a list all external users for a given site that have at least the viewpages permission
        /// </summary>
        /// <param name="web">Tenant administration web</param>
        /// <param name="siteUrl">Url of the site fetch the external users for</param>
        /// <returns>A list of <see cref="OfficeDevPnP.Core.Entities.ExternalUserEntity"/> objects</returns>
        public static List <ExternalUserEntity> GetExternalUsersForSiteTenant(this Web web, Uri siteUrl)
        {
            if (siteUrl == null)
            {
                throw new ArgumentNullException("siteUrl");
            }

            Tenant          tenantAdmin = new Tenant(web.Context);
            Office365Tenant tenant      = new Office365Tenant(web.Context);
            Site            site        = tenantAdmin.GetSiteByUrl(siteUrl.OriginalString);

            web = site.RootWeb;

            List <ExternalUserEntity> externalUsers = new List <ExternalUserEntity>();
            int pageSize = 50;
            int position = 0;
            GetExternalUsersResults results = null;

            while (true)
            {
                results = tenant.GetExternalUsersForSite(siteUrl.OriginalString, position, pageSize, string.Empty, SortOrder.Ascending);
                web.Context.Load(results, r => r.UserCollectionPosition, r => r.TotalUserCount, r => r.ExternalUserCollection);
                web.Context.ExecuteQuery();

                foreach (var externalUser in results.ExternalUserCollection)
                {
                    User user = web.SiteUsers.GetByEmail(externalUser.AcceptedAs);
                    web.Context.Load(user);
                    web.Context.ExecuteQuery();

                    var permission = web.GetUserEffectivePermissions(user.LoginName);
                    web.Context.ExecuteQuery();
                    var doesUserHavePermission = permission.Value.Has(PermissionKind.ViewPages);
                    if (doesUserHavePermission)
                    {
                        externalUsers.Add(new ExternalUserEntity()
                        {
                            DisplayName = externalUser.DisplayName,
                            AcceptedAs  = externalUser.AcceptedAs,
                            InvitedAs   = externalUser.InvitedAs,
                            InvitedBy   = externalUser.InvitedBy,
                            UniqueId    = externalUser.UniqueId,
                            WhenCreated = externalUser.WhenCreated
                        });
                    }
                }

                position = results.UserCollectionPosition;

                if (position == -1 || position == results.TotalUserCount)
                {
                    break;
                }
            }

            return(externalUsers);
        }
Example #10
0
        protected override void ExecuteCmdlet()
        {
            if (string.IsNullOrWhiteSpace(IdProperty))
            {
                throw new InvalidEnumArgumentException(@"IdProperty cannot be empty");
            }

            switch (ParameterSetName)
            {
            case ParameterSet_UPLOADFILE:
                if (string.IsNullOrWhiteSpace(Path))
                {
                    throw new InvalidEnumArgumentException(@"Path cannot be empty");
                }

                var webCtx = ClientContext.Clone(PnPConnection.Current.Url);
                var web    = webCtx.Web;
                var webServerRelativeUrl = web.EnsureProperty(w => w.ServerRelativeUrl);
                if (!Folder.ToLower().StartsWith(webServerRelativeUrl))
                {
                    Folder = UrlUtility.Combine(webServerRelativeUrl, Folder);
                }
                if (!web.DoesFolderExists(Folder))
                {
                    throw new InvalidOperationException($"Folder {Folder} does not exist");
                }
                var folder = web.GetFolderByServerRelativeUrl(Folder);

                var  fileName = System.IO.Path.GetFileName(Path);
                File file     = folder.UploadFile(fileName, Path, true);
                Url = new Uri(webCtx.Url).GetLeftPart(UriPartial.Authority) + file.ServerRelativeUrl;
                break;

            case ParameterSet_URL:
                if (string.IsNullOrWhiteSpace(Url))
                {
                    throw new InvalidEnumArgumentException(@"Url cannot be empty");
                }
                break;
            }

            var o365           = new Office365Tenant(ClientContext);
            var propDictionary = UserProfilePropertyMapping.Cast <DictionaryEntry>().ToDictionary(kvp => (string)kvp.Key, kvp => (string)kvp.Value);
            var id             = o365.QueueImportProfileProperties(IdType, IdProperty, propDictionary, Url);

            ClientContext.ExecuteQueryRetry();

            var job = o365.GetImportProfilePropertyJob(id.Value);

            ClientContext.Load(job);
            ClientContext.ExecuteQueryRetry();
            WriteObject(job);
        }
        protected override void ExecuteCmdlet()
        {
            if (!string.IsNullOrEmpty(Url))
            {
                var siteProperties = Tenant.GetSitePropertiesByUrl(Url, Detailed);
                ClientContext.Load(siteProperties);
                ClientContext.ExecuteQueryRetry();
                Model.SPOSite site = null;
                if (ParameterSpecified(nameof(DisableSharingForNonOwnersStatus)))
                {
                    var office365Tenant = new Office365Tenant(ClientContext);
                    var clientResult    = office365Tenant.IsSharingDisabledForNonOwnersOfSite(Url);
                    ClientContext.ExecuteQuery();
                    site = new Model.SPOSite(siteProperties, clientResult.Value);
                }
                else
                {
                    site = new Model.SPOSite(siteProperties, null);
                }
                WriteObject(site, true);
            }
            else
            {
                SPOSitePropertiesEnumerableFilter filter = new SPOSitePropertiesEnumerableFilter()
                {
                    IncludePersonalSite = IncludeOneDriveSites.IsPresent ? PersonalSiteFilter.Include : PersonalSiteFilter.UseServerDefault,
                    IncludeDetail       = Detailed,
#pragma warning disable CS0618 // Type or member is obsolete
                    Template = Template,
#pragma warning restore CS0618 // Type or member is obsolete
                    Filter = Filter,
                };
                SPOSitePropertiesEnumerable sitesList = null;
                var sites = new List <SiteProperties>();
                do
                {
                    sitesList = Tenant.GetSitePropertiesFromSharePointByFilters(filter);
                    Tenant.Context.Load(sitesList);
                    Tenant.Context.ExecuteQueryRetry();
                    sites.AddRange(sitesList.ToList());
                    filter.StartIndex = sitesList.NextStartIndexFromSharePoint;
                } while (!string.IsNullOrWhiteSpace(sitesList.NextStartIndexFromSharePoint));

                if (Template != null)
                {
                    WriteObject(sites.Where(t => t.Template == Template).OrderBy(x => x.Url), true);
                }
                else
                {
                    WriteObject(sites.OrderBy(x => x.Url), true);
                }
            }
        }
        /// <summary>
        /// Query the Tenant UPS based on Site Collection
        /// </summary>
        /// <param name="siteUrl"></param>
        /// <param name="invitedAs"></param>
        /// <returns></returns>
        public static List <SPExternalUserEntity> CheckExternalUserForSite(this ClientContext adminContext, ITraceLogger logger, string siteUrl, string invitedAs = "")
        {
            if (siteUrl == null)
            {
                throw new ArgumentNullException("siteUrl");
            }


            var externalUsers = new List <SPExternalUserEntity>();
            int pageSize      = 50;
            int position      = 0;
            GetExternalUsersResults results = null;

            var officeTenantContext = new Office365Tenant(adminContext);

            while (true)
            {
                logger.LogInformation($"Checking External User with {invitedAs} at start {position} and page size {pageSize}");

                results = officeTenantContext.GetExternalUsersForSite(siteUrl, position, pageSize, invitedAs, SortOrder.Ascending);
                adminContext.Load(results, r => r.UserCollectionPosition, r => r.TotalUserCount, r => r.ExternalUserCollection);
                adminContext.ExecuteQueryRetry();

                foreach (ExternalUser externalUser in results.ExternalUserCollection)
                {
                    externalUsers.Add(new SPExternalUserEntity()
                    {
                        AcceptedAs  = externalUser.AcceptedAs,
                        DisplayName = externalUser.DisplayName,
                        InvitedAs   = externalUser.InvitedAs,
                        InvitedBy   = externalUser.InvitedBy,
                        UniqueId    = externalUser.UniqueId,
                        UserId      = externalUser.UserId,
                        WhenCreated = externalUser.WhenCreated
                    });
                }

                position = results.UserCollectionPosition;

                if (position == -1 || position == results.TotalUserCount)
                {
                    break;
                }
            }

            return(externalUsers);
        }
        protected override void ExecuteCmdlet()
        {
            if (ShouldProcess($"Sign out user {User} from all devices"))
            {
                var office365Tenant = new Office365Tenant(ClientContext);

                var result = office365Tenant.RevokeAllUserSessions(User);
                ClientContext.Load(result);
                ClientContext.ExecuteQueryRetry();
                switch (result.State)
                {
                case SPOUserSessionRevocationState.FeatureDisabled:
                {
                    WriteWarning("This cmdlet will be available in the future, but is not ready for use in your organization yet.");
                    break;
                }

                case SPOUserSessionRevocationState.Failure:
                {
                    WriteWarning($"Sorry, something went wrong and we could not sign out {User} from any device.");
                    break;
                }

                case SPOUserSessionRevocationState.InstantaneousSuccess:
                {
                    WriteWarning($"We succesfully signed out {User} from all devices.");
                    break;
                }

                case SPOUserSessionRevocationState.NonInstantaneousSuccess:
                {
                    WriteWarning($"It can take up to an hour to sign out {User} from all devices.");
                    break;
                }

                case SPOUserSessionRevocationState.UserNotFound:
                {
                    WriteWarning($"We could not find the user {User}. Check for typos and try again.");
                    break;
                }

                default:
                    throw new PSInvalidOperationException();
                }
            }
        }
        protected override void ExecuteCmdlet()
        {
            var context = ClientContext;
            var site    = ClientContext.Site;
            var siteUrl = ClientContext.Url;

            if (ParameterSpecified(nameof(Identity)))
            {
                context = ClientContext.Clone(Identity.Url);
                site    = context.Site;
                siteUrl = context.Url;
            }

            Office365Tenant office365Tenant = new Office365Tenant(context);

            context.Load(office365Tenant);
            office365Tenant.DisableSharingForNonOwnersOfSite(siteUrl);
            context.ExecuteQueryRetry();
        }
Example #15
0
        /// <summary>
        /// Returns a list all external users in your tenant
        /// </summary>
        /// <param name="web">Tenant administration web</param>
        /// <returns>A list of <see cref="OfficeDevPnP.Core.Entities.ExternalUserEntity"/> objects</returns>
        public static List <ExternalUserEntity> GetExternalUsersTenant(this Web web)
        {
            Tenant          tenantAdmin = new Tenant(web.Context);
            Office365Tenant tenant      = new Office365Tenant(web.Context);

            List <ExternalUserEntity> externalUsers = new List <ExternalUserEntity>();
            int pageSize = 50;
            int position = 0;
            GetExternalUsersResults results = null;

            while (true)
            {
                results = tenant.GetExternalUsers(position, pageSize, string.Empty, SortOrder.Ascending);
                web.Context.Load(results, r => r.UserCollectionPosition, r => r.TotalUserCount, r => r.ExternalUserCollection);
                web.Context.ExecuteQuery();

                foreach (var externalUser in results.ExternalUserCollection)
                {
                    externalUsers.Add(new ExternalUserEntity()
                    {
                        DisplayName = externalUser.DisplayName,
                        AcceptedAs  = externalUser.AcceptedAs,
                        InvitedAs   = externalUser.InvitedAs,
                        InvitedBy   = externalUser.InvitedBy,
                        UniqueId    = externalUser.UniqueId,
                        WhenCreated = externalUser.WhenCreated
                    });
                }

                position = results.UserCollectionPosition;

                if (position == -1 || position == results.TotalUserCount)
                {
                    break;
                }
            }

            return(externalUsers);
        }
        protected override void ExecuteCmdlet()
        {
            var office365Tenant = new Office365Tenant(ClientContext);

            var results = office365Tenant.RemoveExternalUsers(UniqueIDs);

            if (this.ShouldProcess(nameof(UniqueIDs), "Remove External Users"))
            {
                var resultObject = new PSObject();
                ClientContext.Load(results);
                ClientContext.ExecuteQueryRetry();
                if (results.RemoveSucceeded.Length > 0)
                {
                    resultObject.Properties.Add(new PSNoteProperty("Succeeded", results.RemoveSucceeded));
                }
                if (results.RemoveFailed.Length > 0)
                {
                    resultObject.Properties.Add(new PSNoteProperty("Failed", results.RemoveFailed));
                }
                WriteObject(resultObject);
            }
        }
Example #17
0
        protected override void ExecuteCmdlet()
        {
            var context = ClientContext;
            var site    = ClientContext.Site;
            var siteUrl = ClientContext.Url;

            if (ParameterSpecified(nameof(Identity)))
            {
                context = ClientContext.Clone(Identity.Url);
                site    = context.Site;
                siteUrl = context.Url;
            }

            Office365Tenant office365Tenant = new Office365Tenant(context);

            context.Load(office365Tenant);
            var isSharingDisabledForNonOwnersOfSite = office365Tenant.IsSharingDisabledForNonOwnersOfSite(siteUrl);

            context.ExecuteQueryRetry();

            // Inverting the outcome here on purpose as the wording of the cmdlet indicates that a true means sharing for owners and members is allowed and false would mean only sharing for owners would be allowed
            WriteObject(!isSharingDisabledForNonOwnersOfSite.Value);
        }
Example #18
0
        public ActionResult GetCDNSettings()
        {
            var cdnManagerModel = new CDNManagerModel();

            using (var clientContext = GetClientContext())
            {
                clientContext.Load(clientContext.Web, w => w.Url);

                var tenant            = new Office365Tenant(clientContext);
                var publicCDNEnabled  = tenant.GetTenantCdnEnabled(SPOTenantCdnType.Public);
                var publicCdnOrigins  = tenant.GetTenantCdnOrigins(SPOTenantCdnType.Public);
                var publicCDNPolicies = tenant.GetTenantCdnPolicies(SPOTenantCdnType.Public);

                clientContext.ExecuteQuery();

                cdnManagerModel.PublicCDNEnabled = publicCDNEnabled.Value;
                cdnManagerModel.Origins          = publicCdnOrigins; //Origins will need refactor. It is just a string now, not an object
                var fileTypes = publicCDNPolicies.Where(s => s.StartsWith(SPOTenantCdnPolicyType.IncludeFileExtensions.ToString())).First();
                cdnManagerModel.Filetypes  = ConvertToList(fileTypes);
                cdnManagerModel.SPOSiteUrl = clientContext.Web.Url;
            }

            return(Json(cdnManagerModel, JsonRequestBehavior.AllowGet));
        }
Example #19
0
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestMessage req, TraceWriter log)
        {
            log.Info("Triggering Azure Function to process the JSON");

            // parse query parameter
            string fileName = req.GetQueryNameValuePairs()
                              .FirstOrDefault(q => string.Compare(q.Key, "fileName", true) == 0)
                              .Value;

            string tenantAdminUrl = "https://m365x131504-admin.sharepoint.com";
            // User name and pwd to login to the tenant
            string userName = "";
            string pwd      = "";

            string fileUrl = "https://m365x131504.sharepoint.com/sites/PowerApps/Shared%20Documents/" + fileName;
            ClientResult <Guid> workItemId;
            string status = string.Empty;

            // Get access to source tenant with tenant permissions
            using (var ctx = new ClientContext(tenantAdminUrl))
            {
                //Provide count and pwd for connecting to the source
                var passWord = new SecureString();
                foreach (char c in pwd.ToCharArray())
                {
                    passWord.AppendChar(c);
                }
                ctx.Credentials = new SharePointOnlineCredentials(userName, passWord);

                // Only to check connection and permission, could be removed
                ctx.Load(ctx.Web);
                ctx.ExecuteQuery();
                string title = ctx.Web.Title;

                // Let's get started on the actual code!!!
                Office365Tenant tenant = new Office365Tenant(ctx);
                ctx.Load(tenant);
                ctx.ExecuteQuery();

                /// /// /// /// /// /// /// /// ///
                /// DO import based on file whcih is already uploaded to tenant
                /// /// /// /// /// /// /// /// ///

                // Type of user identifier ["PrincipleName", "EmailAddress", "CloudId"]
                // in the User Profile Service.
                // In this case we use email as the identifier at the UPA storage
                ImportProfilePropertiesUserIdType userIdType = ImportProfilePropertiesUserIdType.Email;

                // Name of user identifier property in the JSON
                var userLookupKey = "IdName";

                var propertyMap = new System.Collections.Generic.Dictionary <string, string>();
                // First one is the file, second is the target at User Profile Service
                // Notice that we have here 2 custom properties in UPA called 'City' and 'Office'
                propertyMap.Add("MyCustomProperty", "MyCustomProperty");
                propertyMap.Add("MyCustomProperty1", "MyCustomProperty1");

                // Returns a GUID, which can be used to see the status of the execution and end results
                workItemId = tenant.QueueImportProfileProperties(
                    userIdType, userLookupKey, propertyMap, fileUrl
                    );

                ctx.ExecuteQuery();

                var job = tenant.GetImportProfilePropertyJob(workItemId.Value);
                ctx.Load(job);
                ctx.ExecuteQuery();

                status = string.Format("ID: {0} - Request status: {1} - Error status: {2}",
                                       job.JobId, job.State.ToString(), job.Error.ToString());
            }


            return(workItemId == null
                ? req.CreateResponse(HttpStatusCode.BadRequest, "Some Error Occurred")
                : req.CreateResponse(HttpStatusCode.OK, status));
        }
Example #20
0
        static void Main(string[] args)
        {
            #region Variables:
            string adminURL      = "https://pcfromdc-admin.sharepoint.com";       // SPO Admin Site URL
            string siteURL       = "https://pcfromdc.sharepoint.com/sites/spc18"; // Site where we upload JSON file
            string importFileURL = "https://pcfromdc.sharepoint.com/sites/spc18/upaSync/upaOutput-WebJob.txt";
            string docLibName    = "UPA Sync";                                    // Document Library Name for upload
            string spoUserName   = ConfigurationManager.AppSettings["spoUserName"];
            string spoPassword   = ConfigurationManager.AppSettings["spoPassword"];
            #endregion

            #region Query SQL and Build JSON'ish String for upload to O365
            SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
            builder.DataSource     = "pcdemo.database.windows.net";
            builder.UserID         = ConfigurationManager.AppSettings["dataBaseUserName"];
            builder.Password       = ConfigurationManager.AppSettings["dataBasePW"];
            builder.InitialCatalog = "pcDemo_Personnel";
            #endregion

            #region Start to build jsonOutput string
            StringBuilder jsonSB = new StringBuilder();
            jsonSB.AppendLine("{");
            jsonSB.AppendLine("\"value\":");
            jsonSB.AppendLine("[");
            #endregion

            #region Get info from Azure SQL Table
            using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
            {
                connection.Open();
                StringBuilder sb = new StringBuilder();
                sb.Append("SELECT TOP(10) mail, city  ");
                sb.Append("FROM pcDemo_SystemUsers ");
                sb.Append("Where city is not null ");
                sb.Append("and mail like '*****@*****.**' ");
                sb.Append("or mail like '%pcdemo.net'");
                String sql = sb.ToString();

                using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            jsonSB.AppendLine("{");
                            jsonSB.AppendLine("\"IdName\": \"" + reader.GetString(0) + "\",");
                            jsonSB.AppendLine("\"Property1\": \"" + reader.GetString(1) + "\"");
                            jsonSB.AppendLine("},");
                        }
                    }
                }
            }
            Console.WriteLine("SQL query completed...");
            #endregion

            #region finish json'ish string and convert to stream
            // Clean up jsonSB and remove last comma
            string jasonClean = jsonSB.ToString();
            jasonClean = (jasonClean.Trim()).TrimEnd(',');
            // Add jasonClean back into StringBuilder
            StringBuilder jsonEnd = new StringBuilder(jasonClean);
            jsonEnd.AppendLine("");
            jsonEnd.AppendLine("]");
            jsonEnd.AppendLine("}");
            string jsonOutput = jsonEnd.ToString();
            Console.WriteLine("JSON build completed...");

            // Convert String to Stream
            byte[]       byteArray = Encoding.UTF8.GetBytes(jsonOutput);
            MemoryStream stream    = new MemoryStream(byteArray);
            Console.WriteLine("JSON converted...");
            #endregion

            #region Upload JSON file to SPO
            using (var clientContext = new ClientContext(siteURL))
            {
                // set username and password
                var passWord = new SecureString();
                foreach (char c in spoPassword.ToCharArray())
                {
                    passWord.AppendChar(c);
                }
                clientContext.Credentials = new SharePointOnlineCredentials(spoUserName, passWord);

                Web web = clientContext.Web;
                FileCreationInformation newFile = new FileCreationInformation();
                newFile.Overwrite     = true;
                newFile.ContentStream = stream;
                newFile.Url           = importFileURL;
                List docLibrary = web.Lists.GetByTitle(docLibName);
                docLibrary.RootFolder.Files.Add(newFile);
                clientContext.Load(docLibrary);
                clientContext.ExecuteQuery();
            }
            Console.WriteLine("File Uploaded...");
            #endregion

            #region Bulk Upload API
            using (var clientContext = new ClientContext(adminURL))
            {
                // set username and password
                var passWord = new SecureString();
                foreach (char c in spoPassword.ToCharArray())
                {
                    passWord.AppendChar(c);
                }
                clientContext.Credentials = new SharePointOnlineCredentials(spoUserName, passWord);

                // Get Tenant Context
                Office365Tenant tenant = new Office365Tenant(clientContext);
                clientContext.Load(tenant);
                clientContext.ExecuteQuery();

                // Only to check connection and permission, could be removed
                clientContext.Load(clientContext.Web);
                clientContext.ExecuteQuery();
                string title = clientContext.Web.Title;
                Console.WriteLine("Logged into " + title + "...");

                clientContext.Load(clientContext.Web);
                ImportProfilePropertiesUserIdType userIdType = ImportProfilePropertiesUserIdType.Email;
                var userLookupKey = "IdName";
                var propertyMap   = new System.Collections.Generic.Dictionary <string, string>();
                propertyMap.Add("Property1", "City");
                // propertyMap.Add("Property2", "Office");
                var workItemId = tenant.QueueImportProfileProperties(userIdType, userLookupKey, propertyMap, importFileURL);
                clientContext.ExecuteQuery();
            }
            Console.WriteLine("UPA Bulk Update Completed...");
            #endregion
        }
Example #21
0
        /// <summary>
        /// Returns a list all external users for a given site that have at least the viewpages permission
        /// </summary>
        /// <param name="web">Tenant administration web</param>
        /// <param name="siteUrl">Url of the site fetch the external users for</param>
        /// <returns>A list of <see cref="OfficeDevPnP.Core.Entities.ExternalUserEntity"/> objects</returns>
        public static List<ExternalUserEntity> GetExternalUsersForSiteTenant(this Web web, Uri siteUrl)
        {
            if (siteUrl == null)
                throw new ArgumentNullException("siteUrl");

            Tenant tenantAdmin = new Tenant(web.Context);
            Office365Tenant tenant = new Office365Tenant(web.Context);
            Site site = tenantAdmin.GetSiteByUrl(siteUrl.OriginalString);
            web = site.RootWeb;

            List<ExternalUserEntity> externalUsers = new List<ExternalUserEntity>();
            int pageSize = 50;
            int position = 0;
            GetExternalUsersResults results = null;

            while (true)
            {
                results = tenant.GetExternalUsersForSite(siteUrl.OriginalString, position, pageSize, string.Empty, SortOrder.Ascending);
                web.Context.Load(results, r => r.UserCollectionPosition, r => r.TotalUserCount, r => r.ExternalUserCollection);
                web.Context.ExecuteQuery();

                foreach (var externalUser in results.ExternalUserCollection)
                {

                    User user = web.SiteUsers.GetByEmail(externalUser.AcceptedAs);
                    web.Context.Load(user);
                    web.Context.ExecuteQuery();

                    var permission = web.GetUserEffectivePermissions(user.LoginName);
                    web.Context.ExecuteQuery();
                    var doesUserHavePermission = permission.Value.Has(PermissionKind.ViewPages);
                    if (doesUserHavePermission)
                    {
                        externalUsers.Add(new ExternalUserEntity()
                        {
                            DisplayName = externalUser.DisplayName,
                            AcceptedAs = externalUser.AcceptedAs,
                            InvitedAs = externalUser.InvitedAs,
                            InvitedBy = externalUser.InvitedBy,
                            UniqueId = externalUser.UniqueId,
                            WhenCreated = externalUser.WhenCreated
                        });
                    }

                }

                position = results.UserCollectionPosition;

                if (position == -1 || position == results.TotalUserCount)
                {
                    break;
                }
            }

            return externalUsers;
        }
Example #22
0
        /// <summary>
        /// Returns a list all external users in your tenant
        /// </summary>
        /// <param name="web">Tenant administration web</param>
        /// <returns>A list of <see cref="OfficeDevPnP.Core.Entities.ExternalUserEntity"/> objects</returns>
        public static List<ExternalUserEntity> GetExternalUsersTenant(this Web web)
        {
            Tenant tenantAdmin = new Tenant(web.Context);
            Office365Tenant tenant = new Office365Tenant(web.Context);

            List<ExternalUserEntity> externalUsers = new List<ExternalUserEntity>();
            int pageSize = 50;
            int position = 0;
            GetExternalUsersResults results = null;

            while (true)
            {
                results = tenant.GetExternalUsers(position, pageSize, string.Empty, SortOrder.Ascending);
                web.Context.Load(results, r => r.UserCollectionPosition, r => r.TotalUserCount, r => r.ExternalUserCollection);
                web.Context.ExecuteQuery();

                foreach (var externalUser in results.ExternalUserCollection)
                {
                    externalUsers.Add(new ExternalUserEntity()
                    {
                        DisplayName = externalUser.DisplayName,
                        AcceptedAs = externalUser.AcceptedAs,
                        InvitedAs = externalUser.InvitedAs,
                        InvitedBy = externalUser.InvitedBy,
                        UniqueId = externalUser.UniqueId,
                        WhenCreated = externalUser.WhenCreated
                    });
                }

                position = results.UserCollectionPosition;

                if (position == -1 || position == results.TotalUserCount)
                {
                    break;
                }
            }

            return externalUsers;
        }
Example #23
0
        static void Main(string[] args)
        {
            ConsoleColor defaultForeground = Console.ForegroundColor;
            // Something like: https://contoso-admin.sharepoint.com
            string tenantAdminUrl = GetInput("Enter the admin URL of your tenant", false, defaultForeground);
            // User name and pwd to login to the tenant
            string userName = GetInput("Enter your user name", false, defaultForeground);
            string pwd      = GetInput("Enter your password", true, defaultForeground);
            // File URL to the profile value like: https://contoso.sharepoint.com/Shared%20Documents/sample.txt
            string fileUrl = GetInput("Enter the URL to the file located in your tenant", false, defaultForeground);

            // Get access to source tenant with tenant permissions
            using (var ctx = new ClientContext(tenantAdminUrl))
            {
                //Provide count and pwd for connecting to the source
                var passWord = new SecureString();
                foreach (char c in pwd.ToCharArray())
                {
                    passWord.AppendChar(c);
                }
                ctx.Credentials = new SharePointOnlineCredentials(userName, passWord);

                // Only to check connection and permission, could be removed
                ctx.Load(ctx.Web);
                ctx.ExecuteQuery();
                string title = ctx.Web.Title;

                // Let's get started on the actual code!!!
                Office365Tenant tenant = new Office365Tenant(ctx);
                ctx.Load(tenant);
                ctx.ExecuteQuery();

                /// /// /// /// /// /// /// /// ///
                /// DO import based on file whcih is already uploaded to tenant
                /// /// /// /// /// /// /// /// ///

                // Type of user identifier ["PrincipleName", "EmailAddress", "PrincipalName"]
                // in the User Profile Service.
                // In this case we use email as the identifier at the UPA storage
                ImportProfilePropertiesUserIdType userIdType =
                    ImportProfilePropertiesUserIdType.Email;

                // Name of user identifier property in the JSON
                var userLookupKey = "IdName";

                var propertyMap = new System.Collections.Generic.Dictionary <string, string>();
                // First one is the file, second is the target at User Profile Service
                // Notice that we have here 2 custom properties in UPA called 'City' and 'OfficeCode'
                propertyMap.Add("Title", "Title");
                propertyMap.Add("City", "City");
                propertyMap.Add("Office", "OfficeCode");

                // Returns a GUID, which can be used to see the status of the execution and end results
                var workItemId = tenant.QueueImportProfileProperties(
                    userIdType, userLookupKey, propertyMap, fileUrl
                    );

                ctx.ExecuteQuery();

                /// /// /// /// /// /// /// /// /// ///
                // CALL CHECK STATUS in OWN method with the received GUID
                /// /// /// /// /// /// /// /// /// ///
                CheckStatusOfRequestedProcess(ctx, workItemId.Value);

                // Just to pause and indicate that it's all done
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("\n-----------------------------------------");
                Console.WriteLine("We are all done. Press enter to continue.");
                Console.ReadLine();
            }
        }
Example #24
0
        static void Main(string[] args)
        {
            //get governance variables such as warning duration and cutoff duration
            int    warningDuration = Convert.ToInt32(ConfigurationManager.AppSettings["WarningDuration"]);
            int    cutoffDuration  = Convert.ToInt32(ConfigurationManager.AppSettings["CutoffDuration"]);
            string tenantName      = ConfigurationManager.AppSettings["TenantName"];
            string tenantUpnDomain = ConfigurationManager.AppSettings["TenantUpnDomain"];
            Uri    tenantAdminUri  = new Uri(String.Format("https://{0}-admin.sharepoint.com", tenantName));

            string webUrl = "";

            #if DEBUG
            webUrl = "http://localhost:25440/";
            #else
            webUrl = "https://sposharing.azurewebsites.net/";
            #endif

            foreach (var siteUrl in sites)
            {
                //initialize a process date for this site and clean up to match SQL percision
                DateTime processDate     = DateTime.Now;
                string   stringTicks     = processDate.Ticks.ToString();
                int      adjustmentTicks = Convert.ToInt32(stringTicks.Substring(stringTicks.Length - 5));
                processDate = processDate.Subtract(TimeSpan.FromTicks(adjustmentTicks));

                //use O365 Tenant Administration to get all the external sharing details for this site
                List <ExternalShareDetails> shares = new List <ExternalShareDetails>();
                string adminRealm = TokenHelper.GetRealmFromTargetUrl(tenantAdminUri);
                var    adminToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, tenantAdminUri.Authority, adminRealm).AccessToken;
                using (var clientContext = TokenHelper.GetClientContextWithAccessToken(tenantAdminUri.ToString(), adminToken))
                {
                    //load the tenant
                    var tenant = new Office365Tenant(clientContext);
                    clientContext.Load(tenant);
                    clientContext.ExecuteQuery();

                    //initalize varables to going through the paged results
                    int  position = 0;
                    bool hasMore  = true;
                    while (hasMore)
                    {
                        //get external users 50 at a time (this is the limit and why we are paging)
                        var externalUsers = tenant.GetExternalUsersForSite(siteUrl, position, 50, String.Empty, SortOrder.Descending);
                        clientContext.Load(externalUsers, i => i.TotalUserCount);
                        clientContext.Load(externalUsers, i => i.ExternalUserCollection);
                        clientContext.ExecuteQuery();

                        //convert each external user to our own entity
                        foreach (var extUser in externalUsers.ExternalUserCollection)
                        {
                            position++;
                            shares.Add(new ExternalShareDetails()
                            {
                                AcceptedAs  = extUser.AcceptedAs.ToLower(),
                                DisplayName = extUser.DisplayName,
                                InvitedAs   = extUser.InvitedAs.ToLower(),
                                InvitedBy   = (String.IsNullOrEmpty(extUser.InvitedBy)) ? null : extUser.InvitedBy.ToLower(),
                                UserId      = extUser.UserId,
                                WhenCreated = extUser.WhenCreated
                            });
                        }

                        //determine if we have more pages to process
                        hasMore = (externalUsers.TotalUserCount > position);
                    }
                }

                //get an AppOnly accessToken and clientContext for the site collection
                Uri    siteUri     = new Uri(siteUrl);
                string realm       = TokenHelper.GetRealmFromTargetUrl(siteUri);
                string accessToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, siteUri.Authority, realm).AccessToken;
                using (var clientContext = TokenHelper.GetClientContextWithAccessToken(siteUri.ToString(), accessToken))
                {
                    //first we need to load the site to determine if external sharing is enabled (Site.ShareByEmailEnabled)
                    var site      = clientContext.Site;
                    var siteOwner = clientContext.Site.Owner;
                    clientContext.Load(site);
                    clientContext.Load(siteOwner); //include the site owner in case the share "InvitedBy" is null...we will send them email instead
                    clientContext.ExecuteQuery();

                    //validate that the site has sharing turned on
                    if (site.ShareByEmailEnabled)
                    {
                        //process all of the shares
                        foreach (var externalShare in shares)
                        {
                            //look for an existing record in the database
                            using (ExternalSharingDataEntities entities = new ExternalSharingDataEntities())
                            {
                                var shareRecord = entities.ExternalShares.FirstOrDefault(i => i.LoginName.Equals(externalShare.AcceptedAs));
                                if (shareRecord != null)
                                {
                                    //Update LastProcessedDate column of the record with the processDate
                                    shareRecord.LastProcessedDate = processDate;
                                    entities.SaveChanges();
                                }
                                else
                                {
                                    //get the original share date
                                    var details = getREST(accessToken, String.Format("{0}/_api/Web/SiteUserInfoList/Items({1})/FieldValuesAsText", siteUrl, externalShare.UserId));
                                    externalShare.WhenCreated = Convert.ToDateTime(details.Descendants(ns + "Created").FirstOrDefault().Value);
                                    shareRecord = new ExternalShare()
                                    {
                                        UniqueIdentifier   = Guid.NewGuid(),
                                        SiteCollectionUrl  = siteUrl.ToLower(),
                                        LoginName          = externalShare.AcceptedAs,
                                        UserId             = externalShare.UserId,
                                        InvitedBy          = (String.IsNullOrEmpty(externalShare.InvitedBy)) ? siteOwner.Email : externalShare.InvitedBy,
                                        OriginalSharedDate = externalShare.WhenCreated,
                                        LastProcessedDate  = processDate
                                    };
                                    entities.ExternalShares.Add(shareRecord);
                                    entities.SaveChanges();
                                }

                                //check if the record falls inside the warnings
                                double daysActive = processDate.Subtract(shareRecord.OriginalSharedDate).TotalDays;
                                if (shareRecord.RefreshSharedDate != null)
                                {
                                    daysActive = processDate.Subtract((DateTime)shareRecord.RefreshSharedDate).TotalDays;
                                }

                                //check for cutoff
                                if (daysActive > cutoffDuration)
                                {
                                    //remove the SPUser from the site
                                    clientContext.Web.SiteUsers.RemoveById(externalShare.UserId);
                                    clientContext.ExecuteQuery();

                                    //delete the record
                                    entities.ExternalShares.Remove(shareRecord);
                                    entities.SaveChanges();
                                }
                                else if (daysActive > warningDuration)
                                {
                                    int expiresIn = Convert.ToInt32(cutoffDuration - daysActive);
                                    //send email to InvitedBy (which will be site collection owner when null)
                                    EmailProperties email = new EmailProperties();
                                    email.To = new List <String>()
                                    {
                                        shareRecord.InvitedBy
                                    };
                                    email.Subject = String.Format("Action Required: External sharing with {0} about to expire", externalShare.AcceptedAs);
                                    email.Body    = String.Format("<html><body><p>You are receiving this message because you are the site administrator of <a href='{0}'>{0}</a> OR you shared it with {1}. The external access for this user is set to expire in {2} days. Use the link below to view additional details and perform actions to revoke OR extend access for another {3} days. If you do not act on this notice, the external access for this user to terminate in {2} days.</p><ul><li><a href='{4}Details/{5}'>View Details</a></li><li><a href='{4}Extend/{5}'>Extend {3} Days</a></li><li><a href='{4}Revoke/{5}'>Revoke Access</a></li></ul></body></html>", siteUrl, externalShare.AcceptedAs, expiresIn.ToString(), cutoffDuration.ToString(), webUrl, shareRecord.UniqueIdentifier);
                                    Utility.SendEmail(clientContext, email);
                                    clientContext.ExecuteQuery();
                                }
                            }
                        }
                    }
                }

                //delete all database records for this site that have an older processDate...these should represent external users deleted by manually
                using (ExternalSharingDataEntities entities = new ExternalSharingDataEntities())
                {
                    var cleanUpRecords = entities.ExternalShares.Where(i => i.SiteCollectionUrl.Equals(siteUrl.ToLower()) && i.LastProcessedDate < processDate);
                    foreach (var record in cleanUpRecords)
                    {
                        entities.ExternalShares.Remove(record);
                        entities.SaveChanges();
                    }
                }
            }
        }
Example #25
0
        protected override void ExecuteCmdlet()
        {
            var context = ClientContext;
            var site    = ClientContext.Site;
            var siteUrl = ClientContext.Url;

            var executeQueryRequired = false;

            if (!string.IsNullOrEmpty(Identity))
            {
                context = ClientContext.Clone(Identity);
                site    = context.Site;
                siteUrl = context.Url;
            }


            if (MyInvocation.BoundParameters.ContainsKey("Classification"))
            {
                site.Classification  = Classification;
                executeQueryRequired = true;
            }
            if (MyInvocation.BoundParameters.ContainsKey("LogoFilePath"))
            {
                var webTemplate = ClientContext.Web.EnsureProperty(w => w.WebTemplate);
                if (webTemplate == "GROUP")
                {
                    if (!System.IO.Path.IsPathRooted(LogoFilePath))
                    {
                        LogoFilePath = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, LogoFilePath);
                    }
                    if (System.IO.File.Exists(LogoFilePath))
                    {
                        var bytes    = System.IO.File.ReadAllBytes(LogoFilePath);
                        var mimeType = System.Web.MimeMapping.GetMimeMapping(LogoFilePath);
                        var result   = OfficeDevPnP.Core.Sites.SiteCollection.SetGroupImage(context, bytes, mimeType).GetAwaiter().GetResult();
                    }
                    else
                    {
                        throw new System.Exception("Logo file does not exist");
                    }
                }
                else
                {
                    throw new System.Exception("Not an Office365 group enabled site.");
                }
            }
            if (executeQueryRequired)
            {
                context.ExecuteQueryRetry();
            }

            if (IsTenantProperty())
            {
                var tenantAdminUrl = UrlUtilities.GetTenantAdministrationUrl(context.Url);
                context = context.Clone(tenantAdminUrl);

                executeQueryRequired = false;
                Func <TenantOperationMessage, bool> timeoutFunction = TimeoutFunction;
                Tenant tenant         = new Tenant(context);
                var    siteProperties = tenant.GetSitePropertiesByUrl(siteUrl, false);
                if (LockState.HasValue)
                {
                    tenant.SetSiteLockState(siteUrl, LockState.Value, Wait, Wait ? timeoutFunction : null);
                    WriteWarning("You changed the lockstate of this site. This change is not guaranteed to be effective immediately. Please wait a few minutes for this to take effect.");
                }

                if (Owners != null && Owners.Count > 0)
                {
                    var admins = new List <UserEntity>();
                    foreach (var owner in Owners)
                    {
                        var userEntity = new UserEntity {
                            LoginName = owner
                        };
                        admins.Add(userEntity);
                    }
                    tenant.AddAdministrators(admins, new Uri(siteUrl));
                }
                if (Sharing.HasValue)
                {
                    siteProperties.SharingCapability = Sharing.Value;
                    executeQueryRequired             = true;
                }
                if (StorageMaximumLevel.HasValue)
                {
                    siteProperties.StorageMaximumLevel = StorageMaximumLevel.Value;
                    executeQueryRequired = true;
                }
                if (StorageWarningLevel.HasValue)
                {
                    siteProperties.StorageWarningLevel = StorageWarningLevel.Value;
                    executeQueryRequired = true;
                }
#pragma warning disable CS0618 // Type or member is obsolete
                if (UserCodeWarningLevel.HasValue)
                {
                    siteProperties.UserCodeWarningLevel = UserCodeWarningLevel.Value;
                    executeQueryRequired = true;
                }
                if (UserCodeMaximumLevel.HasValue)
                {
                    siteProperties.UserCodeMaximumLevel = UserCodeMaximumLevel.Value;
                    executeQueryRequired = true;
                }
#pragma warning restore CS0618 // Type or member is obsolete

                if (AllowSelfServiceUpgrade.HasValue)
                {
                    siteProperties.AllowSelfServiceUpgrade = AllowSelfServiceUpgrade.Value;
                    executeQueryRequired = true;
                }
                if (NoScriptSite.IsPresent)
                {
                    siteProperties.DenyAddAndCustomizePages = (NoScriptSite == true ? DenyAddAndCustomizePagesStatus.Enabled : DenyAddAndCustomizePagesStatus.Disabled);
                    executeQueryRequired = true;
                }
                if (CommentsOnSitePagesDisabled.IsPresent)
                {
                    siteProperties.CommentsOnSitePagesDisabled = CommentsOnSitePagesDisabled;
                    executeQueryRequired = true;
                }
                if (DefaultLinkPermission.HasValue)
                {
                    siteProperties.DefaultLinkPermission = DefaultLinkPermission.Value;
                    executeQueryRequired = true;
                }
                if (DefaultSharingLinkType.HasValue)
                {
                    siteProperties.DefaultSharingLinkType = DefaultSharingLinkType.Value;
                    executeQueryRequired = true;
                }
                if (DisableAppViews.HasValue)
                {
                    siteProperties.DisableAppViews = DisableAppViews.Value;
                    executeQueryRequired           = true;
                }
                if (DisableCompanyWideSharingLinks.HasValue)
                {
                    siteProperties.DisableCompanyWideSharingLinks = DisableCompanyWideSharingLinks.Value;
                    executeQueryRequired = true;
                }
                if (DisableFlows.IsPresent)
                {
                    siteProperties.DisableFlows = DisableFlows ? FlowsPolicy.Disabled : FlowsPolicy.NotDisabled;
                    executeQueryRequired        = true;
                }
                if (LocaleId.HasValue)
                {
                    siteProperties.Lcid  = LocaleId.Value;
                    executeQueryRequired = true;
                }
                if (!string.IsNullOrEmpty(NewUrl))
                {
                    siteProperties.NewUrl = NewUrl;
                    executeQueryRequired  = true;
                }
                if (RestrictedToGeo.HasValue)
                {
                    siteProperties.RestrictedToRegion = RestrictedToGeo.Value;
                    executeQueryRequired = true;
                }
                if (SocialBarOnSitePagesDisabled.IsPresent)
                {
                    siteProperties.SocialBarOnSitePagesDisabled = SocialBarOnSitePagesDisabled;
                    executeQueryRequired = true;
                }
                if (executeQueryRequired)
                {
                    siteProperties.Update();
                    tenant.Context.ExecuteQueryRetry();
                }

                if (DisableSharingForNonOwners.IsPresent)
                {
                    Office365Tenant office365Tenant = new Office365Tenant(context);
                    context.Load(office365Tenant);
                    context.ExecuteQueryRetry();
                    office365Tenant.DisableSharingForNonOwnersOfSite(siteUrl);
                    context.ExecuteQuery();
                }
            }
        }
Example #26
0
        /// <summary>
        /// Syncs from Azure Active Directory to SharePoint Online user profiles
        /// </summary>
        /// <param name="clientContext">A ClientContext which can be used to interact with SharePoint Online</param>
        /// <param name="users">Azure AD User objects that need to be synced</param>
        /// <param name="userProfilePropertyMappings">Hashtable with the mapping from the Azure Active Directory property (the value) to the SharePoint Online User Profile Property (the key)</param>
        /// <param name="sharePointFolder">Location in the currently connected to site where to upload the JSON file to with instructions to update the user profiles</param>
        /// <param name="onlyCreateAndUploadMappingsFile">Boolean indicating if only the mappings file should be created and uploaded to SharePoint Online (true) or if the import job on that file should also be invoked (false)</param>
        public static async Task <ImportProfilePropertiesJobInfo> SyncFromAzureActiveDirectory(ClientContext clientContext, IEnumerable <PnP.PowerShell.Commands.Model.AzureAD.User> users, Hashtable userProfilePropertyMappings, string sharePointFolder, bool onlyCreateAndUploadMappingsFile = false)
        {
            var webServerRelativeUrl = clientContext.Web.EnsureProperty(w => w.ServerRelativeUrl);

            if (!sharePointFolder.ToLower().StartsWith(webServerRelativeUrl))
            {
                sharePointFolder = UrlUtility.Combine(webServerRelativeUrl, sharePointFolder);
            }
            if (!clientContext.Web.DoesFolderExists(sharePointFolder))
            {
                throw new InvalidOperationException($"Folder {sharePointFolder} to upload the user profile update file to does not exist on SharePoint Online in the site {clientContext.Url}");
            }

            var folder = clientContext.Web.GetFolderByServerRelativeUrl(sharePointFolder);

            var bulkUpdateBuilder = new StringBuilder();
            var userUpdateBuilder = new StringBuilder();

            foreach (var user in users)
            {
                foreach (DictionaryEntry userProfilePropertyMapping in userProfilePropertyMappings)
                {
                    if (userProfilePropertyMapping.Key != null && userProfilePropertyMapping.Value != null)
                    {
                        // Check if the property is a property directly on the user object
                        var aadUserProperty = user.GetType().GetProperty(userProfilePropertyMapping.Value.ToString(), BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
                        if (aadUserProperty != null)
                        {
                            // Construct an entry with the SharePoint Online User Profile property name and the value it should be set to coming from a property on the User object
                            if (aadUserProperty.PropertyType == typeof(IEnumerable <string>))
                            {
                                // AAD User property is an array, join all entries with a comma and add the combined string to the mapping output
                                userUpdateBuilder.AppendFormat(@"""{0}"":""{1}"",", userProfilePropertyMapping.Key, string.Join(",", ((IEnumerable)aadUserProperty.GetValue(user)).Cast <string>().ToArray()));
                            }
                            else
                            {
                                // AAD User property is a string, add its value to the mapping output
                                userUpdateBuilder.AppendFormat(@"""{0}"":""{1}"",", userProfilePropertyMapping.Key, aadUserProperty.GetValue(user));
                            }
                        }
                        else if (user.AdditionalProperties != null && user.AdditionalProperties.TryGetValue(userProfilePropertyMapping.Value.ToString(), out object userProfilePropertyMappingValue))
                        {
                            // Construct an entry with the SharePoint Online User Profile property name and the value it should be set to coming from a property on the AdditionalProperties dictionary on the User object
                            userUpdateBuilder.AppendFormat(@"""{0}"":""{1}"",", userProfilePropertyMapping.Key, userProfilePropertyMappingValue != null ? userProfilePropertyMappingValue.ToString() : string.Empty);
                        }
                    }
                }

                if (userUpdateBuilder.Length > 0)
                {
                    bulkUpdateBuilder.Append(@"{""IdName"":""");
                    bulkUpdateBuilder.Append(user.UserPrincipalName);
                    bulkUpdateBuilder.Append(@""",");
                    bulkUpdateBuilder.Append(userUpdateBuilder.ToString().TrimEnd(','));
                    bulkUpdateBuilder.Append("},");

                    userUpdateBuilder.Clear();
                }
            }

            // Check if there's anything to update
            if (bulkUpdateBuilder.Length == 0)
            {
                return(null);
            }

            // Construct the entire JSON message with the user profiles and properties to update
            var json = @"{ ""value"": [" + bulkUpdateBuilder.ToString().TrimEnd(',') + "] }";

            // Define the filename to save the file under on SharePoint Online
            var fileName = $"userprofilesyncdata-{DateTime.Now.ToString("yyyyMMddHHmmss")}-{Guid.NewGuid().ToString().Replace("-", "")}.json";

            // Upload the JSON to SharePoint Online
            File file = null;

            using (var stream = new System.IO.MemoryStream())
            {
                using (var writer = new System.IO.StreamWriter(stream))
                {
                    await writer.WriteAsync(json);

                    writer.Flush();
                    stream.Position = 0;

                    file = folder.UploadFile(fileName, stream, true);
                }
            }

            // Check if we should kick off the process to import the file
            if (onlyCreateAndUploadMappingsFile)
            {
                return(null);
            }

            // Instruct SharePoint Online to process the JSON file
            var o365           = new Office365Tenant(clientContext);
            var propDictionary = userProfilePropertyMappings.Cast <DictionaryEntry>().ToDictionary(kvp => (string)kvp.Key, kvp => (string)kvp.Key);
            var url            = new Uri(clientContext.Url).GetLeftPart(UriPartial.Authority) + file.ServerRelativeUrl;
            var id             = o365.QueueImportProfileProperties(ImportProfilePropertiesUserIdType.PrincipalName, "IdName", propDictionary, url);

            clientContext.ExecuteQueryRetry();

            // Retrieve the import json details
            var job = o365.GetImportProfilePropertyJob(id.Value);

            clientContext.Load(job);
            clientContext.ExecuteQueryRetry();

            return(job);
        }
Example #27
0
        private void SetSiteProperties(Func <TenantOperationMessage, bool> timeoutFunction)
        {
            var props          = GetSiteProperties(Identity.Url);
            var updateRequired = false;

            if (ParameterSpecified(nameof(Title)))
            {
                props.Title    = Title;
                updateRequired = true;
            }

            if (ParameterSpecified(nameof(DenyAddAndCustomizePages)))
            {
                props.DenyAddAndCustomizePages = DenyAddAndCustomizePages ? DenyAddAndCustomizePagesStatus.Enabled : DenyAddAndCustomizePagesStatus.Disabled;
                updateRequired = true;
            }

            if (ParameterSpecified(nameof(LocaleId)))
            {
                props.Lcid     = LocaleId;
                updateRequired = true;
            }

            if (ParameterSpecified(nameof(AllowSelfServiceUpgrade)))
            {
                props.AllowSelfServiceUpgrade = AllowSelfServiceUpgrade;
                updateRequired = true;
            }

            if (ParameterSpecified(nameof(SharingAllowedDomainList)))
            {
                props.SharingAllowedDomainList = SharingAllowedDomainList;
                updateRequired = true;
            }
            if (ParameterSpecified(nameof(SharingBlockedDomainList)))
            {
                props.SharingBlockedDomainList = SharingBlockedDomainList;
                updateRequired = true;
            }
            if (ParameterSpecified(nameof(SharingDomainRestrictionMode)))
            {
                props.SharingDomainRestrictionMode = SharingDomainRestrictionMode;
                updateRequired = true;
            }
            if (ParameterSpecified(nameof(StorageQuota)))
            {
                props.StorageMaximumLevel = StorageQuota;
                updateRequired            = true;
            }
            if (ParameterSpecified(nameof(StorageQuotaWarningLevel)))
            {
                props.StorageWarningLevel = StorageQuotaWarningLevel;
                updateRequired            = true;
            }
            if (ParameterSpecified(nameof(StorageQuotaReset)))
            {
                props.StorageMaximumLevel = 0;
                updateRequired            = true;
            }
            if (ParameterSpecified(nameof(ResourceQuota)))
            {
                props.UserCodeMaximumLevel = ResourceQuota;
                updateRequired             = true;
            }
            if (ParameterSpecified(nameof(ResourceQuotaWarningLevel)))
            {
                props.UserCodeWarningLevel = ResourceQuotaWarningLevel;
                updateRequired             = true;
            }
            if (ParameterSpecified(nameof(SharingCapability)))
            {
                props.SharingCapability = SharingCapability;
                updateRequired          = true;
            }
            if (ParameterSpecified(nameof(DefaultLinkPermission)))
            {
                props.DefaultLinkPermission = DefaultLinkPermission;
                updateRequired = true;
            }
            if (ParameterSpecified(nameof(ShowPeoplePickerSuggestionsForGuestUsers)))
            {
                Tenant.EnsureProperty(t => t.ShowPeoplePickerSuggestionsForGuestUsers);
                if (!Tenant.ShowPeoplePickerSuggestionsForGuestUsers)
                {
                    WriteWarning("ShowPeoplePickerSuggestionsForGuests users has been disabled for this tenant. See Set-PnPTenant");
                }
                props.ShowPeoplePickerSuggestionsForGuestUsers = ShowPeoplePickerSuggestionsForGuestUsers;
                updateRequired = true;
            }
            if (ParameterSpecified(nameof(DefaultSharingLinkType)))
            {
                props.DefaultSharingLinkType = DefaultSharingLinkType;
                updateRequired = true;
            }
            if (ParameterSpecified(nameof(DefaultLinkToExistingAccess)))
            {
                props.DefaultLinkToExistingAccess = DefaultLinkToExistingAccess.Value;
                updateRequired = true;
            }
            if (ParameterSpecified(nameof(DefaultLinkToExistingAccessReset)))
            {
                props.DefaultLinkToExistingAccessReset = true;
                updateRequired = true;
            }
#pragma warning disable CS0618
            if (ParameterSpecified(nameof(BlockDownloadOfNonViewableFiles)) || ParameterSpecified(nameof(AllowDownloadingNonWebViewableFiles)))
            {
                var value = ParameterSpecified(nameof(BlockDownloadLinksFileTypes)) ? !BlockDownloadOfNonViewableFiles : AllowDownloadingNonWebViewableFiles;
                if (ConditionalAccessPolicy == SPOConditionalAccessPolicyType.AllowLimitedAccess)
                {
                    props.AllowDownloadingNonWebViewableFiles = value;
                    updateRequired = true;
                    if (!value)
                    {
                        WriteWarning("Users will not be able to download files that cannot be viewed on the web. To allow download of files that cannot be viewed on the web run the cmdlet again and set AllowDownloadingNonWebViewableFiles to true.");
                    }
                }
                else
                {
                    if (ShouldContinue("To set AllowDownloadingNonWebViewableFiles parameter you need to set the -ConditionalAccessPolicy parameter to AllowLimitedAccess. We can set the Conditional Access Policy of this site to AllowLimitedAccess. Would you like to continue?", string.Empty))
                    {
                        ConditionalAccessPolicy                   = SPOConditionalAccessPolicyType.AllowLimitedAccess;
                        props.ConditionalAccessPolicy             = SPOConditionalAccessPolicyType.AllowLimitedAccess;
                        props.AllowDownloadingNonWebViewableFiles = value;
                        if (!value)
                        {
                            WriteWarning("Users will not be able to download files that cannot be viewed on the web. To allow download of files that cannot be viewed on the web run the cmdlet again and set AllowDownloadingNonWebViewableFiles to true.");
                        }
                    }
                }
            }
#pragma warning restore CS0618

            if (ParameterSpecified(nameof(CommentsOnSitePagesDisabled)))
            {
                props.CommentsOnSitePagesDisabled = CommentsOnSitePagesDisabled;
                updateRequired = true;
            }

            if (ParameterSpecified(nameof(DisableAppViews)))
            {
                props.DisableAppViews = DisableAppViews;
                updateRequired        = true;
            }

            if (ParameterSpecified(nameof(DisableCompanyWideSharingLinks)))
            {
                props.DisableCompanyWideSharingLinks = DisableCompanyWideSharingLinks;
                updateRequired = true;
            }

            if (ParameterSpecified(nameof(DisableFlows)))
            {
                props.DisableFlows = DisableFlows;
                updateRequired     = true;
            }

            if (ParameterSpecified(nameof(EnablePWA)))
            {
                props.PWAEnabled = EnablePWA ? PWAEnabledStatus.Enabled : PWAEnabledStatus.Disabled;
                updateRequired   = true;
            }

            if (ParameterSpecified(nameof(OverrideTenantAnonymousLinkExpirationPolicy)))
            {
                props.OverrideTenantAnonymousLinkExpirationPolicy = OverrideTenantAnonymousLinkExpirationPolicy.ToBool();
                updateRequired = true;
            }

            if (ParameterSpecified(nameof(AnonymousLinkExpirationInDays)) && AnonymousLinkExpirationInDays.HasValue)
            {
                props.AnonymousLinkExpirationInDays = AnonymousLinkExpirationInDays.Value;
                updateRequired = true;
            }

            if (ParameterSpecified(nameof(DisableSharingForNonOwners)))
            {
                var office365Tenant = new Office365Tenant(ClientContext);
                ClientContext.Load(office365Tenant);
                ClientContext.ExecuteQueryRetry();
                office365Tenant.DisableSharingForNonOwnersOfSite(Identity.Url);
            }

            if (ParameterSpecified(nameof(ConditionalAccessPolicy)) && ConditionalAccessPolicy == SPOConditionalAccessPolicyType.ProtectionLevel)
            {
                if (IsRootSite(Identity.Url))
                {
                    throw new PSInvalidOperationException("You cannot set the conditional access policy 'ProtectionLevel' on the root site.");
                }
                if (string.IsNullOrEmpty(ProtectionLevelName))
                {
                    props.AuthContextStrength = null;
                }
                else
                {
                    props.AuthContextStrength = ProtectionLevelName;
                }
                updateRequired = true;
            }
            else
            {
                if (ParameterSpecified(nameof(ProtectionLevelName)))
                {
                    throw new PSArgumentException("ConditionalAccessPolicy has to be set too when using this parameter.");
                }
                if (ParameterSpecified(nameof(ConditionalAccessPolicy)))
                {
                    props.AuthContextStrength = null;
                    updateRequired            = true;
                }
            }

            if (ClientContext.ServerVersion >= new Version(16, 0, 8715, 1200)) // ServerSupportsIpLabelId2
            {
                if (ParameterSpecified(nameof(SensitivityLabel)))
                {
                    props.SensitivityLabel2 = SensitivityLabel;
                    updateRequired          = true;
                }
                if (ParameterSpecified(nameof(RemoveLabel)))
                {
                    props.SensitivityLabel2 = null;
                    updateRequired          = true;
                }
            }
            else
            {
                WriteWarning("Server does not support setting sensitity label");
            }

            if (ParameterSpecified(nameof(LimitedAccessFileType)))
            {
                if (ConditionalAccessPolicy == SPOConditionalAccessPolicyType.AllowLimitedAccess)
                {
                    props.LimitedAccessFileType = LimitedAccessFileType;
                    updateRequired = true;
                }
                else if (ShouldContinue("To set LimitedAccessFileType you need to set the -ConditionalAccessPolicy parameter to AllowLimitedAccess. We can set the Conditional Access Policy of this site to AllowLimitedAccess. Would you like to continue?", string.Empty))
                {
                    ConditionalAccessPolicy       = SPOConditionalAccessPolicyType.AllowLimitedAccess;
                    props.ConditionalAccessPolicy = SPOConditionalAccessPolicyType.AllowLimitedAccess;
                    props.LimitedAccessFileType   = LimitedAccessFileType;
                    updateRequired = true;
                }
            }

            if (ParameterSpecified(nameof(AllowEditing)))
            {
                if (ConditionalAccessPolicy == SPOConditionalAccessPolicyType.AllowLimitedAccess)
                {
                    props.AllowEditing = AllowEditing;
                }
                else if (ShouldContinue("To set AllowEditing you need to set the -ConditionalAccessPolicy parameter to AllowLimitedAccess. We can set the Conditional Access Policy of this site to AllowLimitedAccess. Would you like to continue?", string.Empty))
                {
                    ConditionalAccessPolicy       = SPOConditionalAccessPolicyType.AllowLimitedAccess;
                    props.ConditionalAccessPolicy = SPOConditionalAccessPolicyType.AllowLimitedAccess;
                    props.AllowEditing            = AllowEditing;
                }
            }

            if (ParameterSpecified(nameof(RestrictedToGeo)))
            {
                props.RestrictedToRegion = RestrictedToGeo;
                updateRequired           = true;
            }

            if (ParameterSpecified(nameof(ExternalUserExpirationInDays)))
            {
                props.ExternalUserExpirationInDays = ExternalUserExpirationInDays;
                updateRequired = true;
            }

            if (ParameterSpecified(nameof(OverrideTenantExternalUserExpirationPolicy)))
            {
                props.OverrideTenantExternalUserExpirationPolicy = OverrideTenantExternalUserExpirationPolicy;
                updateRequired = true;
            }

            if (ParameterSpecified(nameof(AddInformationSegment)) && AddInformationSegment.Length > 0)
            {
                props.IBSegmentsToAdd = AddInformationSegment;
                updateRequired        = true;
            }

            if (ParameterSpecified(nameof(RemoveInformationSegment)) && RemoveInformationSegment.Length > 0)
            {
                props.IBSegmentsToRemove = RemoveInformationSegment;
                updateRequired           = true;
            }

            if (ParameterSpecified(nameof(BlockDownloadLinksFileType)))
            {
                props.BlockDownloadLinksFileType = BlockDownloadLinksFileType;
                updateRequired = true;
            }

            if (ParameterSpecified(nameof(OverrideBlockUserInfoVisibility)))
            {
                props.OverrideBlockUserInfoVisibility = OverrideBlockUserInfoVisibility;
                updateRequired = true;
            }

            if (ParameterSpecified(nameof(HubSiteId)))
            {
                var hubsiteProperties = Tenant.GetHubSitePropertiesById(HubSiteId);
                ClientContext.Load(hubsiteProperties);
                ClientContext.ExecuteQueryRetry();
                if (hubsiteProperties == null || string.IsNullOrEmpty(hubsiteProperties.SiteUrl))
                {
                    throw new PSArgumentException("Hubsite not found with the ID specified");
                }
                if (hubsiteProperties.ID != Guid.Empty)
                {
                    Tenant.ConnectSiteToHubSiteById(Identity.Url, hubsiteProperties.ID);
                }
                else
                {
                    Tenant.ConnectSiteToHubSite(Identity.Url, hubsiteProperties.SiteUrl);
                }
                ClientContext.ExecuteQueryRetry();
            }

            if (updateRequired)
            {
                var op = props.Update();
                ClientContext.Load(op, i => i.IsComplete, i => i.PollingInterval);
                ClientContext.ExecuteQueryRetry();

                if (Wait)
                {
                    WaitForIsComplete(ClientContext, op, timeoutFunction, TenantOperationMessage.SettingSiteProperties);
                }
            }

            if (Owners != null && Owners.Count > 0)
            {
                var admins = new List <UserEntity>();
                foreach (var owner in Owners)
                {
                    var userEntity = new UserEntity {
                        LoginName = owner
                    };
                    admins.Add(userEntity);
                }
                Tenant.AddAdministrators(admins, new Uri(Identity.Url));
            }
        }
Example #28
0
        protected override void ExecuteCmdlet()
        {
            ClientContext.ExecuteQueryRetry();
            if (ParameterSpecified(nameof(Identity)))
            {
                var siteProperties = Tenant.GetSitePropertiesByUrl(Identity.Url, Detailed);
                ClientContext.Load(siteProperties);
                ClientContext.ExecuteQueryRetry();
                Model.SPOSite site = null;
                if (ParameterSpecified(nameof(DisableSharingForNonOwnersStatus)))
                {
                    var office365Tenant = new Office365Tenant(ClientContext);
                    var clientResult    = office365Tenant.IsSharingDisabledForNonOwnersOfSite(Identity.Url);
                    ClientContext.ExecuteQuery();
                    site = new Model.SPOSite(siteProperties, clientResult.Value);
                }
                else
                {
                    site = new Model.SPOSite(siteProperties, null);
                }
                WriteObject(site, true);
            }
            else
            {
                SPOSitePropertiesEnumerableFilter filter = new SPOSitePropertiesEnumerableFilter()
                {
                    IncludePersonalSite = IncludeOneDriveSites.IsPresent ? PersonalSiteFilter.Include : PersonalSiteFilter.UseServerDefault,
                    IncludeDetail       = Detailed,
#pragma warning disable CS0618 // Type or member is obsolete
                    Template = Template,
#pragma warning restore CS0618 // Type or member is obsolete
                    Filter = Filter,
                };

                if (ClientContext.ServerVersion >= new Version(16, 0, 7708, 1200))
                {
                    if (ParameterSpecified(nameof(GroupIdDefined)))
                    {
                        filter.GroupIdDefined = GroupIdDefined.Value == true ? 1 : 2;
                    }
                }
                else if (ParameterSpecified(nameof(GroupIdDefined)))
                {
                    throw new PSArgumentException("Filtering by Group Id is not yet available for this tenant.");
                }

                SPOSitePropertiesEnumerable sitesList = null;
                var sites = new List <SiteProperties>();
                do
                {
                    sitesList = Tenant.GetSitePropertiesFromSharePointByFilters(filter);
                    Tenant.Context.Load(sitesList);
                    Tenant.Context.ExecuteQueryRetry();
                    sites.AddRange(sitesList.ToList());
                    filter.StartIndex = sitesList.NextStartIndexFromSharePoint;
                } while (!string.IsNullOrWhiteSpace(sitesList.NextStartIndexFromSharePoint));

                if (Template != null)
                {
                    WriteObject(sites.Where(t => t.Template == Template).OrderBy(x => x.Url).Select(s => new Model.SPOSite(s, null)), true);
                }
                else
                {
                    WriteObject(sites.OrderBy(x => x.Url).Select(s => new Model.SPOSite(s, null)), true);
                }
            }
        }
Example #29
0
        protected override void ExecuteCmdlet()
        {
            var context = ClientContext;
            var site    = ClientContext.Site;
            var siteUrl = ClientContext.Url;

            var executeQueryRequired = false;

            if (!string.IsNullOrEmpty(Identity))
            {
                context = ClientContext.Clone(Identity);
                site    = context.Site;
                siteUrl = context.Url;
            }

            if (ParameterSpecified(nameof(Classification)))
            {
                site.Classification  = Classification;
                executeQueryRequired = true;
            }
            if (ParameterSpecified(nameof(LogoFilePath)))
            {
                site.EnsureProperty(s => s.GroupId);
                if (site.GroupId != Guid.Empty)
                {
                    if (!System.IO.Path.IsPathRooted(LogoFilePath))
                    {
                        LogoFilePath = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, LogoFilePath);
                    }
                    if (System.IO.File.Exists(LogoFilePath))
                    {
                        var bytes = System.IO.File.ReadAllBytes(LogoFilePath);

                        var mimeType = "";
                        if (LogoFilePath.EndsWith("gif", StringComparison.InvariantCultureIgnoreCase))
                        {
                            mimeType = "image/gif";
                        }
                        if (LogoFilePath.EndsWith("jpg", StringComparison.InvariantCultureIgnoreCase))
                        {
                            mimeType = "image/jpeg";
                        }
                        if (LogoFilePath.EndsWith("png", StringComparison.InvariantCultureIgnoreCase))
                        {
                            mimeType = "image/png";
                        }
                        var result = PnP.Framework.Sites.SiteCollection.SetGroupImageAsync(context, bytes, mimeType).GetAwaiter().GetResult();
                    }
                    else
                    {
                        throw new Exception("Logo file does not exist");
                    }
                }
                else
                {
                    throw new Exception("Not an Office365 group enabled site.");
                }
            }
            if (executeQueryRequired)
            {
                context.ExecuteQueryRetry();
            }

            if (IsTenantProperty())
            {
                var tenantAdminUrl = UrlUtilities.GetTenantAdministrationUrl(context.Url);
                context = context.Clone(tenantAdminUrl);

                executeQueryRequired = false;
                Func <TenantOperationMessage, bool> timeoutFunction = TimeoutFunction;
                Tenant tenant         = new Tenant(context);
                var    siteProperties = tenant.GetSitePropertiesByUrl(siteUrl, false);

                if (ParameterSpecified(nameof(OverrideTenantAnonymousLinkExpirationPolicy)))
                {
                    siteProperties.OverrideTenantAnonymousLinkExpirationPolicy = OverrideTenantAnonymousLinkExpirationPolicy.ToBool();
                    executeQueryRequired = true;
                }
                if (ParameterSpecified(nameof(AnonymousLinkExpirationInDays)) && AnonymousLinkExpirationInDays.HasValue)
                {
                    siteProperties.AnonymousLinkExpirationInDays = AnonymousLinkExpirationInDays.Value;
                    executeQueryRequired = true;
                }
                if (LockState.HasValue)
                {
                    tenant.SetSiteLockState(siteUrl, LockState.Value, Wait, Wait ? timeoutFunction : null);
                    WriteWarning("You changed the lockstate of this site. This change is not guaranteed to be effective immediately. Please wait a few minutes for this to take effect.");
                }
                if (Owners != null && Owners.Count > 0)
                {
                    var admins = new List <UserEntity>();
                    foreach (var owner in Owners)
                    {
                        var userEntity = new UserEntity {
                            LoginName = owner
                        };
                        admins.Add(userEntity);
                    }
                    tenant.AddAdministrators(admins, new Uri(siteUrl));
                }
                if (Sharing.HasValue)
                {
                    siteProperties.SharingCapability = Sharing.Value;
                    executeQueryRequired             = true;
                }
                if (StorageMaximumLevel.HasValue)
                {
                    siteProperties.StorageMaximumLevel = StorageMaximumLevel.Value;
                    executeQueryRequired = true;
                }
                if (StorageWarningLevel.HasValue)
                {
                    siteProperties.StorageWarningLevel = StorageWarningLevel.Value;
                    executeQueryRequired = true;
                }
                if (AllowSelfServiceUpgrade.HasValue)
                {
                    siteProperties.AllowSelfServiceUpgrade = AllowSelfServiceUpgrade.Value;
                    executeQueryRequired = true;
                }
                if (NoScriptSite.HasValue)
                {
                    siteProperties.DenyAddAndCustomizePages = (NoScriptSite == true ? DenyAddAndCustomizePagesStatus.Enabled : DenyAddAndCustomizePagesStatus.Disabled);
                    executeQueryRequired = true;
                }
                if (CommentsOnSitePagesDisabled.HasValue)
                {
                    siteProperties.CommentsOnSitePagesDisabled = CommentsOnSitePagesDisabled.Value;
                    executeQueryRequired = true;
                }
                if (DefaultLinkPermission.HasValue)
                {
                    siteProperties.DefaultLinkPermission = DefaultLinkPermission.Value;
                    executeQueryRequired = true;
                }
                if (DefaultSharingLinkType.HasValue)
                {
                    siteProperties.DefaultSharingLinkType = DefaultSharingLinkType.Value;
                    executeQueryRequired = true;
                }
                if (DisableAppViews.HasValue)
                {
                    siteProperties.DisableAppViews = DisableAppViews.Value;
                    executeQueryRequired           = true;
                }
                if (DisableCompanyWideSharingLinks.HasValue)
                {
                    siteProperties.DisableCompanyWideSharingLinks = DisableCompanyWideSharingLinks.Value;
                    executeQueryRequired = true;
                }
                if (DisableFlows.HasValue)
                {
                    siteProperties.DisableFlows = DisableFlows.Value ? FlowsPolicy.Disabled : FlowsPolicy.NotDisabled;
                    executeQueryRequired        = true;
                }
                if (LocaleId.HasValue)
                {
                    siteProperties.Lcid  = LocaleId.Value;
                    executeQueryRequired = true;
                }
                if (RestrictedToGeo.HasValue)
                {
                    siteProperties.RestrictedToRegion = RestrictedToGeo.Value;
                    executeQueryRequired = true;
                }
                if (SocialBarOnSitePagesDisabled.HasValue)
                {
                    siteProperties.SocialBarOnSitePagesDisabled = SocialBarOnSitePagesDisabled.Value;
                    executeQueryRequired = true;
                }
                if (executeQueryRequired)
                {
                    siteProperties.Update();
                    tenant.Context.ExecuteQueryRetry();
                }

                if (DisableSharingForNonOwners.IsPresent)
                {
                    Office365Tenant office365Tenant = new Office365Tenant(context);
                    context.Load(office365Tenant);
                    context.ExecuteQueryRetry();
                    office365Tenant.DisableSharingForNonOwnersOfSite(siteUrl);
                    context.ExecuteQueryRetry();
                }
            }
        }
Example #30
0
        static void Main(string[] args)
        {
            ConsoleColor defaultForeground = Console.ForegroundColor;
            // Something like: https://contoso-admin.sharepoint.com
            string tenantAdminUrl = GetInput("Enter the admin URL of your tenant", false, defaultForeground);
            // User name and pwd to login to the tenant
            string userName = GetInput("Enter your user name", false, defaultForeground);
            string pwd = GetInput("Enter your password", true, defaultForeground);
            // File URL to the profile value like: https://contoso.sharepoint.com/Shared%20Documents/sample.txt
            string fileUrl = GetInput("Enter the URL to the file located in your tenant", false, defaultForeground);

            // Get access to source tenant with tenant permissions
            using (var ctx = new ClientContext(tenantAdminUrl))
            {
                //Provide count and pwd for connecting to the source
                var passWord = new SecureString();
                foreach (char c in pwd.ToCharArray()) passWord.AppendChar(c);
                ctx.Credentials = new SharePointOnlineCredentials(userName, passWord);

                // Only to check connection and permission, could be removed
                ctx.Load(ctx.Web);
                ctx.ExecuteQuery();
                string title = ctx.Web.Title;

                // Let's get started on the actual code!!!
                Office365Tenant tenant = new Office365Tenant(ctx);
                ctx.Load(tenant);
                ctx.ExecuteQuery();

                /// /// /// /// /// /// /// /// ///
                /// DO import based on file whcih is already uploaded to tenant
                /// /// /// /// /// /// /// /// ///

                // Type of user identifier ["PrincipleName", "EmailAddress", "CloudId"] 
                // in the User Profile Service.
                // In this case we use email as the identifier at the UPA storage
                ImportProfilePropertiesUserIdType userIdType = 
                            ImportProfilePropertiesUserIdType.Email;

                // Name of user identifier property in the JSON
                var userLookupKey = "IdName";

                var propertyMap = new System.Collections.Generic.Dictionary<string, string>();
                // First one is the file, second is the target at User Profile Service
                // Notice that we have here 2 custom properties in UPA called 'City' and 'Office'
                propertyMap.Add("Property1", "City");
                propertyMap.Add("Property2", "Office");

                // Returns a GUID, which can be used to see the status of the execution and end results
                var workItemId = tenant.QueueImportProfileProperties(
                                        userIdType, userLookupKey, propertyMap, fileUrl
                                        );

                ctx.ExecuteQuery();

                /// /// /// /// /// /// /// /// /// /// 
                // CALL CHECK STATUS in OWN method with the received GUID
                /// /// /// /// /// /// /// /// /// /// 
                CheckStatusOfRequestedProcess(ctx, workItemId.Value);

                // Just to pause and indicate that it's all done
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("\n-----------------------------------------");
                Console.WriteLine("We are all done. Press enter to continue.");
                Console.ReadLine();
            }
        }
Example #31
0
        /// <summary>
        /// Demonstrates how to check status for specific submission or for all submissions
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="workItemId"></param>
        private static void CheckStatusOfRequestedProcess(ClientContext ctx, Guid workItemId)
        {
            ///
            /// CHECK STATUS of the property job with GUID - notice that there's additional logs in the folder as well
            ///
            
            // Check status of specific request based on received GUID
            Office365Tenant tenant = new Office365Tenant(ctx);
            var job = tenant.GetImportProfilePropertyJob(workItemId);
            ctx.Load(job);
            ctx.ExecuteQuery();
            Console.Write("\n--\n");
            Console.WriteLine(string.Format("ID: {0} - Request status: {1} - Error status: {2}",
                                  job.JobId, job.State.ToString(), job.Error.ToString()));
            Console.Write("\n--\n");

            /// 
            /// Get list of all jobs in the tenant
            /// 
            var jobs = tenant.GetImportProfilePropertyJobs();
            ctx.Load(jobs);
            ctx.ExecuteQuery();
            foreach (var item in jobs)
            {
                Console.WriteLine(string.Format("ID: {0} - Request status: {1} - Error status: {2}",
                                   item.JobId, item.State.ToString(), item.Error.ToString()));
            }
        }
Example #32
0
        static void Main(string[] args)
        {
            //get governance variables such as warning duration and cutoff duration
            int warningDuration = Convert.ToInt32(ConfigurationManager.AppSettings["WarningDuration"]);
            int cutoffDuration = Convert.ToInt32(ConfigurationManager.AppSettings["CutoffDuration"]);
            string tenantName = ConfigurationManager.AppSettings["TenantName"];
            string tenantUpnDomain = ConfigurationManager.AppSettings["TenantUpnDomain"];
            Uri tenantAdminUri = new Uri(String.Format("https://{0}-admin.sharepoint.com", tenantName));

            string webUrl = "";
            #if DEBUG
            webUrl = "http://localhost:25440/";
            #else
            webUrl = "https://sposharing.azurewebsites.net/";
            #endif

            foreach (var siteUrl in sites)
            {
                //initialize a process date for this site and clean up to match SQL percision
                DateTime processDate = DateTime.Now;
                string stringTicks = processDate.Ticks.ToString();
                int adjustmentTicks = Convert.ToInt32(stringTicks.Substring(stringTicks.Length - 5));
                processDate = processDate.Subtract(TimeSpan.FromTicks(adjustmentTicks));

                //use O365 Tenant Administration to get all the external sharing details for this site
                List<ExternalShareDetails> shares = new List<ExternalShareDetails>();
                string adminRealm = TokenHelper.GetRealmFromTargetUrl(tenantAdminUri);
                var adminToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, tenantAdminUri.Authority, adminRealm).AccessToken;
                using (var clientContext = TokenHelper.GetClientContextWithAccessToken(tenantAdminUri.ToString(), adminToken))
                {
                    //load the tenant
                    var tenant = new Office365Tenant(clientContext);
                    clientContext.Load(tenant);
                    clientContext.ExecuteQuery();

                    //initalize varables to going through the paged results
                    int position = 0;
                    bool hasMore = true;
                    while (hasMore)
                    {
                        //get external users 50 at a time (this is the limit and why we are paging)
                        var externalUsers = tenant.GetExternalUsersForSite(siteUrl, position, 50, String.Empty, SortOrder.Descending);
                        clientContext.Load(externalUsers, i => i.TotalUserCount);
                        clientContext.Load(externalUsers, i => i.ExternalUserCollection);
                        clientContext.ExecuteQuery();

                        //convert each external user to our own entity
                        foreach (var extUser in externalUsers.ExternalUserCollection)
                        {
                            position++;
                            shares.Add(new ExternalShareDetails()
                            {
                                AcceptedAs = extUser.AcceptedAs.ToLower(),
                                DisplayName = extUser.DisplayName,
                                InvitedAs = extUser.InvitedAs.ToLower(),
                                InvitedBy = (String.IsNullOrEmpty(extUser.InvitedBy)) ? null : extUser.InvitedBy.ToLower(),
                                UserId = extUser.UserId,
                                WhenCreated = extUser.WhenCreated
                            });
                        }
                        
                        //determine if we have more pages to process
                        hasMore = (externalUsers.TotalUserCount > position);
                    }
                }

                //get an AppOnly accessToken and clientContext for the site collection
                Uri siteUri = new Uri(siteUrl);
                string realm = TokenHelper.GetRealmFromTargetUrl(siteUri);
                string accessToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, siteUri.Authority, realm).AccessToken;
                using (var clientContext = TokenHelper.GetClientContextWithAccessToken(siteUri.ToString(), accessToken))
                {
                    //first we need to load the site to determine if external sharing is enabled (Site.ShareByEmailEnabled)
                    var site = clientContext.Site;
                    var siteOwner = clientContext.Site.Owner;
                    clientContext.Load(site);
                    clientContext.Load(siteOwner); //include the site owner in case the share "InvitedBy" is null...we will send them email instead
                    clientContext.ExecuteQuery();

                    //validate that the site has sharing turned on
                    if (site.ShareByEmailEnabled)
                    {
                        //process all of the shares
                        foreach (var externalShare in shares)
                        {
                            //look for an existing record in the database
                            using (ExternalSharingDataEntities entities = new ExternalSharingDataEntities())
                            {
                                var shareRecord = entities.ExternalShares.FirstOrDefault(i => i.LoginName.Equals(externalShare.AcceptedAs));
                                if (shareRecord != null)
                                {
                                    //Update LastProcessedDate column of the record with the processDate
                                    shareRecord.LastProcessedDate = processDate;
                                    entities.SaveChanges();
                                }
                                else
                                {
                                    //get the original share date
                                    var details = getREST(accessToken, String.Format("{0}/_api/Web/SiteUserInfoList/Items({1})/FieldValuesAsText", siteUrl, externalShare.UserId));
                                    externalShare.WhenCreated = Convert.ToDateTime(details.Descendants(ns + "Created").FirstOrDefault().Value);
                                    shareRecord = new ExternalShare()
                                    {
                                        UniqueIdentifier = Guid.NewGuid(),
                                        SiteCollectionUrl = siteUrl.ToLower(),
                                        LoginName = externalShare.AcceptedAs,
                                        UserId = externalShare.UserId,
                                        InvitedBy = (String.IsNullOrEmpty(externalShare.InvitedBy)) ? siteOwner.Email : externalShare.InvitedBy,
                                        OriginalSharedDate = externalShare.WhenCreated,
                                        LastProcessedDate = processDate
                                    };
                                    entities.ExternalShares.Add(shareRecord);
                                    entities.SaveChanges();
                                }

                                //check if the record falls inside the warnings
                                double daysActive = processDate.Subtract(shareRecord.OriginalSharedDate).TotalDays;
                                if (shareRecord.RefreshSharedDate != null)
                                    daysActive = processDate.Subtract((DateTime)shareRecord.RefreshSharedDate).TotalDays;

                                //check for cutoff
                                if (daysActive > cutoffDuration)
                                {
                                    //remove the SPUser from the site
                                    clientContext.Web.SiteUsers.RemoveById(externalShare.UserId);
                                    clientContext.ExecuteQuery();

                                    //delete the record
                                    entities.ExternalShares.Remove(shareRecord);
                                    entities.SaveChanges();
                                }
                                else if (daysActive > warningDuration)
                                {
                                    int expiresIn = Convert.ToInt32(cutoffDuration - daysActive);
                                    //send email to InvitedBy (which will be site collection owner when null)
                                    EmailProperties email = new EmailProperties();
                                    email.To = new List<String>() { shareRecord.InvitedBy };
                                    email.Subject = String.Format("Action Required: External sharing with {0} about to expire", externalShare.AcceptedAs);
                                    email.Body = String.Format("<html><body><p>You are receiving this message because you are the site administrator of <a href='{0}'>{0}</a> OR you shared it with {1}. The external access for this user is set to expire in {2} days. Use the link below to view additional details and perform actions to revoke OR extend access for another {3} days. If you do not act on this notice, the external access for this user to terminate in {2} days.</p><ul><li><a href='{4}Details/{5}'>View Details</a></li><li><a href='{4}Extend/{5}'>Extend {3} Days</a></li><li><a href='{4}Revoke/{5}'>Revoke Access</a></li></ul></body></html>", siteUrl, externalShare.AcceptedAs, expiresIn.ToString(), cutoffDuration.ToString(), webUrl, shareRecord.UniqueIdentifier);
                                    Utility.SendEmail(clientContext, email);
                                    clientContext.ExecuteQuery();
                                }
                            }
                        }
                    }
                 }

                //delete all database records for this site that have an older processDate...these should represent external users deleted by manually
                using (ExternalSharingDataEntities entities = new ExternalSharingDataEntities())
                {
                    var cleanUpRecords = entities.ExternalShares.Where(i => i.SiteCollectionUrl.Equals(siteUrl.ToLower()) && i.LastProcessedDate < processDate);
                    foreach (var record in cleanUpRecords)
                    {
                        entities.ExternalShares.Remove(record);
                        entities.SaveChanges();
                    }
                }
            }
        }