Salesforce DX CLI Cheat Sheet

The Salesforce trailhead is good, although its verbose style makes it hard to use for a quick reference. This list is just for my benefit to quickly remember the relevant commands, but may be of wider use as well:

Salesforce DX Trailheads:


Action Command
Update the CLI sfdx update
Set the dev hub instance sfdx force:auth:web:login –setdefaultdevhubusername –setalias my-hub-org
Create a new project sfdx force:project:create -n myAwesomeNewProject
Create a scratch org sfdx force:org:create -s -f config/project-scratch-def.json -a GeoAppScratch
Open the scratch org sfdx force:org:open
Pull the configurations & customizations from your scratch org to your local project sfdx force:source:pull
Pull data from your scratch org to your local project sfdx force:data:tree:export -q “SELECT Name, Location__Latitude__s, Location__Longitude__s FROM Account WHERE Location__Latitude__s != NULL AND Location__Longitude__s != NULL” -d ./data
Push your local project back to your scratch org sfdx force:source:push
Create a new Lightning component in your local project sfdx force:lightning:component:create -n AccountListItem -d force-app/main/default/aura
Create a new Lightning event in your local project sfdx force:lightning:event:create -n AccountsLoaded -d force-app/main/default/aura
Create another scratch org sfdx force:org:create -f config/project-scratch-def.json -a GeoTestOrg
Push local project to new scratch org sfdx force:source:push -u GeoTestOrg
Assign permission set to new scratch org sfdx force:user:permset:assign -n Geolocation -u GeoTestOrg
Upload data to new scratch org sfdx force:data:tree:import -f data/Account.json -u GeoTestOrg


Manage Dev Hub and packaging

Action Command
Set the dev hub user name sfdx force:config:set
Create new project sfdx force:org:create -f config/project-scratch-def.json -a TempUnmanaged
Generate new password for scratch org sfdx force:user:password:generate -u TempUnmanaged
Display dev hub sratch org details sfdx force:org:display -u TempUnmanaged
Pull the source sfdx force:source:pull -u TempUnmanaged
Pull in package sfdx force:mdapi:retrieve -s -r ./mdapipackage -p DreamInvest -u TempUnmanaged -w 10
Open resulting package unzip -d
Convert to metadata sfdx force:mdapi:convert -r mdapipackage/
Delete the scratch org sfdx force:org:delete -u TempUnmanaged
Create a new sratch org sfdx force:org:create -s -f config/project-scratch-def.json
Push local project to new scratch org sfdx force:source:push
Assign permission set to new org sfdx force:user:permset:assign -n DreamInvest
Convert to metadata sfdx force:source:convert -d mdapioutput/
List all orgs in dev hub sfdx force:org:list
Deploy to new scratch org sfdx force:mdapi:deploy -d mdapioutput/ -u MyTPO -w 100

Dynamics 365 – Adding an administrator Web Role to an Employee Self Service Portal

In order to edit the content directly in a Portal on Dynamics 365, you need your user (specifically the contact record related to your User record) to have a Web Role with editing privileges.

This can be confusing, because this security setting is set on the Contact and not the User. Portals concern themselves with Contact logins first, and although the Employee Self-Service (ESS) Portal leverages the Azure Active Directory, it still looks for the role on the Contact record.

There isn’t a nice easy way (that I was able to find) to manage web roles for users, and it is all done through Invitations. Again, this is confusing because Users for the ESS don’t need invitations. They just log in if they have a Dynamics 365 license. Nevertheless, we need to go through the motions in order to get the Web Role assigned.

First, create a normal Dynamics 365 User:

Screen Shot 2017-08-06 at 9.17.02 pm.png

I now have a User but no Contact:

Screen Shot 2017-08-06 at 9.20.57 pm.png

We can create our Contact by just letting John log in once:

Screen Shot 2017-08-06 at 9.23.07 pm.png

And that will create their Contact record automatically (related directly to their User record):

Screen Shot 2017-08-06 at 9.24.39 pm

Now go the the Contact record and click ‘Create Invitation’ at the top:

Screen Shot 2017-08-06 at 9.26.05 pm

First thing click ‘Save’ on the Invitation form in order to create an Invitation record for this Contact:

Screen Shot 2017-08-06 at 9.27.03 pm.png

And then in the ‘Assign to Web Roles’ box just add them to ‘Administrators’:

Screen Shot 2017-08-06 at 9.29.30 pm.png

Then go to the ‘…’ button, and select ‘Other Activities’

Screen Shot 2017-08-06 at 9.32.32 pm

And then click ‘Invite Redemption’:

Screen Shot 2017-08-06 at 9.35.27 pm.png

In the following Dialog Box, just enter the Contact record and any username and click ‘Save’:

Screen Shot 2017-08-06 at 9.37.04 pm.png

Now go back to the John Smith’s Portal session and refresh the browser. The toolbar will now appear:

Screen Shot 2017-08-06 at 9.38.26 pm.png

All of this wasn’t very obvious from the documentation at all, and I would hope in future that Microsoft will add an option to manage Web Roles directly on the Contact record. It is possible I missed an easier to do this, and if I find it then I will update this article accordingly.





Microsoft Dynamics 365 Employee Self-Service Portal Access with Azure AD Integrated Apps settings

Microsoft Dynamics 365 Portal is a great new addition, having matured greatly from the ADX acquisition and possible to set up in a few clicks. They don’t offer a massive amount of extensibility, but does the job well (i.e. let a Contact log in, raise a case, check case progress, browse a knowledge base, add simple access to other entities).

I did face an interesting problem in a customer scenario where I set up an Employee Self Service Portal, and found that users could just not log in.

Screen Shot 2017-08-06 at 2.22.47 pm.png

Google didn’t provide any hits for the phrase “Microsoft CRM Portals needs permission to access resources in your organization that only an Admin can grant” – so seemed a good candidate for an article!

After some investigation, we found that an earlier Security Audit had recommended turning off the ‘Integrated Apps’ setting in Azure AD. This meant that users could not consent to have the Portal read their AD profile:

Screen Shot 2017-08-06 at 2.07.41 pm.png

Screen Shot 2017-08-06 at 2.17.25 pm.png

The immediate fix is just to enable this setting back on again. I also had to restart my Portal to get this working.

Screen Shot 2017-08-06 at 3.34.55 pm.png



Mac OS Taskbar Calendar

Calendars are important to consultants, and Windows has a quick and easy to use one when you click on the time. When using a Mac you don’t have this and going into the Calendar view in Microsoft Outlook (or other app) can often distract you from the task at hand (i.e. you are writing an email suggesting to meet next Wednesday, but you want to be really sure that next Wednesday is the 9th). WinCal
Itsycal is a great utility that does this for your Mac, is free and simple:


Start and connect to your Azure VM from the Mac command line

Update 11th October: OK, I didn’t realize is was now very trivial to set a static IP and a DNS name in Azure Public IP Address configuration for Azure. Still I think the commands in this article are still interesting to illustrate how to interact with Azure.

Microsoft Azure is great, but I’m not really a big fan of the Azure portal . I find it rather messy to navigate, and multiple clicks to find the function that you want.

My first simple scenario is to start and connect to one of my Azure developer machines. It costs a great deal to run it 24 hours a day, and I may only use it between 1 and 4 hours each day. It can be started and stopped on the portal, but with some Azure CLI tools and bash scripting I can start and be in quickly.

First let’s check the version installed:

Azure --version


Then login, which will ask you to open and enter the given code. You can then link your subscription through the browser.

Azure login

Screen Shot 2016-10-07 at 8.59.40 AM.png

If succesful, then all your MSDN subscription will get added (in this example I have 3)

Screen Shot 2016-10-07 at 9.03.08 AM.png

So now your environment is ready.

List out all your available VM’s with

azure vm list

Screen Shot 2016-10-07 at 9.26.38 AM.png

and start with

azure vm start -g -n


I was looking for a command that would download the remote desktop file (RDP), but seems there isn’t. No problem because it is easy to create from the VM’s IP address:
azure vm show |grep "Public IP address" | awk -F ":" '{print $3}'

So with a little Bash scripting, you can derive and launch the remote session automatically. This assumes that you have installed Microsoft Remote Desktop for Mac. Just create a new bash script file with the following contents, changing the environment variables to you Azure and local configuration:


echo "RDP Generator"
#Change to your Azure resource group

#Change to your Azure VM name

#Change to the user name on that VM

#Set the location of the temp RDP file

#This should be the default location for Microsoft RDP install
VarRemoteDesktopLocation="/Applications/Microsoft Remote"

VarResult1=$(azure vm show $VarResourceGroupName $VarVMName |grep "Public IP address" )
VarResult2="$(echo $VarResult1 | cut -f3 -d ':')"

VarBegin="full address:s:"

echo $VarRemoteDesktopLocation

touch $VarRDPLocation
#overwrite existing file
echo $VarBegin$VarResult2$VarEnd > $VarRDPLocation
echo "prompt for credentials:i:1" >> $VarRDPLocation
echo "administrative session:i:1" >> $VarRDPLocation
echo "username:s:"$VarUserName >> $VarRDPLocation

#Launch remote desktop session with new file
open -a "$VarRemoteDesktopLocation" $VarRDPLocation

Just run your new script file and it will launch the Microsoft RDP client automatically.


Create Azure ASP.NET applications on a Mac

I recently started to get back into ASP.NET after a long absence and was suprised by the ‘reboot’ of ASP.NET Core (formally known as ASP.NET 5). It is wrong to think of it as the next big version after ASP.NET 4 since it is a completely different beast. It is smaller and (for now) far less featured than ASP.NET 4. It is highly portable across Windows, Azure, Mac, Linux etc.

If I was architecting a new project then I might be tempted to stay with the saftey of the ASP.NET 4 platform since it is a mature product with great tooling as well as still being activally developed.

Luckially this was just for fun, and I wanted to try some things out with Azure services. I shunned Visual Studio 2015 for the simplicity of Visual Studio Code on the Mac. The two products are not comparable for the most part, but since I was relearning ASP.NET doing so in a new simple way was very compelling.

Microsoft have a tutorial for this.

The main issue was installation. Installing the .NET Core SDK on the Mac required installing an additional few layers of separate dependancies (Yeoman, Homebrew, etc) which didn’t seem to work. After some Google of error messages I got everything working after about 20 minutes.

Screen Shot 2016-07-22 at 3.10.19 PM.png

Building the scaffolding of a simple ASP.NET page was trivial, and running it on my local Mac was extreemly easy.

Screen Shot 2016-07-22 at 3.14.01 PM.png

Screen Shot 2016-07-22 at 3.17.48 PM

I wasn’t looking forward to deploying it to Azure. I guess my history with ASP.NET made me expect that deploying to a new site would be painful. In fact once you set up GIT in Azure and locally, the push is really easy and worked as expected first time!


So basically I could build an ASP.NET application on my MacBook, try it out, and then publish it to Azure with no Mirosoft Windows or Visual Studio required in the process at all.


I’m definately a convert to this new way of working now. If you are considering learning .NET Core then I’d really recommend ditching Visual Studio, even if you have a Windows environment. You might miss out on some graphical familiarity, but it is easy to start from the basics.












Delete all Opportunity Records in Salesforce

This seems rather simple, but it was hard to find out how to delete all Opportunity records from your Salesforce organization.

The main reason was that the easiest way is to use DataLoader to extract all the record ID’s and then bulk delete them. Unfortunately this method requires me to leave my laptop open for a few hours whilst it deletes the 1 million records.

As an alternative I adapted this Apex class that implements the Database Batchable interface. This then sets up the required number of individual batches to delete all the records (5,000 at a time).


global class example_Batch implements Database.Batchable<sObject>{

global Database.QueryLocator start(Database.BatchableContext BC) {

String query = ‘SELECT ID FROM Opportunity’;

return Database.getQueryLocator(query);

global void execute(Database.BatchableContext BC, List<sObject> scope) {



global void finish(Database.BatchableContext BC) {



It then runs in the background freeing up my laptop.

Screen Shot 2016-06-15 at 4.14.47 PM