Introduction
In this article, we'll learn about the capabilities that Microsoft Azure provides to help us get our devices connected to the cloud. We'll start things off by looking at the device provisioning process at a high level. We'll learn about the roles involved, as well as the steps that need to be performed. We'll move on to looking at the solution Microsoft Azure provides for dealing with device provisioning challenges, Azure IoT Hub Device Provisioning Service. We'll learn about the core capabilities that this service provides, and see how these capabilities can help us streamline our device provisioning process. For a device to connect to our hub, our device needs some way to uniquely, securely identify itself. We'll look at the various methods that the Device Provisioning Service supports. Finally, we'll work together to create, configure, and use an instance of the Device Provisioning Service using a virtual device application that I've already created for you. Let's get started.
Road map
- Azure IoT hub device provisioning system setup
- Configuring Azure IoT Hub DPS
- Creating an individual enrollment
- Auto-provisioning a device
Prerequisites
An existing Azure IoT Hub service in the same resource group as our Device Provisioning Service. You can find the method of creating an IoT hub here.
Azure IoT hub DPS setup
I'm going to start by going to the Azure portal to create a new instance of the device provisioning service. Let's start by going to our resource group and let's add a new resource. We want to add a device provisioning service. Let's quickly create and now we can configure our service.

Click on create and you will be directed to the service creation screen. Enter all the relevant information for the service. Make sure the resource group is the same as that of our IoT Hub Click. Click on Create.

Configuring Azure IoT hub DPS
Now that we have our service, we need to tell it about which IoT hub or hubs we want to use. We just finished creating our device provisioning service. If you don't see it on your dashboard, you can get to it by going to your resource groups and drilling into the resource group that contains our service. Now what we need to do is link it to the IoT that we have that we already created. We can do that by going to (Our DPS ) > Linked IoT Hubs.

After that click the add button and then we can choose our existing hub.

I do want to point out that we can link any hub from our subscription or any subscription we have access to you. It doesn't even have to be in the same region we chose for our device provisioning service. We also need to choose an access policy. We could define a custom policy, but the built-in IoT owner policy will work just fine. Our IoT device provisioning service and our hub are now linked. That means it's time to enroll a device.
Creating an individual enrollment
Now that we have a hub, and we have an instance of the Device Provisioning Service, that means we're ready to enroll a device. We are going to enroll a device manually. In a real solution, we would either enroll a trusted root certificate, which would allow any device signed by that certificate to be enrolled, or we would provide our device manufacturer with some automated mechanism for uploading device identities once they've been extracted from the physical hardware. You will need the. NET Core SDK version 2 or greater if you want to implement the code.
You will need to create a .Net Core project, which will have a Program.cs, and add 2 files, name one Device.cs and the other CertificateFactory.cs.
Program.cs code
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
namespace DeviceProvisioningSample
{
class Program
{
static async Task Main(string[] args)
{
if (args == null || args.Length < 1)
{
Console.WriteLine("You must specify an action!");
return;
}
if (args[0] == "setup")
{
CertificateFactory.CreateTestCert();
}
else
{
var scopeId = args[0];
var device = new Device(scopeId);
await device.Provision();
await device.ConnectAndRun();
}
}
}
}
Device.cs code
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.Devices.Provisioning.Client;
using Microsoft.Azure.Devices.Provisioning.Client.Transport;
using Microsoft.Azure.Devices.Shared;
using Microsoft.Azure.Devices.Client;
namespace DeviceProvisioningSample
{
public class Device
{
private string scopeId;
private string assignedHub;
private DeviceAuthenticationWithX509Certificate auth;
public Device(string scopeId)
{
this.scopeId = scopeId;
}
public async Task Provision()
{
var certificate = LoadPrivateKey("key.pfx");
using (var securityProvider = new SecurityProviderX509Certificate(certificate))
using (var transport = new ProvisioningTransportHandlerAmqp(TransportFallbackType.TcpOnly))
{
var client = ProvisioningDeviceClient.Create("global.azure-devices-provisioning.net", this.scopeId, securityProvider, transport);
var result = await client.RegisterAsync();
Console.WriteLine($"Provisioning result: {result.Status}");
if (result.Status != ProvisioningRegistrationStatusType.Assigned)
{
throw new InvalidOperationException("Something went wrong while trying to provision.");
}
this.assignedHub = result.AssignedHub;
this.auth = new DeviceAuthenticationWithX509Certificate(result.DeviceId, securityProvider.GetAuthenticationCertificate());
}
}
private static X509Certificate2 LoadPrivateKey(string key)
{
if (!File.Exists(key))
{
Console.WriteLine("No private key found. Execute `dotnet run setup` first.");
Environment.Exit(-1);
}
var certificateCollection = new X509Certificate2Collection();
certificateCollection.Import(key);
foreach (var element in certificateCollection)
{
if (element.HasPrivateKey)
{
return element;
}
else
{
element.Dispose();
}
}
throw new InvalidOperationException("No private key found. Execute `dotnet run setup` first.");
}
internal async Task ConnectAndRun()
{
using (var client = DeviceClient.Create(this.assignedHub, this.auth, TransportType.Amqp))
{
Console.Write($"Connecting to hub: {this.assignedHub}... ");
await client.OpenAsync();
Console.WriteLine("Connected!");
Console.Write("Sending D2C message... ");
await client.SendEventAsync(new Message(Encoding.UTF8.GetBytes("Hello from a provisioned device!")));
Console.WriteLine("Sent!");
Console.Write("Closing connection... ");
await client.CloseAsync();
Console.WriteLine("Connection Closed!");
}
}
}
}










Matias EzequielPosted Jun 17, 2020, 11:24 AM
Nice article; but im running into an issue, when i run the app with the ID scope im gettin an "Unauthorized" message and i cant register the device into the iot hub
suri surendraPosted Apr 22, 2020, 7:24 AM
Hi Usman, Article was very good can you please provide sample .net core project.
Chittaranjan SwainPosted Dec 11, 2019, 11:23 PM
Nice article.