A quick start guide for Deploying and Configuring Node-RED as an Azure WebApp

Introduction

I’ve been experimenting and messing around with IoT devices for well over 10 years. Back then it wasn’t called IoT, and it was very much a build it and write it yourself approach.

Fast forward to 2017 and you can buy a microprocessor for a couple of dollars that includes WiFi. Environmental sensors are available for another couple of dollars and we can start to publish environmental telemetry without having to build circuitry and develop code. And rather than having to design and deploy a database to store the telemetry (as I was doing 10+ years ago) we can send it to SaaS/PaaS services and build dashboards very quickly.

This post provides a quick start guide to those last few points. Visualising data from IoT devices using Azure Platform-as-a-Service services. Here is a rudimentary environment dashboard I put together very quickly.

NodeRedDashboardUI.PNG

Overview

Having played with numerous services recently for my already API integrated IoT devices, I knew I wanted a solution to visualise the data, but I didn’t want to deploy dedicated infrastructure and I wanted to keep the number of moving parts to a minimum. I looked at getting my devices to publish their telemetry via MQTT which is  great solution (for scale or rapidly changing data), but when you are only dealing with a handful of sensors and data that isn’t highly dynamic it is over-kill. I wanted to simply poll the devices as required and obtain the current readings and visualise it. Think temperature, pressure, humidity.

Through my research I like the look of Node-RED for its quick and simplistic approach to obtaining data and manipulating it for presentation. Node-RED relies on NodeJS which I figured I could deploy as an Azure WebApp (similar to what I did here). Sure enough I could. However not long after I got it working I discovered this project. A Node-RED enabled NodeJS Web App you can deploy straight from Github. Awesome work Juan Manuel Servera.

Prerequisites

The quickest way to start then is to use Juan’s Azure WebApp wrapper for Node-RED. Follow his instructions to get that deployed to your Azure Subscription. Once deployed you can navigate to your Node-RED WebApp and you should see something similar to the image below.

DefaultNode-Red.PNG

The first thing you need to do is secure the app. From your WebApp Application Settings in the Azure Portal, use Kudu to navigate to the WebApp files. Under your wwwroot/WebApp directory you will find the settings.js file. Select the file and select the Edit (pencil) icon.

Node-Red-Settings

Comment in the adminAuth section around lines 93-100. To generate the encrypted password on a local install of NodeJS I ran the following command and copied the hash. Change ‘whatisagoodpassword’ for your desired password.

node -e "console.log(require('bcryptjs').hashSync(process.argv[1], 8));" whatisagoodpassword

Select Save, then Restart your application.

Node-Red-Password

On loading your WebApp again you will be prompted to login. Login and lets get started.

Login

Configuring Node-RED

Now it is time to pull in some data and visualise it. I’m not going to go into too much detail as what you want to do is probably quick different to me.

At its simplest though I want to trigger on a timer a call to my sensor API’s to return the values and display them as either text, a graph or a gauge. Below graphically shows he configuration for the dashboard shown above.

ConfigureNodeRED.PNG

For each entity on the dashboard there is and input. For me this is trigger every 15 minutes. That looks like this.

Get-15mins

Next is the API to get the data. The API I’m calling is an open GET with the API key in the URL so looks like this.

HTTPRequest

With the JSON response from the API I retrieve the temperature value and return it as msg for use in the UI.

Function

I then have the Gauge for Temperature. I’ve set the minimum and maximum values and gone with the defaults for the colours.

Guage

I’m also outputting debug info during setup for the raw response from the Function ….

DebugParsedOutput

….. and from the parsed function.

DebugHTTPRequest

These appear in the Debug pane on the right hand side.

DebugWindow

After each configuration change simply select Deploy and then switch over to your Node-RED WebApp. That will looks like your URI for your WebApp with UI on the end eg. http://.azurewebsites.net/ui

Conclusion

Thanks to Azure PaaS services and the ability to use a graphical IoT tool like Node-RED we can quickly deploy a solution to visualise IoT data without having to deploy any backend infrastructure. The only hardware is the IoT sensors, everything else is serverless.

Display Microsoft Identity Manager Sync Engine Statistics in the MIM Portal

Introduction

In the Microsoft / Forefront Identity Manager Synchronization Service Manager under Tools we have a Statistics Report. This gives a break down of each of the Management Agents and the Connectors on each MA.

I had a recent requirement to expose this information for a customer but I didn’t want them to have to connect to the Synchronization Server (and be given the permissions to allow them to). So I looked into another way of providing a subset of this information in the MIM Portal itself.  This post details that solution.

MIM / FIM Synchronization Server Management Agent & Metaverse Statistics

MIM / FIM Synchronization Server Management Agent & Metaverse Statistics

Overview

I approached this in a similar way I did for the User Object Report I recently developed. The approach is;

  • Azure PowerShell Function App that uses Remote PowerShell to connect to the MIM Sync Server and leverage the Lithnet MIIS Automation PowerShell Module to enumerate all Management Agents and build a report on the information required in the report
  • A NodeJS WebApp calls the Azure PowerShell Function App onload to generate the report and display it
  • The NodeJS WebApp is embedded in the MIM Portal as a new Nav Bar Resource and Page

The graphic below details the basic logical integration.

MVStatsReportOverview

Prerequisites

The prerequisites to perform this I’ve covered in other posts. In concept as described above it is similar to the User Object report, that has the same prerequisites and I did a pretty good job on detailing those here. To implement this then that post is the required reading to get you ready.

Azure PowerShell Function App

Below is the raw script from my Function App that connects to the MIM Sync Server and retrieves the Management Agent Statistics for the report.

NodeJS Web App

The NodeJS Web App is the app that gets embedded in the MIM Portal that calls the Azure Function to retreive the data and then display it. To get started you’ll want to start with a based NodeJS WebApp. This post will get you started. Implementing a NodeJS WebApp using Visual Studio Code 

The only extension I’m using on top of what is listed there is JQuery. So once you have NodeJS up and running in your VSCode Terminal type npm install jquery and then npm install.

I’ve kept it simple and contained all in a single HTML file using JQuery.

In you NodeJS project you will need to reference your report.html file. It should look like this (assuming you name your report report.html)

var express = require('express');
var router = express.Router();
/* GET - Report page */
router.get('/', function(req, res, next) {
   res.sendFile('report.html', { root:'./public'});
});

module.exports = router;

The Embedded Report

This is what my report looks like embedded in the MIM Portal.

Microsoft Identity Manager Statistics Report

Microsoft Identity Manager Statistics Report

Summary

Integration of FIM / MIM with Azure Platform as a Service Services opens a world of functionality including the ability to expose information that was previously only obtainable by the FIM / MIM Administrator.

Integration of Microsoft Identity Manager with Azure Platform-as-a-Service Services

Overview

This isn’t an out of the box solution. This is a bespoke solution that takes a number of elements and puts them together in a unique way. I’m not expecting anyone to implement this specific solution (but you’re more than welcome to) but to take inspiration from it to implement solutions relevant to your environment(s). This post supports a presentation I did to The MIM Team User Group on 14 June 2017.

This post describes a solution that;

  • Leverages an Azure WebApp (NodeJS) to present a simple website. That site can be integrated easily in the FIM/MIM Portal
  • The NodeJS website leverages an Azure Function App to get a list of users from the FIM/MIM Synchronization Server and allows the user to use typeahead functionality to find the user they want to generate a FIM/MIM object report on
  • On selection of a user, a request will be sent to another Azure Function App to generate and return the report to the user in a new browser window

This is shown graphically below.

 

Report Request UI

The NodeJS WebApp is integrated into the FIM/MIM portal. Bootstrap Typeahead is used to find the user to generate a report on. The Typeahead userlist if fulfilled by an Azure Function into the MIM Sync Metaverse. The Generate Report button fires off a call to FIM/MIM via another Azure Function into the MIM Sync and MIM Service to generate the report.

The returned report opens in a new tab in the users browser. The report contains details of the FIM/MIM connectors the user is represented on.

The values of all attributes for the users hologram from the Metaverse are displayed along with the MA the value came from and the last modified date.

Finally the metadata report from the MIM Service MA Connector Space and the MIM Service.

Prerequisites

These are numerous, but I’ve previously posted about them. You will need;

I encourage you to digest those posts to understand how to configure the prerequisites for this solution.

Additional Solution Requirements

To bring all the individual components together, there are a few additional tasks to enable this solution.

  • Enable CORS on your Azure Function App Configuration (see details further below)
  • If you want to display User Object Photos as part of the report, you will likely need to synchronize them into FIM/MIM from an authoritative source (e.g. Office365/Exchange Online)   Checkout this post  and additional details further below
  • In order to embed the NodeJS WebApp into the FIM/MIM Portal, this post provides the details. Change the target URL from PowerBI URL to your NodeJS site
  • Object Report Request WebApp (see below for sample site)

Azure Functions Cross Origin Resource Sharing (CORS)

You will need to configure CORS to allow the NodeJS WebApp to access the Azure Functions (from both local and Azure). Reflect your port number if it is different from 3000, and use the DNS name for your Azure WebApp.

Sample UI NodeJS HTML

Here is a sample HTML file for your NodeJS WebApp with the UI to provide Input for LoginID fulfilled by the NodeJS Javascript file further below.

Sample UI NodeJS JavaScript

The following NodeJS JavaScript supports the HTML UI above. It populates the LoginID typeahead box and takes the Submit Report button to fulfill the report for the desired object(s). Yes if you use the UI to select (individually) multiple different objects all will be returned in their separate output windows.

As the HTML file above indicates you will need to obtain and make available as part of your NodeJS project the typeahead.bundle.js library.

Azure PowerShell Trigger Function App for AccountNames Lookup

The following Azure Function takes the call from the load of the NodeJS WebApp to populate the typeahead userlist.

Azure PowerShell Trigger Function App for User Object Report

Similar in structure to the Username List Lookup Azure Function above, but in the ScriptBlock you embed the Report Generation Script that is detailed here. Modify for what you want to report on.

Photos in the Report

If you want to display images in your report, you will need to determine if the user has an image during the MV metadata report generation part of the script. Add the following lines (updating for the name of your Image attribute; mine is named EXOPhoto) after the Try {} Catch {} in this section $obj = @() ; foreach ($attr in $attributes.Keys)

 # Display the Objects Photo rather than Base64 string 
if ($attr.equals("EXOPhoto")){ 
   $objectphoto = "<img src=$([char]0x22)data:image/jpeg;base64,$($attributes.$attr.Values.Valuestring)$([char]0x22)>" 
   $val = "System.Byte[]" 
}

Then in the output of the HTML report at the end of the report generation insert the $objectphoto variable into the HTML stream.

# Output MIM Service Object Data 
$MIMServiceObjOut = $MIMServiceObjectMetaData | Sort-Object -Property Attribute | ConvertTo-Html -Fragment 
$htmlreport = ConvertTo-HTML -Body "$htmlcss<h1>Microsoft Identity Manager User Object Report</h1><h2>Query</h2>$sourcequery</br><b><center>$objectphoto</br>NOTE: Only attributes with values are displayed.</center></b><h2>Connector(s) Summary</h2>$connectorsummary<h2>MetaVerse Data</h2>$objectmetadata <h2>MIM Service CS Object Data</h2>$MIMServiceCSobjectmetadata <h2>MIM Service Object Data</h2>$MIMServiceObjOut" -Title "MIM Object Report" 

 

As you can see above I’ve also injected the CSS ($htmlcss) into the output stream at the beginning of the Body section.  Somewhere in your script block you will need to define your CSS values. e.g.

 # StyleSheet for nice pretty output 
$htmlcss = "<style> 
   h1, h2, th { text-align: center; } 
   table { margin: auto; font-family: Segoe UI; box-shadow: 10px 10px 5px #888; border: thin ridge grey; } 
   th { background: #0046c3; color: #fff; max-width: 400px; padding: 5px 10px; } 
   td { font-size: 11px; padding: 5px 20px; color: #000; } 
   tr { background: #b8d1f3; } 
   tr:nth-child(even) { background: #dae5f4; } 
   tr:nth-child(odd) { background: #b8d1f3; } 
</style>"

Summary

An interesting solution integrating Azure PaaS Services with Microsoft Identity Manager via PowerShell and the extremely versatile Lithnet FIM/MIM PowerShell Modules.

Please share your implementations enhancing your FIM/MIM Solution.

How to build and deploy an Azure NodeJS WebApp using Visual Studio Code

Introduction

This week I had the need to build a small web application with a reasonably simple front end that will later be integrated inside a Portal. The web application isn’t going to be high use and didn’t necessitate deployment of infrastructure (VM’s). I’d messed with NodeJS a while back in this post where I configured a UI for Microsoft Identity Manager and Azure based functions.

In the back of my mind I knew I didn’t want to have to go for a full Visual Studio Project Solution for this, and with the recent updates to Visual Studio Code I figured it must be possible to do it using it. There wasn’t much around on doing it, so I dived in and worked it out for myself. Here I share the end-to-end process to make it easy for you to started.

Overview

What you will need on your development workstation before you start are the following components. Download and install them on your development machine.

You will also need an Azure Subscription to where you will publish your NodeJS site.

This post details setting up Visual Studio Code to build a shell NodeJS site and deploy it to Azure using a local GIT Repository. Let’s get started.

Visual Studio Code Extensions

A really smart and handy extension for VS Code is Azure Tools for VS Code. Release a few months ago (January 2017), this extension allows you to quickly create a Web App (Resource Group, App Service, Application Service Plan etc) from within VS Code. With VSCode on your development machine from the prerequisites above click on the Extensions Icon (bottom left) in the VSCode menu and type Azure Tools. Click the green Install button.

Azure Tools for VS Code

Creating the NodeJS Site in VS Code

I had a couple of attempts at doing this before I found a quick, neat and repeatable method of getting started. In order to get the Web App deployed and accessible correctly in Azure I found it easiest to use the Sample Azure NodeJS Hello World example from here. Download that sample and extract the contents to a new folder on your workstation. I created a new path on mine named …\NodeJS\nodejssite and dropped the sample in there so it looked like below.

After creating the folder structure and putting the sample in it, whilst in the sub-directory type:

code .

That will startup Visual Studio Code in the newly created folder with the starter sample.

Install Express for NodeJS

To that base sample site we’ll install Express. From the Terminal tab in the lower pane type:

npm install -g express-generator

Express App

With Express now on our machine, lets add the Express App to our new NodeJS site. Type express in the Terminal window.

express

Accept that the directory is not empty

This will create the folder structure for Express.

Now to get all the files and modules for our site configured for our app run npm install

Now type npm start in the terminal window to start our new site.

The NodeJS site will start. Open a Web Browser and go to http://localhost:3000 and you should see the Express empty site.

Navigate to views => index.jade Update the text like I have below.

Refresh your browser window and you should see the text updated.

In the terminal windows press Cntrl + C to stop NodeJS.

Test Deploy to Azure

Now let’s do a test deploy of our shell site as an Azure WebApp.

Press Cntrl + Shift + P or from the View menu select Command Palette.

Type Azure: Login 

This will generate a code and give you a link to open in your browser and login

Paste in the code from the clipboard and select continue

Then login with your account for the Tenant where you want to deploy the WebApp too. You’ll then be authorized.

From the Command Palette type azure sub and choose Azure: List Azure Subscriptions and choose the subscription where you will create and deploy the WebApp

Now from the Command Palette type Azure Create a Web App (Simple).

Give the WebApp a name. This will become the WebApp Name, and the basis for the all the associated WebApp components. Use Create a Web App (Advanced) if you want to be more specific about the name of the App Resources etc.

If you watch the bottom VS Code Status bar you will see the Azure Tools extension create the new Resource Group, Web App and Web App Plan.

Login to the Azure Portal, select the new Web App.

Select Deployment Options and then Local Git Repository. Select OK.

Select Deployment credentials and provide a username and password. You’ll need this shortly to publish your site.

Click Overview. Copy the Git clone url.

Back in VS Code, select the GIT icon (under the magnifying glass) and from the top choose Initialize Repository.

Then in the terminal window type git remote add azure <git clone url> obtained from the step above.

Type Initial Commit as the message and click the tick icon in the Source Control menu bar.

Select and select Publish

Select azure as the remote target we setup earlier.

You’ll be prompted to authenticate. Use the account you created above in Deployment Credentials.

Back in the Azure Portal under the Web App under Deployment Options you will see the initial commit.

Click on Overview and you should see that it is running. Click on URL and the site will open in a new tab in your browser.

Updating our WebApp

Now, let’s make a change to our WebApp.

Back in VS Code, click on the files and folder icon in the top left corner, navigate to views => index.jade and update the title. Hit Cntrl + S (or select Save from the File menu). In Terminal below type npm start to start our NodeJS site locally.

Check out the update locally. In a browser navigate to the local NodeJS site on localhost:3000. You’ll see the changed page.

Select the Git icon on the left menu, give the update some text e.g. ‘updated page text’ and select the tick from the top menu.

Select the and choose Push to publish the changes to our Azure WebApp.

Go back to your browser which was on the Azure WebApp URL and reload. Our change and been push and reflected in the WebApp.

Summary

Very quickly and easily using Visual Studio Code (with NodeJS and Git Desktop installed locally) we have;

  • Created an Azure WebApp
  • Created a base NodeJS site
  • Have a local NodeJS site we can develop
  • Publish it to Azure

Now go create something awesome.

How to configure a Graphical PowerShell Dev/Admin/Support User Interface for Azure/Office365/Microsoft Identity Manager

During the development of an identity management solution I find myself with multiple PowerShell/RDP sessions connected to multiple environments using different credentials often to obtain trivial data/information. It is easy to trip yourself up as well with remote powershell sessions to differing environments. If only there was a simple UI that could front-end a set of PowerShell modules and make those simple queries quick and painless. Likewise to allow support staff to execute a canned set of queries without providing them elevated permissions.

I figured someone would have already solved this problem and after some searching with the right keywords I found the powershell-command-executor-ui from bitsofinfo . Looking into it he had solved a lot of the issues with building a UI front-end for PowerShell with the powershell-command-executor and the stateful-process-command-proxy. That solution provided the framework for what I was thinking. The ability to provide a UI for PowerShell using powershell modules including remote powershell was exactly what I was after. And it was built on NodeJS and AngularJS so simple enough for some customization.

Introduction

In this blog post I’ll detail how I’ve leveraged the projects listed above for integration with;

Initially I had a vision of serving up the UI from an Azure WebApp. NodeJS on Azure WebApp’s is supported, however with all the solution dependencies I just couldn’t get it working.

My fallback was to then look to serve up the UI from a Windows Server 2016 Nano Server. I learnt from my efforts that a number of the PowerShell modules I was looking to provide a UI for, have .NET Framework dependencies. Nano Server does not have full .NET Framework support. Microsoft state to do so would mean the server would no longer be Nano.

For now I’ve deployed an Azure Windows Server 2016 Server secured by an Azure NSG to only allow my machine to access it. More on security later.

Overview

Simply, put the details in Github for the powershell-command-executor provide the architecture and integration. What I will detail is the modifications I’ve made to utilize the more recent AzureADPreview PowerShell Module over the MSOL PowerShell Module. I also updated the dependencies of the solution for the latest versions and hooked it into Microsoft Identity Manager. I also made a few changes to allow different credentials to be used for Azure and Microsoft Identity Manager.

Getting Started

I highly recommend you start with your implementation on a local development workstation/development virtual machine. When you have a working version you’re happy with you can then look at other ways of presenting and securing it.

NodeJS

NodeJS is the webserver for this solution. Download NodeJS for your Windows host here. I’m using the 64-bit version, but have also implemented the solution on 32-bit. Install NodeJS on your local development workstation/development virtual machine.

You can accept all the defaults.

Following the installation of NodeJS download the powershell-command-executor-ui from GitHub. Select Clone 0r Download, Download ZIP and save it to your machine.

Right click the download when it has finished and select Extract All. Select Browse and create a folder at the root of C:\ named nodejs. Extract powershell-command-executor-ui.

Locate the c:\nodejs\powershell-command-executor-ui-master\package.json file.

Using an editor such as Notepad++ update the package.json file ……

…… so that it looks like the following. This will utilise the latest versions of the dependencies for the solution.

From an elevated (Administrator) command prompt in the c:\nodejs\powershell-command-executor-ui-master directory run “c:\program files\nodejs npm” installThis will read the package.json file you edited and download the dependencies for the solution.

You can see in the screenshot below NodeJS has downloaded all the items in package.json including the powershell-command-executor and stateful-process-command-proxy.

When you now list the directories under C:\nodejs\powershell-command-executor-ui-master\node_modules you will see those packages and all their dependencies.

We can now test that we have a working PowerShell UI NodeJS website. From an elevated command prompt whilst still in the c:\nodejs\powershell-command-executor-ui-master directory run “c:\Program Files\nodejs\node.exe” bin\www

Open a browser on the same host and go to http://localhost:3000&#8221;. You should see the default UI.

Configuration and Customization

Now it is time to configure and customize the PowerShell UI for our needs.

The files we are going to edit are:

  • C:\nodejs\powershell-command-executor-ui-master\routes\index.js
    • Update Paths to the encrypted credentials files used to connect to Azure, MIM. We’ll create the encrypted credentials files soon.
  • C:\nodejs\powershell-command-executor-ui-master\public\console.html
    • Update for your customizations for CSS etc.
  • C:\nodejs\powershell-command-executor-ui-master\node_modules\powershell-command-executor\O365Utils.js
    • Update for PowerShell Modules to Import
    • Update for Commands to make available in the UI

We also need to get a couple of PowerShell Modules installed on the host so they are available to the site. The two I’m using I’ve mentioned earlier. With WMF5 intalled using Powershell we can simply install them as per the commands below.

Install-Module AzureADPreview
Install-Module LithnetRMA

In order to connect to our Microsoft Identity Manager Synchronization Server we are going to need to enable Remote Powershell on our Microsoft Identity Manager Synchronization Server. This post I wrote here details all the setup tasks to make that work. Test that you can connect via RPS to your MIM Sync Server before updating the scripts below.

Likewise for the Microsoft Identity Manager Service Server. Make sure after installing the LithnetRMA Powershell Module you can connect to the MIM Service using something similar to:

# Import LithnetRMA PS Module
import-module lithnetrma

# MIM AD User Admin
$username = "mimadmin@mim.mydomain.com"
# Password 
$password = "Secr3tSq1rr3l!" | convertto-securestring -AsPlainText -Force
# PS Creds
$credentials = New-Object System.Management.Automation.PSCredential $Username,$password

# Connect to the FIM service instance
# Will require an inbound rule for TCP 5725 (or your MIM Service Server Port) in you Resource Group Network Security Group Config
Set-ResourceManagementClient -BaseAddress http://mymimportalserver.:5725 -Credentials $credentials

 

\routes\index.js

This file details the encrypted credentials the site uses. You will need to generate the encrypted credentials for your environment. You can do this using the powershell-credentials-encryption-tools. Download that script to your workstation and unzip it. Open the credentialEncryptor.ps1 script using an Administrator PowerShell ISE session.

I’ve changed the index.js to accept two sets of credentials. This is because your Azure Admin Credentials are going to be different from your MIM Administrator Credentials (both in name and password). The username for my Azure account looks something like myname@mycompany.com whereas for MIM it is Domainname\Username.

Provide an account name for your Azure environment and the associated password.

The tool will create the encrypted credential files.

Rename the encrypted.credentials file to whatever makes sense for your environment. I’ve renamed it creds1.encrypted.credentials.

Now we re-run the script to create another set of encrypted credentials. This time for Microsoft Identity Manager. Once created, rename the encrypted.credentials file to something that makes sense in your environment. I’ve renamed the second set to creds2.encrypted.credentials.

We now need to copy the following files to your UI Website C:\nodejs\powershell-command-executor-ui-master directory:

  • creds1.encrypted.credentials
  • creds2.encrypted.credentials
  • decryptUtil.ps1
  • secret.key

Navigate back to Routes.js and open the file in an editor such as Notepad++

Update the index.js file for the path to your credentials files. We also need to add in the additional credentials file.

The changes to the file are, the paths to the files we just copied above along with the addition var PATH_TO_ENCRYPTED_RPSCREDENTIALS_FILE for the second set of credentials used for Microsoft Identity Manager.

var PATH_TO_DECRYPT_UTILS_SCRIPT = "C:\\nodejs\\powershell-command-executor-ui-master\\decryptUtil.ps1";
var PATH_TO_ENCRYPTED_CREDENTIALS_FILE = "C:\\nodejs\\powershell-command-executor-ui-master\\creds1.encrypted.credentials";
var PATH_TO_ENCRYPTED_RPSCREDENTIALS_FILE = "C:\\nodejs\\powershell-command-executor-ui-master\\creds2-encrypted.credentials";
var PATH_TO_SECRET_KEY = "C:\\nodejs\\powershell-command-executor-ui-master\\secret.key";


Also to initCommands to pass through the additional credentials file


initCommands: o365Utils.getO365PSInitCommands(
 PATH_TO_DECRYPT_UTILS_SCRIPT,
 PATH_TO_ENCRYPTED_CREDENTIALS_FILE,
 PATH_TO_ENCRYPTED_RPSCREDENTIALS_FILE,
 PATH_TO_SECRET_KEY,
 10000,30000,3600000),

Here is the full index.js file for reference.

 

public/console.html

The public/console.html file is for formatting and associated UI components. The key things I’ve updated are the Bootstrap and AngularJS versions. Those are contained in the top of the html document. A summary is below.

https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js
https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular-resource.min.js
http://javascripts/ui-bootstrap-tpls-2.4.0.min.js
http://javascripts/console.js
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">

You will also need to download the updated Bootstrap UI (ui-bootstrap-tpls-2.4.0.min.js). I’m using v2.4.0 which you can download from here. Copy it to the javascripts directory.

I’ve also updated the table types, buttons, colours, header, logo etc in the appropriate locations (CSS, Tables, Div’s etc). Here is my full file for reference. You’ll need to update for your colours, branding etc.

powershell-command-executor\O365Utils.js

Finally the O365Utils.js file. This contains the commands that will be displayed along with their options, as well as the connection information for your Microsoft Identity Manager environment.

You will need to change:

  • Line 52 for the address of your MIM Sync Server
  • Line 55 for the addresses of your MIM Service Server
  • Line 141 on-wards for what commands and parameters for those commands you want to make available in the UI

Here is an example with a couple of AzureAD commands, a MIM Sync and a MIM Service command.

Show me my PowerShell UI Website

Now that we have everything configured let’s start the site and browse to it. If you haven’t stopped the NodeJS site from earlier go to the command window and press Cntrl+C a couple of times. Run “c:\Program Files\nodejs\node.exe” bin\www again from the C:\nodejs\powershell-command-executor-ui-master directory unless you have restarted the host and now have NodeJS in your environment path.

In a browser on the same host go to http://localhost:3000 again and you should see the site as it is below.

Branding and styling from the console.html, menu options from the o365Utils.js and when you select a command and execute it data from the associated service …….

… you can see results. From the screenshot below a Get-AzureADUser command for the associated search string executed in milliseconds.

 

Summary

The powershell-command-executor-ui from bitsofinfo is a very extensible and powerful NodeJS website as a front-end to PowerShell.

With a few tweaks and updates the look and feel can be easily changed along with the addition of any powershell commands that you wish to have a UI for.

As it sits though keep in mind you have a UI with hard-coded credentials that can do whatever commands you expose.

Personally I am running one for my use only and I have it hosted in Azure in its own Resource Group with an NSG allowing outgoing traffic to Azure and my MIM environment. Incoming traffic is only allowed from my personal management workstations IP address. I also needed to allow port 3000 into the server on the NSG as well as the firewall on the host. I did that quickly using the command below.

# Enable the WebPort NodeJS is using on the firewall 
netsh advfirewall firewall add rule name="NodeJS WebPort 3000" dir=in action=allow protocol=TCP localport=3000

Follow Darren on Twitter @darrenjrobinson

Gracefully managing Gulp process hierarchy on Windows

Process Tree

When developing client side JavaScript, one thing that really comes in handy is the ability to create fully functional stubs that can mimic real server APIs. This decouples project development dependencies and allows different team members to work in parallel against an agreed API contract.

To allow people to have an isolated environment to work on and get immediate feedback on their changes, I leverage the Gulp.js + Node.js duo.

“Gulp.js is a task runner that runs on Node.js that it is normally used to automate UI development workflows such as LESS to CSS conversion, making HTML templates, minify CSS and JS, etc. However, it can also be used to fire up local web servers, custom processes and many other things.”

To make things really simple, I set up Gulp to allow anyone to enter gulp dev on a terminal to start the following workflow:

  1. Prepare distribution files
    – Compile LESS or SASS style sheets
    – Minify and concatenate JavaScript files
    – Compile templates (AngularJS)
    – Version resources for cache busting (using a file hash) 
    – etc
  2. Start stub servers
    – Start an API mockup server
    – Start a server that can serve local layouts HTML files
  3. Open a browser pointing to the local App (chrome or IE depending on the platform)
  4. Fire up file watchers to trigger specific builds and browser reloads when project files change.

The following is an extract of the entry point for these gulp tasks (gulp and gulp dev):

The DEV START.servers task is imported by the requireDir('./gulp-tasks') instruction. This task triggers other dependent workflows that spin up plain Node.js web servers that are, in turn, kept alive by a process supervisor library called forever-monitor.

There is a catch, however. If you are working on a Unix-friendly system (like a Mac), processes are normally managed hierarchically. In a normal situation, a root process (let’s say gulp dev) will create child processes (DEV START.api.server and DEV START.layouts.server) that will only live during the lifetime of their parent. This is great because whenever we terminate the parent process, all its children are terminated too.

In a Windows environment, processes management is done in a slightly different way – even if you close a parent process its child processes will stay alive doing what they were already doing. Child processes will contain only the parent ID as a reference. This means that it is still possible to mimic Unix process tree behaviour, but it is just a little bit more tedious and some library creators avoid dealing with the problem. This is the case with Gulp.

So in our scenario we listen to the SIGINT signal and gracefully terminate all processes when it is raised through keyboard input (hitting Ctrl-B). This prevents developers on windows from having to go to the task manager and terminate orphaned child processes themselves.

I am also using process.once(... event listener instead of process.on(... to prevent an error surfaced on Macs when Ctrl-B is hit more than once. We don’t want the OS to complain when we try to terminate a process that has already been terminated :).

That is it for now..

Happy hacking!

Creating a simple nodejs API on AWS (including nginx)

On a recent project I was part of a team developing an AngularJS website with a C# ASP.NET backend API hosted in Azure.  It was a great project as I got to work with a bunch of new tools, but it got me wondering on how simple it could be to use a Javascript API instead.  That way the entire development stack would be written in Javascript.

And so a personal project was born.  To create a simple JS API and get it running in the cloud.

Getting started

So here goes, a quick guide on setting up a nodejs API using the express framework.

I’ll start by getting the environment running locally on my mac in 6 simple steps:

# 1. Create a directory for your application
$ mkdir [your_api_name]

# 2. Install Express (the -g will install it globally)
$ npm install express -g

# 3. Use the express generator as it makes life easier!
$ npm install express-generator -g

# 4. Create your project
$ express [your_project_name_here]

# 5. Install any missing dependencies
$ npm install

# 6. Start your API
$ npm start

That’s it. You now have a nodejs API running locally on your development environment!

To test it, and prove to yourself it’s working fine, run the following curl command:

$ curl http://localhost:3000/users

If everything worked as planned, you should see “respond with a resource” printed in your terminal window. Now this is clearly as basic as it gets, but you can easily make it [a bit] more interesting by adding a new file to your project called myquickapi.js in your [app name]/routes/ folder, and add the following content:

var express = require('express');
var router = express.Router();

// get method route
router.get('/', function (req, res) {
res.send('You sent a get request');
});

// post method route
router.post('/', function(req, res) {
res.send('You sent me ' + req.param('data'));
});

module.exports = router;

A quick change to the app.js file to update our routes, by adding the following 2 lines:

var myquickapi = require(‘./routes/myquickapi');
app.use('/myquickapi', myquickapi);

Re-start your node service, and run:


$ curl -X POST http://localhost:3000/myquickapi?data=boo

And you will see the API handle the request parameter and echo it back to the caller.

Spin up an AWS EC2 instance

Log into the AWS portal and create a new EC2 instance.  For my project, as it is only a dev environment, I have gone for a General Purpose t2.Micro Ubuntu Server.  Plus it’s free which happens to be okay too!

Once the instance is up and running you will want to configure the security group to allow all inbound traffic using port 443, and 80 – after all it is a web api and I guess you want to access it!  I also enabled SSH for my local network:

Security_group

Using your pem file ssh into your new instance, and once connected, run the following commands:


# 1. update any out of date packages
sudo apt-get update

# 2. install nodejs
sudo apt-get install nodejs

# 3. install node package manager
sudo apt-get install npm

Now you can run node using the nodejs command. This is great, but not for the JS packages we’ll be using later on.  They reference the node command instead.  A simple fix is to create a symlink to the nodejs command:


$ sudo ln -s /usr/bin/nodejs /usr/bin/node

Set up nginx on you EC2 instance

We’ll use nginx on our server to proxy network traffic to the running nodejs instance.  Install nginx using the following commands:


# 1. install nginx

$ sudo apt-get install nginx

# 2. make a directory for your sites
$ sudo mkdir -p /var/www/express-api/public

# 3. set the permission of the folder so it is accessible publicly
$ sudo chmod 755 /var/www

# 4. remove the default nginx block
$ sudo rm /etc/nginx/sites-enabled/default

# 5. create the virtual hosts file
$ sudo nano /etc/nginx/sites-available/[your_api_name]

Now copy the following content into your virtual hosts file and save it:

upstream app_nodejs {
server 127.0.0.1:3000;
keepalive 8;
}

server {
listen 80;
listen [::]:80 default_server ipv6only=on;
listen 443 default ssl;

root /var/www/[your_site_folder]/public/[your_site_name];
index index.html index.htm;

# Make site accessible from http://localhost/
server_name [your_server_domain_name];

location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;

proxy_pass http://localhost:3000/;
proxy_redirect off;
}
}

This basically tells your server to listen on ports 80 and 443 and redirect any incoming traffic to your locally running nodes server on port 3000. A simple approach for now, but all that is needed to get our API up and running.

Activate your newly created hosts file by running the following command:

$ sudo ln -s /etc/nginx/sites-available/[your_api_name] /etc/nginx/sites-enabled/[your_api_name]

Now restart nginx to make your settings take place:

$ sudo service nginx restart

As a sanity test you can run the following command to confirm everything is setup correctly. If you are in good shape you will see a confirmation that the test has run successfully.

$ sudo nginx -c /etc/nginx/nginx.conf -t

Final steps

The last step in the process, which you could argue is the most important, is to copy your api code onto your new web server.  If you are creating this for a production system then I would encourage a deployment tool at this stage (and to be frank, probably a different approach altogether), but for now a simple secure copy is probably all that’s required:


$ scp -r [your_api_directory] your_username@aws_ec2_api:/var/www/[your_site_folder]/public/

And that’s it.  Fire up a browser and try running the curl commands against your EC2 instance rather than your local machine.  If all has gone well then you should get the same response as you did with your local environment (and it’ll be lightning fast).

… Just for fun

If you disconnect the ssh connection to your server it will stop the application from running.  A fairly big problem for a web api, but a simple fix to resolve.

A quick solution is to use the Forever tool.

Install it, and run your app (you’ll be glad you added the symlink to nodejs earlier):


$ sudo npm install -g forever

$ sudo forever start /var/www/[your_site_folder]/public/[your_site_name]/bin/www

 

Hopefully this will have provided a good insight into setting up a nodejs API on AWS. At the moment it is fairly basic, but time permitting, I would like to build on the API and add additional features to make it more useable – I’d particularly like to add a Javascript OAuth 2.0 endpoint!

Watch this space for future updates, as I add new features I will be sure to blog about the learnings I find along the way.

As Always; any questions, then just reach out to me, or post them below