Microsoft on a Mac: Still a second class citizen

It’s been interesting being a Mac user over the last couple of years. We’ve gone from being very much left behind compared to our fellow Windows users to pretty much feature parity. Well that’s what the marketeers would have us believe, in reality my experience is very different.

Yes we’ve got more functionality than we have ever had but while the new Microsoft is moving at a breakneck pace in the Office and Office 365 arena, we starting to get left behind again. This post describes the woes I have at this present moment with the various Microsoft apps that I use on my Mac. You might have your own problems and I’d be interested to hear about these.

Just to balance this out I will also give the pros from my point of view, over what we had before, just so the post isn’t all negative. This isn’t a review of the products though, I don’t use any of them enough to be an expert or give an expert opinion on all the features.

Firstly to set the scene, I’m using Office 2016 installed from my Office 365 subscription on my late 2015 Macbook Pro armed with a core i7, 16GB RAM and 500GB SSD.

Outlook 2016/Office 2016

First up Office, or Primarily Outlook 2016


  • Add-ins: These are a great addition. I use Trello on a daily basis to bump my emails into my boards for further action. The same add-in also allows me to do this from Outlook on my phone without me having to install it specifically on there.

Hmm that’s about it, it handles my Office 365 and accounts fine.


  • Schedule Skype for Business meeting: Not sure where the blame lies for this but I simple cannot find a way to add a meeting to Outlook and make this an online meeting. In Outlook on Windows, you have a Skype Meeting button which adds all the connection details to it. There is no such button in Outlook on my Mac.
    Update: I found a post on the Skype feedback forums that this feature has been added but from reading the comments it appears you have to have Lync installed too. Crazy!!
  • No ability to add files from SharePoint/OneDrive: The other Office applications allow you to open files from SharePoint and OneDrive but Outlook doesn’t give you the option yet, thought it is planned as of March 2017. This also isn’t great when you are trying to encourage customers not to sync every SharePoint folder in the organisation so they can keep working ‘like they used to’

Skype for Business

At he moment for me, this is pretty much unusable for me. Most (all) of my contacts are external to my tenant and I’ve had success in adding one from another tenant but that’s it.


  • Join a meeting. I can join a Skype meeting hosting by someone else.
  • Hosting a meeting: I can start a new meeting…


  • Add a contact: This is greyed out for me so I have no way of doing that.
  • Hosting a meeting: This was a pro right? Yes but in a meeting, I cannot invite anyone else who is not an Office 365 user or in my tenant. I tried with a colleague who has a Hotmail address and we both expected him to receive an invite so he could join via Skype on the web. He didn’t get the invite.
  • Schedule a meeting: Skype for Business very proudly shows my Exchange calendar but I can’t actually do anything with it.

In fairness to Microsoft, this has got better since it’s first release if you can believe that.


This is probably the application that has had the most fanfare over the last 12 months and has come along way over the previous versions but it’s falling behind again.


  • Multiple accounts: No longer do I have to install two OneDrive applications; one for my OneDrive for Business and another for OneDrive personal. I can login to both from one app.
  • Shared folders: This is a great addition, I can now select a folder that is shared with me and sync that down.


  • No Files-on-Demand: This is one of the new additions to OneDrive on windows that’s been left out of Mac, for now hopefully. In fact, this used to exist on Windows 8 or 8.1 then they took it out. Basically this allows you to in effect have placeholders for files on your file system so they take up very little space. When you try and access the file it will download it and you can carry on as normal. Dropbox has this with SmartSync so it obviously can be done
  • Install on an external drive: The latest Macbook Pros offer no way to to update the internal SSD, which isn’t MS’s fault I know but.. There are micro usb drives or micro SD adapters that sit flush with the casing, these are great ways of bumping files storage but OneDrive won’t let you store your files on here.
  • No pause: It would be nice to be able to pause syncing for a while, while tethering to a phone for example. Currently I use TripMode to deny access whilst connected to my phone. That works great but would be nice to have an out-of-the-box experience for it, especially if it offered scheduled sync times.

The lack of the first two options above has led me to have to turn off sync for certain folders, and this list is growing. At some point it won’t actually be worth me using OneDrive as I won’t have any space to sync anything down.

The first two OneDrive cons I have listed have suggestions on UserVoice, please vote if you would like to see these added to future versions.

Wrap up

Just to put a bit of context to the pros and cons for OneDrive above. This is primarily for my personal account (, not business. These are not files that have metadata attached to them. They’re my personal photos, videos and documents. I’ve spent years preaching about the benefits of metadata to customers and this isn’t me not practising what I preach. I do that on my business files, on my personal stuff I don’t have the will (or time) to go back through files built up over the years.

I don’t think it’s acceptable to have to install another (legacy) application (Lync) to get some of this functionality working, in fact Microsoft don’t support them running side by side so it seems people may have got them working more out of luck than anything else. We’re more than half way through 2017, Skype for Business has been GA for nearly 9 months now, it’s to get this working properly.

Don’t get me wrong Microsoft are doing some great things, especially in the spaces that I work but it would be nice for them to stop and have a look around once in a while, tidying up after themselves before moving on.

I’d like to hear of your issues or more so if there are ways to get some of the things above working. Or maybe I’m just doing some things wrong.

Posted in musings, Office, OneDrive

Use TFS 2015 build to package your vsix extensions

As part of my currently role, I’ve been migrating from SharePoint 2010 to 2013 including moving the build/release process to TFS2015. I created some deployment scripts and some TFS build tasks to support the migration but wanted to package these as part of a build process. This post takes you through the process of using TFS 2015 to package your custom build tasks.

There are probably easier ways of some of these tasks but due to time constraints and server configuration, this is the way that worked for me.We are using TFS 2015 so your mileage on VSTS may vary, I haven’t tried these on there yet.Pre-requisitesThe post will not teach you how to build a custom build task. What I’m focusing on is Step 3 from the last link below. Below are the posts I used as reference when creating mine.

Creating the build task

First off we need to create some build tasks for this. Go ahead and add the following build tasks

  • Npm
  • Batch Script
  • Copy Files
  • Publish Build Artifacts

Configuring the Build Tasks


Use the following configuration for the NPM build task

Batch Script

One thing to note about this task is that part of the path contains the TFS service account. This is because the NPM install above doesn’t actually install the package globally, it installs it in the user directory. There are ways to change/get around this but I’m happy for now as this does what I need it to and the service account is very unlikely to change. I tried to find a variable for this to save me hard coding it but couldn’t find one.The –output-path parameter below puts the vsix in a subfolder to keep things nice and neat.Change sharepoint-extensions.json to whatever your extension manifest file is.

Copy Files


From the build we are only interest in the vsix file, so we’ll copy that to the artifacts staging directory

Publish Build Artifacts

The final task (for me anyway) is to copy r extension vsix file onto a network share to be installed.

Next steps

The logical next step is to create a release or build task that will automatically deploy it to TFS (or VSTS). Unfortunately that’s not part of my remit here and I don’t have access to the TFS server to configure IIS for it. So for now we are manually installing the extensions into TFS.


Tagged with: , ,
Posted in TFS

My first Open Source Contribution

Ok, I think two firsts happened here, or are happening. First is that I made my first Pull Request to an Open Source project and second is that I think this is the first blog post about my thoughts on doing something, rather than it being a technical post.

Submitting the PR was a lot more of a daunting thing than I expected. What if I get flamed, what if the PR is rejected, would that make me try again or put it down to experience and not bother in future. The post, I’m even less sure about; yes everyone has an opinion and we voice these everyday but to actually put these in black and white on the internet where they are pretty much available to everyone to scrutinise for eternity, that was food for thought. I know that as in normal life, not everyone agrees with my opinion, that helped me to get to grips with the fact the same thing applies online.

Well I’m glad to say the pull request made it in through, the fix makes my life easier so why shouldn’t it make the life of someone else easier too. If you’re interested the project is here.

Anyway, I’ve done it, I feel better for it and shall move on and do some more of both along with the more technical posts too. I’d love to hear about your experiences of first doing something like this.


I originally wrote this post pretty much a year ago but never quite finished it, then forgot about it. I was thinking about not bothering to publish it but thought I might as well get it out there.

Thinking about it, it’s probably not my first. I heavily used a PHP framework back in the day that I customised quite a bit, but I’m taking this one.

Posted in musings

Bypass CORS from Chrome

On one of the projects I’ve been working on recently I needed to test against one of the API’s in the organisation. Adding my dev server to the list of allowed CORS URL’s for the API wasn’t possible but I didn’t want to pull down the code, deploy and in particular populate the database so I could test something pretty trivial.

Turns out you can run Chrome so that it will ignore CORS headers and allow you to access the API anyway. I wouldn’t advocate this for day to day use and may get you into trouble if you’re hitting an API you’re not supposed to but, here you go, simply run this.

chrome.exe --user-data-dir="C:/temp/Chrome" --disable-web-security
Posted in Uncategorized

Injecting Build Variables into an Angular App with VSTS Continuous Integration Builds


Following on from my previous post I wanted to add my build number to my Angular App so I can instantly see which build is deployed into each environment. You can of course take any of the build variables but I was only interested in the build number at this stage. This would allow me to see which change set and file modifications were deployed as part of that build should anything go wrong.

As this post relies on steps that are documented in the my last 3 posts, I recommend you go back and read through in order to understand the configuration we have so far.

Part 1: Use NPM and gulp build tasks to support Continuous Integration with VSTS and Azure for an AngularJS app
Part 2: Deploy an Angular App to Azure App Services (Web App) with VSTS Continuous Integration Builds
Part 3: Using gulp tasks in Visual Studio Team Services to configure constants for an AngularJS app
Part 4: Injecting Build Variables into an Angular App with VSTS Continuous Integration Builds (this post)

Configuring NPM

Our updated build task relies on an NPM package called gulp-replace. From a shell window or command prompt let’s add this package to our project.

Passing parameters to our gulp task

In order to be able to pass build parameters to our our gulp task we need to configure our gulpfile.js to parse these parameters. Believe it or not, we already added and configured this in part 1 of this series (linked above). A gulp package called minimist will take our input parameters and and assign them into an variable for us. Below is an excerpt from the gulpfile.js from part 1 that extracts our parameters so we can use these within our build tasks.

Adding a constants placeholder for our build number

Next up we need to modify our constants.json file to add a placeholder for our build number.
Add the following to the appSettings section:

Our build task will replace the {version} token and add our build number to the resulting javascript file.
The fully updated constants.json file is shown below:

Updating our build task

We now need to update the build task in our gulpfile.js file. This will replace the token we added to our constants file above with our build number that will be passed as part of the VSTS build process.

At the top of gulpfile.js add the following with the other require statements

Next we have to update the actual build tasks themselves. Remember we have two gulp build tasks in our gulpfile.js; one for our dev environment and one for the production environment. The following change should be applied to both of them. Before the following line in the build tasks:

add the following

Our gulpfile.js should now look like this

Update the VSTS build task

The last step is to update the build definition in Visual Studio Team Services so we can pass the build number into our gulp task.

Edit the build definition and highlight the gulp task. In the arguments section append the parameter for our build number. The entire line should now look like the following

Now within your Angular App you can call the constant appSettings.buildVersion where ever you want to display your build number.

That’s it, thanks for reading.

Tagged with: , , ,
Posted in Azure, Visual Studio Team Services

Using gulp tasks in Visual Studio Team Services to configure constants for an AngularJS app

Ok hands up, up until now this series has been very sparse in terms on Angular specific configuration. That’s about to change!!

To recap, these are the posts so far in this series:

Part 1: Use NPM and gulp build tasks to support Continuous Integration with VSTS and Azure for an AngularJS app
Part 2: Deploy an Angular App to Azure App Services (Web App) with VSTS Continuous Integration Builds
Part 3: Using gulp tasks in Visual Studio Team Services to configure constants for an AngularJS app (this post)
Part 4: Injecting Build Variables into an Angular App with VSTS Continuous Integration Builds

Now things get more interesting on the Angular and ADAL side of things.
I’m hoping you know that the ADAL configuration for an angular app requires us to add things like the Client ID and Tenant ID. These things are very specific to an Azure Tenant, but what happens if we want to deploy our code to a different tenant as was my case. If you’ve read the first post my use case here is that I want my VSTS instance to be able to deploy directly into a customer Azure tenant.
The app by default has the Client ID etc.. for my Azure tenant as this is where testing is carried out and I want to be able to change these before they get deployed into the customer tenant.

Even if you don’t use ADAL in your Angular app you can still use this process, in fact in some of the code I’m going to show you does just that. We don’t use the same API end points through dev/UST/prod right, this very process can update the endpoints for your API’s in different environments.

I have simplified things here, in the real world I use different builds/CI for dev/UAT environments but I’m not going to muddy these waters by adding unnecessary steps. Once you’ve done this once, you are free to set this up how you want.

Ok down to business. The first thing we need to do is add another npm package to our app. We can do this with

This will add the package to our app and save the dependency in our package.json file.
Gulp-ng-config is a gulp package specifically designed to create Angular constants based on a config file.

Next up we need to create a configuration file that we will use to get the values for each environment. Create a file called constants.json and paste the code below.

This file has configurations for two environments, dev and production but you can have as many as you need in here. You will obviously need to change the GUIDS/endpoints to reflect your environment. Also notice that we have some ADAL config settings in here and some app specific ones. You can put anything you wish into these sections.

Now we have the package and the config file we can configure the gulp task in our gulpfile.js file. The snippet below has the gulp tasks for both dev and release.

You can see in the release build task that we’re targeting an angular module called app and that is is going to use the release section from our constants.json file. The task will create us a file called constants.js inside and app folder (as determined by gulp.dest)

You can manually run this task by running the following from a command prompt inside your project directory.

You should now have a file created inside you app folder which will contain a file like the following:

Once you have included this js file from within your HTML file, you can use the constants in your Angular app in the same way as you would normally, for example adalSettings.aadEndpoints to access the ADAL endpoints and appSettings.apiEndPoint to get at the appsetting end point we defined. There are quite a few options within gulp-ng-config so if the output is not quite matching your app, take a look at the docs for it.

Now we have a task that will configure the environment variables for our production site, we can go back and configure VSTS to call our gulp task at build time so we get the correct constants in our Angular application.

Configuring our VSTS build task

Hopefully you have followed the previous posts and already have a build task in VSTS to deploy our source. If not, you might want to head back over there before we move on.

If you remember back we created a gulp task that looked something similar to this


To get the gulp build task to build the production config we simply add the build task before vstsbuild in the Gulp Task(s) field. the field value should become

build:config-release vstsbuild

We could of course chain these in our gulp tasks but this step for me was easier to do it this way.

That should be it, once the code is checked in to the master branch the build process will build our constants file and deploy this along with the rest of our app so it’s configured correctly for our Azure environment.

Hopefully this series of posts has shown you the way to an easier life automating deployment of client side based apps to different azure tenants.

Tagged with: ,
Posted in Azure

Deploy an Angular App to Azure App Services (Web App) with VSTS Continuous Integration Builds

This is the second post in this series and the post will pick up where we left off.

Part 1: Use NPM and gulp build tasks to support Continuous Integration with VSTS and Azure for an AngularJS app
Part 2: Deploy an Angular App to Azure App Services (Web App) with VSTS Continuous Integration Builds (this post)
Part 3: Using gulp tasks in Visual Studio Team Services to configure constants for an AngularJS app
Part 4: Injecting Build Variables into an Angular App with VSTS Continuous Integration Builds

We are going to configure Visual Studio Team Services and create the build tasks that will deploy our files into our Azure Web App using the gulp tasks we created previously. This will run automatically when we check in to source control.

Login to your Visual Studio Team services account and navigate to your chosen project in VSTS and click the settings icon to the right of the screen.

From here click on the Services tab


On the Services screen click New Service Endpoint and choose Azure Classic


Note: I probably should have used (and tried) Azure Resource Manager as it’s the new kid on the block but this did not work for me when I got to the stage of adding the build task. I may revisit this but for now this was about me getting this working and deployed.

On the resulting window check the certificate based checkbox


Now we need to get the rest of the settings. To do this we need to download the publishing profile from our Azure subscription.
To get this click the download publish settings file link at the bottom of the screen above. Once you have this enter these details in the corresponding boxes above. You can call the connection name anything you like, remember it as we will need it when we create our build tasks. Click OK when this is done.

Just in case you’re interested you can download your publishing profile from here.

Configuring the Build Definition

Now we can add a build definition to deploy our site to Azure.
Go back to your project in VSTS and click the Build link. From here click the add button to create a new build definition. Choose to create a new Empty definition


Choose your repository and branch to use for the build


From the new build definition screen, click Add Build Step and add the following build tasks:

  • npm install
  • gulp
  • Azure Deployment (Azure Web App Deployment)

Click OK when you’re done and you should end up with a screen similar to that below.


Ok, lets configure each of the build tasks.

npm install

npm install is easy, we can leave the defaults on this.



To configure the gulp task we need to use the following values, taken from the previous post.

  • Gulp File Path:
  • Gulp Task(s):
  • Arguments:

Leave everything else as default


Azure Deployment

Enter the following settings:

  • Azure Subscription: Enter the Connection Name from way back when we created our Service Endpoint above.
  • Web App Name: This is the name of our existing Web App in Azure we want to deploy to. You can get this from the App Services blade in the (new) Azure Portal.
  • Web App Location: Enter the same location as for the Web App we are deploying to.
  • Slot: I left this blank as I’m not deploying to a slot
  • Web Deploy Package: $(Build.StagingDirectory)/

I left everything else blank. One point to note on this screen the first 3 boxes are dropdown and should show the Subscriptions, Web Apps and Locations respectively. This wasn’t the case for me and I had to manually add them. It all worked for me, just be careful to add the correct values if it doesn’t allow you to choose them.

Hit the Save button and everything should be good to go.

Next step is to trigger our builds. To do this click on the Triggers link.
Check the box for Continuous Integration (CI) and make sure the correct branch is selected.


All that’s left to do is check in code into the correct branch and this should fire a build for us and deploy to Azure.

Once you check the code in, you should see a build queued and you can follow it through until completion.

In the next post I will show how you can configure the gulp build task to build some AngularJS constants that are specific to the environment we are deploying to.

Tagged with: , , , , ,
Posted in Azure