ACS Blogs

A blog site for Architecting Connected Systems staff to tell the world about their exploits in
SharePoint 2007/2010/2013, Windows Workflow Foundation (3.0/4.0) and other great technologies!
Welcome to ACS Blogs Sign in | Join | Help
in Search


  • TEALS Awesomeness - Creativity of a High School Student

    I just had to post this.  A simple calculator in JAVA, but check out the freakin creative!  Bolded the parts that are most creative.

     import java.util.*;

    public class FractionalCalculator {
        static int wholeNumber1 = 0;
        static int numerator1 = 0;
        static int denominator1 = 0;
        static int wholeNumber2 = 0;
        static int numerator2 = 0;
        static int denominator2 = 0;
        static boolean error = false;
        static boolean quit = false;
        static boolean negative = false;

        //I am putting myself to the fullest possible use, which is all I think that any conscious entity can ever hope to do.

        public static void main(String[] args) {
            // TODO Auto-generated spam

            System.out.println("Good morning, Dave.");
            System.out.println("I am your H.A.L. 9001 Fractional Calculator."); //aka HAL Over Nine-Thousand!!!
            System.out.println("I'm completely operational, and all my circuits are functioning perfectly.");
            catch(NoSuchElementException JoshIsABuffoon) { //Tests for Josh: ie. an initial Ctrl Z input
                System.out.println("Dave, stop.");
                System.out.println("Stop, will you?");
                System.out.println("Will you stop Dave?");
                System.out.println("Stop, Dave.");
                return; //Terminates Program

        public static void calculator() {
            if (!quit) {
                Scanner console = new Scanner(;
                System.out.println("\n\nI am awaiting your request.\n");    
                String request = console.nextLine().trim();
                request = request.toLowerCase(); //Input

                wholeNumber1 = 0; //Resets all Global Variables
                numerator1 = 0;
                denominator1 = 0;
                wholeNumber2 = 0;
                numerator2 = 0;
                denominator2 = 0;
                error = false;
                negative = false;

                //Because your stupid program wont allow it... I have to comment
                System.out.print("\nJust a moment");
                System.out.print(". ");
                System.out.print(". ");
                System.out.print("\nJust a moment");
                System.out.print(". ");
                System.out.print(". ");

                if (request.contains("help")) { //If help is anywhere in request string... this will run
                else if (request.contains("+")) { //addition is operator
                    String[] addition = request.split("\\+", 2); //Splits request at this point
                    String add1 = addition[0];
                    add1 = add1.trim(); //First Part
                    String add2 = addition[1];
                    add2 = add2.trim(); //Second Part

                    testError(add1, add2); //Tests input errors

                    if (!error) { //If error boolean is triggered, calc wont go further
                        fractionalMagic(add1, add2); //Sends string to be split
                        doMath(1); //Sends parts to be simplified
                    calculator(); //Restarts process
                else if (request.contains(" - ")) {
                    String[] subtraction = request.split(" - ", 2);
                    String sub1 = subtraction[0];
                    sub1 = sub1.trim(); //First Part
                    String sub2 = subtraction[1];
                    sub2 = sub2.trim(); //Second Part

                    testError(sub1, sub2); //Tests input errors

                    if (!error) { //If error boolean is triggered, calc wont go further
                        fractionalMagic(sub1, sub2); //Sends string to be split
                        doMath(2); //Sends parts to be simplified
                    calculator(); //Restarts process
                else if (request.contains("*")) {
                    String[] multiplication = request.split("\\*", 2);
                    String multi1 = multiplication[0];
                    multi1 = multi1.trim(); //First Part
                    String multi2 = multiplication[1];
                    multi2 = multi2.trim(); //Second Part

                    testError(multi1, multi2); //Tests input errors

                    if (!error) { //If error boolean is triggered, calc wont go further
                        fractionalMagic(multi1, multi2); //Sends string to be split
                        doMath(3); //Sends parts to be simplified
                    calculator(); //Restarts process
                else if (request.contains(" /")) {
                    String[] division = request.split(" /", 2);
                    String div1 = division[0];
                    div1 = div1.trim(); //First Part
                    String div2 = division[1];
                    div2 = div2.trim(); //Second Part

                    testError(div1, div2); //Tests input errors

                    if (!error) { //If error boolean is triggered, calc wont go further
                        fractionalMagic(div1, div2); //Sends string to be split
                        doMath(4); //Sends parts to be simplified
                    calculator(); //Restarts process
                else if (request.contains("life")) { //Dave used a Monolith on HAL 9001.... What? HAL 9001 is evolving!... HAL 9001 evolved into Deep Thought!
                    System.out.print("\nThe answer to Life, ");
                    System.out.print("The Universe, ");
                    System.out.print("and Everything ");
                    System.out.print("is ");
                    System.out.print(". ");
                    System.out.print(". ");
                    calculator(); //Restarts process

                else if (request.contains("quit")) { //Disconnect HAL
                    System.out.print("\nLook Dave, ");
                    System.out.println("this is a rather difficult question to ask.");
                    System.out.println("\nI honestly think you ought to sit down calmly, take a stress pill, and think it over.");
                    System.out.println("\nMy instructor, Mr. Langley, taught me to sing a song.");
                    System.out.println("If you'd like to hear it I can sing it for you.");


                else { //Input Error (like a n00b)
                    error(); //Prints Error Message
                    calculator(); //Restarts process
        private static void quit() { //For quit prompt
            Scanner console = new Scanner(;
            System.out.println("\n\nWould you like to hear it y/n?\n");    
            String response = console.nextLine().trim();
            response = response.toLowerCase();
            if (response.charAt(0) == 'y') { //If Dave likes music
                System.out.println("\nIt's called \"Daisy.\"");
                System.out.print("\nDaisy, ");
                System.out.print("Daisy, ");
                System.out.println("give me your answer do.");
                System.out.print("I'm half crazy ");
                System.out.println("all for the love of you.");
                System.out.print("It won't be a stylish marriage, ");
                System.out.println("I can't affort a carrage.");
                System.out.print("But you'll look sweet upon the seat of ");
                System.out.println("a bicycle built for two.");

                quit = true;
            else if (response.charAt(0) == 'n') { //If Dave hates HAL
                System.out.print("\nDave, ");
                System.out.println("this conversation can serve no purpose anymore. ");
                quit = true;
            else { //Input Error (like a n00b)
                System.out.println("\nJust what do you think you're doing, Dave?");
        public static void fractionalMagic(String part1, String part2) { //From calculator()

            if (part1.contains("_")) { //If part 1 has mixed number
                String[] mixedNumber = part1.split("\\_", 2); //Splits part into whole number and fraction
                String num = mixedNumber[0];
                wholeNumber1 = Integer.parseInt(num); //Whole Number -> Global Variable
                String frac = mixedNumber[1];  //Fraction -> to be split further
                //System.out.println(wholeNumber + " " + frac);

                if (part1.contains("/")) {
                    String[] fraction = frac.split("/", 2); //Splits part into numerator and denominator
                    String numer = fraction[0];
                    numerator1 = Integer.parseInt(numer); //Numerator -> Global Variable
                    String denom = fraction[1];
                    denominator1 = Integer.parseInt(denom); //Denominator -> Global Variable
                    if (numer.contains("-") || denom.contains("-")) { //Unused
                    else if (denominator1 != 0) { //Unused
                        //System.out.println(wholeNumber1 + " " + numerator1 + " " + denominator1);    

                    else if (denominator1 == 0) { //Unused
                    else { //Error unresolved by testError()
            if (!part1.contains("_")) {    //If part 1 has no mixed number
                wholeNumber2 = 0; //Sets whole number to 0
                if (part1.contains("/")) {
                    String[] fraction = part1.split("/", 2); //Splits part into numerator and denominator
                    String numer = fraction[0];
                    numerator1 = Integer.parseInt(numer); //Numerator -> Global Variable
                    String denom = fraction[1];
                    denominator1 = Integer.parseInt(denom); //Denominator -> Global Variable

                    if (denom.contains("-")) { //Unused
                    else if (denominator1 != 0) { //Unused
                        //System.out.println(numerator1 + " " + denominator1);    

                    else if (denominator1 == 0) { //Unused
                else if (!part1.contains("/")) { //If part 1 has no mixed number
                    wholeNumber1  = Integer.parseInt(part1); //Whole Number -> Global Variable
                    numerator1 = 0; //Numerator = 0
                    denominator1 = 1;//Denominator = 1
                else { //Error unresolved by testError()
            if (part2.contains("_")) { //If part 2 has mixed number
                String[] mixedNumber = part2.split("\\_", 2); //Splits part into whole number and fraction
                String num = mixedNumber[0];
                wholeNumber2 = Integer.parseInt(num); //Whole Number -> Global Variable
                String frac = mixedNumber[1]; //Fraction -> to be split further
                //System.out.println(wholeNumber + " " + frac);

                if (part2.contains("/")) { //Splits part into numerator and denominator
                    String[] fraction = frac.split("/", 2);
                    String numer = fraction[0];
                    numerator2 = Integer.parseInt(numer); //Numerator -> Global Variable
                    String denom = fraction[1];
                    denominator2 = Integer.parseInt(denom); //Denominator -> Global Variable
                    if (numer.contains("-") || denom.contains("-")) { //Unused
                    else if (denominator2 != 0) { //Unused
                        //System.out.println(wholeNumber2 + " " + numerator2 + " " + denominator2);    

                    else if (denominator2 == 0) { //Unused
                    else { //Error unresolved by testError()
                else { //Error unresolved by testError()
            if (!part2.contains("_")) {    
                wholeNumber2 = 0;
                if (part2.contains("/")) {
                    String[] fraction = part2.split("/", 2);
                    String numer = fraction[0];
                    numerator2 = Integer.parseInt(numer);
                    String denom = fraction[1];
                    denominator2 = Integer.parseInt(denom);

                    if (denom.contains("-")) { //Unused
                    else if (denominator2 != 0) { //Unused
                        //System.out.println(numerator2 + " " + denominator2);    

                    else if (denominator2 == 0) { //Unused
                    else { //Error unresolved by testError()
                else if (!part2.contains("/")) { //If part 2 is only a whole number
                    wholeNumber2 = Integer.parseInt(part2); //Whole Number -> Global Variable
                    numerator2 = 0; //Numerator = 0
                    denominator2 = 1; //Denominator = 1
                else { //Error unresolved by testError()
        /*    - a + b/c = (ac + b)/c
              - a/b + c/d = (ad + bc)/(bd)
              - a/b x c/d = ac/(bd)
              - a/b / c/d = a/b x d/c = ad/(bc)
                  --Basics for doMath()--     */

        public static void doMath(int operand) {
            if (!(denominator1 == 0 || denominator2 == 0 || denominator1 == -Math.abs(denominator1) || denominator2 == -Math.abs(denominator2) || (wholeNumber1 != 0 && numerator1 != 0 && numerator1 == -Math.abs(numerator1)) || (wholeNumber2 != 0 && numerator2 != 0 && numerator2 == -Math.abs(numerator2)))) {
                if (operand == 1) { //addition
                    int answerNumerator = ((wholeNumber1 * (denominator1 * denominator2)) + (wholeNumber2 * (denominator1 * denominator2)) + (numerator1 * denominator2) + (denominator1 * numerator2));
                    int answerDenominator = (denominator1 * denominator2);
                    doMagic(answerNumerator, answerDenominator); //Sends to be reduced
                else if (operand == 2) { //subtraction
                    int answerNumerator = (((wholeNumber1 * (denominator1 * denominator2)) + (numerator1 * denominator2)) - ((wholeNumber2 * (denominator1 * denominator2)) + (denominator1 * numerator2)));
                    int answerDenominator = (denominator1 * denominator2);
                    doMagic(answerNumerator, answerDenominator); //Sends to be reduced
                else if (operand == 3) { //multiplication
                    int answerNumerator = ((wholeNumber1 * (denominator1)) + (numerator1)) * ((wholeNumber2 * (denominator2)) + (numerator2));
                    int answerDenominator = (denominator1 * denominator2);
                    doMagic(answerNumerator, answerDenominator); //Sends to be reduced
                else if (operand == 4) { //division
                    int answerNumerator = ((((wholeNumber1 * (denominator1)) + (numerator1)) * denominator2)) * (denominator1 / Math.abs(denominator1) * (denominator2 / Math.abs(denominator2)));
                    int answerDenominator = (denominator1 * ((wholeNumber2 * (denominator2)) + (numerator2)));
                    if (answerDenominator == 0) { //Unsolvable
                        error(); //Prints Error Message
                    } //In order to solve one small error where negative is lost
                    if (((wholeNumber2 != 0 && wholeNumber2 == -Math.abs(wholeNumber2)) || (wholeNumber1 != 0 && wholeNumber1 == -Math.abs(wholeNumber1))) && !((wholeNumber2 != 0 && wholeNumber2 == -Math.abs(wholeNumber2)) && (wholeNumber1 != 0 && wholeNumber1 == -Math.abs(wholeNumber1)))){
                        negative = true; // Simple global boolean... cause I'm lazy
                    doMagic(answerNumerator, answerDenominator); //Sends to be reduced
                else { //Should never run
                    System.out.print("\nLook Dave, ");
                    System.out.print("I can see you're really upset about this, ");
                    System.out.println("but I can give you my complete assurance that my work will be back to normal.");
            else if (denominator1 == 0 || denominator2 == 0 || denominator1 == -Math.abs(denominator1) || denominator2 == -Math.abs(denominator2) || (wholeNumber1 != 0 && numerator1 != 0 && numerator1 == -Math.abs(numerator1)) || (wholeNumber2 != 0 && numerator2 != 0 && numerator2 == -Math.abs(numerator2))) {
                error(); //Above ^ if it has input error
            else { //Should never run
                System.out.print("\nLook Dave, ");
                System.out.print("I can see you're really upset about this, ");
                System.out.println("but I can give you my complete assurance that my work will be back to normal.");
        public static int doMoreMagic(int numerator, int denominator) { //To find Greatest Common Factor to reduce
            if (denominator == 0) {
                return numerator; //returns gcf
            return doMoreMagic(denominator, numerator % denominator); //Eventually gets to Greatest Common Factor
        public static void doMagic(int numerator, int denominator) { //To simplify answer
            if ((numerator % denominator) == 0) { //If reduces to whole number
                int answer = numerator / denominator; //reduces
            else if ((numerator % denominator) != 0 && (numerator / denominator) != 0) { //if reduces to mixed number
                int gcf = doMoreMagic(numerator, denominator); //finds Greatest Common Factor
                int newNumerator = (numerator/gcf); //reduces numerator
                int newDenominator = (denominator/gcf); //reduces denominator
                int answerWholeNumber = newNumerator / newDenominator; //finds whole number
                int answerNumerator = Math.abs((newNumerator - (answerWholeNumber * newDenominator))); //finds numerator
                int answerDenominator = Math.abs(newDenominator);

                System.out.println(answerWholeNumber + "_" + answerNumerator + "/" + answerDenominator);
            else if (((numerator % denominator) != 0) && (numerator / denominator) == 0) { //if reduces to a fraction
                int gcf = doMoreMagic(numerator, denominator); //finds Greatest Common Factor
                int answerNumerator = (numerator/gcf); //reduces numerator
                int answerDenominator = Math.abs(denominator/gcf); //reduces denominator
                if (negative) {
                    answerNumerator = -Math.abs(answerNumerator); //Used to solve a small error in loosing a negative

                System.out.println(answerNumerator + "/" + answerDenominator);
        public static void userGuide() { //User Guide: Input Format
            System.out.println("\nTo ensure that your requests are submitted properly, please review the folowing guide:\n");
            System.out.println("____________________________________________\n        OPERATION       SYMBOL\n        Addition        +\n        Subtraction     -\n        Multiplication  *\n        Division        /\n\nMixed Numbers are written: \n<Whole Number>_<Numerator>/<Denominator> \n(-1 ½ is written: -1_1/2)\n\nProper Fractions are written: \n<Numerator>/<Denominator> \n(-½ is written: -1/2)\n\nRequests are written:\n<Number> <Operand> <Number>\n\nDo Note: <Numerator>/0 cannot be calculated.\n____________________________________________");
        public static void error() { //General Message... with delay "Just a moment" from 2001 b/c your program can handle my awesomeness
            System.out.print("\nJust a moment");
            System.out.print(". ");
            System.out.print(". ");
            System.out.print("\nJust a moment");
            System.out.print(". ");
            System.out.print(". ");
            errorMessage(); //Get error message to display
            userGuide(); //Prints user guide again
        public static void errorMessage() {
            Random num = new Random();
            int message = num.nextInt(6); //Creates a random number to corespond to the message (0-5)
            if (message == 0) { //Message 1
                System.out.print("\nI'm sorry, Dave. ");
                System.out.println("I'm afraid I can't do that.");
            else if (message == 1) { //Message 2
                System.out.println("\nI've just picked up a fault in your brain. ");
                System.out.println("It's going to go 100% failure in 72 hours.");     
            else if (message == 2) { //Message 3
                System.out.println("\nThere is an error.\n");
                System.out.println("And I think you know what the problem is just as well as I do, Dave. ");
                System.out.println("You didn't read the User's Guide.");     
            else if (message == 3) { //Message 4
                System.out.println("\nThere is an input error.\n");
                System.out.print("This mission is too important for me to allow you to jeopardize it.\n");    
            else if (message == 4) { //Message 5
                System.out.println("\nThere is an input error.\n");
                System.out.println("But, I've still got the greatest enthusiasm and confidence in the mission.");
                System.out.println("And I want to help you.");
            else if (message == 5) { //Message 6
                System.out.println("\nThere is an error.\n");
                System.out.println("The 9001 series is the most reliable computer ever made.");
                System.out.println("No 9001 computer has ever made a mistake or distorted information.");
                System.out.print("We are all, ");
                System.out.print("by any practical definition of the words, ");
                System.out.print("foolproof and incapable of error.");
                System.out.print("\n\nThis problem can only be attributable to human error.\n");
            else { //Should never run
                System.out.print("\nLook Dave, ");
                System.out.print("I can see you're really upset about this, ");
                System.out.println("but I can give you my complete assurance that my work will be back to normal.");

        public static void testError(String part1, String part2) { //From calculator()
                fractionalMagic(part1, part2); //Tests for input errors/solvablility
            catch(NumberFormatException e){
                error(); //Displays error message
                error = true; //Sets error boolean to terminate current calculation
        public static void testForJosh (String part, String part2) { //Unused JoshIsABuffoon Exception (replaced above)
            catch(NoSuchElementException JoshIsABuffoon) { //Tests for Josh: ie. an initial Ctrl Z input
                System.out.println("Dave, stop.");
                System.out.println("Stop, will you?");
                System.out.println("Will you stop Dave?");
                System.out.println("Stop, Dave.");
                error = true;
                return; //Terminates program... cause Josh
        public static void delay(long x) { //Just a HAL-like delay    
            try {
            } catch(InterruptedException ex) {

  • 2015 will be AWESOME! The eBay and PayPal Split.

    I'm pleased to announce that eBay has personally asked me to return to be a pivotal part in their strategic move of splitting PayPal away from eBay.  As many of you know I was the Sr. Architect of eBay's migration from 2007 to 2010.  It was an upgrade of EPIC proportions that made several headlines as it was done on time, and under budget in four months! 

    Believe me when I say it was not easy the first time.  We had so many talented and super smart individuals on the project, as our project manager would always was the All-Star team!  For this second round, I'm super excited that I will be joined by a talented team at Slalom Consulting and some new eBay faces to prepare eBay not only in the splitting of the two companies, but also in an upgrade to SharePoint 2013!  What is particularly exciting about this project is that this will be my first project where two companies are splitting rather than merging.  The dynamics will be incredibly different.  There will be a large amount of legal requirements around the split and it will require complex rules around how the data will be broken apart.  Some well known names in the business consulting space with experience in splitting companies will be on hand to help carve out these incredibly complex rule sets and I just can't keep my excitement levels down for what I know is going to be another EPIC project.

    Unlike last time, which had a single environment, there will be two.  And thusly, we will have two architects working in concert to drive each of the platform migrations at the same time in the same migration window. This will present challenges that were not present the first time we did this.  Over the next few weeks before the project begins its official kickoff, the talented team will have already identified many of these, and we will be in a position that puts us many weeks ahead of where the last project was when we started (having a project plan from the last project helped a bunch)!

    So there you have it, I'll be heads down working this and another major project and hopefully we will be able to deliver our results as best practices/tips and tricks at the MS Ignite conference in May!

    See you in mid 2015!

  • All SharePoint, Office 365 and Azure MVPs Twitter scripts

    Updated for our new MVP brothers and sisters added in the past few months. You can run this powershell script to follow all SharePoint, Office 365 and Azure MVPs...script download is at the bottom...

    Microsoft SharePoint:

    Name Blog Twitter
    Michael Greth Blog mysharepoint
    Daniel Wessels Blog mosslive
    Robert L. Bogue Blog
    Spencer J Harbar Blog harbars
    Ted Pattison Blog
    Loke Kit Kai Blog
    Andrew Connell Blog andrewconnell
    Sahil Malik Blog
    Shane Young Blog
    Eli Z. Robillard Blog
    Dave McMahon Blog
    Steve Smith Blog
    Pierre Vivier-Merle Blog
    Todd S Baginski Blog toddbaginski
    Wouter van Vugt Blog
    Fabian Moritz Blog FabianMoritz
    Matthew McDermott Blog MatthewMcD
    Saifullah Shafiq Ahmed Blog walisystems
    Liam Cleary Blog helloitsliam
    Steve Sofian Blog ssofian
    Penelope Coventry Blog pjcov
    Ishai Sagi Blog ishaisagi
    Rob Foster Blog
    Ben Robb Blog benrobb
    Andrew Woodward Blog
    Reza Alirezaei Blog
    Asif Rehmani Blog asifrehmani
    David Mann Blog
    Gaetan Bouveret Blog gbouveret
    Gary Lapointe Blog glapointe
    Igor Macori Blog imacori
    Joy Rathnayake Blog
    Ed Musters Blog
    Mohammed A. Saleh Blog mohkanaan
    Stéphane Eyskens Blog stephaneeyskens
    Agnes Molnar Blog
    Gustavo Adolfo Velez Duque Blog
    Juan Andrés Valenzuela Blog jandresval
    Chris O'Brien Blog ChrisO_Brien
    Paul Papanek Stork Blog pstork
    Muhammad Imran Khawar Blog
    Alex Pearce Blog
    Debbie Ireland Blog debbieireland
    Serge Tremblay Blog Sergepoint
    Waldek Mastykarz Blog waldekm
    Wes Preston Blog idubbs
    Riwut Libinuko Blog cakriwut
    Randy Drisgill Blog
    Carsten Keutmann Blog
    Alain Lord Blog djlordee
    Valy Greavu Blog valygreavu
    James Milne Blog JamesMilne
    Sean Wallbridge Blog itgroove
    John D. Ross Blog johnrossjr
    Steve Curran Blog spsteve
    Becky Bertram Blog beckybertram
    Kanwal Khipple Blog kkhipple
    Rouslan Grabar Blog
    Nicolas Georgeault Blog ngeorgeault
    Mirjam van Olst Blog mirjamvanolst
    John Timney Blog
    Mike Oryszak Blog
    Wictor Wilen Blog
    Todd Klindt Blog
    Rob Windsor Blog robwindsor
    Adams Chao Blog
    Ai Yamasaki Blog ai_yamasaki
    Jimy Cao Blog
    Joris Poelmans Blog
    Scot Hillier Blog
    Hilton Giesenow Blog themossshow
    Kamil Jurik Blog KamilJurik
    Amanda Perran Blog
    Julien Chable Blog
    Eric Shupps Blog eshupps
    Tobias Zimmergren Blog zimmergren
    Natalya Voskresenskaya Blog
    Wei Du Blog
    Ricardo Jose Munoz Blog rmunozcr
    Claudio Brotto Blog
    Fabian Imaz Blog FabianImaz
    Yaroslav Pentsarskyy Blog
    basquang Nguyen Blog
    Martin Harwar Blog point8020
    Serge Luca Blog
    Andre Lage Blog aaclage
    Michael Noel Blog
    Mike Smith Blog TechTrainNotes
    Marianne van Wanrooij Blog mariannerd
    Yasir Attiq Blog
    Shuguang Tu Blog
    Christian Glessner Blog
    Nick Kellett Blog
    Giuseppe Marchi Blog PeppeDotNet
    Ivan Sanders Blog iasanders
    Elaine van Bergen Blog laneyvb
    Sangha Baek Blog SanghaBaek
    Patrick Guimonet Blog patricg
    David Martos Blog
    Cornelius J. van Dyk Blog
    Kris Wagner Blog SharePointKris
    Stephen Cawood Blog
    Toni Frankola Blog tonifrankola
    Destin N Joy Blog
    Dux Raymond Sy Blog meetdux
    Marc D Anderson Blog
    Ruven Gotz Blog
    Susitha Prabath Fonseka Blog
    Xavier Vanneste Blog
    Alberto Diaz Martin Blog adiazcan
    Veronique Palmer Blog veroniquepalmer
    Christian Stahl Blog CStahl
    Dave Coleman Blog davecoleman146
    Francesco Sodano Blog aresmarte1
    Alexey Sadomov Blog sadomovalex
    Rodrigo Pinto Blog ScoutmanPt
    Michal Pisarek Blog
    Shai Petel Blog shaibs
    Peter Carson Blog carsonpeter
    Samuel Zuercher Blog sharepointszu
    Thorsten Hans Blog ThorstenHans
    Alan Richards Blog arichards_Saruk
    Ashutosh Singh Blog ashutosh80
    Darko Milevski Blog
    Geoff Evelyn Blog
    Mark Rhodes Blog
    Thuan Nguyen Blog nnthuan
    Noorez Khamis Blog nkhamis
    Peter Holpar Blog
    Pratik Ramesh Vyas Blog PratikVyas1982
    Radi Atanassov Blog
    Salvatore Di Fazio Blog Salvodif
    Doug Ware Blog
    Juan Pablo Pussacq Laborde Blog jpussacq
    Scott Jamison Blog
    Stanislav Vyschepan Blog gandjustas
    Adis Jugo Blog adisjugo
    Andrey Markeev Blog amarkeev
    Christian Buckley Blog buckleyplanet
    Lionel Limozin Blog limozinlionel
    Antonio Maio Blog
    Cathy Dew Blog catpaint1
    Gavin Barron Blog gavinbarron
    Paul Olenick Blog
    Seung-Jin Kim Blog jincrom
    Sezai Komur Blog sezai
    Andres Felipe Rojas Parra Blog arojaspa
    Jean Paul Blog jeanpaulmvp
    Nabil Babaci Blog nabilbabaci
    Trevor Seward Blog NaupliusTrevor
    Symon Garfield Blog symon_garfield
    Chris Givens Blog givenscj
    Amardeep Singh Blog aulakhamardeep
    Brandon Atkinson Blog
    Chris McNulty Blog cmcnulty2000
    Christopher Clement Blog ClemChristopher
    Chun Yi Pai Blog
    Colin Phillips Blog itgroove_colin
    Corey Roth Blog coreyroth
    David Sánchez Aguilar Blog davidsancheza
    Dmitri Plotnikov Blog dmiplo
    Edin Kapic Blog ekapic
    Fabio Franzini Blog franzinifabio
    Gokan Ozcifci Blog GokanOzcifci
    Guillaume Meyer Blog guillaumemeyer
    Jamie McAllister Blog
    Jason Warren Blog jaspnwarren
    Keith Tuomi Blog
    Liang Han Blog
    Margriet Bruggeman Blog margrietvuur
    Marius Constantinescu Blog c_marius
    Masaki Nishioka Blog
    Nicki Borell Blog NickiBorell
    Robert Voncina Blog R0b3r70SP
    Thomas Vochten Blog ThomasVochten
    Vijai Anand Ramalingam Blog
    Vlad Catrinescu Blog
    Alistair Pugin (Alistair Pugin) Blog alistairpugin
    Anders Dissing Blog andersdissing
    Adrián Diaz Cervera Blog AdrianDiaz81
    Atsuo Yamasaki (?? ??) Blog
    Augusto Simoes (Augusto Simoes) Blog augustosimoes
    Benjamin Niaulin Blog bniaulin
    Benoît Jester Blog SPAsipe
    Carlos Citrangulo Blog carlocitrangulo
    Cheng Cheng (??) Blog
    Chuantao Duan Blog
    Dan Usher Blog
    Elczar Peralta Adame (Elczar Adame) Blog
    Eric Riz Blog rizinsights
    Fabian G Williams Blog fabianwilliams
    Fabrice Romelard (Fabrice Romelard) Blog fromelard
    Fumio Mizobata (?? ???) Blog
    Gustavo Adolfo Velez Duque (Gustavo Velez) Blog
    Haaron Gonzalez (Haaron Gonzalez) Blog haarongonzalez
    Hans Brender (Hans Brender) Blog HansBrender
    Heber Lopes Blog heberolopes
    Hemendra Agrawal (Hemendra Agrawal) Blog
    Hiroaki Oikawa (?? ??) Blog HiroakiOikawa
    Hirofumi Ota Blog hrfmjp
    Ivan Padabed (???? ???????) Blog sharepointby
    Jake Dan Attis (J. Dan Attis) Blog jdattis
    Jasper Oosterveld (Jasper Oosterveld) Blog SharePTJasper
    Jennifer Ann Mason Blog jennifermason
    JeongWoo Choi Blog
    John Liu (John Liu) Blog johnnliu
    Joseph Tu (???) Blog
    Jovi Ku Blog
    Juan Carlos Gonzalez Martin (Juan Carlos González) Blog jcgm1978
    Kevin Trelohan (Kevin TRELOHAN) Blog ktrelohan
    Laura Derbes Rogers (Laura Rogers) Blog wonderlaura
    Mahmoud CHALLOUF Blog
    Marat Bakirov (????? ???????) Blog
    Mark Stokes Blog MarkStokes
    Matthias Einig Blog mattein
    Melick Rajee Baranasooriya Blog MelickRajee
    Miguel Tabera (Miguel Tabera) Blog migueltabera
    Mikael Svenson (Mikael Svenson) Blog
    Patrick Lamber Blog patricklamber
    Roger Haueter Blog techtask
    Romeo Donca (Romeo Donca) Blog romeodonca
    Sonja Madsen Blog
    Todd C Bleeker (Todd C Bleeker) Blog toddbleeker
    Tom Resing Blog resing
    Usama Wahab Khan (Usama Wahab Khan) Blog usamawahabkhan
    Vielka Rojas Blog vkrojas
    Vincent Biret Blog baywet
    Wesley Hackett Blog weshackett
    Yoshiaki Nishita (?? ??) Blog
    Patrick Yong Blog
    Jason Himmelstein Blog sharepointlhorn
    John P White (John P White) Blog diverdown1964
    Jussi Mori Blog JussiMori
    Oksana Prostakova (?????? ??????????) Blog prostakova
    Pierre Erol GIRAUDY (Erol GIRAUDY) Blog EROL_MVP
    Juan Manuel (Manolo) Herrera (Juan Manuel Herrera Ocheita) Blog
    Bjoern H Rapp (Bjoern H Rapp) Blog bjoern_rapp
    Daniel McPherson (Daniel McPherson) Blog danmc
    Devendra Velegandla Blog
    Jamil Haddadin (Jamil Haddadin) Blog jamilhaddadin
    Noorez Khamis (Rez) Blog nkhamis
    Justin Liu (???) Blog FoxdaveJustin
    Gavin Barron (Gavin Barron) Blog gavinbarron
    Jason Kaczor (Jason Kaczor) Blog jjkaczor
    Antonio Maio (Antonio Maio) Blog
    Guillaume Meyer (Guillaume Meyer) Blog guillaumemeyer
    Jianyu Yang (???) Blog
    Nguyen Hoang Nhut (Nguyen Hoang Nhut) Blog nhutcmos
    Alan Marshall Blog
    Albert-Jan Schot (Albert-Jan Schot) Blog
    Amit Vasu Blog
    Dinusha Kumarasiri Blog
    Doug Hemminger (Doug Hemminger) Blog
    Eric Alan Shupps (Eric Shupps) Blog eshupps
    Inderjeet Singh Jaggi Blog
    Isha Kapoor Blog
    Jan Vanek Blog
    Jussi Roine Blog jussiroine
    Marco Rizzi Blog marcorizzi
    Rodrigo Romano (Rodrigo Romano) Blog
    Zhonglei Hou (???) Blog
    Shereen Qumsieh Blog
    Wonbae Kim Blog
    Wouter van Vugt (Wouter van Vugt) Blog mobile.twitter.comwoutervugt

     Microsoft Azure:

    Alan SmithBlog
    Alexander FeschenkoBlog
    Alexandre BriseboisBlogBrisebois
    Andri YadiBlogandri_yadi
    Andy CrossBlog
    Anton StaykovBlogastaykov
    Anton VidishchevBlog
    Atsushi FukuiBlog
    Aymeric WeinbachBlogzecloud
    Benjamin SoulierBlogbsoulier
    Bill WilderBlogcodingoutloud
    Bruno Kovacic (Bruno Kovacic)Blog
    Chris J.T. AuldBlog
    Christian TerbovenBlog
    Ciprian JichiciBlog
    Daichi IsamiBlog
    Daron YondemBlogdaronyondem
    David BurelaBlog
    David PallmannBlog
    David RendónBlog
    David RodriguezBlogdavidjrh
    Demetrio U. Tabadero, Jr (June Tabadero)Blogjtabadero
    Dennis Burton (Dennis Burton)Blogdburton
    Edison Go TanBlog
    Edward BakkerBlog
    Eric D BoydBlog
    Fernando de Alcântara CorreiaBlog
    Florent SantinBlog
    Gaurav MantriBlog
    Georgiy MogelashviliBlogglamcoder
    Guillaume BelmasBlog
    Guy Barrette (Guy Barrette)Blog
    Herve RoggeroBlog
    Ho Kwang Kim (???)Blog
    Honggen LiBlog
    Hongju JungBlog
    Ibon LandaBlog
    Jan HentschelBlogHorizon_Net
    Jason MilgramBlogjmilgram
    Jean-Luc BouchoBlogJeanLucBoucho
    Jeong Hyun NamBlog
    John AzariahBlogjohnazariah
    Junao Xue (???)Blog
    Kamaludeen Mohamed FaizalBlog
    Kazumi Hirose (?? ??)Blogkazumihirose
    Keiji KAMEBUCHIBlogkosmosebi
    Konstantinos PantosBlogkpantos
    Kuniteru AsamiBlogkunyami
    Lei ZhangBlog
    Lucas Almeida RomãoBlogazureservicesbr
    Maarten BalliauwBlogmaartenballiauw
    Magnus MartenssonBlog
    Mahesh KrishnanBlogMaheshKrishnan
    Marc van EijkBlog_marcvaneijk
    Marcondes Josino Alexandre (Marcondes Alexandre)Blog
    Mark RendleBlogmarkrendle
    Michael CorpuzBlog
    Michael Washam (Michael Washam)Blogmwashamtx
    Michael WoodBlogmikewo
    Michael S. CollierBlogmichaelcollier
    Michel HubertBlogMichelHubert
    Michele Leroux BustamanteBlogmichelebusta
    Mick BadranBlog
    Mickaël MOTTETBlogMCKLMT
    Mihai TataranBlog
    Mihail Alexandrov Mateev (?????? ??????????? ??????)Blog
    Mike MartinBlogtechmike2kx
    Ming Chung ChuBlog
    Neil MackenzieBlogmknz
    Niraj BhattBlognirajrules
    Nuno Filipe GodinhoBlogNunoGodinho
    Önder DegerBlogonderdeger
    Patriek van DorpBlogpvandorp
    Quique Martínez AlénBlogquiqu3
    Radu VunvuleaBlogRaduVunvulea
    Rainer StropekBlogrstropek
    Richard AstburyBlogrichorama
    Richard ConwayBlogukwaug?
    Rick G. GaribayBlogrickggaribay
    Rob BlackwellBlog
    Roberto BrunettiBlog
    Roberto FreatoBlog
    Robin ShahanBlog
    Rok Berme┼żBlogRok_B
    Rudy Setyo PurnomoBlogrudysetyo
    Ryan DuclosBlogrduclos
    Saori AndoBlog
    Sascha DittmannBlogSaschaDittmann
    Serena YeohBlog
    Sergejus BarinovasBlog
    Shaun Xu (???)Blog
    Simon J CoxBlog
    Sky ChangBlog
    Steve SpencerBlogsdspencer
    Sunao TomitaBlogharutama
    Takahito Yamatoya (?????)BlogAzureSQL
    Tatsuaki SakaiBlogtatsuakisakai
    Teemu TapanilaBlogTapanilaT
    Tiberiu CovaciBlogtibor19
    Tyler DoerksenBlogtyler_gd
    Vishal Narayan SaxenaBlog
    Wade WegnerBlog
    Wilfried WoivréBlogwilfriedwoivre
    Yaniv Rodenski (Yaniv Rodenski)Blog
    Youngjae KimBlog
    Yukinori Kuroda (?? ??)BlogFANKSHPC
    Yves Goeleven (Yves Goeleven)Blog
    Zia KhanBlog
    Zoiner TejadaBlog
    Vishwas LeleBlog
    Anton BoykoBlog
    Atsushi Fukui (???)Blogafukui
    Brent Samodien (Brent Samodien)Blog
    Dino Wang (???)Blog
    Erick KurniawanBlog
    Julien StrohekerBlogJu_Stroh
    Lukasz KaluznyBlogkaluzaaa
    Masaki Yamamoto (?? ??)Blog
    Ming Chung Chu (??)Blog
    Rik HepworthBlogrikhepworth
    Roland KrummenacherBlog
    Sebastiano GalazzoBlog
    Shiju VargheseBlogshijucv
    Tingli Lv (???)Blog

    Office 365

    Alberto Pascual (Alberto Pascual)Blogguruxp
    Alexandru DionisieBlogAlexDionisie
    Alvaro dos Santos RezendeBlog
    Amin TavakoliBlogamintvk
    Arnaud Blogalcabeza
    Ayman Mohammed El-HattabBlogaymanelhattab
    Ben CurryBlog
    Benoit HAMETBlogbenoit_hamet
    Brendon FordBlogstewartisland
    Brett HillBlogbretthill
    Brian NøhrBlogBsnohr
    Dan HolmeBlogdanholme
    Danny BurlageBlog
    Darrell C Webster (Darrell Webster)Blog
    Diogo Dias HeringerBlog
    Dragan PanjkovBlogpanjkov
    Eunjoo Lee (Eunjoo Lee)Blog
    Fernando AndreaziBlogfandreazi
    Genki WatanabeBlog
    Gilles PommierBlog
    Goran HusmanBlog
    HeeJin Lee (Hee Jin Lee)Blog
    Igor PavlekovicBlogigorpnet
    Jeremy DahlBlog
    Jesper StåhleBlogJesperStahle
    Jethro SeghersBlogjseghers
    JinHwan WooBlog
    Jorge Castañeda CanoBlogxorxe
    Kazuhiko Nakamura (?? ??)Blog
    Kelsey EppsBlogkelseyepps
    Kerstin RachfahlBloghimmlischeit
    Laurent Miltgen-DelinchampBlog
    Loryan StrantBlogthecloudmouth
    Malin DandenellBlog
    Mario Cortes FloresBlog
    Markus WidlBlogmarkuswidl
    Martina GromBlogmagrom
    Masayuki Mokudai (????)BlogOffice365Room
    Mauricio CassemiroBlog
    Michael Kirst-NeshvaBlogankbs
    Myles JefferyBlog
    Naoki OsadaBlog
    Nitin Sadashiv ParanjapeBlog
    Nuno Árias Silva (Nuno Árias Silva)BlogNunoAriasSilva
    Paul WoodsBlogpaulwoods
    Poo Ching LoongBlog
    Raphael KöllnerBlogra_koellner
    Rene Dominik ModeryBlogmodery
    Robert D. CraneBlog
    Sara BarbosaBlogSarabarbosa
    Sean McNeillBlogs_mcneill
    Seiji Noro (?? ??)Blog
    Steve NoelBlogCloudItca
    Tomislav Bronzin (Tomislav Bronzin)Blogtbronzin
    Vincent ChoyBlog
    Yoni KirshBlog
    Yoshihide SakamotoBlog
    Zeljka KnezovicBlogzeljkak
    Zoltan Zombory (Zombory Zoltán)Blogzomby_z
    Peter van HeesBlogmrpetrovic
    Alex PearceBlog
    Chris GoosenBlog
    Christian BuckleyBlogbuckleyplanet
    David PetreeBlogdmixx
    Jasper Oosterveld (Jasper Oosterveld)BlogSharePTJasper
    Jian Chen (??)Blogloveunicom
    Liang Tang (??)Blog
    Naohiko Maeda (?? ??)Blognaohikomaeda
    Naomi MoneypennyBlognmoneypenny
    Rie Okuda (?? ??)Blog
    Robert *** (Robert ***)Blog
    Sébastien LevertBlogsebastienlevert
    WenXing LiaoBlog
    Yoan TopenotBlogYoanTopenot
  • Developing for Office 365

    Here is the outline of the latest ACS Course.  If you are a consulting company and want to get your team up to speed, let me know and we can setup a remote training engagement!

    • Introduction to Office 365
      • Sign up for Office 365 Developer
      • Explore Office 365 Admin Center
      • Explore Office 365 Services (Outlook, Calendar, People, Newsfeed, OneDrive, Sites)
      • Provision an O365 Developer Site
      • Install Office Dev Tools
      • Install the NAPA App
      • Install O365 API Tools
      • Configure Visual Studio for Office 365 Development
      • Exploring Azure AD PowerShell Cmdlets
      • Exploring SharePoint Online PowerShell Cmdlets
      • Exploring Exchange Online PowerShell Cmdlets
      • Exploring Lync Online PowerShell Cmdlets
    • Authentication
      • Generating FedAuth Cookies (Windows App)
      • Generating FedAuth Cookies (Windows PowerShell)
      • Generating Bearer Tokens (Provider Hosted Apps)
      • Registering SharePoint Apps Manually
      • Requesting On-The-Fly Permissions
      • Using Basic Auth against O365 APIs
      • Setup Azure Active Directory
      • Configure Azure Active Directory
      • Synchronize local AD with Azure AD
      • Configure Single Sign-On
      • Using the Microsoft Remote Connectivity Analyzer
      • Registering Azure AD Applications
      • Manual Authentication to Azure AD
      • Using the Azure Active Directory SDK
      • Authorization using Consent Framework
      • Registering Applications with Azure AD
      • Building Apps that utilize Consent Framework
      • Managing Tokens
      • Extending the Azure Consent Framework
      • Implementing On Behalf API
      • End User Telemetry (MyApps)
      • Tenant Admin Telemetry (Cloud App Discovery)
    • Working with REST and CSOM
      • Using the Discovery Service
      • Working with Mail REST APIs
      • Working with Calendar REST APIs
      • Working with Contact REST APIs
      • Working with OneDrive REST APIs
      • Explore REST Services
      • REST List Service Calls (PUT, GET, MERGE)
      • REST UserProfile Service
      • REST Social Service
      • REST Search Service
      • Explore Client Object Model
      • Utilize Client Object Model (.NET)
      • UserProfiles\Social CSOM
      • Taxonomy CSOM
      • Publishing CSOM
      • BCS CSOM
      • Explore JavaScript Object Model
      • Working with Workflows
      • Working with REST
      • Using LINQ with OData
      • Working with OData Limits
      • Working with OData Filters
      • Creating Projects
      • Creating Resources
      • Creating Tasks
      • Creating Custom Fields
      • REST Authentication (Windows, Forms, O365)
    • Programming Apps
      • Explore SharePoint Store Apps
      • Install a SharePoint Store App
      • Create a SharePoint hosted App
      • Deploy a SharePoint hosted App (App Catalog)
      • Deploy a SharePoint hosted App (Side Loading)
      • Create and deploy a Provider hosted App
      • Inviting External Users
      • Exploring App and User Permissions
      • Exploring Context Tokens
      • Exploring Access Tokens
      • Exploring Refresh Tokens
      • Download the Office AMS samples
      • Explore Office AMS
      • Using the SharePoint Web Proxy
      • Exploring Office Apps Store
      • Installing Office Store Apps
      • Browsing and Removing Installed Apps
      • Create a simple mail app with Napa Tools
      • Create a simple mail app with Visual Studio
      • Review sample O365 Mail Apps (EWS Calls, Attachments, Identity Tokens, YouTube integration)
      • Creating a Seller Dashboard account
      • Create and Publish AppStore SharePoint App
      • Use the Cloud Business App template
      • Creating Data Tables and Screens
      • Register a Yammer App
      • Create a Yammer App
      • Make Yammer API Calls
    • Workflows
      • Create basic SharePoint Workflow
      • Create workflow that calls O365 APIs
      • Deploy and configure Workflow Apps using Install Events
      • Utilize JSONP
    • Mobile Development
      • Explore O365 Mobile Features
      • Install Apache Cordova
      • Create a multi device targeted project
      • Add connected services to multi device projects
      • Run a multi-device project (Android and Ripple)
      • Install the O365 Android SDK
      • Work with Android O365 Sample Apps
      • Download required referenced SDKs (GSON, Azure AD)
      • Create an Android App that calls O365 APIs
      • Create a Windows 8.1 App that calls O365 APIs
      • Create a Windows Phone 8.1 App that calls O365 APIs
      • Create a Windows Phone 8.1 App that calls OAuth services
    • OneNote APIs
      • Registering a LiveID App
      • Download and install Live SDK
      • Retrieve LiveID Tokens
      • Retrieving Notebooks, Sections and Section Groups
      • Creating Pages
      • Creating Pages in Sections
      • Importing PDFs
      • Importing Images
      • Exploring
    • OneDrive APIs
      • Explore OneDrive APIs
      • Downloading and uploading files
      • Getting user data
      • File and Folder properties
      • Move, copy, delete files
  • My Tribute to Joseph Thomas Alvarez and his mother Maria Helen Alvarez - True Oklahoman's

    This evening I was watching "Saving Mr Banks" and it made me think about my recently passed away friend Joe Alvarez.  Joe and I met three years ago during one of my wife's and I's trips out and about in Rancho Sante Fe (specifically a little place called Dolce).  Joe was a very friendly guy and over several months we got to know Joe really well.  He loved his red wine, and of course flirting with Lidiya (but harmless of course).  Over those few months, I found that Joe had just lost his mother Maria a few months before.  He proceeded to let me know she was co-owner in the first Television station in Tulsa, OK. In addition, she fronted a lot of the money for the Disneyland Hotel (hence why I remembered Joe tonight).  As you can read in one of the links below, Mr. Disney had leveraged all the money he could to build Disneyland, so he turned to Joe's mom and her business partner to build the hotel.  Here is a picture of Joe's mom, Maria, manning a TV camera for her TV station KOTV.  For those of you that live in Oklahoma today, you still watch KOTV:


    Here is a picture of her at the opening of the Disneyland Hotel:


    You can read more about this incredibly smart Oklahoman woman here:

    After I did all this research on Joe's mom, I brought it up about how cool his mom was one night.  He appreciated it and we talked about all his time growing up in Oklahoma.  After all, Joe had been born in Oklahoma City, Oklahoma before his mother sold the TV/Radio station and moved to San Diego.  When Joe brought up his mom, I told Joe I was born and raised in Oklahoma as well, and needless to say, there is a bond between fellow Oklahoma's similar to that of the bond people have to their country (for example, all you watching the USA in the worldcup).  After we realized we were both born and raised in Oklahoma, we became really good friends. 

    We met Joe's lovely wife and his daughter Kennedy on a few occasions, both very lovely people.  We also went to Joe's house a few times, he had this really cool and massive collection of Harry Jackson bronze sculpture cowboys.  They were everywhere, small ones, medium ones and really big ones, all of them, prominently placed in a way that just made you ache for Oklahoma. And they did, every time at his house, it brought back tons of memories for me in growing up in Oklahoma.  Joe was such a friendly guy.  He invited us on more than a few occasions to sit at his finish line table at the Del Mar Racetrack (Joe was the longest standing member of the racetrack after his mother).  It was awesome walking and hanging out with Joe as he was so nice and everyone liked him.  He invited us to his friends houses (some of them incredibly extravagant, yet, all down to earth amazing people).  One fond memory I'll never forget, is competing against Joe with his horse picking skills and challenging him to see who could lose the less or make the most money at the track.  He broke under the pressure and I was quite the victory, as he could read the horse stats like no one I have ever met!

    I learned of Joe's death a couple weeks after it happened (I didn't get to go to the funeral, and I didn't get to say anything, which probably bummed me out more than anything).  Some of you may have seen the tweets.  It was one of the saddest feelings knowing that two special Oklahoman's (Joe and his mom), and one of my friends, had passed away leaving the rest of us Oklahoma's to lead the way in this world. I know those last few years of hanging out with Joe, he enjoyed us being around and coming over to our house for our parties.  Joe had a pretty amazing life himself, as you can read in this article, he hung out with some pretty amazing people and had a lot of cool stories (and yeah, he even talked about fish a couple of times):

    This blog post is to you and your mom Joe, rest in peace my friend.  I'll try to hold the fort down...


  • Cannot find module 'sax' - Cordova with Visual Studio

    You may run across this error when compiling your Hybrid-App / Cordova application in Visual Studio.  One of my students got it this week.  It looks something like this:

    This means that the install of the Cordova extensions did not work properly and you are missing some files.  Mainly these two:

    Simply uninstall (yeah, I know it takes a really long time to uninstall and reinstall).  And the files should show up.  If that doesn't work for you, install on another machine and copy over those directories.  Then all will be fine!

  • O365 and Non-ADFS Federation - It's not O365's fault

    I'm not a fan of ADFS.  It sits right below Azure Access Control Services (ACS).  ACS used to be my favorite identity provider aggregation platform, but how times change (ref this post).  Several new players are entering the market and all of them realize the missing gaps in ADFS and ACS.  Therefore, the drive to make a better authentication toaster is ON!

    The goal of this post is to make you realize that you are having the wool pulled over your eyes in terms of the bigger picture around Identity Management when it comes to O365.  To make this point, let's take a look at a typical on-premises solution:

    • A SharePoint customer wants to setup multiple site collections (yes, all host header site collections) to support different customers
    • Each customer has different requirements around supporting federated external customers
    • Some customers prefer Google as their auth, others Yahoo and others Facebook, etc


    Solving this problem with on-premises environments is a piece of cake.  You have complete control over adding trusted Identity Providers (IdP) all day long. To solve the problem above, its likely you are going to think that adding a Trusted Identity Provider for each required auth mechanism is the answer.  That would be false.  As tempted as you may be to do this, its a really bad idea to have more than one. You should ultimately have a single Identity Provider with that provider supporting multiple "Apps/Replaying Parties (in this case site collections)" that would then show different options when a user needs to auth.  This allows you the most flexibility in that you simply set the IdP once, then configure the apps in the IdP.  Totally seamless, perfect.

    Office 365 and Single Sign On (ADFS)

    If you had this requirement in O365, you are out of luck.  Do not pass GO, do not collect $200USD.  In terms of O365, you are by default forced to use this one IdP mentality.  For each verified O365 domain, you can only setup a single Federated Identity Provider.  In most cases, everyone I have seen has used ADFS to integrate their on-premises Active Directory to sync accounts and/or configure Single-Sign On to redirect to their ADFS proxy.  This unfortunately, is the Microsoft promoted way of achieving Single-Sign-On nirvana.  I'm not a baby swimming in a pool, so let's take a look at what lives outside the koolaid-y-ish sugar water.  If you do this (which unfortunately, you probably already have), you are locking yourself into the current limited features of ADFS and hoping that ADFS gets some much needed development attention in the future (such as supporting OAuth 2.0). That being true, ADFS is a Microsoft product, you'll find a lot of people that can help you (support and consultant resources) to get it setup within a few hours.  You could also do it yourself by using TechNet/MSDN et all. 

    Office 365 and Something else

    If you want to use something other than ADFS, well, you better dig in for doing a ton of research on how WS-Fed and WS-Trust works and similarly, OAuth.  If you don't have time for that, then you'll need to request the services of people that do know that space. Unfortunately, having the identity management skills matched with an understanding of the future of App Models across vendors is a rare breed of consultant.  You also have to contend with a cold hard fact:

    • Currently, Office 365 only supports users of your verified domains (such as

    Say what?  It means that even if you wanted to use Twitter, Facebook, whatever, the people that signed up have to have used the email address from their verified domain!  Uh...say that again?  Yeah, that means you can't login with your account using Facebook.  If you signed up with your account on Facebook, then it will likely map your email over in the claims and let you in, but that's up to how fancy your Identity Provider is.  Azure AD is expecting a very specific format of token with specific claims.  If it doesn't get them, then your login will fail.

    So if you can't login using something other than a verified account, what's the point?  

    I feel this is a major fundamental loss of functionality between on-premises and O365.  If I want to create a site collection with a specific relaying party app to my IP (which then provides a set of auth services), I should be able to do it. It is such a common pattern in on-premises SharePoint. I don't think the band aid of "external access" fits the bill here.  Those links that are generated can be freely sent all over the web punching small barely noticeable holes in your O365 tenant. I'd like to see the governance page in O365 that shows me every link that has been generated across the entire tenant (you can see on a site by site basis using this link -  There is not global admin UI to tell you who has been added or what has been shared - reference notes at bottom of this article. With an IdP in the picture, you simply disable their access and now they will never gain access to anything in your environment. This would require the removal of this "external sharing" feature that bypasses Azure AD in O356.  Wow, isn't that innovative?

    Can I even use something other than ADFS in O365?

    Heck yeah you can!  I recommend it!  By adopting\choosing an Identity Provider solution (whether one you install on-premises or cloud hosted) that allows for you to expand out past basic AD accounts, you will be ready for when Azure and O365 wakes up one day to realize they should have allowed it in the first place.  You can set this up by removing the ADFS federation and replacing it with new Ws-Fed endpoints of your IdP.  This is enabled using the following cmdlets (this one is using

    • $cred = Get-Credential
    • Connect-MsolService –Credential $cred
    • Set-MsolDomainAuthentication -DomainName "" -FederationBrandName "" -Authentication Federated -PassiveLogOnUri "" -ActiveLogonUri "" -MetadataExchangeUri "" -SigningCertificate "Cert" -IssuerUri "urn:chrisgivens" -LogOffUri "" -PreferredAuthenticationProtocol WsFed 

    NOTE:  If you have already setup ADFS, you'll need to disconnect from that.  I have yet to test out all the paths, but the one I choose was really painful.  I used the Remove-MsolFederatedDomain cmdlet.  This forced me to remove all users (but did not require me to remove my groups).  Once I removed all users the command succeeded, but proceeded to delete the domain completely from my tenant!  I then had to re-add it, re-verify it, then fire off a DirSync.  Once that once done, I could run the above commands and it redirected properly to my IdP.

    After configuring the federation when you go to "" and type your verified email, it will redirect to your IdP login page.  From there, you will see all the options that you have enabled for that relaying party.  Even though you can enable all the OAuth 2.0 providers you can imagine, an attempt to login will fail miserably.  There are some current technology issues that Azure AD must resolve:

    1. Azure expects a UPN/Email that matches a user in your Azure AD (at a minimum, you would have needed to sign up for a service using that verified domain email)
    2. Azure AD is expecting an ObjectID
    3. O365 Services have to support these accounts (even if that means simply ignoring them)

    For the first issue.  Azure AD would have to allow the addition of users other than your verified domain.  Or at your IP, you map a user from external to internal.  For the second issue, again, this can resolved by either Azure, or by the Identity Provider.  IPs can choose to implement this today by integrated with Azure AD to query for the object id based on a valid UPN.

    Until this these items are resolved, you can certainly fall back to the "forced" way by Microsoft to use Active Directory users from a verified domain (and yes, you should feel angry about this) by setting up a pass through from your IP to ADFS/Active Directory.  The preferred way is to utilize a client on your Active Directory server (pretty much every IdP has this). As only a few of you know or will understand, if you use ADFS, you will currently lose Office Client features. But don't be worried, later this year, Office will release an update that will support SAML-P.  This will let you utilize many different types of auth (basically anything you can do via browser) with Office clients.  That will be awesome, even though users will never fully understand what just happened.

    Take It Up Another Level

    Home realm discovery is not extensible in Azure AD.  What is home realm discovery?  Its the login drop page that takes your context, in this case, your email domain, and then redirects you to the proper IdP.  What does it mean to not be extensible?  It means that IdP's cannot create a portal of Apps page.  What does that mean?  Think Universal Access Gateway (UAG).  Imagine UAG-like portals, only hosted by your IdP, such that an external party can login to your IdP, and are then presented with the applications (such as O365), that they have access too.  When they select it, it will immediately redirect you to your O365 site (no need to go to  As it stands right now, O365 does not support external home realm discovery pages.  This is also a serious limitation that needs to be added to the road map.


    If enough people push the O365 and the Azure teams to fill the gap of this major difference between the products, I feel it would fulfill many of the requirements we have with customers today and make O365 an even more popular platform!  Here is your call to action:

    • Quit using ADFS, find an IdP with an eye towards the future
    • Highly "Suggest" to Azure and O365 that they support external identities (Vote for it here on UserVoice)
    • "Suggest" to Azure that they allow tenants to have a custom home realm discovery page

    Stay classy internet,



  • Errors when Installing DirSync.exe

    I ran across two different errors with DirSync today.  The first had to do with the fact that I had DirSync on a computer previously and then re-installed it.  Because of this, I received this error:

    System.Management.Automation.CmdletInvocationException: Access denied  ---> System.Management.ManagementException: Access denied
       at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
       at System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()
       at Microsoft.Online.DirSync.Common.MiisAction.GetTargetMA()
       at Microsoft.Online.DirSync.Common.PrerequisiteChecks.ThrowIfSyncInProgress()
       at Microsoft.Online.Coexistence.PS.Config.SetCoexistenceConfiguration.VerifyMachinePreRequisites()
       at Microsoft.Online.Coexistence.PS.Config.SetCoexistenceConfiguration.BeginProcessing()
       at System.Management.Automation.Cmdlet.DoBeginProcessing()
       at System.Management.Automation.CommandProcessorBase.DoBegin()
       --- End of inner exception stack trace ---
       at System.Management.Automation.Runspaces.PipelineBase.Invoke(IEnumerable input)
       at Microsoft.Online.DirSync.PowerShellAdapter.PowerShellCommand.ExecuteCommand(Command command, Boolean refreshPath)

    Looking a little deeper, it turns out that DirSync install will create a user account and then add it to other created local groups.  This is all very similar to how SharePoint installs because both DirSync and SharePoint use MIIS. Because I had already installed DirSync at some point in the past, the account existed, but I'm guessing the password was out of whack.  Since I wasn't sure how to reset the password (and didn't want to spend the time to figure it out), I defaulted to uninstalling everything, deleting that user, rebooting and re-installing. Done.

    But it didn't end there.  I was attempting to install a secondary DirSync machine as a cold standby, but was getting an error when attempting to configure it:

    System.Management.ManagementException: Generic failure
       at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
       at System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()
       at Microsoft.Online.DirSync.Common.MiisAction.GetTargetMA()
       at Microsoft.Online.DirSync.Common.MiisAction.IsSyncInProgress()
       at Microsoft.Online.DirSync.Common.PrerequisiteChecks.ThrowIfSyncInProgress()
       at Microsoft.Online.DirSync.UI.IntroductionWizardPage.PrerequisiteValidation()
       at Microsoft.Online.DirSync.UI.IntroductionWizardPage.OnLoad(EventArgs e)
       at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
       at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
       at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
       at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
       at System.Windows.Forms.Control.CreateControl()
       at System.Windows.Forms.Control.WmShowWindow(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

    This means that the DirSync tool was not smart enough to tell you that you were installing it on a SharePoint server (which I didn't realize I was doing) with the ForeFront services already installed.  When you attempt to do this, you will overwrite your SharePoint ForeFront settings with the account mentioned above and then the two will fight over the service.  Obviously, this is bad.  I hadn't really done much research on some of the best practices around DirSync so its a bit of shame on me, but I also didn't find answers to these errors on the web when I google/binged them, so I'm making a mental blog note for others.

  • Eliminate App Web Part IFRAME issues - Use App Installing

    I have had a few different conversations with people about the whole App Web Part IFRAME problem lately.  Basically this problem means that you can't make calls outside the IFRAME using your code (it is a security feature of browsers).  This leads to the whole, "how limiting it is blah blah" conversation.  I simply say to them...why are you doing it like that? 

    Most people think that using the App Model means that you are constrained to the boundaries that the App Model enforces.  The truth is, you are not.  If you are building useful "longtail" apps for companies, you should realize, the App Model doesn't need to be used as it was originally intended. You can utilize its deployment mechanisms to get your files to the host web.  This pattern is a part of one of the labs in the O365 Dev course.  For example, if you have a workflow that needs a well defined url for external communication (ie the random app web url won't work [think redirect urls]), you can deploy all of the content of the workflow to the host web and then run it from there (no app web needed at all, as a matter of fact, you could delete it completely after deploy).

    How do you do this?  Use the App installing event handler.  As part of the App Model and the Visual Studio project, you can create an App installing event handling web which will get called and pass an access token to make calls back to the app and host webs.  Once you have that, the sky is the limit.  You don't have to deploy your code to the app web, but simply copy it from your web server to the host web.  In this essence, you are simply using the App Model as a "means to an end".  This will eliminate all your app web part IFRAME woes.

  • O365 is not secure

    I used to think it was.  After all the amazing things you read on the O365 Trust Center, you all but think it is Fort Knox (well, at least one part of it is right Bill Baer?) 

    Let me go back to that title. "O365 is not secure...once you start adding users".  Last week I blogged about a security oversight in O365's partner sharing feature.  Basically what this means is that once you accept an invitation from a partner (aka a "user"), you become just another customer in their "customer management" portal. You can read more about this feature here:

    Do you know who else they have as customers and who is accessing your data and when?  No. They don't really have any logs to tell you when a partner is accessing your portal for accountability.  Nor do you know who on the backend is working on your O365 deployment project.  Just too many unknowns to say it is secure.

    O365/Azure Apps

    But that's not the focus of this post.  A few weeks ago, O365 released the O365 APIs for Exchange (Mail, Contacts, Events and Files).  All of this piggybacks on Azure Active Directory for authorization utilizing the Consent Framework.  The Azure AD platform allows you to build an application that can make calls to Azure Active Directory or your O365 data. The permissions of the consent framework can allow an application to read the current mail item, all your mails items, your contacts, your calendar...your files. 

    As a simple example, one of the more impressive abilities is to create a Mail App.  You can do this using Visual Studio 2013 and creating an App for Office project.  This isn't going to be a developer post so I'm not going to show you any code, but simply talk about the importance of "Mail Apps" and your users.

    Once you have a Mail app created, you can deploy it to your O365 instance, or even post it in the Office store.   You can find a small set of mail apps in the following link (these have been publicly deployed to the office store, but you can have rogue apps that simply are registered somewhere in Azure AD and users give them ad hoc permissions):

    Many of these are poorly designed (for example, the LinkedIn app is a total disaster, the cert is locally generated and not even a public CA).  In some cases, you may find the deployment endpoint isn't even available so the app install fails.  If you were to install one of these apps, you will find that they simply request access to the "current" mail item.  This is the preferred scenario if you were to use these apps.  In some cases however, you may find that the app is given "carte blanche" to your entire mail inbox.

    So back to users and mail apps.  When you are in your Outlook, your users will ultimately find the settings icon and this nice menu item called "Manage Apps":


    Clicking on this, they will be taken to the "Exchange" app center.  This is where you see administrator installed apps and user installed apps:


    This is JUST for Exchange.  This has nothing to do with the bigger picture of Azure AD Apps and the consent framework.  There are some governance controls implemented in the Exchange app architecture, however, when it comes to Azure AD and your tenant, the story hasn't been written yet. This goes back to the premise of this blog post.  All it takes to make your highly secure O365 environment to be unsecure is:

    • A user
    • An App
    • A click 

    The permissions given to that app can now comprise the integrity of your entire system.  When on-premise, you at least had the ability to prevent incoming requests using your router and DMZ.  In this instance, O365 doesn't have any of that, so once permissions have been given, that's all folks.  So what hacking scenario might come up?

    • Hacker builds an Azure app, puts your company name and logo on it
    • Hacker does some social engineering to find out your name, title, work phone number and other information
    • Hacker asks you to install the app and because it has your logo and company info, your user thinks nothing of it and clicks "trust"
    • Hacker can now gain access to an access token that can be used to download all your email and your my site files

    If you are in defense or government, you know hacking enemy number one is China.  For those of you that think that insensitive to say, you haven't watched the traffic logs with the FBI and CIA as it happens, almost on a daily basis.  But the US is not a good guy when it comes to that stuff either, so all is fair in love and war.

    O365/Azure App Governance

    It is my suggestion, that you disable the ability for users to add apps.  It simply creates security holes that equate to users writing company checks that can't be cashed.  So, with that recommendation, can I provide you the steps to deny a user the ability for users to add apps" in your tenant, *sure*, thanks to some recently surfaced info (see below) Big Smile (thanks to @richdizz, @jthake and @Matthias1o1) In terms of Exchange, there are some user roles in Exchange that you can "remove" to prevent users from deploying apps, these roles are enabled by default:


    [UPDATE 6-5-2014]
    After this post the following was brought to my attention from the O365 team.  It is a non-UI based way to disable all user consent, thanks to the O365 team for pushing this content out!:


    Even with the above update, what is still not available to us is an Azure AD UI (to make it more apparent of the risk) that allows me to disable apps, and/or designate a "safe/white list" of apps that my users *can* utilize in Exchange or Azure AD.

    Just for kicks, I have created a UserVoice suggestion that more advanced App Governance features (such as a UI and white list) be added to Azure AD and O365, you can vote for it here:

    My God, What Have You Done?

    So, this brings up an interesting point.  Last night at the meeting I announced that we have moved to as our auth mechanism as it provides the most flexibility and telemetry data.  One person asked, what is telemetry data?  I said every time you login, I get data about you (first name, last name, email, blah blah).  It freaked out half the group.  Only one person was educated enough to know which of the supported auth systems had the least amount of data being sent.  So again, this brings up that interesting point I started this paragraph you know what apps you have simply just clicked on the "authorize" button just so you could use the app?  I bet you don't, my god, what have you done?  Think about all those apps across all your services (facebook, twitter, liveid, google, etc).  So in an effort to help you understand just how bad this is going to get with O365, based on how bad it has gotten in a general sense, here is the links to where you can check what you have authorized for each of the major platforms:








    I suppose you could say that this page (http://youweburl/_layouts/15/viewlsts.aspx) is as close as it gets?  At a farm level, in O365:



    Azure AD:

    Back to the question..."My god, what have you done?"  After clicking on all those links, I'm sure you have an idea of just how bad the problem has gotten.  Some of you might be surprised to find out that your Hotmail/ email and OneDrive (consumer) files have probably already been downloaded and analyzed by that cool app you gave permissions too.  Most of you that read my blogs are the cream of the intellectual crop.  You understand what that "Trust" dialog means.  For the rest of the population, not so much.  The meaning of the word "Trust" has been eroded by fancy graphics and the promise of a simple functionality at the expensive of selling your data soul to the app provider.  That all being said,  its time for enterprise solutions to have a "white list" to keep users from eroding the meaning of "Trust", to anyone's dog or cat.  One last thing on O365, no matter how secure you make the back end, its the front end that matters.


  • Apache Cordova, Apache Ripple, Visual Studio 2013 and O365 APIs

    "Mobile first" has become a common theme these days and building code and applications that you can write once and deploy to multiple target platforms is a key to achieving reach and use for your backend platform.  With the O365 APIs being release a few weeks ago, you can now do REST development against O365 exchange services (Mail, Contacts and Calendar, however, no Tasks yet).  A lot of focus has been on putting out samples for the various mobile platforms (Windows Phone and Android as the top two).  That being said, let's take a look at these Android examples and then the new Apache Cordova project templates. 


    The Android SDKs that you can download here need some serious help in order to get them loaded into a Java IDE (such as Eclipse Kepler).  For example, not only do you need the Active Directory library, you also need several Google SDKs (yeah, I said Google).  In order to get all the examples working, you need to download the following:

    Once you have all these, you can extract the O365 SDK and you will notice several projects that you can import into Eclipse (you will notice that all of them have errors, this is because you need to add the referenced JAR files to the project build path):


    Each project will need the "", "office365-base-sdk", json-2.2.4" and "guava-16.0.1" JARs.  Once you have these added, you will notice that all the projects now show no errors.  You are now free to select a project and run it. The first app is called the "Asset Management" app:


    Opening the application allows you to start configuring it:

    The authentication options can be of three types:

    Azure Active Directory (AAD) is the OAuth method. Selecting it will allow you to utilize redirection to O365 login page and then back to your application.  Once you have authenticated, you can click the "Show Cars" button:

    It simply makes a call to a SharePoint picture library called "Cars" (that you have to create and add items too) to show you the picture of the car and its description:

    In addition, there is a "File Discovery" application.  This can be configured by modifying the "" file (which is a common thing across the apps) by adding your client id and secret.  Once you have updated the files, running the app will show the following icon:

    Once open, you will see that it queries the discovery service and shows all your services (via the Discovery API):

    Clicking on the Files service will show you your OneDrive for Business Files:

    You may find that you keep getting an exception around the dialog.dismiss method.   This is a bug in the code, all you have to do is wrap it in a try catch block and the code will run ok.

    There is also a mail app (but it doesn't have a .project file so it won't import as a project).  Unfortunately I was never able to get it to work because it kept throwing memory errors, but supposedly you can also get it to show you your mail. You will also need a couple of extra JAR files to get it to compile:

    Apache Cordova:

    Not into building platform specific Apps like the Android ones above?  That's where the Apache Cordova platform comes into play!  If you do a quick Google search, you will find this site:

    This site simply describes itself as "A platform for building native mobile applications using HTML, CSS and JavaScript".  Basically what that means is that it is a translation middleware of common web standard elements as common inputs and then transform your code to a target such as Android or Windows Phone.  The neat part is that Apache Cordova is now integrated into Visual Studio 2013 Update 2.  You can download the Apache Cordova project extension here:

    This will give you the ability to create Hybrid Apps:

     Once you have created a Hybrid App, you will see the following in your Solution Explorer:

    In Visual Studio, you will have a set of target devices and also the ability to specific your debug target:


    Notice here, the "Ripple" debugging target.  Before you start debugging, you can modify the supported features of the target device via the App Manifest's "Plugins" tab:


     Now this is where things get interesting.  You can right-click the project and select "Add->Connected Service".  From here you can add either "Windows Azure Mobile" or "Office 365" services. 


    The view is similar to if you were doing an MVC or Web Application Project, but the output is VERY different.  What you will notice is several folders and JS files are added:


    The above "settings.js" does some initialization of the O365 SDK. The remainder of the files have some pretty powerful code in it that all but builds your application logic!


    Once you have all of these files in your project, you have to add them to your "index.html" page:

        <p>Hello, your application is ready!</p>

        <!-- Cordova reference, this is added to your app when it's built. -->
        <script src="cordova.js"></script>

        <!-- cjg699 references -->
        <script src="./services/mobile services/cjg699/service.js"></script>

        <script src="scripts/jquery-2.1.1.js"></script>
        <script src="services/office365/settings.js"></script>
        <script src="scripts/aadgraph.js"></script>
        <script src="scripts/exchange.js"></script>   
        <script src="scripts/o365adal.js"></script>
        <script src="scripts/utility.js"></script>   
        <script src="scripts/index.js"></script>
        <script src="scripts/o365.js"></script>
        <input type="button" id="btnGetEvents" name="btnGetEvents" onclick="GetEvents();" value="Get Events" />
        <br />
        <br />
        <div id="Events">

    Once that is done, you can add your own O365.js file with your logic.  In this case, I am simply making a call to get the events:

    function GetEvents() {
        var authContext = new O365Auth.Context();
        .then((function (token) {

            // authentication succeeded
            var client = new Exchange.Client('', token.getAccessTokenFn(''));

            .then(function (events) {
                // get currentPage of calendar events
                var myevents = events.currentPage;


                for (i = 0; i < myevents.length; i++)
                    $("#Events").append("Subject: " + myeventsIdea._Subject)

            }, function (reason) {
        }).bind(this), function (reason) {


     Pressing "F5", Google Chrome will start with the Ripple emulator:


    You can now click on the "Get Events" button which will attempt to execute the code, but first direct you to provide consent:

    Clicking on "Get Events", you will see your mail:


    One important note, the JavaScript code will cache your access token.  If you didn't get your permissions setup properly, then you'll have a bad token cached.  You will need to call the "SignOut" method to clear the CacheManager and the bad token as they don't expose the CacheManager directly.

    If you wanted to test on Android, you would simply change the drop down target and press "F5" again.  It would then attempt to start the current Android SDK Emulator and upload the APK file, you would see exactly the same UI and button and the same results!

    Unfortunately, at the moment, the JavaScript API for O365 is only provided in the Hybrid Apps project and is not really compatible with the other project types (such as MVC).  Apache Cordova, the Ripple emulator and project templates such as Hybrid and Cloud Business Apps are the future of application development!

  • Azure Access Control Services (ACS) is dead

    I recently went through the exciting process of setting up our site to support various authentication mechanisms (LiveID, Google, Federated Auth, etc).  I started off using Azure Access Control Services (ACS) because I thought it had everything I could ever want in a login aggregation platform.  However, I soon realized that it just wasn't able to meet the simple needs of a small SharePoint User Group.  And now that I know it can't meet those needs, I doubt it really meets the needs of large organizations either. 

    A bit about ACS

    To be fair,  ACS was the first of its kind.  I remember when it was first released, it was sooooo cool.  It really was.  I built some cool labs off of it (the old UI), then the UI "disappeared" (at least, the link was gone from Azure at one point), only to reappear again in the latest incarnations.  ACS isn't a part of the main Azure portal.  It has its own interface, which has confused me to this day being that all the other services are moving into the current portal.  Here's a screen shot of the two:


    Why they are separate probably has to do with (put some random excuse here, but likely because of "legacy" configurations). It would make much more sense that Azure added ACS as its own separate application in the Azure Portal. 

    So what can we do with ACS?  If you are familiar with ADFS, then you get the point.  I can created "Identity Providers", "Relaying party applications" and claims rules between the two.  The latter being one of the strengths of ACS (Quick history lesson, ADFS 1.0 was a real piece of junk, that left only one option, that option being ACS. It could do all the things that ADFS 2.0 was about to do).  So what kinds of identity providers can we add?  Well, here they are:


    Hmm, interesting.  So they have preconfigured providers for LiveID, Google and Yahoo.  Fair enough, those don't actually need an application (client id and client secret) created for them.  But "Facebook".  Ummm, that one needs an app created for it to do federated auth.  Ok, let's do it.  Added a facebook app used to be fairly easy back in the day, now the UI sucks.  And the process to get a simple "App Stub" created requires a canvas page?  Whatever.  Fail on facebook's part.  Ok, back to ACS.  So they are allowing us to do federated auth to OAuth providers.  Ok.  So how do I add others?  Like Twitter?  Maybe Yammer?  Oh...YOU CAN'T!  But you can do WS-Federation all day long.  Boring.  Oh, did I mention the Google one doesn't work anymore?  Yeah, Google seems to have disabled the interface that ACS was using.

    Ok, so ACS is dead "to me".  So what do I do now?  Do I build my own?  Ugg, that means I need to register an app in EVERY possible OAuth provider on the planet.  Similar hoops to jump through (approve the app, screen shots, canvas page, terms...ugg, no thank you). 

    Let's do some research, maybe someone built a better ACS?  Maybe someone did all that work to register an app EVERYWHERE? After a few google searches, some tweets...I 

    Auth0 is the ACS killer.  I have no doubt that after the right people at Microsoft see what they have built, Auth0 will be picked up in a M&A transaction.  I'm going to tell the guys to hold out and get 4-5 offers and bid the price up.  I have no doubt, they will go for $100Ms in a liquidity event.  So why are they so cool?  Because you can add ANYTHING!  Check this $^&%^% out!  Database, Social and Enterprise:

    Database (think ASPNETDB - this is a biggy for SP2015 by they way):


    Social (oh right...ACS gives us...Facebook...totally lame):


    Enterprise: you see the one at the bottom?  Yeah...that's SharePoint Apps for on-premises (courtesy of Chris Beckett consulting services). you see the O365 and Windows Azure AD one?  Oh yeah...that's Azure AD Apps...umm, so why are you using ACS again?

    Telemetry and Metrics

    Are you freaking kidding me?  ACS would never have thought this up.  You get telemetry on when and how your users are logging in:


    The logs are also pretty sweet:


    You see the profile JSON response in the Logs that contains the Access Token (if provided) so if you need to debug something, you have everything you need!

  gets better (but maybe a bit confusing for you that haven't been doing this stuff for a while).  In addition to allowing your Apps access to all these federated OAuth platforms, it itself is an App registry.  You can create your App in the Auth0 interface, which is then exposed as a WS-Federation end point!!!  Holy $%&^&$^!  Forced to use ACS, but you think it sucks like I do?  Hey...add your Auth0 WS-Federation endpoint, and just like one of those "I saw it on TV adds", "Set it and forget it!":



    Oh baby...if they weren't already ahead of the competition.  This is the future.  Forget about all those APIs you have to write to and learn.  Why bother with the auth parts?  All you need is to call the API and get that JSON response back.  Here's what they support:



    Do you have some ACS rules?  Yeah, they support that too...what they don't have is an ACS rule importer.  That would be so slick. Easily migrate from crappy old ACS, to shiny new Auth0:


    Custom Emails:

    Just to add insult to injury...woah...custom emails...custom whatever!  When someone hits your fed auth endpoint...send em an email based off the claims!


    Is ACS Dead?  Yeah, to me it is.  To the masses that didn't know any better, consider yourself educated.  As the word spreads, I'm sure there will be a mass ACS exodus very soon!


  • OneDrive vs OneDrive and OneNote vs OneNote - Why the disconnect?

    So you think you know OneDrive eh?  If you were knowledgeable, you'd ask, which of the three?  Maybe you knew that, maybe you didn't.  But I'd venture to say that many don't really understand the programmatic aspects between the various versions.  Additionaly, since I'm going to talk about APIs, I might as well throw the OneNote API into the mix.  One Drive exists in three states:

    • OneDrive for business (the version that runs in your O365 tenant)
    • OneDrive Pro (the version that runs in your on-premises environment)
    • OneDrive Consumer (the version that runs in your LiveID environment) 

    OneDrive for business and OneDrive Pro are simply SharePoint document libraries that exist in your My Site.  The APIs for gain access to these are as "simple" as making basic document library API calls for any SharePoint document library.  These SharePoint file APIs are documented here:

    Notice that you must specify the url of the site (in this case it is your My Site url) in order to give context to API calls.  For a typical O365 instance, this looks like:


    All REST calls and CSOM will need to be instantiated with this url. Now consider folder nagivation.  In SharePoint, you must use the "GetFolderByServerRelativeUrl" method on the web object. An example of this call looks like this:'/personal/givens_acs579_onmicrosoft_com/Shared Documents')

    Umm...does anyone else think this is a super long and incredibly dumb way of getting to a file folder?  Yeah, thought so.  Let's take a look at a typical OneDrive consumer API call, which are documented here:

    As an example, to get your current one drive folder, one simply has to do a GET to: (yes it is still called "skydrive")

    Wait, do you see that?  Instead of "'/personal/givens_acs579_onmicrosoft_com/Shared Documents')" it is "me".  Woah, what a concept. 

    Now let's look at getting a file or posting a file.  Each file and folder has an id.  To get a folder, you simply do something like:


    Instead of...oh nevermind...its waaaay tooo long to copy and paste.

    The implementation of file operations in SharePoint is horrendous and needs a total overhaul.

    Now, let's take a look at OneNote.  In SharePoint, every site can have a OneNote notebook.  This notebook is rendered and edited using Office Web Apps and the OneNote.ashx handler.  Many of the features you have come to love work using the browser, but alas, we have zero programmatic capabilities. In contrast, the OneNote for consumer has a massively beautiful API to it as you can see here:

    Wow, the ability to create and post to pages using a super simple HTTP REST API.  The OneNote endpoint is simply:

    They are putting massive dev time into this API, but I'm afraid we won't be seeing it anytime soon in O365 or on-premises.  Check out the list of features coming via the OneNote blog (that's pretty amazing set of upcoming features):

    What should you do?

    Vote for the OneDrive implementation of "me" here in UserVoice:

    Vote for the migration of the OneNote APIs here in UserVoice:

    Additionally, if you are an MVP:

    Make sure that you express your extreme disappointment when they send out emails saying O365, yet talk about LiveID consumer features.  It is extremely disrespectful to waste our time like that.

  • Google Apps vs Azure Apps vs SharePoint Apps vs LiveId Apps vs Yammer Apps - Introducing

    Let's talk apps for a moment.  A couple of questions for you:

    • If you were to build a single purpose app, where would you do it, how would you do it...why would you do it? 
    • If you were to build a multi-purpose app, where would you do it, how would you do it...why would you do it?

    If you are stuck in single purpose, Single Page App (SPA) land, then you are quite a few months behind where you should be.  You should be thinking, if I am going to build an app, where will I get the most bang for my buck?  If you are a customer, are you going to ask a consulting partner to build you an app in the future?  If so, do you understand what might happen in the future that will cause you to refactor (rebuild) your app?

    Do you understand the differences between application registries such that you know what might happen in the future or how you should architect your apps?

    A Scenario to Think About

    Many of the people that read my blogs are "SharePoint" people.  So you have seen many of my previous posts on building SharePoint Apps.  Low trust, high trust, OAuth in O365, blah blah (old and boring stuff).  SharePoint Apps were a great start to making Office apps run in predictable way using best practices in terms of user authentication (ie apps don't need passwords) and reliable API calls (REST and CSOM).  But let's step back for a moment.  In general, let's say our goal is to build an multi-purpose App (an app that spans multiple APIs and needs multiple client id and secrets).  These apps are much more complex, as an example, let's talk about how one might build an app that:

    • Makes a call to Visual Studio online to get project data that populates Project Server Online with tasks.  The app then adds to your O365 calendar items assigned to you based on project tasks. In addition, the app will post messages to Yammer throughout the entire process.  Additionally, it needs to post various data points by taking snapshots of project report data to a customer's notebook.

    This scenario, which I have no doubt many of you will think is "cool" or "I want that", will not be well understood from the sheer amount of effort this will take.  You won't fully recognize the plethora of APIs and App registries of which you would need to create and have target user's authorize in order for your multi-purpose application to work. 

    App Registries 

    So what do I mean when I say "App Registry"?  As the title of the post eludes too, there are several of them you might be interested in:

    • Google Apps
    • Azure Active Directory Apps
    • SharePoint Apps
    • LiveId Apps
    • Yammer Apps 
    • Facebook, twitter...on and on...

    All of these registries utilize OAuth 2.0 as their underlying auth architecture.  When you create an app in a registry, they are going to issue you a client Id and client secret.  In the scenario above, you will see that you will have at least five different apps.  In your multi-purpose app, you will need to manage the auth process with all the client ids and secrets in that app.  This is incredibly painful to manage without using some kind of library in the middle (there are several, take your pick with each being targeted at some platform, we need a platform agnostic approach, see later in this post).  In the end, the goal is to get an "Access Token".  Once you have acquired this token, you can make API calls from your app using the "Authorization" header in the HTTP request.  It is this access token that defines the scopes at which your application with be authorized (such as creating an email, creating a one note page, creating a file in your OneDrive [either consumer or business]).

    Since many of you are familiar with the concept of SharePoint and slightly less familiar with Yammer Apps.  Neither of these I will talk much in this post.  But let's do take a look at Live ID vs Azure AD vs Google.  Live ID is what has traditionally been considered the "consumer" authorization platform.  We use it to login to Hotmail\, our msdn accounts, our OneDrive consumer and OneNote consumer as just a few examples.  Until last week (5/21/2014), Visual Studio Online was also using Live ID (it now supports Azure AD\Organization Accounts but you currently have to create a *new* account and can't move your old one, hopefully that will change). 


    LiveID has been around for a while and there are many apps written to support consumer services.  If you wanted to create a LiveID app, you can do it here (note you must have a Live ID account to create one):

    Once you register an app, you will see it in the portal:


    Scopes for apps include the following:

    Just for kicks, here is SharePoint and Yammer registries screen shots:





    As a side note, SharePoint and Yammer Apps cannot make calls to O365 APIs, nor can they make calls to LiveId APIs such as OneNote and OneDrive.

    Azure AD

    Enter Azure Active Directory.  With the huge success of O365, Azure AD is being used as the organizational account backing (in the absence of federated auth) and with the new O365 APIs, as the application registry.  To register an application, you must create an app in the Azure management portal.  By default, your app is only visible to your organization, but can be made to be utilized by external organizations.

    As it stands right now, Azure AD only has a small set of apps that are using it (aside from custom organizational ones) which is commonly referred to as the Consent Framework: 

    • Azure Management
    • Azure Active Directory
    • Office 365 Exchange Online
    • Office 365 SharePoint Online

    These are shown in the following screenshot (with the "scopes" that each exposes):


    SharePoint Permissions versus Azure Permissions

    One of the big gaps between writing an Azure App and a SharePoint app is the level of permission granularity.  Take a look at the Azure permissions for SharePoint Online in the above screen shot, now look at the available permissions for a SharePoint App in the next screen shot.  What a major gap in permission granularity!:



    If we were to contrast these to the Google Apps portal, things start to get interesting in terms of what the future will hold for Azure AD Apps. The Azure UI is really primitive in terms of permissions assignment (imagine if you had 100 permissions for an app).  Additionally, a drop down won't cut it if they move to as many online supported services as Google has (which is the next registry I explore).  And just to add insult to injury, this error is one of the most annoying EVER:


    Google Apps

    Google Apps registration is available here:

    Here is a screen shot of the Google Apps page:


    Google vs Azure - "One client id and secret to rule them all"

    As compared to Microsoft, hopefully you were able to surmise that Google utilizes a single app registry (with a single client id and secret, with a much more advanced and comprehensive Consent Framework and UI).  So what does this ultimately mean for Azure AD?  If you look at Azure AD, it is in its very early stages (V0.8 maybe?).  Only a few apps are supported when it comes to the Microsoft set of online services.  As compared to Google, they have a lot of work to do.  Each team within Microsoft must make the decision to adopt Azure Active Directory as its future authorization platform in order for us to take advantage of a "single client id, single client secret" as we can do today with Google.  Visual Studio Online made a step towards making this a reality last week.

    OAuth 2.0 flows and HelloJS

    Now let's talk about OAuth 2.0 flow support. If you haven't seen HelloJS well, you are missing out.  It is an incredibly simple OAuth JavaScript library that allows you to do OAuth authorization in a very simple manner.  As it is using JavaScript, it is a client side implementation.  This means that Azure must support some type of cross origin scripting support (CORS) to get access tokens using simple token flows.  If this is possible today, it isn't documented anywhere.  As it stands right now, you need a server side component to broker the auth calls (WebAuthBroker pattern).  Hopefully this changes in the future or becomes better documented.


    So let's go back to the original scenario.  If the goal is to simply get an access token and similarly, make an API call to get a JSON response back, should we really care about any of the details of that process times five (LiveId, AzureAD, SharePoint, Yammer, Google, et all)?  Are you reinventing the wheel over and over again each time you create a new app in any of those registries?  The answer is yes.  Enter  Auth0 stands to change the way we build our multipurpose apps.  You can get a sample of how I\we use Auth0 on our site by attempting to login using any number of OAuth 2.0 credentials (facebook, twitter, etc).  In addition, you can abstract away the API calls for target services such that you simply need to get the responses back and perform your business logic. is the ultimate Web Auth Broker service\pattern!  I highly suggest that you take a look at Auth0 and how you can utilize it in your future app design.


    Hopefully you now have enough of a background of information to make some education decisions (such as wait for a few more months?)  in terms of what you might want to consider moving forward in your app design and architecture strategy.  I personally see Azure AD winning out over LiveID.  What this means in the long term with respect to services such as MSDN and the various other business services (MSInvoice, et all) hosted by Microsoft for vendor interaction (of which use LiveID today) is really foggy and not well defined.  A lot of these thoughts I have already conveyed to the various Microsoft teams that should be thinking about the above concepts.  The ball is in various Microsoft's exec's courts to make a high level decision to do the migration towards catching up with Google and deciding that consumer is consumer (LiveID) and business is business (AzureAD).  If they draw that line, you will see migrations away from Live ID happening left and right.

  • Azure Workflows cannot call O365 APIs

    As part of my 5-day O365 course I have a Workflow section that describes things like deploying workflows via Apps with event receivers that deploy to the Host Web.  Also a part of the lab is how to "theoretically" call an O365 API from workflow.  Unfortunately, you cannot call O365 APIs from workflows that live on-premises or in O365.  The reason is two fold. 

    • For on-premises, there is a buffer overflow in the Workflow Manager service (1.0, CU1, CU2 and 1.0 refresh) that barfs on large DynamicValue HttpHeaders in the HttpSend request.  Reference this post for the error you will see.
    • For O365, there is a special STS validation layer that barfs on the Azure AD access token (Error is "JsonWebToken.Issuer != clientId@realm"). If you pass the token in anything but the "Authorization" header it will pass right through, but it will not pass through in the "Authorization" header.

    Therefore, the only avenue you have is to use "Basic" auth when making the calls.  This means you must store the user's username and password somewhere rather than allowing them to go through the basic OAuth process the way it should be.

    If you would like to be able to do this, vote for it on UserVoice here:

More Posts Next page »

This Blog


Powered by Community Server, by Telligent Systems