Thursday, 19 February 2015

CRM Javascript Functions

1.  Get the GUID value of a lookup field:
Note: this example reads and pops the GUID of the primary contact on the Account form
1
2
3
4
function AlertGUID() {
    var primaryContactGUID = Xrm.Page.data.entity.attributes.get("primarycontactid").getValue()[0].id;
    alert(primaryContactGUID);
}
2.  Get the Text value of a lookup field:
Note: this example reads and pops the name of the primary contact on the Account form
1
2
3
4
function AlertText() {
    var primaryContactName = Xrm.Page.data.entity.attributes.get("primarycontactid").getValue()[0].name;
    alert(primaryContactName);
}
3.  Get the value of a text field:
Note: this example reads and pops the value of the Main Phone (telephone1) field on the Account form
1
2
3
4
function AlertTextField() {
    var MainPhone = Xrm.Page.data.entity.attributes.get("telephone1").getValue();
    alert(MainPhone);
}
4.  Get the database value of an Option Set field:
Note: this example reads and pops the value of the Address Type (address1_addresstypecode) field on the Account form
1
2
3
4
5
6
function AlertOptionSetDatabaseValue() {
    var AddressTypeDBValue = Xrm.Page.data.entity.attributes.get("address1_addresstypecode").getValue();
    if (AddressTypeDBValue != null) {
        alert(AddressTypeDBValue);
    }
}
5.  Get the text value of an Option Set field:
Note: this example reads and pops the value of the Address Type (address1_addresstypecode) field on the Account form
1
2
3
4
5
6
function AlertOptionSetDisplayValue() {
   var AddressTypeDisplayValue = Xrm.Page.data.entity.attributes.get("address1_addresstypecode").getText();
    if (AddressTypeDisplayValue != null) {
        alert(AddressTypeDisplayValue);
    }
}
6.  Get the database value of a Bit field:
1
2
3
4
// example GetBitValue("telephone1");
function GetBitValue(fieldname) {
    return Xrm.Page.data.entity.attributes.get(fieldname).getValue();
}
7.  Get the value of a Date field:
returns a value like: Wed Nov 30 17:04:06 UTC+0800 2011
and reflects the users time zone set under personal options
1
2
3
4
// example GetDate("createdon");
function GetDate(fieldname) {
    return Xrm.Page.data.entity.attributes.get(fieldname).getValue();
}
8.  Get the day, month and year parts from a Date field:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// This function takes the fieldname of a date field as input and returns a DD-MM-YYYY value
// Note: the day, month and year variables are numbers
function FormatDate(fieldname) {
    var d = Xrm.Page.data.entity.attributes.get(fieldname).getValue();
    if (d != null) {
        var curr_date = d.getDate();
        var curr_month = d.getMonth();
        curr_month++;  // getMonth() considers Jan month 0, need to add 1
        var curr_year = d.getFullYear();
        return curr_date + "-" + curr_month + "-" + curr_year;
    }
    else return null;
}
 
// An example where the above function is called
alert(FormatDate("new_date2"));
9.  Set the value of a string field:
Note: this example sets the Account Name field on the Account Form to “ABC”
1
2
3
4
function SetStringField() {
    var Name = Xrm.Page.data.entity.attributes.get("name");
    Name.setValue("ABC");
}
10.  Set the value of an Option Set (pick list) field:
Note: this example sets the Address Type field on the Account Form to “Bill To”, which corresponds to a database value of “1”
1
2
3
4
function SetOptionSetField() {
    var AddressType = Xrm.Page.data.entity.attributes.get("address1_addresstypecode");
    AddressType.setValue(1);
}
11.  Set a Date field / Default a Date field to Today:
1
2
//set date field to now (works on date and date time fields)
Xrm.Page.data.entity.attributes.get("new_date1").setValue(new Date());
12.  Set a Date field to 7 days from now:
1
2
3
4
5
6
function SetDateField() {
    var today = new Date();
    var futureDate = new Date(today.setDate(today.getDate() + 7));
    Xrm.Page.data.entity.attributes.get("new_date2").setValue(futureDate);
    Xrm.Page.data.entity.attributes.get("new_date2").setSubmitMode("always"); // Save the Disabled Field
}
13.  Set the Time portion of a Date Field:
1
2
3
4
5
6
7
8
9
10
11
// This is a function you can call to set the time portion of a date field
function SetTime(attributeName, hour, minute) {
        var attribute = Xrm.Page.getAttribute(attributeName);
        if (attribute.getValue() == null) {
            attribute.setValue(new Date());
        }
        attribute.setValue(attribute.getValue().setHours(hour, minute, 0));
}
 
// Here's an example where I use the function to default the time to 8:30am
SetTime('new_date2', 8, 30);
14.  Set the value of a Lookup field:
Note: here I am providing a reusable function…
1
2
3
4
5
6
7
8
9
10
11
// Set the value of a lookup field
function SetLookupValue(fieldName, id, name, entityType) {
    if (fieldName != null) {
        var lookupValue = new Array();
        lookupValue[0] = new Object();
        lookupValue[0].id = id;
        lookupValue[0].name = name;
        lookupValue[0].entityType = entityType;
        Xrm.Page.getAttribute(fieldName).setValue(lookupValue);
    }
}
Here’s an example of how to call the function (I retrieve the details of one lookup field and then call the above function to populate another lookup field):
1
2
3
4
5
6
var ExistingCase = Xrm.Page.data.entity.attributes.get("new_existingcase");
if (ExistingCase.getValue() != null) {
    var ExistingCaseGUID = ExistingCase.getValue()[0].id;
    var ExistingCaseName = ExistingCase.getValue()[0].name;
    SetLookupValue("regardingobjectid", ExistingCaseGUID, ExistingCaseName, "incident");
}
15.  Split a Full Name into First Name and Last Name fields:
1
2
3
4
5
6
7
8
function PopulateNameFields() {
    var ContactName = Xrm.Page.data.entity.attributes.get("customerid").getValue()[0].name;
    var mySplitResult = ContactName.split(" ");
    var fName = mySplitResult[0];
    var lName = mySplitResult[1];
    Xrm.Page.data.entity.attributes.get("firstname").setValue(fName);
    Xrm.Page.data.entity.attributes.get("lastname").setValue(lName);
}
16.  Set the Requirement Level of a Field:
Note: this example sets the requirement level of the Address Type field on the Account form to Required. 
Note: setRequiredLevel(“none”) would make the field optional again.
1
2
3
4
function SetRequirementLevel() {
    var AddressType = Xrm.Page.data.entity.attributes.get("address1_addresstypecode");
    AddressType.setRequiredLevel("required");
}
17.  Disable a field:
1
2
3
4
function SetEnabledState() {
    var AddressType = Xrm.Page.ui.controls.get("address1_addresstypecode");
    AddressType.setDisabled(true);
}
18.  Force Submit the Save of a Disabled Field:
1
2
// Save the Disabled Field
Xrm.Page.data.entity.attributes.get("new_date1").setSubmitMode("always");
19.  Show/Hide a field:
1
2
3
4
function hideName() {
    var name = Xrm.Page.ui.controls.get("name");
    name.setVisible(false);
}
20.  Show/Hide a field based on a Bit field
1
2
3
4
5
6
7
8
9
function DisableExistingCustomerLookup() {
   var ExistingCustomerBit = Xrm.Page.data.entity.attributes.get("new_existingcustomer").getValue();
    if (ExistingCustomerBit == false) {
       Xrm.Page.ui.controls.get("customerid").setVisible(false);
    }
    else {
       Xrm.Page.ui.controls.get("customerid").setVisible(true);
    }
}
21.  Show/Hide a nav item:
Note: you need to refer to the nav id of the link, use F12 developer tools in IE to determine this
1
2
3
4
function hideContacts() {
    var objNavItem = Xrm.Page.ui.navigation.items.get("navContacts");
    objNavItem.setVisible(false);
}
22.  Show/Hide a Section:
Note: Here I provide a function you can use.  Below the function is a sample.
1
2
3
4
5
6
7
8
function HideShowSection(tabName, sectionName, visible) {
    try {
        Xrm.Page.ui.tabs.get(tabName).sections.get(sectionName).setVisible(visible);
    }
    catch (err) { }
}
 
HideShowSection("general", "address", false);   // "false" = invisible
23.  Show/Hide a Tab:
Note: Here I provide a function you can use. Below the function is a sample.
1
2
3
4
5
6
7
8
function HideShowTab(tabName, visible) {
    try {
        Xrm.Page.ui.tabs.get(tabName).setVisible(visible);
    }
    catch (err) { }
}
 
HideShowTab("general", false);   // "false" = invisible
24.  Save the form:
1
2
3
function SaveAndClose() {
    Xrm.Page.data.entity.save();
}
25.  Save and close the form:
1
2
3
function SaveAndClose() {
    Xrm.Page.data.entity.save("saveandclose");
}
26.  Close the form:
Note: the user will be prompted for confirmation if unsaved changes exist
1
2
3
function Close() {
    Xrm.Page.ui.close();
}
27.  Determine which fields on the form are dirty:
1
2
3
4
5
6
7
8
9
var attributes = Xrm.Page.data.entity.attributes.get()
 for (var i in attributes)
 {
    var attribute = attributes[i];
    if (attribute.getIsDirty())
    {
      alert("attribute dirty: " + attribute.getName());
    }
 }
28.  Determine the Form Type:
Note: Form type codes: Create (1), Update (2), Read Only (3), Disabled (4), Bulk Edit (6)
1
2
3
4
5
6
function AlertFormType() {
    var FormType = Xrm.Page.ui.getFormType();
     if (FormType != null) {
        alert(FormType);
    }
}
29.  Get the GUID of the current record:
1
2
3
4
5
6
function AlertGUID() {
    var GUIDvalue = Xrm.Page.data.entity.getId();
    if (GUIDvalue != null) {
        alert(GUIDvalue);
    }
}
30.  Get the GUID of the current user:
1
2
3
4
5
6
function AlertGUIDofCurrentUser() {
    var UserGUID = Xrm.Page.context.getUserId();
     if (UserGUID != null) {
        alert(UserGUID);
    }
}
31.  Get the Security Roles of the current user:
(returns an array of GUIDs, note: my example reveals the first value in the array only)
1
2
3
function AlertRoles() {
    alert(Xrm.Page.context.getUserRoles());
}
32.  Determine the CRM server URL:
1
2
3
4
5
6
7
// Get the CRM URL
var serverUrl = Xrm.Page.context.getServerUrl();
 
// Cater for URL differences between on premise and online
if (serverUrl.match(/\/$/)) {
    serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}
33.  Refresh a Sub-Grid:
1
2
var targetgird = Xrm.Page.ui.controls.get("target_grid");
targetgird.refresh();
34.  Change the default entity in the lookup window of a Customer or Regarding field:
Note: I am setting the customerid field’s lookup window to offer Contacts (entityid 2) by default (rather than Accounts). I have also hardcoded the GUID of the default view I wish displayed in the lookup window.
1
2
3
4
5
function ChangeLookup() {
    document.getElementById("customerid").setAttribute("defaulttype", "2");
    var ViewGUID= "A2D479C5-53E3-4C69-ADDD-802327E67A0D";
    Xrm.Page.getControl("customerid").setDefaultView(ViewGUID);
}
35.  Pop an existing CRM record (new approach):
1
2
3
4
5
6
7
8
function PopContact() {
    //get PrimaryContact GUID
    var primaryContactGUID = Xrm.Page.data.entity.attributes.get("primarycontactid").getValue()[0].id;
    if (primaryContactGUID != null) {
        //open Contact form
        Xrm.Utility.openEntityForm("contact", primaryContactGUID)
    }
}
36.  Pop an existing CRM record (old approach):
Note: this example pops an existing Case record.  The GUID of the record has already been established and is stored in the variable IncidentId.
01
02
03
04
05
06
07
08
09
10
11
12
//Set features for how the window will appear
var features = "location=no,menubar=no,status=no,toolbar=no";
 
// Get the CRM URL
var serverUrl = Xrm.Page.context.getServerUrl();
 
// Cater for URL differences between on premise and online
if (serverUrl.match(/\/$/)) {
    serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}
 
window.open(serverUrl + "/main.aspx?etn=incident&pagetype=entityrecord&id=" + encodeURIComponent(IncidentId), "_blank", features, false);
37.  Pop a blank CRM form (new approach):
1
2
3
function PopNewCase() {
    Xrm.Utility.openEntityForm("incident")
}
38.  Pop a new CRM record with default values (new approach):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function CreateIncident() {
    //get Account GUID and Name
    var AccountGUID = Xrm.Page.data.entity.getId();
    var AccountName = Xrm.Page.data.entity.attributes.get("name").getValue();
    //define default values for new Incident record
    var parameters = {};
    parameters["title"] = "New customer support request";
    parameters["casetypecode"] = "3";
    parameters["customerid"] = AccountGUID;
    parameters["customeridname"] = AccountName;
    parameters["customeridtype"] = "account";
    //pop incident form with default values
    Xrm.Utility.openEntityForm("incident", null, parameters);
}
39.  Pop a new CRM record with default values (old approach):
Note: this example pops the Case form from the Phone Call form, defaulting the Case’s CustomerID based on the Phone Call’s SenderID and defaulting the Case Title to “New Case”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//Collect values from the existing CRM form that you want to default onto the new record
var CallerGUID = Xrm.Page.data.entity.attributes.get("from").getValue()[0].id;
var CallerName = Xrm.Page.data.entity.attributes.get("from").getValue()[0].name;
 
//Set the parameter values
var extraqs = "&title=New Case";
extraqs += "&customerid=" + CallerGUID;
extraqs += "&customeridname=" + CallerName;
extraqs += "&customeridtype=contact";
 
//Set features for how the window will appear
var features = "location=no,menubar=no,status=no,toolbar=no";
 
// Get the CRM URL
var serverUrl = Xrm.Page.context.getServerUrl();
 
// Cater for URL differences between on premise and online
if (serverUrl.match(/\/$/)) {
    serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}
 
//Pop the window
window.open(serverUrl + "/main.aspx?etn=incident&pagetype=entityrecord&extraqs=" + encodeURIComponent(extraqs), "_blank", features, false);
40.  Pop a Dialog from a ribbon button
Note: this example has the Dialog GUID and CRM Server URL hardcoded, which you should avoid.  A simple function is included which centres the Dialog when launched.
01
02
03
04
05
06
07
08
09
10
11
12
13
function LaunchDialog(sLeadID) {
    var DialogGUID = "128CEEDC-2763-4FA9-AB89-35BBB7D5517D";
    serverUrl = serverUrl + "cs/dialog/rundialog.aspx?DialogId=" + "{" + DialogGUID + "}" + "&EntityName=lead&ObjectId=" + sLeadID;
    PopupCenter(serverUrl, "mywindow", 400, 400);
    window.location.reload(true);
}
 
function PopupCenter(pageURL, title, w, h) {
    var left = (screen.width / 2) - (w / 2);
    var top = (screen.height / 2) - (h / 2);
    var targetWin = window.showModalDialog(pageURL, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);
}
41.  Pop a URL from a ribbon button
Great info on the window parameters you can set here:  http://javascript-array.com/scripts/window_open/
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function LaunchSite() {
    // read URL from CRM field
    var SiteURL = Xrm.Page.data.entity.attributes.get("new_sharepointurl").getValue();
    // execute function to launch the URL
    LaunchFullScreen(SiteURL);
}
 
function LaunchFullScreen(url) {
 // set the window parameters
 params  = 'width='+screen.width;
 params += ', height='+screen.height;
 params += ', top=0, left=0';
 params += ', fullscreen=yes';
 params += ', resizable=yes';
 params += ', scrollbars=yes';
 params += ', location=yes';
 
 newwin=window.open(url,'windowname4', params);
 if (window.focus) {
     newwin.focus()
 }
 return false;
}
42.  Pop the lookup window associated to a Lookup field:
1
window.document.getElementById('new_existingcase').click();
43.  Pop a Web Resource (new approach):
1
2
3
function PopWebResource() {
    Xrm.Utility.openWebResource("new_Hello");
}
44. Using a SWITCH statement
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function GetFormType() {
    var FormType = Xrm.Page.ui.getFormType();
    if (FormType != null) {
        switch (FormType) {
            case 1:
                return "create";
                break;
            case 2:
                return "update";
                break;
            case 3:
                return "readonly";
                break;
            case 4:
                return "disabled";
                break;
            case 6:
                return "bulkedit";
                break;
            default:
                return null;
        }
    }
}
45.  Pop an Ok/Cancel Dialog
1
2
3
4
5
6
7
8
9
10
11
12
13
function SetApproval() {
    if (confirm("Are you sure?")) {
        // Actions to perform when 'Ok' is selected:
        var Approval = Xrm.Page.data.entity.attributes.get("new_phaseapproval");
        Approval.setValue(1);
        alert("Approval has been granted - click Ok to update CRM");
        Xrm.Page.data.entity.save();
    }
    else {
        // Actions to perform when 'Cancel' is selected:
        alert("Action cancelled");
    }
}
46.  Retrieve a GUID via REST (default the Price List field)
In this example (intended for the Opportunity form’s Onload event) I execute a REST query to retrieve the GUID of the Price List named “Wholesale Price List”.  I then execute the DefaultPriceList function to default the Price List field.  As this uses REST your CRM form will need json2 and jquery libraries registered on the CRM form (I have these libraries in a solution file I import when needed):
image
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
function RetrieveGUID() {
    // Get CRM Context
    var context = Xrm.Page.context;
    var serverUrl = context.getServerUrl();
    // Cater for URL differences between on-premise and online
    if (serverUrl.match(/\/$/)) {
        serverUrl = serverUrl.substring(0, serverUrl.length - 1);
    }
    // Define ODATA query
    var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";
    var ODATA_EntityCollection = "/PriceLevelSet";
    var PriceListName = 'Wholesale Price List';
    var QUERY = "?$select=PriceLevelId&$filter=Name%20eq%20'" + PriceListName + "'&$top=1";
    var URL = serverUrl + ODATA_ENDPOINT + ODATA_EntityCollection + QUERY;
    //Asynchronous AJAX call
    $.ajax({
        type: "GET",
        contentType: "application/json; charset=utf-8",
        datatype: "json",
        url: URL,
        beforeSend: function (XMLHttpRequest) {
            //Specifying this header ensures that the results will be returned as JSON.
            XMLHttpRequest.setRequestHeader("Accept", "application/json");
        },
        success: function (data, textStatus, XmlHttpRequest) {
            //This function will trigger asynchronously if the Retrieve was successful
            var GUID_Retrieved = data.d.results[0].PriceLevelId;
            DefaultPriceList(GUID_Retrieved, PriceListName);
        },
        error: function (XmlHttpRequest, textStatus, errorThrown) {
            //This function will trigger asynchronously if the Retrieve returned an error
            alert("ajax call failed");
        }
    });
}
 
function DefaultPriceList(GUID, NAME){
        var lookupValue = new Array();
        lookupValue[0] = new Object();
        lookupValue[0].id = GUID;
        lookupValue[0].name = NAME;
        lookupValue[0].entityType = "pricelevel";
        Xrm.Page.getAttribute("pricelevelid").setValue(lookupValue);
}

Here is a little more info that will help you get your head around the general design of all this…
Depending upon what you want to do you will interact with one of the following:
Xrm.Page.data.entity.attributes – The data fields represented by fields on the form
Xrm.Page.ui.controls – The user interface controls on the form
Xrm.Page.ui.navigation.items – The navigation items on the form
Xrm.Utility – A container of helpful functions
When referring to fields or controls you must specify the name of the field and surround with quotes (and make sure you get the case right):
image
When referring to nav items you must specify the nav ID and surround it with quotes.  To determine the nav ID:
– open the CRM form in IE
– hit F12 to activate IE’s developer tools (if it doesn’t appear, check for it under Task Manager and maximise it from there)
– in the developer tools window click the arrow to activate the “Select element by click” mode
– on the CRM form click the nav item (the dev tools window will take you to HTML definition of that element)
image
– just above there you will see the nav ID specified, look for id=”nav<something>”
image
When setting properties to true/false do not surround the true/false value with quotes.
Typically there are 2 steps to interacting with fields.  First you get the field as an object.  Then you interact with that object to get or set the property value you are interested in.


Hide/Show Field

1
2
3
4
5
6
function HideShowField(fieldName, show) {
    var field = Xrm.Page.ui.controls.get(fieldName);
 
    if (field != null)
        field.setVisible(show);
}


Hide/Show Field but removing white space
1
2
3
4
5
6
7
function HideShowFieldRemoveSpace(fieldname, show) {
    var displayStyle = show ? 'block' : 'none';
    if (document.getElementById(fieldname + '_c') != null && document.getElementById(fieldname + '_d') != null) {
        document.getElementById(fieldname + '_c').style.display = displayStyle;
        document.getElementById(fieldname + '_d').style.display = displayStyle;
    }
}


Disable/Not Disable Field

1
2
3
4
5
6
function SetDisableField(fieldName, disabled) {
    var field = Xrm.Page.getControl(fieldName);
 
    if (field != null)
        field.setDisabled(disabled);
}


Set Requirement Level

1
2
3
4
5
6
function SetRequirementLevel(fieldName, reqLevel) {
    var field = Xrm.Page.getAttribute(fieldName);
 
    if (field != null)
        field.setRequiredLevel(reqLevel);
}


Set Required Level

1
2
3
4
5
6
function SetRequirementLevel(fieldName, reqLevel) {
    var field = Xrm.Page.getAttribute(fieldName);
 
    if (field != null)
        field.setRequiredLevel(reqLevel);
}


Validate Number Field and Character Limit

1
2
3
4
5
6
7
8
9
10
function validateNumberField(context, limit) {
    var value = context.getEventSource().getValue();
    var fieldName = context.getEventSource().getName();
    var labelName = Xrm.Page.ui.controls.get(fieldName).getLabel();
    var valueRegex = new RegExp("^\\d{" + limit + "}$");
    if (!value.match(valueRegex)) {
        event.returnValue = false;
        alert("The format of the " + labelName + " is incorrect");
    }
}


Validate Future DateTime

1
2
3
4
5
6
7
8
9
function ValidateFutureDate(fieldname) {
    var today = new Date();
    var dueDate = Xrm.Page.getAttribute(fieldname).getValue();
 
    if (dueDate != null && dueDate < today) {
        alert("Date value needs to be in the future");
        Xrm.Page.getAttribute(fieldname).setValue(today);
    }
}


Example function to hide left navigation item based on a condition

1
2
3
4
5
6
7
8
9
10
11
12
function ShowBankDetails() {
    var payeeRole = "new_rolepayee";
    var payeeChkBox = Xrm.Page.ui.controls.get(payeeRole);
    var payeeChkBoxValue = payeeChkBox.getAttribute().getValue();
 
    if (payeeChkBoxValue == true) {
        Xrm.Page.ui.navigation.items.get("nav_new_account_new_bankdetail").setVisible(true);
    }
    else {
        Xrm.Page.ui.navigation.items.get("nav_new_account_new_bankdetail").setVisible(false);
    }
}


Avoiding the checkbox OnChange bug so that it fires off immediately (put this in OnLoad event of the form)

1
2
3
function TriggerCheckBoxClick() {
    crmForm.all.new_checkbox.onclick = function () { crmForm.all.new_checkbox.FireOnChange(); };
    }


Set Lookup Value

1
2
3
4
5
6
7
8
9
10
11
function SetLookupValue(fieldName, id, name, entityType) {
    if (fieldName != null) {
        var lookupValue = new Array();
        lookupValue[0] = new Object();
        lookupValue[0].id = id;
        lookupValue[0].name = name;
        lookupValue[0].entityType = entityType;
 
        Xrm.Page.getAttribute(fieldName).setValue(lookupValue);
    }
}
Hide Picklist Item Text

1
2
3
4
5
6
7
8
9
10
11
function HidePicklistItemWithText(fieldName, withText) {
    var picklist = document.getElementById(fieldName);
 
    for (var i = picklist.options.length - 1; i >= 0; i--) {
        var picklistItemText = picklist.options[i].text;
 
        if (picklistItemText.match(withText) == withText && picklist.selectedIndex != i) {
            picklist.options.remove(i);
        }
    }
}


Tuesday, 10 February 2015

Entity Relationship Diagrams in Microsoft Dynamics CRM

You can also create ERDs for custom entities. The generator is buried deep inside of the SDK (…\sdk\samplecode\cs\metadata\diagram ). You will need Visual Studio and Visio 2010 to run the document generator.
1. First, open the above file path and open the file MetadataDiagram.csproj in Visual Studio.
2. Next, from the toolbar, click the Build Solution icon.meta1
3. You could run the program now. However, it will map all of the entities, their attributes and their relationship to each other. This will take a very long time, but more importantly, it's complexity may render it useless to most people. What I have found useful it to map one entity at a time, or at the most two or three.
4. In order to draw one or more specific entities, click the debug tab, then enter the logical name in the Command line argument box. You can enter as many entities as you would like to map here. For instance, if you would like to map accounts, then simply enter "account". If you would like to map an custom entity then enter "new_entityname". If you would like to map the relationships between you custom entity and accounts, then enter "account new_entityname". Remember, that will map your new entity, accounts, and the relationships between them. If you want a map for accounts and another map for your custom entity, you will need to run the program twice.
5. To run the program, hit the Start Debugging button in the toolbar.
6. This will bring up a command prompt. It will ask for a CRM server and a port. It is very simply orgname.domainname.net (no https:, etc.) Then you enter your username and password just as you would if you were logging into CRM as a user.CP1
7. The program will run (usually a few minutes) and create a Visio document in the path: (..sdk\samplecode\cs\metadata\diagram\bin\Debug ). The name of the file will be simply "account.vsd". It is important to note that if you use the program to create another account diagram, and there is already a file called "account.vsd" in the Debug file, the command prompt will issue an error and the document will not be created. It is a good best practice to move your finished files from the Debug folder as you finish them.


A sample of the output is below. This is for the entity 'sharepointsite' in ootb CRM.
sp1

Wednesday, 29 October 2014

Export / Import Lab Virtual Machines

  1. De-provision the lab. Use the Stop-AzureVM and Export-AzureVM cmdlets in the PowerShell snippet below to shutdown and export lab VMs when they are not being used.  
     
    # Specify the Name of the VM to Export
     
    $myVM = "XXXlabad01" 
     
    # Stop the VM prior to exporting it
     
    Stop-AzureVM -ServiceName $myVM -Name $myVM 
     
    # Set the Export folder path for the VM configuration file.  Make sure this folder exists!

     
    $ExportPath = "C:\ExportVMs\ExportAzureVM-$myVM.xml" 
     
    # Export the VM to a file
     
    Export-AzureVM -ServiceName $myVM -name $myVM -Path $ExportPath  
     
    # After you've confirmed that the Export file exists, delete the VM
     
    Remove-AzureVM -ServiceName $myVM -name $myVM

     
  2. Re-provision the lab. Use the Import-AzureVM and Start-AzureVM cmdlets in the PowerShell snippet below to import and start lab VMs when needed again.
     
    # Specify the Name of the VM to Import

    $myVM = “XXXlabad01" 

    # Specify the Name of the Virtual Network on which to Import the VM

    $myVNet = "XXXlabnet01"

    # Specify the Import Path of the VM’s exported configuration file.
     
    $ImportPath = "C:\ExportVMs\ExportAzureVM-$myVM.xml"

    # Specify the Windows Azure Storage Account to be used.

    $myStorageAccount = "XXXlabstor01"

    Get-AzureSubscription | Set-AzureSubscription -CurrentStorageAccount $myStorageAccount 
     
    # Import the VM to Windows Azure
     
    Import-AzureVM -Path $ImportPath | New-AzureVM -ServiceName $myVM -VNetName $myVNet 
     
    # Start the VM  
    Start-AzureVM -ServiceName $myVM -name $myVM

Tuesday, 21 October 2014

Build SharePoint 2013 in the Cloud with Windows Azure

 

Prerequisites


  1. Login to the Windows Azure Management Portal.
     
    Login to the web-based Windows Azure Management Portal with the same logon credentials you used to sign-up for the FREE 90-day Trial above.  Once you’ve logged in, you should see the main Windows Azure Management portal dashboard.
     
    Portal01
    Windows Azure Management Portal dashboard
     
    On the Windows Azure Management Portal, you’ll find the options ( highlighted in the image above ) for managing Virtual Machines, Virtual Networks and Storage in the cloud.  These are the items we’ll be primarily working with in this article series.
     
  2. Define a new Windows Azure Affinity Group.
     
    Affinity Groups in Windows Azure are used to group your cloud-based services together, such as Virtual Machines, Virtual Networks and Storage, in order to achieve optimal performance.  When you use an affinity group, Windows Azure will keep all services that belong to your affinity group running within the same data center as close as possible to each other to reduce latency and increase performance.

    - Create a new Affinity Group by selecting Settings from the side navigation bar in the Windows Azure Management Portal. 
     
    - On the Settings page, select the Affinity Groups tab on the top navigation bar. 
     
    - Click the +ADD button on the bottom navigation bar.
     
  3. On the Create Affinity Group form, enter the following details:
     
    - Name: Enter a unique name for your new Affinity Group, such as XXXlab01 (where XXX is replaced with your initials)
     
    - Region: Select the closest Windows Azure data center region to your locale.  This is the data center region in which your services will be provisioned.
     
  4. Create a new Windows Azure Storage Account.
     
    Virtual Machines that are provisioned in Windows Azure are stored in the world-wide cloud-based Windows Azure Storage service.  In terms of high availability, the Storage service provides built-in storage replication capability – where every VM is replicated to three separate locations within the Windows Azure data center region you select.  In addition, Windows Azure Storage provides a geo-replication feature for also replicating your VMs to a remote data center region.
     
    Create a new Storage account by clicking the +NEW button on the bottom toolbar in the Windows Azure Management Portal and then select Data Services | Storage | Quick Create.  
     
    Portal03
    Creating a new Storage account in Windows Azure
     
    Complete the following fields for creating your Storage account:

    - URL: Enter a unique name for your new storage account, such as XXXlabstor01 (where XXX is replaced with your initials)
     
    - Region/Affinity Group: Select the Affinity Group you created in Step 3 above.
     
    - Enable Geo-Replication: By default, this option is selected.  Leave the default option in place.
     
    Click the CREATE STORAGE ACCOUNT button to create your new Windows Azure Storage account.
     
  5. Download, Install and Configure the Windows Azure PowerShell Management Tools
     
    In addition to managing Windows Azure via the web-based Management Portal, we also provide a Windows Azure PowerShell module for scripted management of Windows Azure services.  We’ll be using both the Management Portal and PowerShell in this series, so you’ll want to download, install and configure the Windows Azure PowerShell cmdlets to get prepared.
     
    - Download and Install the Windows Azure PowerShell cmdlets. Note that a restart may be required after installing this module.

    - Right-click on Windows PowerShell in your Start Menu or Start Screen and choose Run As Administrator.

    - Set the PowerShell Execution Policy for scripts by running the following command at the PowerShell command prompt:

         PS C:\> Set-ExecutionPolicy RemoteSigned

    Import the Windows Azure PowerShell module and supporting cmdlets by running the following command at the PowerShell command prompt:

         PS C:\> Import-Module Azure

    - Download and save your Windows Azure Publish Settings file by running the following command at the PowerShell command prompt:

         PS C:\> Get-AzurePublishSettingsFile

    - Import the saved Windows Azure Publish Settings file by running the following command at the PowerShell command prompt:

         PS C:\> Import-AzurePublishSettingsFile
                "full_path_to_saved_file.publishsettings"

Exercise 1: Register a DNS Server in Windows Azure

 Register the internal IP address that our domain controller VM will be using for Active Directory-integrated Dynamic DNS services by performing the following steps:
  1. Sign in at the Windows Azure Management Portal with the logon credentials used when you signed up for your Free Windows Azure Trial.
     
  2. Select Networks located on the side navigation panel on the Windows Azure Management Portal page.
     
  3. Click the +NEW button located on the bottom navigation bar and select Networks | Virtual Network | Register DNS Server.
     
  4. Complete the DNS Server fields as follows:
     
    - NAME: XXXlabdns01
    - DNS Server IP Address: 10.0.0.4
     
  5. Click the REGISTER DNS SERVER button.

Exercise 2: Define a Virtual Network in Windows Azure

Define a common virtual network in Windows Azure for running Active Directory, Database and SharePoint virtual machines by performing the following steps:
  1. Sign in at the Windows Azure Management Portal with the logon credentials used when you signed up for your Free Windows Azure Trial.
     
  2. Select Networks located on the side navigation panel on the Windows Azure Management Portal page.
     
  3. Click the +NEW button located on the bottom navigation bar and select Networks | Virtual Network | Quick Create.
     
  4. Complete the Virtual Network fields as follows:
     
    - NAME: XXXlabnet01
    - Address Space: 10.---.---.---
    - Maximum VM Count: 4096 [CIDR: /20]
    - Affinity Group: Select the Affinity Group defined in the Getting Started steps from the Prerequisites section above.
    - Connect to Existing DNS: Select XXXlabdns01 – the DNS Server registered in Exercise 1 above.
     
  5. Click the CREATE A VIRTUAL NETWORK button.

Exercise 3: Configure Windows Server Active Directory in a Windows Azure VM


Provision a new Windows Azure VM to run a Windows Server Active Directory domain controller in a new Active Directory forest by performing the following steps:
  1. Sign in at the Windows Azure Management Portal with the logon credentials used when you signed up for your Free Windows Azure Trial.
     
  2. Select Virtual Machines located on the side navigation panel on the Windows Azure Management Portal page.
     
  3. Click the +NEW button located on the bottom navigation bar and select Compute | Virtual Machines | From Gallery.
     
  4. In the Virtual Machine Operating System Selection list, select Windows Server 2012 Datacenter and click the Next button.
     
  5. On the Virtual Machine Configuration page, complete the fields as follows:
     
    - Version Release Date: Select the latest version release date to build a new VM with the latest OS updates applied.
    - Virtual Machine Name: XXXlabad01
    - New User Name: Choose a secure local Administrator user account to provision.
    - New Password and Confirm Password fields: Choose and confirm a new local Administrator password.
    - Size: Small (1 core, 1.75GB Memory)
     
    Click the Next button to continue.
     
    Note: It is suggested to use secure passwords for Administrator users and service accounts, as Windows Azure virtual machines could be accessible from the Internet knowing just their DNS.  You can also read this document on the Microsoft Security website that will help you select a secure password: http://www.microsoft.com/security/online-privacy/passwords-create.aspx.
     
  6. On the Virtual Machine Mode page, complete the fields as follows:
     
    - Standalone Virtual Machine: Selected
    - DNS Name: XXXlabad01.cloudapp.net
    - Storage Account: Select the Storage Account defined in the Getting Started steps from the Prerequisites section above.
    - Region/Affinity Group/Virtual Network: Select XXXlabnet01 – the Virtual Network defined in Exercise 2 above.
    - Virtual Network Subnets: Select Subnet-1 (10.0.0.0/23)
     
    Click the Next button to continue.
     
  7. On the Virtual Machine Options page, click the Checkmark button to begin provisioning the new virtual machine.
     
    As the new virtual machine is being provisioned, you will see the Status column on the Virtual Machines page of the Windows Azure Management Portal cycle through several values including Stopped, Stopped (Provisioning), and Running (Provisioning).  When provisioning for this new Virtual Machine is completed, the Status column will display a value of Running and you may continue with the next step in this guide.
     
  8. After the new virtual machine has finished provisioning, click on the name ( XXXlabad01 ) of the new Virtual Machine displayed on the Virtual Machines page of the Windows Azure Management Portal.
     
  9. On the virtual machine Dashboard page for XXXlabad01, make note of the Internal IP Address displayed on this page located on the right-side of the page.  This IP address should be listed as 10.0.0.4
     
    If a different internal IP address is displayed, the virtual network and/or virtual machine configuration was not completed correctly.  In this case, click the DELETE button located on the bottom toolbar of the virtual machine details page for XXXlabad01, and go back to Exercise 2 and Exercise 3 to confirm that all steps were completed correctly.
     
  10. On the virtual machine Dashboard page for XXXlabad01, click the Attach button located on the bottom navigation toolbar and select Attach Empty Disk.  Complete the following fields on the Attach an empty disk to the virtual machine form:
     
    - Name: XXXlabad01-data01
    - Size: 10 GB
    - Host Cache Preference: None
     
    Click the Checkmark button to create and attach the a new virtual hard disk to virtual machine XXXlabad01.
     
  11. On the virtual machine Dashboard page for XXXlabad01, click the Connect button located on the bottom navigation toolbar and click the Open button to launch a Remote Desktop Connection to the console of this virtual machine.  Logon at the console of your virtual machine with the local Administrator credentials defined in Step 5 above.
     
  12. From the Remote Desktop console of XXXlabad01, create a new partition on the additional data disk attached above in Step 10 and format this partition as a new F: NTFS volume.  This volume will be used for NTDS DIT database, log and SYSVOL folder locations.
     
    If you need additional guidance to complete this step, feel free to leverage the following study guide for assistance: Windows Server 2012 “Early Experts” Challenge – Configure Local Storage
     
  13. Using the Server Manager tool, install Active Directory Domain Services and promote this server to a domain controller in a new forest with the following parameters:
     
    - Active Directory Forest name: contoso.com
    - Volume Location for NTDS database, log and SYSVOL folders: F:
     
    If you need additional guidance to complete this step, feel free to leverage the following study guide for assistance: Windows Server 2012 “Early Experts” Challenge – Install and Administer Active Directory
     
  14. After Active Directory has been installed, create the following user accounts that will be used when installing and configuring SharePoint Server 2013 later in this step-by-step guide:

    - CONTOSO\sp_farm – SharePoint Farm Data Access Account
    - CONTOSO\sp_serviceapps – SharePoint Farm Service Applications Account
     
    If you need additional guidance to complete this step, feel free to leverage the following study guide for assistance: Windows Server 2012 “Early Experts” Challenge – Install and Administer Active Directory
The configuration for this virtual machine is now complete, and you may continue with the next exercise in this step-by-step guide.

Exercise 4: Configure SQL Server 2012 in a Windows Azure VM


Provision a new Windows Azure VM to run SQL Server 2012 by performing the following steps:
  1. Sign in at the Windows Azure Management Portal with the logon credentials used when you signed up for your Free Windows Azure Trial.
     
  2. Select Virtual Machines located on the side navigation panel on the Windows Azure Management Portal page.
     
  3. Click the +NEW button located on the bottom navigation bar and select Compute | Virtual Machines | From Gallery.
     
  4. In the Virtual Machine Operating System Selection list, select SQL Server 2012 SP1 Enterprise and click the Next button.
     
  5. On the Virtual Machine Configuration page, complete the fields as follows:

    - Virtual Machine Name: XXXlabdb01
    - New User Name: Choose a secure local Administrator user account to provision.
    - New Password and Confirm Password fields: Choose and confirm a new local Administrator password.
    - Size: Medium (2 cores, 3.5GB Memory)
     
    Click the Next button to continue.
     
  6. On the Virtual Machine Mode page, complete the fields as follows:
     
    - Standalone Virtual Machine: Selected
    - DNS Name: XXXlabdb01.cloudapp.net
    - Storage Account: Select the Storage Account defined in the Getting Started steps from the Prerequisites section above.
    - Region/Affinity Group/Virtual Network: Select XXXlabnet01 – the Virtual Network defined in Exercise 2 above.
    - Virtual Network Subnets: Select Subnet-1 (10.0.0.0/23)
     
    Click the Next button to continue.
     
  7. On the Virtual Machine Options page, click the Checkmark button to begin provisioning the new virtual machine.
     
    As the new virtual machine is being provisioned, you will see the Status column on the Virtual Machines page of the Windows Azure Management Portal cycle through several values including Stopped, Stopped (Provisioning), and Running (Provisioning).  When provisioning for this new Virtual Machine is completed, the Status column will display a value of Running and you may continue with the next step in this guide.
     
  8. After the new virtual machine has finished provisioning, click on the name ( XXXlabdb01 ) of the new Virtual Machine displayed on the Virtual Machines page of the Windows Azure Management Portal.
     
  9. On the virtual machine Dashboard page for XXXlabdb01, make note of the Internal IP Address displayed on this page.  This IP address should be listed as 10.0.0.5
     
    If a different internal IP address is displayed, the virtual network and/or virtual machine configuration was not completed correctly.  In this case, click the DELETE button located on the bottom toolbar of the virtual machine details page for XXXlabdb01, and go back to Exercise 2 and Exercise 3 to confirm that all steps were completed correctly.
     
  10. On the virtual machine Dashboard page for XXXlabdb01, click the Attach button located on the bottom navigation toolbar and select Attach Empty Disk.  Complete the following fields on the Attach an empty disk to the virtual machine form:
     
    - Name: XXXlabdb01-data01
    - Size: 50 GB
    - Host Cache Preference: None
     
    Click the Checkmark button to create and attach the a new virtual hard disk to virtual machine XXXlabdb01.
     
  11. On the virtual machine Dashboard page for XXXlabdb01, click the Connect button located on the bottom navigation toolbar and click the Open button to launch a Remote Desktop Connection to the console of this virtual machine.  Logon at the console of your virtual machine with the local Administrator credentials defined in Step 5 above.
     
  12. From the Remote Desktop console of XXXlabdb01, create a new partition on the additional data disk attached above in Step 10 and format this partition as a new F: NTFS volume. After formatting this new volume, create the following folders:
     
    1. Create F:\MSSQL folder
       
    2. Create F:\MSSQL\DATA folder
       
    3. Create F:\MSSQL\LOGS folder
       
    4. Create F:\MSSQL\BACKUP folder
  13. Open SQL Server Management Studio from Start | All Programs | Microsoft SQL Server 2012 | SQL Server Management Studio and update default folder locations to the F: volume.
    1. Connect to the SQL Server 2012 default instance using your Windows Account.
       
    2. Now, you will update the database's default locations for DATA, LOGS and BACKUP folders. To do this, right click on your SQL Server instance and select Properties.
       
    3. Select Database Settings from the left side pane.
       
    4. Locate the Database default locations section and update the default values for each path to point to the new folder paths defined above in Step 12.
       
    5. Close SQL Server Management Studio.
  14. In order to allow SharePoint to connect to the SQL Server, you will need to add an Inbound Rule for the SQL Server requests in the Windows Firewall. To do this, open Windows Firewall with Advanced Security from Start | All Programs | Administrative Tools.
    1. Select Inbound Rules node, right-click it and select New Rule to open the New Inbound Rule Wizard.
    2. In the Rule Type page, select Port and click Next.
    3. In Protocols and Ports page, leave TCP selected, select Specific local ports, and set its value to 1433. Click Next to continue.
    4. In the Action page, make sure that Allow the connection is selected and click Next.
    5. In the Profile page, leave the default values and click Next.
    6. In the Name page, set the Inbound Rule's Name to SQLServerRule and click Finish
    7. Close Windows Firewall with Advanced Security window.
  15. Using the Server Manager tool, join this server to the contoso.com domain and restart the server to complete the domain join operation.
  16. After the server restarts, connect again via Remote Desktop to the server’s console and login with the local Administrator credentials defined above in Step 5.
  17. Open SQL Server Management Studio from Start | All Programs | Microsoft SQL Server 2012 | SQL Server Management Studio and add the CONTOSO\Administrator user to SQL Server with the Sysadmin server role selected.
    1. Expand Security folder within the SQL Server instance. Right-click Logins folder and select New Login.
    2. In the General section, set the Login name to CONTOSO\Administrator, and select the Windows Authentication option.
    3. Click Server Roles on the left pane.  Select the checkbox for the Sysadmin server role.
    4. Click the OK button and close SQL Server Management Studio.
The configuration for this virtual machine is now complete, and you may continue with the next exercise in this step-by-step guide.


Exercise 5: Configure SharePoint Server 2013 in a Windows Azure VM


Provision a new Windows Azure VM to run SharePoint Server 2013 by performing the following steps:
  1. Sign in at the Windows Azure Management Portal with the logon credentials used when you signed up for your Free Windows Azure Trial.
     
  2. Select Virtual Machines located on the side navigation panel on the Windows Azure Management Portal page.
     
  3. Click the +NEW button located on the bottom navigation bar and select Compute | Virtual Machines | From Gallery.
     
  4. In the Virtual Machine Operating System Selection list, select SharePoint Server 2013 Trial and click the Next button.
     
  5. On the Virtual Machine Configuration page, complete the fields as follows:

    - Virtual Machine Name: XXXlabapp01
    - New User Name: Choose a secure local Administrator user account to provision.
    - New Password and Confirm Password fields: Choose and confirm a new local Administrator password.
    - Size: Large (4 cores, 7GB Memory)
     
    Click the Next button to continue.
     
  6. On the Virtual Machine Mode page, complete the fields as follows:
     
    - Standalone Virtual Machine: Selected
    - DNS Name: XXXlabapp01.cloudapp.net
    - Storage Account: Select the Storage Account defined in the Getting Started steps from the Prerequisites section above.
    - Region/Affinity Group/Virtual Network: Select XXXlabnet01 – the Virtual Network defined in Exercise 2 above.
    - Virtual Network Subnets: Select Subnet-1 (10.0.0.0/23)
     
    Click the Next button to continue.
     
  7. On the Virtual Machine Options page, click the Checkmark button to begin provisioning the new virtual machine.
     
    As the new virtual machine is being provisioned, you will see the Status column on the Virtual Machines page of the Windows Azure Management Portal cycle through several values including Stopped, Stopped (Provisioning), and Running (Provisioning).  When provisioning for this new Virtual Machine is completed, the Status column will display a value of Running and you may continue with the next step in this guide.
     
  8. After the new virtual machine has finished provisioning, click on the name ( XXXlabapp01 ) of the new Virtual Machine displayed on the Virtual Machines page of the Windows Azure Management Portal.
     
  9. On the virtual machine Dashboard page for XXXlabapp01, make note of the Internal IP Address displayed on this page.  This IP address should be listed as 10.0.0.6
     
    If a different internal IP address is displayed, the virtual network and/or virtual machine configuration was not completed correctly.  In this case, click the DELETE button located on the bottom toolbar of the virtual machine details page for XXXlabapp01, and go back to Exercise 2,  Exercise 3 and Exercise 4 to confirm that all steps were completed correctly.
     
  10. On the virtual machine Dashboard page for XXXlabapp01, click the Connect button located on the bottom navigation toolbar and click the Open button to launch a Remote Desktop Connection to the console of this virtual machine.  Logon at the console of your virtual machine with the local Administrator credentials defined in Step 5 above.
     
  11. In the Server Manager tool, click on Local Server in the left navigation pane and click on the Workgroup option.  Join this server to the contoso.com domain and restart the server to complete the domain join operation.
     
  12. After the server restarts, re-establish a Remote Desktop connection to the server and logon with the CONTOSO\Administrator domain user credentials defined earlier in Exercise 3.
  13. In the Server Manager tool, click on Local Server in the left navigation pane and select IE Enhanced Security Configuration.  Turn off enhanced security for Administrators and click the OK button.
     
    Note: Modifying Internet Explorer Enhanced Security configurations is not good practice for production environments and is only for the purpose of this particular step-by-step lab guide.
  14. On the Desktop, double-click on the SharePoint 2013 Products Configuration Wizard shortcut to launch the configuration wizard.  Click the Next button to continue. If prompted to start or reset services, click the Yes button.
  15. In the SharePoint Products Configuration Wizard, when prompted on the Connect to server farm dialog, select the option to Create a new server farm.
     
  16. On the Specify Configuration Database Settings, specify the following values for each field:
     
    - Database Server: XXXlabdb01
    - Username: CONTOSO\sp_farm
    - Password: Type the password specified when the sp_farm domain user account was created earlier in Exercise 3, Step 14.
     
  17. Click the Next > button and accept all other default values in the SharePoint Products Configuration Wizard.  Click the Finish button when prompted to complete the wizard.
     
  18. The SharePoint 2013 Central Administration web page should launch automatically.  When prompted, click the Start the Wizard button to begin the Initial Farm Configuration Wizard.
     
  19. When prompted for Service Account, type the CONTOSO\sp_serviceapps domain username and password specified when this account was created earlier in Exercise 3, Step 14.
     
  20. Accept all other default values and click the Next > button to continue.
     
  21. On the Create a Site Collection page, create a new top-level Intranet site collection using the following field values:
     
    - Title and Description: Enter your preferred Title and Description for the new site collection
    - URL: Select the root URL path – http://XXXlabapp01/
    - Select experience version:
    2013
    - Select a template: Publishing | Publishing Portal
     
    Click the OK button to provision a new top-level Intranet site collection. 
     
    After the new top-level Intranet site collection is provisioned, test navigating to the URL for this site collection from within the Remote Desktop session to the server.
     
  22. On the SharePoint 2013 Central Administration site, configure a Public URL alternate access mapping for accessing the new top-level Intranet site collection from the Internet.
     
    1. On the Central Administration site home page, click the Configure alternate access mappings link.
       
    2. On the Alternate Access Mappings page, click the Edit Public URLs link.
       
    3. On the Edit Public Zone URLs page, select and specify the following values:
       
      - Alternate Access Mapping Collection: SharePoint - 80
      - Internet: http://XXXlabapp01.cloudapp.net
       
      Click the Save button to complete the Alternate Access Mapping configuration.
       
  23. Close the Remote Desktop session to the server.
     
  24. Sign in at the Windows Azure Management Portal with the logon credentials used when you signed up for your Free Windows Azure Trial.
     
  25. Select Virtual Machines located on the side navigation panel on the Windows Azure Management Portal page.
     
  26. On the Virtual Machines page, click on the name of the SharePoint virtual machine – XXXlabapp01.
     
  27. On the XXXlabapp01 virtual machine details page, click on Endpoints in the top navigation area of the page.
     
  28. Click the +Add Endpoint button in the bottom navigation bar of the page to define a new virtual machine endpoint that will permit HTTP web traffic inbound to the SharePoint virtual machine. 
     
  29. On the Add an endpoint to a virtual machine form, select the Add Endpoint option and click the Next button to continue.
     
  30. On the Specify the details of the endpoint form, specify the following field values:
     
    - Name: WebHTTP
    - Protocol: TCP
    - Public Port: 80
    - Private Port: 80
     
    Click the Checkmark button to create a new endpoint definition that will permit inbound web traffic to the SharePoint virtual machine.
     
  31. After the endpoint configuration has been successfully applied, test browsing to the following public URL to confirm that you are able to access the Intranet site collection that is configured on SharePoint:
     
    - URL: http://XXXlabapp01.cloudapp.net
The configuration for this virtual machine is now complete, and you may continue with the next exercise in this step-by-step guide. Be sure to shutdown your lab VMs from the Windows Azure Management Portal when not in use to save on compute charges.