If somebody like the post and its helpful in your work then, add comments.

Monday, April 24, 2017

Office 365 : send email from SharePoint Online using CSOM PowerShell


Below script:

Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll'
Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll'
  
$username = "[UserName]"
$securePassword = ConvertTo-SecureString "[Password]" -AsPlainText -Force
       
$spoCred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $securePassword)
$context = New-Object Microsoft.SharePoint.Client.ClientContext("[https://[XXXXXXXXXXXXXXXXXX]/")
$context.Credentials = $spoCred                                                                
$toEmail ="[Email1]","[Email2]"  
$toSubject ="[Subject]"
$toBody ="[BODY]"       

[String[]]$email =  $toEmail
$emailProperties = New-Object Microsoft.SharePoint.Client.Utilities.EmailProperties

write-host  $emailProperties
$emailProperties.To = $email
$emailProperties.CC = [String[]]("[Email]")
$emailProperties.From = "[Email]"
$emailProperties.Subject = $toSubject
$emailProperties.Body = $toBody
[Microsoft.SharePoint.Client.Utilities.Utility]::SendEmail($context,$emailProperties)
$context.ExecuteQuery()  
                        

Windows PowerShell : Create Month folders

To create folder user below script in WINDOWS ISE.

$path ="[Path]\"
$months = "April 2018","May 2018","June 2018","July 2018","August 2018","September 2018","October 2018","November 2018","December 2018","January 2019","February 2019","March 2019"
foreach($month in $months)
{
    New-Item -ItemType Directory -Path "$path$month"
}

Friday, November 6, 2015

SharePoint Office 365 ECMA : Get version of the List Item

Hi,

To get version of the SharePoint list items; there are two option in JavaScript
  1. SPServices
$().SPServices({
            operation: "GetVersionCollection",
            async: false,
            strlistID: "Deviations",
            strlistItemID: DID,
            strFieldName: "PreventionDescription",
            completefunc: function (xData, Status) {
                // alert(xData.responseXML.xml)
                $(xData.responseText).find("Version").each(function () {
                    preventiveListTemp.push({
                        "Description": $(this).attr("PreventionDescription"),
                        "Editor": $(this).attr("Editor").split(",#")[4],
                        "Modified": $(this).attr("Modified"),
                        "Image": "/_layouts/15/userphoto.aspx?size=S&accountname=" + $(this).attr("Editor").split(",#")[3].toLowerCase().replace("@", "%40")
                    });
                });
            }
        });
  1. ECMA 

  • var filePath = '/sites/dk/sites/Departments/qms/Lists/Deviations/' + DID + '_.000'
    var clientContext = new SP.ClientContext;
    //var oList = clientContext.get_web().get_lists().getByTitle('Deviations');
    var web = clientContext.get_web();
    var listItemInfo = web.getFileByServerRelativeUrl(filePath);
    var listItemFields = listItemInfo.get_listItemAllFields();
    clientContext.load(web);
    clientContext.load(listItemInfo);
    clientContext.load(listItemFields);
    clientContext.executeQueryAsync(function (sender, args) {
        var fileVersions = listItemInfo.get_versions();
        clientContext.load(fileVersions);
        clientContext.executeQueryAsync(function (sender, args) {
            var fieldEnumerator = fileVersions.getEnumerator();
            while (fieldEnumerator.moveNext()) {
                var oListItemVersion = fieldEnumerator.get_current();

                // preventiveListTemp.push({

                // });

            }

        }, onQueryFailed);

    }, onQueryFailed);
  • Friday, May 22, 2015

    SharePoint ECMA : Get pages library items in ECMA

    To get the pages library items,  using the JavaScript/JSOM. For that in the clientContext.load we have to pass "File" parameter and than the site columns(internal names)

    getNewsPages = function() {
                     var clientContext = new SP.ClientContext.get_current();
                    var oList = clientContext.get_web().get_lists().getByTitle('Pages');
                    var camlQuery = new SP.CamlQuery();
                    camlQuery.set_viewXml(" 50");
                    selectedDoc = oList.getItems(camlQuery);
                    clientContext.load(selectedDoc , 'Include(Id, Title,File,PublishedDate1,TeaserText,TeaserImage,FileRef,NewsFilter)');
                    clientContext.executeQueryAsync(gettingNewsPagesSuccess , onQueryFailed);

                },
                gettingNewsPagesSuccess = function() {
                    var listItemEnumerator = selectedDoc.getEnumerator();
                    while (listItemEnumerator.moveNext()) {
                        var oListItem = listItemEnumerator.get_current();
                        tempList.push({
                            "Id": oListItem.get_id(),
                            "Title": oListItem.get_item('Title') ,
                            "PublishedDate": oListItem.get_item('PublishedDate1'),
                            "TeaserText": oListItem.get_item('TeaserText') ,
                            "TeaserImage": oListItem.get_item('TeaserImage'),
                            "Path": oListItem.get_item('FileRef'),
                            "NewsFilter": oListItem.get_item('NewsFilter')
                        });
                    }

                },

    Monday, March 2, 2015

    Office 365 : Create a site using custom site template

    To create a site using your designed custom site template in JSOM/ECMA, we can use below example :

     createProjectSite = function ($data) {
                dialogValue = SP.UI.ModalDialog.showWaitScreenWithNoClose("Site Creation", "Working on it...", 120, 400);
                id($data.Id);
                var url = $data.Title.replace(/[^a-z0-9\s]/gi, '').replace(/[_\s]/g, '');
                currentProjectObject = $data;
                var clientContext = CORO.megaMenucontext;
       


                var WCI = new SP.WebCreationInformation();
                WCI.set_webTemplate('{a5269682-aec6-49d7-b3f5-7481039abff8}#ProjectTemplate');
                WCI.set_description($data.ProjectDescription);
                WCI.set_title($data.Title);
                WCI.set_url(url);
                WCI.set_language('1033');
                if ($data.Access == "Public") { WCI.set_useSamePermissionsAsParentSite(true); }//To inherit the permission
                if ($data.Access == "Closed") { WCI.set_useSamePermissionsAsParentSite(false); }//To break the permission
                newWeb = projectWeb.get_webs().add(WCI);
                //save changes and generate callbacks
                clientContext.load(projectWeb);
                clientContext.executeQueryAsync(onCreationSuccess, onQueryFailed);
            },

    Office 365 : How to update quick launch node in SharePoint 2013

    To update a navigation note in SharePoint quick lanuch, we can do by JSOM. In below example we are updating the red box node.
            collChildNavNode =null,
            getNavigationNode = function(web, listData)
            {
                 var clientContext = CORO.megaMenucontext;
                // Get the Quick Launch navigation node collection.
                quickLaunchNodeCollection = web.get_navigation().get_quickLaunch();
                clientContext.load(quickLaunchNodeCollection);
                clientContext.executeQueryAsync(getNavigationNodeSuccess,onQueryFailed);
            },
            getNavigationNodeSuccess = function (sender, args) {
                var url = currentProjectObject .Title.replace(/[^a-z0-9\s]/gi, '').replace(/[_\s]/g, '');
                var clientContext = CORO.megaMenucontext;
                collChildNavNode = quickLaunchNodeCollection.get_item(0);     
                clientContext.load(collChildNavNode);
                clientContext.executeQueryAsync(createNavNode ,onQueryFailed);
            },
            createNavNode = function()
            {
                var url = currentProjectObject .Title.replace(/[^a-z0-9\s]/gi, '').replace(/[_\s]/g, '');
                var clientContext = CORO.megaMenucontext;
                collChildNavNode.set_title('Home');
                collChildNavNode.set_url("/sites/dk/sites/projects/" +url);       
                collChildNavNode.update();    
                clientContext.executeQueryAsync(createNavNodeSuccess, onQueryFailed);
            },
            createNavNodeSuccess = function()
            {
                console.log("Created navigation node");
            },

    Thursday, September 18, 2014

    SharePoint 2013 : Running the pre-requisite in Windows Server 2012 R2

    Well, when we want to start the installing SharePoint 2013 or SharePoint 2013 foundation in Windows Server 2012 R2 there is more often problem comes that the pre-requisite didn’t run in the in Windows Server 2012 R2 machine. There is due to because the pre- requisite is searching for the SeverManagerCmd.exe in Windows/System32 location, instead of that in R2 version the application name is SeverManager.exe.

    So, to run the pre-requisite in Windows Server 2012 R2, Copy the SeverManager.exe, and paste in the same location i.e Windows/System32 and rename to SeverManagerCmd.exe. Then run the pre-requisite application from SharePoint iso/disc/installer. It will work fine

    Friday, August 29, 2014

    SharePoint 2013 : How to open and close SP.UI.ModalDialog.showWaitScreenWithNoClose

    How to use SP.UI.ModalDialog.showWaitScreenWithNoClose to display custom loading message. Simplest way is that just write below code where you have to call the loader/model box of waiting

    var value = SP.UI.ModalDialog.showWaitScreenWithNoClose(title, message, height, width);
    and to close just add below code
    value.close(0);
    value=null;
     
    There are lost of option are also available, which can be seen on 
    http://msdn.microsoft.com/en-us/library/office/ff408140%28v=office.14%29.aspx
     
    image

    Friday, August 1, 2014

    Yammer : How to get current logged in user unseen message count

    Well this is my first application of Yammer, I was wondering how to start on the application. So, first thing come in my mind that to explore the Yammer,

    What is yammer?

    How can we use it?

    What are the entities in yammer, which we can use or integrate in our application. etc

    So, logged in Yammer, created network added the people. So, now when all thing are up then for just creating a sample application a scenario occurs in my mind “current logged in user unseen message count”. How to start on the, where to deploy that????

    I added one more Technology my FAV one, SharePoint. Final scenario showing  current logged in user unseen message count in SharePoint online. Created a trial account in that and create on page. First I tried with yammer default feed JS code. It works find ….OK.

    So, for custom development I looked on Google and found the wonderful description on yammer API. How to consume in various domains, how add in various platforms. Link is below

    https://developer.yammer.com/connect/

    To get current logged in user unseen message count

    <h1><b>Yammer</b></h1> 
        <h3 > Unseeen Messages</h3><div id="numberOfMessages"></div>
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
        <script type="text/javascript" data-app-id="[Your App ID]" src="https://assets.yammer.com/assets/platform_js_sdk.js"></script>
     

        <span id="yammer-login"></span>
       
        <script type="text/javascript" >
            yam.getLoginStatus(
          function(response) {
            if (response.authResponse) {
                  console.log("logged in");            
                   yam.platform.request({
                    url: "networks/current.json",
                    method: "GET",       
                    beforeSend: function (req) { //print message response information to the console
                        yam.platform.setAuthToken(response.access_token);
                    } ,
                   
                    success: function (user) { //print message response information to the console
                        document.getElementById('numberOfMessages').innerHTML= user[0].unseen_message_count;
                    },
                    error: function (user) {
                      alert("There was an error with the request.");
                    }
                  });

            }     
          }
        );
        </script>

    but before adding the above code we have to create on app in yammer

    image

    image

    image

    remember this redirect URL should be match with your domain and JavaScript origin will be the URL of page where the JS or JS is rendering.

    Click Save

    image

    This big bold highlighted one is the key point where I stuck an have goggling for like 2 days Smile

    image

    image

    Monday, June 30, 2014

    SharePoint 2013 : How to add Device Channel in site/master page

    A Device Channel Panel is a control that you can add to a master page or page layout to control what content is rendered in each channel that you create. A Device Channel Panel is a container that specifies one or more channels; if one or more of those channels are active when the page is rendered, all of the contents of the Device Channel Panel are also rendered. A Device Channel Panel can include almost any type of content, including a link to a CSS file or a .js file. It is an easy way to include specific content for specific channels.

    There are two limitations to using a Device Channel Panel:

    • Display templates Because display templates are rendered on the client side and Device Channel Panels run on the server side, you cannot use a Device Channel Panel within a display template. Instead, you should use two different Content Search Web Parts within Device Channel Panels on your page layout, or use the JavaScript variable to trigger the behavior you want within the display template itself.

    • Web Part zones You cannot insert a Web Part zone inside a Device Channel Panel. If you want to allow authors to add Web Parts to a page, and if you are not concerned about the page weight for mobile devices, you can add a Rich Text Editor page field to a Device Channel Panel, and then instruct authors to add Web Parts there. You can add Web Parts directly to a Device Channel Panel (without a Web Part zone).

    How to configure device channels?

    1. Go to settings of the site
    2. image
    3. Open the Device Channel from Look and feel section on the page
    4. image
    5. Default View of the Device Channel settings page
    6. image
    7. Add rule for the device
    8. image
    9. Add rule for example for windows phone 8.1
    10. image
    11. image
    12. And save the configuration
    13. Go to site settings and select Master page
    14. image
    15. Open the settings
    16. image

    Having applied the configuration, if you navigate to the website now using a Windows Phone you should see the Device Channel automatically applied.

    Monday, May 5, 2014

    SharePoint 2010 : Share value between itemupdating and itemupdated events in SandBox Event receiver

     

    Well, create one column in the Main List, where values are changes say "OLDVALUES". Set that field using the properties.ListItem["OLDVALUES"]=Value1+";" +Value2+";" +Value3+";"; in ItemUpdating event(take Value1, Values2 and Value3 using the properties.ListItem["Value1"] and son on).

    Now in Item Updating, use like string oldValue = properties.ListItem["OLDVALUES"].ToString(); and slip in array and then you can set global variables and access them in your code. Remember its a SandBox solution approach for event receivers, not for farm solution.

    Thursday, March 13, 2014

    Pager in Knockout JS without using Paged Grid

    Knockout JS as we know is a highly versatile JavaScript library that helps us implement the MVVM pattern on the client by providing us with two way data binding and templating capabilities. Today we will use Knockout JS and JSON data to build a pager.

    Paging is method the break large data in  piece of number of records, which is know as page size. The major component of the Paging are

    1. Previous
    2. Next
    3. Pages
    4. Page Size
    5. Current Page Index
    6. Max Page size
    7. A list with required pages

    So for creation in paging in knockout JS we have to declare certain observables and observable arrays as follows:

    • allPages = ko.observableArray(), // it will have all the information with all the required records
    • pageIndex = ko.observable(1) //Current page index
    • pageSize = ko.observable(10) //Can be configured as required for page size
    • pageCount = ko.observable()
    • maxPageIndex = ko.observable() //Maximum index

     

    Now we have to add some methods for next, previous, move to current ;page etc.

    • First method is move next

    nextPage = function () {
                if (pageIndex() < maxPageIndex()) {
                    pageIndex(pageIndex() + 1);
                

                  updatePageIndex(pageIndex());
                }
            }

    • Second is move to previous

    previousPage = function () {
                if (pageIndex() > 0) {
                    pageIndex(pageIndex() - 1);
                    // your code for array updation

                    updatePageIndex(pageIndex());
                }

            },

    • Third is move to current page

    moveToPage = function (index) {
               pageIndex(index);


                // your code for array updation


               updatePageIndex(index);
           },

    • Fourth for making the page size to 5 and middle logic

      updatePageIndex = function (index) {
                 if (index != 1 && index != 2 && index != maxPageIndex() && index != maxPageIndex() - 1) {
                     allPages([]);
                     allPages.push({ pageNumber: (index - 2) })
                     allPages.push({ pageNumber: (index - 1) })
                     allPages.push({ pageNumber: (index) })
                     allPages.push({ pageNumber: (index + 1) })
                     allPages.push({ pageNumber: (index + 2) })
                 }
                 else if (index == maxPageIndex() && index > 5) {
                     allPages([]);
                     allPages.push({ pageNumber: (index - 4) })
                     allPages.push({ pageNumber: (index - 3) })
                     allPages.push({ pageNumber: (index - 2) })
                     allPages.push({ pageNumber: (index - 1) })
                     allPages.push({ pageNumber: (index) })
                 }
             },

    • Fifth one for updating the pagesize when any index is clicked

                allPages([]);
                pageCount = Math.ceil(totalRequestCount() / pageSize());
                maxPageIndex(pageCount);
                if (pageCount < 6) {
                    for (var i = 0; i < pageCount; i++) {
                        allPages.push({ pageNumber: (i + 1) })
                    }
                }
                else if (pageCount >= 6) {
                    for (var i = 0; i < 5; i++) {
                        allPages.push({ pageNumber: (i + 1) })
                    }
                }

    Now we have need of HTML, which will consume/bind all above variables and methods

     

    <div style="width: 850px; text-align: center; margin: auto;" >
                <div style="">
                    <ul class="pagination">
                        <li><a href="#">
                            <img src="/images/arrow-start.png" width="26" height="25" data-bind=" disable : ( $root.paging.pageIndex() == 1),click: $root.paging.previousPage" /></a> </li>
                    </ul>
                    <ul class="pagination paginationMargin" style="margin:0px;" data-bind="foreach: $root.paging.allPages">
                        <li data-bind="css: { active: $data.pageNumber === ($root.paging.pageIndex()) }"><a href="#" data-bind="    text: $data.pageNumber, click: function () { $root.paging.moveToPage($data.pageNumber); }"></a></li>
                    </ul>
                    <!-- ko if: (($root.paging.maxPageIndex() != $root.paging.pageIndex()) && ($root.paging.maxPageIndex()-2 != $root.paging.pageIndex()) && ($root.paging.maxPageIndex()-1 != $root.paging.pageIndex())  && ($root.paging.maxPageIndex() > 5))-->
                    <ul class="pagination paginationMargin">
                        <li><a href="#">......</a> </li>
                        <li><a href="#" data-bind="text: $root.paging.maxPageIndex(), click: function () { $root.paging.moveToPage($root.paging.maxPageIndex()); }">......</a> </li>
                    </ul>
                    <!-- /ko -->
                    <ul class="pagination">
                        <li><a href="#" >
                            <img src="/images/arrow-end.png" width="26" height="25" data-bind="disable  : ($root.paging.pageIndex() == $root.paging.maxPageIndex()) ,click: $root.paging.nextPage" /></a> </li>
                    </ul>
                </div>

    Well above HTML have some classes which you have to add your self, I have just given the name of that or you can use any other styles also from searching the paging template available from Google. After above JavaScript code and HTML the paging will look like in a page as below :

    image
    image
     

    Monday, February 10, 2014

    SharePoint 2013 : Create a custom web template from publishing site

    Well, to create a custom template in SharePoint 2013 or in Office 365 SharePoint, then it’s a very tricky task to complete. The thing very complex with web template is that, it ok up to publishing feature is not enabled in the Template site. But when the publishing feature is activated the that feature automatically gone from SharePoint web site.

    Now, there is trick for that, to add that feature again in Site Settings, juts open that sit in SharePoint designer 2013 and activate/make it true. As this property sets to true the link for “Save as site template” will available.

    Now, when we save that site template from(Publishing site) then it will have base template be PUBLISHING. So, now we have to add theme to it and also set our custom master etc. They are all be done in the Onet.xml which is get when we export that WSP in visual Studio export wizard template.

    Monday, October 21, 2013

    Create SharePoint(2013) Publishing pages using ECMASCRIPT

    Well, to create paged from page layouts in the Publishing site in SP2013, I have tried the below code

    First get the context for web,

                 context = new SP.ClientContext(webUrl);  web = context .get_web();

    Then get the publishing web for the site

                                   pubweb = SP.Publishing.PublishingWeb.getPublishingWeb(context1, web );

                                    context .load(web );

                                    context .load(pubweb);                               

                                     context .executeQueryAsync(onquerysucced,onqueryfailed);

    In onquerysucced get all the pages in the master page library

                

    var pageLibrary = web.get_lists().getByTitle("Master Page Gallery");  

    var camlQuery = new SP.CamlQuery;

    items = pageLibrary.getItems('');

    context .load(items,'Include(Id,Title,File)');

    context .executeQueryAsync(onPagelayoutsuccess,onqueryfailed);

     

    In onPagelayoutsuccess method

                 var listItemEnumerator = items.getEnumerator();

                 var listItemInfo = '';

                 while (listItemEnumerator .moveNext()) {

                var oListItem = listItemEnumerator.get_current();

                    pageItems.push({

                    "Id":oListItem.get_id(),

                    "Title":oListItem.get_item('Title'),

                    "obj" :oListItem //Add Object in the list            

                    });

                 pageItems.push(oListItem);

                 }

                 //knockout js work for finding the required page layout item from the list

                 var newPage = ko.utils.arrayFirst(pageItems(), function(item) {

                                    return item.Title == "CT_PageLayout.aspx";

                                    }); 

                

              pageInfo = new SP.Publishing.PublishingPageInformation();

              pageInfo.set_name("CT_PageLayout.aspx");

              pageInfo.set_pageLayoutListItem(newPage.obj);

              newPage = pubweb.addPublishingPage(pageInfo);

              context.load(newPage);

              context.executeQueryAsync(onPageCreationSuccess,onqueryfailed);

             };

             function onPageCreationSuccess(){                                

                                                                    listItem = newPage.get_listItem();

                    context.load(listItem);

                     context.executeQueryAsync(onPageSuccess,onqueryfailed);

              };

    Tuesday, October 8, 2013

    SharePoint 2013 : Get SharePoint items in Knockout js observableArray

    To get the list tem in the observableArray, just declare a array in the js and get as below code

    list = ko.observableArray(),


     getCourses = function () {
    var
    clientContext = TRANAPP.context;
    var oList = clientContext.get_web().get_lists().getByTitle('Courses'
    );
    var myQueryString = '<View><RowLimit>1000</RowLimit></View>'
    ;
    var newQuery = new
    SP.CamlQuery();
    newQuery.set_viewXml(myQueryString);
    courseItems = oList.getItems(newQuery);
    clientContext.load(courseItems,
    'Include(Id, Title, CourseDescription, Author)'
    );
    clientContext.executeQueryAsync(onGettingCourses, onQueryFailed);
    },
    onGettingCourses =
    function
    (sender, args) {
    var
    allCourse = courseItems.getEnumerator();
    while
    (allCourse.moveNext()) {
    var
    currentCourse = allCourse.get_current();
    list.push({
    "Title": currentCourse.get_item('Title'
    ),
    "Id"
    : currentCourse.get_id(),
    "CourseDescription": currentCourse.get_item('CourseDescription'
    )
    });
    }
    },
    onQueryFailed = function (sender, args) {
    alert(
    'Request failed. ' + args.get_message() + '\n'
    + args.get_stackTrace());
    },

    SharePoint : Open the list item directly to edit mode.

    To open the list item directly to edit form instead of the display form.

    image

    Then we have to edit the view on which the list item is showing. Just open the view in the designer in advanced mode and click on the “Title” column=>SQL server basics.

    image

    And see the properties which are associated,

    image

    Change the HREF property to below property just change the “$FORM_DISPLAY” to “$FORM_EDIT”

    {$FORM_EDIT}&ID={$ID}&ContentTypeID={$thisNode/@ContentTypeId}

    SharePoint 2013 : Add lookup column from in a list from VS2012

    To add the lookup column in the SharePoint list in visual studio 2012 wizard we have to create first list from we have to add lookup column in anther list.

    image

    Then add anther list, like below in this list Course is lookup column

    image

    Just edit the properties other lookup column ‘Course’, and add the List to =Lists/Courses and  ShowField to Title

    image

    SharePoint 2013 : Add date and time field on your custom page

    Add the date and time SharePoint control in the SharePoint 2013 hosted app.

    image

    Just drag and drop the controls on the page from toolbox of the VS2012

     

    image

    The code block will look like as follows :

    <SharePoint:DateTimeControl ID="srtDate" ClientIDMode="Static" AutoPostBack="false"
                           runat="server" ToolTip="Start date for training beginning" />

    But when you render this control from your app it does not load on the page, and give below screen error.(500 INTERNAL SERVER ERROR)

    image
    Then add the following property of the control : DatePickerFrameUrl="../_layouts/15/iframe.aspx" and add the ralative pat of the app like as I added “../”. After that it will render the control on the page.

    image

    Wednesday, September 25, 2013

    SharePoint 2013 : Create a declarative workflow in O365 SharePoint Hosted App

    Hi,

    Well, recently I encountered Smile with one requirement to send email from Office 365 SharePoint Site. The scenario is like send a mail from SharePoint List, and have to take email address from the SharePoint List column, say Email.

    Snap

     

    image

    Variables image
    image image
    image image
    image image
    image image
    image image
    image image
    image image

    So, In above activity well achieve to send email from list in O365. But still I am looking for sending email’s to other domains.Right Now its sending the email in its domain, like I have created ZapataIndi.onmicrosoft.com.