Using Azure Cognitive Services Language Text Translation with PowerShell

Introduction

Over the last few months whilst developing my Voice Assistant for Microsoft Identity Manager I’ve been leveraging a number of the Azure Cognitive Services. Each one has its own nuance as they all appear to be in differing iterations of maturity. My first hurdle when looking to leverage one, is the examples provided. Often the samples are in languages I’m not fluent in and pretty much always there is no examples of using PowerShell and the awesome Invoke-RestMethod call to interact with them. Of course there are the PowerShell Modules, but I normally like to go direct and not have dependancies on a module.

Once I’ve worked it out how to leverage each service with PowerShell I’ve posted how to set up an API call for future reference. Here are the previous ones;

The final service I was looking to leverage (with respect to Audio and Text) is the Language Translator. This is yet another API with its own quirks and it took me longer than it should have. So as I know I’ll need it again in the future and I’m sure it will help others, I’m detailing it here.

Getting Started with the Microsoft Translate Text Cognitive Service

Like the other Cognitive Services I’ve detailed in the past, the Translator has its own API which is currently up to version 3. Obtain a Translator Text API Key free trial from here.

Here is an example PowerShell script that you will be able to leverage as a getting started guide to interfacing with the Translator Text API with PowerShell. Once I got it working it is quite simple. Here it is;

  • update Line 2 for your API key
  • update Lines 6 and 9 for your From and To languages
  • update Line 17 for the text string you want to convert

Summary

Updating a few lines and stepping through the script we can see that it is possible to quickly leverage the Text Translator service to convert (in this example) from English to German.

Translating Language Text with PowerShell.PNG

Interestingly Klingon is an option to convert to too. Change Line 9 from ‘de‘ to ‘tlh‘ if you want to try it for yourself. It looks like quite a concise language ūüėČ

'Translating between languages is easy with Azure' converted to 'mugh SabtaHbogh Hol ngeD Azure'

Quickly generating a dataset of fictitious Users using Randomised Real Data and PowerShell

Introduction

I’ve lost count of the number of times I’ve had the need to generate a representative dataset of users. Of course I have access to many production datasets but for many reasons they can’t be used. Finding previous datasets I’ve randomly generated always seems to take longer than it should, so with my most recent iteration of having to generate a fictitious list of users with Australian addresses, I’ve documented how I went about it, along with the source data I used and the script to create it.

Source Data

For my data sources to base my dataset off, I wanted representative data for Australia for both people names and locations. After a few quick searches I found;

  • that Data South Australia has lists of baby names¬†for both male and female babies in SA. I downloaded the 2017 lists as CSV’s.
  • for Surname, also from Data South Australia I borrowed the 19th Century Arrivals list and manipulated the Fullname column to separate it on “,” then used the Excel Function to remove duplicates. I deleted all other columns so that I was left with just over 13,000 surnames in a CSV file.
  • Matthew Proctor’s list of Australian Postcodes¬†as a CSV. This provides Postcode, Suburb and State.
  • Brisbane City Council (Australia’s largest Council) has a dataset with all bus locations that includes Street names as a CSV. Like I did for Surname I used the Excel Function to remove duplicates, removed the blanks and the other columns and then had just over 1600 street names.

The Script

The script is pretty simple. It imports each of the CSV’s listed above and generates a random number based on the number of records in each file.

The GitHub Repo contains the PowerShell script along with the source files. Change line 3 for the location where you store the CSV files and change line 66 for the number of users to generate. I’ve left the end of the script empty. I either insert the API call to create the users, or the PowerShell cmdlet with the data to do the creation depending on where I’m creating the users.

darrenjrobinson/Generate-Random-Users

Using real data, randomise it to create realistic users with Australian addresses – darrenjrobinson/Generate-Random-Users

The Output

Here is a sample output in JSON format.

{
"Street": "370 Miskin St",
"Surname": "Burne",
"Suburb": "WOODBROOK",
"Postcode": "3451",
"State": "VIC",
"GivenName": "Miro"
}
{
"Street": "293 Preston Rd",
"Surname": "Partingale",
"Suburb": "MARRARA",
"Postcode": "812",
"State": "NT",
"GivenName": "Daniella"
}
{
"Street": "409 Orchard St",
"Surname": "Liaseyer",
"Suburb": "THURGOONA",
"Postcode": "2640",
"State": "NSW",
"GivenName": "Ariana"
}
{
"Street": "775 Station Rd",
"Surname": "Nevin",
"Suburb": "AVON DOWNS",
"Postcode": "862",
"State": "NT",
"GivenName": "Naria"
}

Summary

Using data publicly available and PowerShell it is possible to quickly generate a dataset of representative users and addresses. Generating other attributes is as easy as extrapolating from the existing data or supplementing it with additional source data files.

Using your Voice to Search Microsoft Identity Manager ‚Äď Part 2

Introduction

Last month I wrote this post that detailed using your voice to search/query Microsoft Identity Manager. That post demonstrated a working solution (GitHub repository coming next month) but was still incomplete if it was to be used in production within an Enterprise. I hinted then that there were additional enhancements I was looking to make. One is an Auditing/Reporting aspect and that is what I cover in this post.

Overview

The one element of the solution that has visibility of each search scenario is the IoT Device. As a potential future enhancement this could also be a Bot. For each request I wanted to log/audit;

  • Device the query was initiated from (it is possible to have many IoT devices; physical or bot leveraging this function)
  • The query
  • The response
  • Date and Time of the event
  • User the query targeted

To achieve this my solution is to;

  • On my IoT Device the query, target user and date/time is held during the query event
  • At the completion of the query the response along with the earlier information is sent to the IoT Hub using the IoT Hub REST API
  • The event is consumed from the IoT Hub by an Azure Event Hub
  • The message containing the information is processed by Stream Analytics and put into Azure Table Storage and Power BI.

Azure Table Storage provides the logging/auditing trail of what requests have been made and the responses.  Power BI provides the reporting aspect. These two services provide visibility into what requests have been made, against who, when etc. The graphic below shows this in the bottom portion of the image.

Auditing Reporting Searching MIM with Speech.png
Voice Search for Microsoft Identity Manager Auditing and Reporting

Sending IoT Device Events to IoT Hub

I covered this piece in a previous post here in PowerShell. I converted it from PowerShell to Python to run on my device. In PowerShell though for initial end-to-end testing when developing the solution the body of the message being sent and sending it looks like this;

[string]$datetime = get-date
$datetime = $datetime.Replace("/","-")
$body = @{
 deviceId = $deviceID
 messageId = $datetime
 messageString = "$($deviceID)-to-Cloud-$($datetime)"
 MIMQuery = "Does the user Jerry Seinfeld have an Active Directory Account"
 MIMResponse = "Yes. Their LoginID is jerry.seinfeld"
 User = "Jerry Seinfeld"
}

$body = $body | ConvertTo-Json
Invoke-RestMethod -Uri $iotHubRestURI -Headers $Headers -Method Post -Body $body

Event Hub and IoT Hub Configuration

First I created an Event Hub. Then on my IoT Hub I added an Event Subscription and pointed it to my Event Hub.

IoTHub Event Hub.PNG
Azure IoT Hub Events

Streaming Analytics

I then created a Stream Analytics Job. I configured two Inputs. One each from my IoT Hub and from my Event Hub.

Stream Analytics Inputs.PNG
Azure Stream Analytics Inputs

I then created two Outputs. One for Table Storage for which I used an existing Storage Group for my solution, and the other for Power BI using an existing Workspace but creating a new Dataset. For the Table storage I specified deviceId for Partition key and messageId for Row key.

Stream Analytics Outputs.PNG
Azure Stream Analytics Outputs

Finally as I’m keeping all the data simple in what I’m sending, my query is basically copying from the Inputs to the Outputs. One is to get the events to Table Storage and the other to get it to Power BI. Therefore the query looks like this.

Stream Analytics Query.PNG
Azure Stream Analytics Query

Events in Table Storage

After sending through some events I could see rows being added to Table Storage. When I added an additional column to the data the schema-less Table Storage obliged and dynamically added another column to the table.

Table Storage.PNG
Table Storage Events

A full record looks like this.

Full Record.PNG
Voice Search Table Storage Audit Record

Events in Power BI

Just like in Table Storage, in Power BI I could see the dataset and the table with the event data. I could create a report with some nice visuals just as you would with any other dataset. When I added an additional field to the event being sent from the IoT Device it magically showed up in the Power BI Dataset Table.

PowerBI.PNG
PowerBI Voice Search Analytics

Summary

Using the Azure IoT Hub REST API I can easily send information from my IoT Device and then have it processed through Stream Analytics into Table Storage and Power BI. Instant auditing and reporting functionality.

Let me know what you think on twitter @darrenjrobinson

Sending Events from IoT Devices to Azure IoT Hub using HTTPS and REST

Overview

Different IoT Devices have different capabilities. Whether it is a Micro-controller or Single Board Computer your options will vary. In this post I detailed using MQTT to send messages from an IoT Device to an Azure IoT Hub as well as using the AzureIoT PowerShell Module.

For a current project I needed to send the events from an IoT Device that runs Linux and had Python support. The Azure IoT Hub includes an HTTPS REST endpoint. For this particular application using the HTTPS REST endpoint is going to be much easier than compiling the Azure SDK for the particular flavour of Linux running on my device.

Python isn’t my language of choice so first I got it working in PowerShell then converted it to Python. I detail both scripts here as a guide for anyone else trying to do something similar but also for myself as I know I’m going to need these snippets in the future.

Prerequisites

You’ll need to have configured an;

Follow this post to get started.

PowerShell Device to Cloud Events using HTTPS and REST Script

Here is the PowerShell version of the script. Update Line 3 for your DeviceID, Line 5 for your IoT Hub Name and LIne 11 for your SAS Token.

Using Device Explorer to Monitor the Device on the associated IoT Hub I can see that the message is received.

Device Explorer

Python Device to Cloud Events using HTTPS and REST Script

Here is my Python version of the same script. Again update Line 5 for your IoT DeviceID, Line 7 for your IoT Hub and Line 12 for the SAS Token.

And in Device Explorer we can see the message is received.

Device Explorer Python

Summary

When you have a device that has the ability to run Python you can use the IoT Hub HTTPS REST API to send messages from the Client to Cloud negating the need to build and compile the Azure IoT SDK to generate client libraries.

Utilising Azure Text to Speech Cognitive Services with PowerShell

Introduction

Recently I’ve been building an IoT Project that leverages Azure Cognitive Services. A couple of the services I needed to use were for converting Text to Speech and Speech to Text. The guides were pretty good from Microsoft, but not obvious for use with native¬†PowerShell. I’ve got it all working, so am documenting it for myself for the future but also to help anyone else trying to work it out.

Accessing the Cognitive Services Text to Speech API

Azure Cognitive Services Text to Speech is a great service that provides the ability as the name suggests, convert text to speech.

First you’ll need to get an API key. Head to the Cognitive Services Getting Started page and select Try Text to Speech¬†and Get API Key.¬†It will give you a trial key and 5000 transactions limited to 20 per minute. If you want to use it longer, provision a Speech to Text service using the Azure Portal.

The Script

I’m using a female voice in English for my output format. All the available output languages and genders are available here.

There are also 8 audio output formats. The two I’ve used most are raw 16khz pcm for .wav format and 16khz mp3 for MP3 output as highlighted below. The script further below is configured for MP3.

  • ssml-16khz-16bit-mono-tts
  • raw-16khz-16bit-mono-pcm
  • audio-16khz-16kbps-mono-siren
  • riff-16khz-16kbps-mono-siren
  • riff-16khz-16bit-mono-pcm
  • audio-16khz-128kbitrate-mono-mp3
  • audio-16khz-64kbitrate-mono-mp3
  • audio-16khz-32kbitrate-mono-mp3

The script below is pretty self-explanatory. Update Line 5 for your API Key, and Lines 11 and 13 if you want the output audio file to go to a different directory or filename.  The text to be converted is in line 59.

Step through it using VSCode or PowerShell ISE.

Summary

Using Azure Cognitive Services you can quickly convert text to audio. Enjoy.

 

Getting started with the Lithnet REST API for the Microsoft Identity Manager Service

Introduction

A common theme with my posts on Microsoft Identity is the extensibility of it particularly with the Lithnet tools that Ryan has released.

One such tool that I’ve used but never written about is the Lithnet REST API for the Microsoft Identity Manger Service. For a small proof of concept I’m working on I was again using this REST API and I needed to update it as Ryan has recently added some new functionality. I realised I hadn’t set it up in a while and while¬†Ryan’s documentation is very good it was written some time ago when IIS Manager looked a little different. So here is a couple of screenshots and a little extra info to get you started if you haven’t used it before to supplement Ryan’s documentation located here.

Configuring the Lithnet REST API for the Microsoft Identity Manager Service

You can download the Lithnet REST API for the FIM/MIM Service from here

If you are using the latest version of the Lithnet Rest API you will need to make sure you have .NET 4.6.1 installed. If you are running Windows Server 2012 R2 you can get it from here.

When configuring your WebSite make sure you choose .NET v4.5 Classic for the Application Pool.

WebSite AppPool Settings.PNG

The web.config must match your MIM version. Currently the latest is 4.4.1749.0 as detailed here. That therefore looks like this.

WebConfig Resource Management Version.PNG

Finally you’ll need an SSL Certificate. For development environments a Self-Signed Certificate is fine. Personally I use this Cert Generator. Make sure you put the certificate in the cert store on the machine you will be testing access with. Here’s an example of my command line for generating a cert.

Cert Generation.PNG

You could also use Lets Encrypt.

In your bindings in IIS have the Host Name match your certificate.

Bindings.PNG

If you’ve done everything right you will be able to hit the v2 endpoint help. By default with Basic Auth enabled you’ll be prompted for a username and password.

v2 EndPoint.PNG

Using PowerShell to query MIM via the Lithnet Rest API

Here is an example script to query MIM via the Lithnet MIM Rest API. Update for your credentials (Lines 2 and 3), the URL of the server running the API Endpoint (Line 11) and what you are querying for (Line 14). My script takes into account Self Signed Certs in a Development environment.

Example output from a query is shown below.

Example Output.PNG

Summary

Hopefully that helps you quickly get started with the Lithnet REST API for the FIM/MIM Service. I showed an example using PowerShell directly, but using an Azure Function is also a valid pattern. I’ve covered similar functionality in the past.
 

Exporting IoT Device Information from Azure IoT Hub(s) using PowerShell

Introduction

I have a number of Azure IoT Hubs each with a number of devices configured on them. I wanted to export the details for each IoT Device. This can’t be done via the Azure Portal (May 2018) so I looked to leverage the Azure.IoTHub New-AzureRmIotHubExportDevices cmdlet.

Now the documentation for New-AzureRmIotHubExportDevices is a little light on. When I was running the¬†New-AzureRmIotHubExportDevices I kept getting the error ‘Operation returned an invalid status code ‘InternalServerError’.

After many attempts (over weeks) I finally was able to export my IoT devices using PowerShell. The key was to generate the SAS Storage Token for the Container rather than creating a blob file to export to and generating a SAS Token for the file. Simply specify the Storage Container to export too.

Overview

My sample script below uses the latest (as of May 2018) version of the Azure.IoTHub Module (v3.1.3). It;

  • enumerates all Resource Groups in an Azure Subscription and looks for IoT Hubs and puts them into a collection
  • then iterates through each IoT Hub, creates an associated Storage Account (if one doesn’t exist)
  • Exports the IoT Devices associated with the IoT Hub to Azure Storage
  • Downloads the IoT Devices Blob File, opens it and displays through PowerShell console output the IoT Device Names and Status

Export IoT Devices 640px

To use the script you will just need to;

  • change your Subscription Name in Line 4
  • The location where you want to download the blob files too in Line 31
  • if you want to display additional info on each device or do something else with the info change line 71 accordingly

The exported file can be found using Azure Storage Explorer as shown below.

Output Blob File.PNG

And the script outputs the status to the PowerShell console as shown below.

Exported IoT Devices.PNG

The exported object contains all the details for each IoT Device as shown below in the IoT Device PSObject.

IoT Device PSObj.PNG

Summary

It is obvious once you work out how the cmdlet works. Hopefully this working example will save someone else a few hours of head scratching.

Integrating Azure IoT Devices with MongooseOS MQTT and PowerShell

Introduction and Recap

In my last post here on IoT I detailed getting started with Azure IoT Hubs and registering an IoT device and sending telemetry from the IoT Device to the Azure IoT Hub. And doing all that using PowerShell.

If you haven’t read that post or worked through those steps, stop here, work through that and then come back. This post details configuring MongooseOS to receive MQTT messages from Azure IoT which is the last mile to making the IoT Device flexible for integration with anything you can think of.

Prerequisites

The only change to my setup from the previous post is I installed the Mongoose Demo App onto my ESP8266 device. Specifically the demo-js App detailed in the application list here. Install is quick and simple on Windows using the MOS Tool. Details are here. I also enabled the Mongoose Dashboard on my Mongoose IoT Device so that I don’t have to have the IoT Device connected to my laptop when configuring and experimenting with it. Essentially check the checkbox for Dashboard when configuring the IoT Device when connected locally via a USB cable.

The rest of the configuration is using the defaults in Azure IoT with respect to MQTT.

MongooseOS MQTT Subscribe Configuration – Init.js

On your IoT Device in the MongooseOS init.js we need to configure the ability to subscribe to a MQTT topic. In the first post we were publishing to send telemetry. Now we want to receive messages from Azure IoT.

Include the following lines in your init.js configuration file and restart your IoT Device. The devices//messages/devicebound/# path for the MQTT Subscription will allow the IoT device to subscribe to messages from the Azure IoT Hub. 

// Receive MQTT Messages from Azure
MQTT.sub('devices/' + Cfg.get('device.id') + '/messages/devicebound/#', function(conn, topic, msg) {
 print('Topic:', topic, 'message:', msg);
}, null);

In order to test the configuration of the IoT Device I initially use the Device Explorer. It is available from GitHub here. The screenshot below shows me successfully sending a message to my IoT Device.

DeviceExplorer to IoT Device.PNG

From the Mongoose OS Dashboard we can inspect the Console Log and see the telemetry we are sending to the IoT Hub, but also the message we have received. Success.

Mongoose Device Log.PNG

Sending MQTT Messages from Azure IoT to MongooseOS using PowerShell

Now that we’ve verified that we have everything setup correctly let’s get to the end goal of sending messages to the IoT Device using PowerShell. Here is a little script that uses the AzureIoT Module that we used previously to assist with configuration automation, to send a message from Cloud to Device.

Update it for your Resource Group, IoTHub, DeviceID and IoTKeyName. Also the message if you feel the need (line 40).

Hello from the Cloud via PowerShell MQTT Message Received.

Cloud to Device ConsoleLog.PNG

Summary

Through the two blog posts I’ve detailed the creation of an Azure IoT Hub, registration of an IoT Device, sending telemetry from MongooseOS on the IoT Device to Azure IoT and now sending messages to the IoT Device from Azure, all via PowerShell. Now we have end to end connectivity bi-directionally, what can we do with it? Stay tuned for future posts.

Validating a Yubico YubiKeys’ One Time Password (OTP) using Single Factor Authentication and PowerShell

Multi-factor Authentication comes in many different formats. Physical tokens historically have been very common and moving forward with FIDO v2 standards will likely continue to be so for many security scenarios where soft tokens (think Authenticator Apps on mobile devices) aren’t possible.

Yubico YubiKeys are physical tokens that have a number of properties that make them desirable. They don’t use a battery (so aren’t limited to the life of the battery), they come in many differing formats (NFC, USB-3, USB-C), can hold multiple sets of credentials and support open standards for multi-factor authentication. You can checkout Yubico’s range of tokens here.

YubiKeys ship with a configuration already configured that allows them to be validated against YubiCloud. Before we configure them for a user I wanted a quick way to validate that the YubiKey was valid.¬†You can do this using Yubico’s demo webpage here but for other reasons I needed to write my own. There wasn’t any PowerShell examples anywhere, so now that I’ve worked it out, I’m posting it here.

Prerequisites

You will need a Yubikey. You will need to register and obtain a Yubico API Key using a Yubikey from here.

Validation Script

Update the following script to change line 2 for your ClientID that  you received after registering against the Yubico API above.

Running the script validates that the Key if valid.

YubiKey Validation.PNG

Re-running the submission of the same key (i.e I didn’t generate a new OTP) gets the expected response that the Request is Replayed.

YubiKey Validation Failed.PNG

Summary

Using PowerShell we can negate the need to leverage any Yubico client libraries and validate a YubiKey against YubiCloud.

 

Commanding your Philips Hue lights with PowerShell

A couple of years ago I bought a number of Philips Hue bulbs and put them in the living areas of my house. Typically we control them via the Hue App on our phones, or via the Google Assistant. This all works very well, but of course I’m a techie and have a bunch of other Internet of Things devices and it would be great to integrate the Hue lights with those.

This post is the first in doing that integration. Setting up access to the Philips Hue Bridge and manipulating the lights. For ease of initial experimentation I’m using PowerShell to perform the orchestration. The API calls can easily be transposed to any other language as they are simple web requests.

Prerequisites

First you will need to have your Philips Hue lights setup with your Philips Hue Bridge. Test the lights are all working via the Philips Hue mobile app.

Locate the IP address of your Philips Hue Bridge. I found mine easily via my Unifi console and you should be able to get it via your home router.

Getting Started

Navigate to your Philips Hue Bridge using a browser and its IP Address. You will see a splash screen with a list of the open source modules that it utilises. Now append the IP Address with /debug/clip.html For me that is;

http://192.168.1.124/debug/clip.html

Create an Account

The Rest API takes a JSON payload. We can quickly create that in the API Debugger. See my example body below and change the URL to /api. Whilst pressing the button on the top of your Philips Hue Bridge select the POST button. This will create an account that you can then use to orchestrate your hue lights.

{“devicetype”:”AzureFunction#iphone Darren”}

Create Philips Hue User.PNG

Via the API we’ve just created an account. Copy the username from the response. We’ll need this for the API calls.

Test Connection

Change the URL in the debugger as shown below and clear the Message Body. Select GET and you should get returned the light(s) connected to your Philip Hue Bridge.

http:///api//lights

Lights.PNG

Controlling a Light

I have many lights. In our kitchen we have three pendant lights in a row that are all Philips Hue lights. I’m going to start by testing with one of them. Choosing one from the list from the response above Light 5 should be the middle light. The command is:

http://<yourHueBridge/api//lights//state

In the body put On and True to turn on. False would be to turn it off. Select PUT. My light turned on. Updating the message body to false and pressing PUT turned it off.

Turn Light On.PNG

Using PowerShell to Manage a Philips Hue Light

Now lets manipulate the Hue Light using PowerShell now that we have an account and know the light we want to manage.

Update the following test script for the IP address of your Philips Hue Bridge, the light number you wish to control and the username you got when you performed the enablement steps earlier. The script will then get the current status of the light and reverse it (turn OFF if it was ON and ON if it was OFF).

Flipping the state of a light

If you have configured everything correctly your light will change and you will get a success reply and the state it transitioned too.

Reverse Light State.PNG

Controlling Multiple Lights

Now let’s do that for multiple lights. In my kitchen we have 3 drop lights over the counter bench. Lets control all three of those. I created a collection of the light numbers, then iterate through each one and flip its state. NOTE: you can also control multiple lights through the Groups method. I won’t be covering that though

I had one set in an inverse state to the other two before I started, to show each is individually updated.

Reverse Multiple Lights State.PNG

Controlling Multiple Lights and Changing Colors

Now lets change the color. Turn the lights on if they aren’t already and make the color PINK.

As you can see, iterating through the lights the script turns them on and makes them Pink.

Turn Lights On and make them PINK.PNG

Finally, effects for multiple lights

Now lets turn on all the lights, and set them to use the color loop effect (transition through the color spectrum) for 15 seconds then make them all pink.

The lights transition through the color spectrum for 15 seconds then the effect is turned off and the color is set to pink.

Turn Lights On Color Effect and make them PINK.PNG

Summary

We created an account on the Philips Hue Bridge, were able to enumerate the lights that we have and then orchestrate them via PowerShell.

Here is a short video showing three lights being turned on, changing color and iterating through the color spectrum then setting them Pink.

Now to integrate them with other IoT Devices.