Azure – PowerShell Capabilities I Love

I use Azure for Development and Testing very heavily with my job as a consultant for Microsoft.  Since most of my work is done deploying systems On-Premises I usually have to build environments for testing of deployment scripts etc.  This means I have the option to go through the Azure Portal and create machine after machine, or I can use PowerShell to script these processes.  As such I have gone through many of the IAAS PowerShell commands and thought I would share some of my commonly used commands.

IAAS Commands I Always Use

Set-AzureRmVMCustomScriptExtension

So, you create a VM and now you want to configure it before you actually log in, like make it a domain controller or join it to a domain.  No problem, the Set-AzureRmVMCustomScriptExtension allows you to push and run a script file on the Azure VM without needing to log in, and you can even pass arguments to the script. This command does require a bit of information (Resource Group Name, Storage Account Name, Container, and others) but being able to create a VM AND set it up as the domain controller without ever logging in first…you can’t beat that.

Set-AzureStorageBlobContent

This command is a MUST KNOW because it allows you to move content from your local machine to an Azure Storage Blob, and if you want to use Set-AzureRmCustomScriptExtentions, your scripts have to be in an Azure Storage Blog.  This command is actually pretty straight forward, give it the filename (blob), Container, Storage Account Context and the local file path and upload away.

New-AzureRmResourceGroup

Every time I create a new “Environment” I create a new resource group partly because I’m lazy, but also because I’m really picky.  I don’t like having 2,  3,  4, … environments inside of one resource group because when I script things I really just want to say something like “Start My Resource Group xyz” and let the script handle the rest.  Also when I’m done with an environment I can easily clean it up by using the Remove-AzureRmResourceGroup, and poof its gone.

New-AzureRmVm

Need a new VM, here you go.  This command isn’t as straight forward as it seems, really to use New-AzureRmVm you must create the Azure RM Config object and all the necessary elements, but this inside of a simple ForEach-Object loop can save you hours of entering information into the Azure Portal forms.

Runbooks – Stay under that spending limit

Azure Runbooks are one of my favorite capabilities available.  First, the interface is web based so you can write and test your PowerShell directly in the Azure Portal which is a really nice capability.  Second, you can schedule these books to run so if you forget to shutdown and environment, the scheduler will do it for you.  Third, if there was a problem your output from each run is available for review so you can always go back and review the Runbook output and check the script health.  Finally, Runbooks have access to variables stored Outside of the Runbook, so no need to include the admin account’s info in your PowerShell script, just save it in the Runbook’s variables (as a Credential, so the password is hashed) and make nice generic runbooks.

I highly recommend using runbooks to at least stop your development, and possibly test, environment on a daily basis.  My Stop-Daily runbook is configured to run every day at 6PM so I know all of my VMs will be shutdown.  I typically keep my runbook(s) in a separate Resource Group from the different Development/Test environments I create, this way I can destroy the environment without losing the runbooks.

Runbook(s) work within a single subscription, so if you have multiple Subscriptions you will need to create runbooks for each.

Another Change

You may have noticed that the site look and feel has changed.  I felt it was about time to get a new theme on the blog since much has recently changed.  For those that didn’t know I began working directly for Microsoft at the end of June 2015.  As I continue to grow professionally I have decided it is time for me to spend a greater amount of time focusing on Identity and to begin to move away from my focus in SharePoint.

The wonderful thing about identity is that I won’t actually leave SharePoint, but now my focus will be on WHO is accessing the portal.  I also get the opportunity to expand my technology base into Skype for Business, CRM, Mobile Apps, basically any and every technology you can think of.  I’m excited about this change and I hope to share lots of new information with everyone.

As always, come back often and if you have questions always reach out.

 

Azure Mobile Angular Services

I recently had a request for a more detailed example of how to use the Azure Mobile Angular Services so I went ahead and created a single page application that has very little capability but is a good example for those getting started with AngularJS and Azure Mobile Angular Services and have pushed it to the GitHub site.  The example is built using Visual Studio but is just a single HTML page and a Scripts folder with the necessary .js files inside.  Once you have pulled the project you will find it does actually read from my Azure Mobile Services, although write is disabled, so you can follow along.

How to Fix the SharePoint Modified Date to use Date and Time

If you’ve started using SharePoint 2013 you probably noticed that Microsoft changed the way they present the Modified value.  In SharePoint 2010 the Modified field showed a Date/Time stamp, but in SharePoint 2013 the Date/Time is replaced with something like “3 minutes ago”.  Personally I like this, but some users may not and the Date/Time stamp may be really important especially for Legal Departments or other Audited applications.

Fortunately there is a very simple fix, using the Client Side Rendering to override SharePoint’s default rendering of the Modified field.

The script is simple enough:

(function() {
var overrideCtx = {};
overrideCtx.Templates = {};

overrideCtx.Templates.Fields = {
‘Modified’: {
View: function(ctx) {
//var utcDate = new Date(ctx.CurrentItem.Modified);

return “<span>” + ctx.CurrentItem.Modified + “</span>”;
}
}
};
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
});

As I’ve discussed in other blogs(here, here, and here) on CSR we use our self executing function and within it we create the Override Context (overrideCtx) object along with it’s Templates and Fields properties.  Within Fields we specify which field, Modified, and what form, View, we are managing the rendering for.  The nice aspect of this is that we can override the rendering on one or many forms and rely on SharePoint to handle the rendering for the forms we don’t want to override.

In the function for our form we simply return an HTML formatted string that should be displayed.  Using the browser developer tools you can view the argument passed to our View function as well as the CurrentItem’s properties and determine what value to display.  In the case of the ‘Last Modified’ Date/Time stamp the property we want to use is Modified.

Finally, in order to make SharePoint use our override template we pass our Override Context object to the RegisterTemplateOverrides and then add a reference to our JavaScript file to the Display Form’s JSLink property.

Client Side Rendering of Form Fields

I’ve been working on a site migration from SharePoint 2010 to SharePoint 2013 and a lot of what we did in 2010 was to customize forms the user interacts with.  One of the requirements we had was to ensure a Project Name and Project Alias field did not contain the same information.  In SharePoint 2010 this had been done by adding some JavaScript to the page, grabbing each control by HTML Element ID, and then comparing their values.  When we migrated these fields all got new HTML Element IDs so our validation logic was broken.

Obviously, we could go and update the JavaScript to use the new IDs, but if we migrated to another environment or performed and upgrade in the future we would probably have an issue again.  Instead SharePoint 2013 added Client Side Rendering which allows us to control the form’s rendering using JavaScript which would should allow our solution to be more portable and enable the field validation.

I have written a couple of other blogs about the Client Side Rendering of a View and Rendering of Specific Field(s).  While those were useful I found I was still missing a lot of information about how we could add the validation, what was needed to make sure values provided in the form were saved, and how to make the controls interact.

Before we begin a word of caution:  Once a Field Template is provided the template must provide the UI Controls for the user to interact with, a method to retrieve the value specified by the user, a method of displaying the previously specified value, and any validation INCLUDING if the field is required or not.  The example below will include elements of all of this, but your implementation may differ based on your scenario.

First, remember that we need to write good JavaScript that does not pollute the global JS space, so remember to wrap everything in your self executing function.

(function() {
//overrideContext code below
})();

Second, we are going to specify an override on the Edit Form for our specific fields, you may also want to do this on a new form but in our case the Project Alias was not available on the new form so we didn’t worry about it there.  Remember once we provide the override for the Field we are fully responsible for the type of input(s)/controls the user will have to interact, retrieving the value for SharePoint, and performing any ‘Required’ field validation along with any other custom validation we may want.  In order to provide the override in the proper format we must create our OverrideContext object with the proper properties.

var overrideCtx = {};
overrideCtx.Templates = {};

overrideCtx.Templates.Fields = {
‘ProjectAlias’ : {
EditForm: function(currentCtx) {
}
},
‘ProjectName’: {
EditForm: function(currentCtx) {
}
}
};

SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);

At this point we have now specified that we want to override the ProjectAlias and ProjectName fields when the Edit Form is rendered.  However, since we have not returned any HTML formatted controls from either function if we placed all this in a JavaScript file and added it as the JS Link on the Edit form what would actually happen is the ProjectAlias and ProjectName input control wouldn’t exist.

Focusing on the ProjectAlias Field we can add the following to return an HTML TextBox for the user to make use of.

var ctx = SPClientTemplates.Utility.GetFormContextForCurrentField(ctxCurrent);
var controlId = ctx.fieldName+ “_davidmcwee_control”;

//Get Field Value, Value Validation, and Validation Error handling code will all get added here

return String.format(‘<input type=”text” id=”{0}” name=”{0}” />’, controlId);

Now we have a simple text box that will render because the function provided to EditForm is expected to return HTML that can be directly embedded in the page for rendering.  Also we are controlling the ID and Name attributes of our HTML Element so our validation later will be much easier.  While we have the control being rendered, if you actually try to provide a value nothing will get saved because we haven’t specified how to get the value from the control.  So before we return our HTML string we need to register our “getter” method so SharePoint knows how to get the value for our overridden field.

ctx.registerGetValueCallback(ctx.fieldName, function() {
return $get(controlId).value;
});

$get is a SharePoint provided function which return the HTML DOM object and is similar to the jQuery $(“#” + controlId).  I’ve used only the SharePoint functionality here to prevent confusion with other JS libraries.

Important thing to note:  The first argument to the register function is the Field’s Name, if you use any other value your function will still get called, but the value you return will not get applied to the field it should be associated with.  I originally used the controlId as the first argument but found the values were never saved, it took a lot of searching and trial and error to finally realize the issue.

Now that we can retrieve and save our control’s value we can implement validation.  In order to provide validation we need to create a Validator object that implements the Validate(…) function.

//Added the Field Validator just below the declaration of overrideCtx.Templates = {};
fieldValidator = function() {
fieldValidator.prototype.Validate = function(value) {
var isError = false;
var errorMessage = “”;

if($get(“ProjectAlias_davidmcwee_control”).value == $get(“ProjectName_davidmcwee_control”).value)
{
isError = true;
errorMessage = (“ProjectName and Project Alias are not allowed to be the same.”);
}

return new SPClientForms.ClientValidation.ValidationResult(isError, errorMessage);
};
};

In the above code you can see we did hard code the HTML IDs, while this was done in our dev code we did move to saving each of the Control IDs as properties so they could be retrieved later and the code would be more generic.  However, the idea is that we will get the two controls value’s and compare them, if they match we will set isError to true and provide a message back to the user.

Now we need to add our Validator to the Form’s list of Validators in association with our field and we also need to handle a validation error.

var validators = new SPClientForms.ClientValidation.ValidatorSet();
validators.RegisterValidator(new fieldValidator());
ctx.registerClientValidator(ctx.fieldName, validators);

These lines handle creating a validator set, so you can have multiple validators on a single field, adding the validator we created above to the set and registering the validator with the field.

ctx.registerValidationErrorCallback(ctx.fieldName, function(errorResult) {
SPFormControl_AppendValidationErrorMessage(controlId, errorResult);
});

These lines handle the Validation Callback, but this function is not always called.  This function is invoked when the input fails validation or if the previous attempt to save failed validation.  The nice thing is that all we really need to do, in this case, is pass along the results as well as the HTML Element ID to the SPFormControl_AppendValidationErrorMessage function.  You could consider adding other logic here to clear, update, or add suggestions to the user for possible “good” values if validation fails.  The errorResult object provided two properties errorMessage which is the message you specified, and validationError which is the Boolean value you specified in your Validation object.

Once all of this is added, you now have a functioning form override with field dependencies.  Here is the entire JavaScript file in PDF format for you to view.

Hero Blog Post of the Day

I was working on a project today where I need to dynamically create a MS Word Document, save it to a SharePoint library, and then present the document to the user for editing.  My first attempt was to create an IFrame that would redirect to the document once it was created, but this would only open the document in ‘Read Only’ Mode.

Enter the Hero Blog Post

After a quick search I found this blog post.  DotNetNinja found a javascript function editDocumentWithProgID2 which performs this exact operation and is part of the SharePoint 2010 Core.js file.

Simple!

AngularJS Module for Azure Mobile Services

A few months back a coworker introduced me to AngularJS as an alternative to using KnockoutJS.  Around the same time Microsoft was pushing a bunch of videos and “How To’s” on the Azure Mobile Services.  After walking through the AngularJS tutorial and playing with the Azure Mobile Services “To Do” Demo I decided it would be interesting to mesh these two items together, use AngularJS in the UI to communicate with Azure Mobile Services for data storage, and who know what else in the future.

The first thing I did was create the To Do demo application and then I started to create the AngularJS partial views for everything.  Once the views and all worked I began working on the actual communication with the Azure Mobile Services, and this is where things went south.

Don’t Assume AngularJS Behaves

So the major problem I ran into was that I *ahem* Assumed that AngularJS would behave with JQuery Deferred objects, in particular with the Ajax objects and the ‘Then’ chaining.  I know AngularJS has its own Ajax methods, but the Azure Mobile Services utilize JQuery and I wanted to stick as close to the “To Do” code as I could.  Well, what I found was AngularJS doesn’t behave well with JQuery Then chaining, and this has to do with Angular’s $q object.  If you read the documentation for $q you will find, somewhat glossed over I believe, the following statement in the section “Differences between Kris Kowal’s Q and $q” the following statement:

$q is integrated with the $rootScope.Scope Scope model observation mechanism in angular, which means faster propagation of resolution or rejection into your models and avoiding unnecessary browser repains, which would result in flickering UI.

The first part of that statement is key: $q is integrated with the $rootScope.Scope which means other deferred objects that change values linked to UI components won’t trigger the $rootScope.Scope to repaint the browser display.  Therefore code like:

$get([some url]).then(function() { someUiBoundVariable = "in then"; });

would fail to update the UI with the “in then” string value.

Solution

So after realizing the issues of $q Deferred objects vs. other JavaScript Library Deferred objects I rewrote my Azure Service to utilize the $q deferred object.  Interestingly, my coworker who introduced me to AngularJS soon contacted me about how to integrate AngularJS with the Azure Mobile Service, so I took my object and made it more generic so he and I could both use the same AngularJS Module.  After we both used this for a little we realized we had a reasonably solid AngularJS Module for the Azure Mobile Services, and so was born the AngularJS Module for Azure Mobile Services NuGet Package and AngularJS Module for Azure Mobile Services Codeplex Project.

Get AngularJS Module for Azure Mobile Services

There are two ways you can use the AngularJS Module for Azure Mobile Services.  First you can use NuGet and add AngularJS Module for Azure Mobile Services to your project.

NuGet Package: http://www.nuget.org/packages/AzureMobileAngularServices

Or you can download the js file directly from CodePlex and add this to your project.

CodePlex Project: http://azuremobileangularservices.codeplex.com/