Get started with device management (.NET)

Back-end apps can use Azure IoT Hub primitives, such as device twins and direct methods, to remotely start and monitor device management actions on devices. This article shows you how a back-end app and a device app can work together to initiate and monitor a remote device reboot using IoT Hub.

Note

The features described in this article are available only in the standard tier of IoT Hub. For more information about the basic and standard/free IoT Hub tiers, see Choose the right IoT Hub tier for your solution.

Use a direct method to initiate device management actions (such as reboot, factory reset, and firmware update) from a back-end app in the cloud. The device is responsible for:

  • Handling the method request sent from IoT Hub.

  • Initiating the corresponding device-specific action on the device.

  • Providing status updates through reported properties to IoT Hub.

You can use a back-end app in the cloud to run device twin queries to report on the progress of your device management actions.

This article shows you how to create:

  • SimulateManagedDevice: a simulated device app with a direct method that reboots the device and reports the last reboot time. Direct methods are invoked from the cloud.

  • TriggerReboot: a .NET console app that calls the direct method in the simulated device app through your IoT hub. It displays the response and updated reported properties.

Prerequisites

  • Visual Studio.

  • An IoT hub in your Azure subscription. If you don't have a hub yet, you can follow the steps in Create an IoT hub.

  • A device registered in your IoT hub. If you don't have a device in your IoT hub, follow the steps in Register a device.

  • Make sure that port 8883 is open in your firewall. The device sample in this article uses MQTT protocol, which communicates over port 8883. This port may be blocked in some corporate and educational network environments. For more information and ways to work around this issue, see Connecting to IoT Hub (MQTT).

Create a device app with a direct method

In this section, you:

  • Create a .NET console app that responds to a direct method called by the cloud.

  • Trigger a simulated device reboot.

  • Use the reported properties to enable device twin queries to identify devices and when they were last rebooted.

Important

This article includes steps to connect a device using a shared access signature, also called symmetric key authentication. This authentication method is convenient for testing and evaluation, but authenticating a device using X.509 certificates is a more secure approach. To learn more, see Security best practices > Connection security.

To create the simulated device app, follow these steps:

  1. Open Visual Studio and select Create a new project, then find and select the Console App (.NET Framework) project template, then select Next.

  2. In Configure your new project, name the project SimulateManagedDevice, then select Next.

    Screenshot that shows how to name a new Visual Studio project.

  3. Keep the default .NET Framework version, then select Create.

  4. In Solution Explorer, right-click the new SimulateManagedDevice project, and then select Manage NuGet Packages.

  5. Select Browse, then search for and select Microsoft.Azure.Devices.Client. Select Install.

    Screenshot that shows how to install the Microsoft.Azure.Devices.Client package.

    This step downloads, installs, and adds a reference to the Azure IoT device SDK NuGet package and its dependencies.

  6. Add the following using statements at the top of the Program.cs file:

    using Microsoft.Azure.Devices.Client;
    using Microsoft.Azure.Devices.Shared;
    
  7. Add the following fields to the Program class. Replace the {device connection string} placeholder value with the device connection string you saw when you registered a device in the IoT Hub:

    static string DeviceConnectionString = "{device connection string}";
    static DeviceClient Client = null;
    
  8. Add the following to implement the direct method on the device:

    static Task<MethodResponse> onReboot(MethodRequest methodRequest, object userContext)
    {
        // In a production device, you would trigger a reboot 
        //   scheduled to start after this method returns.
        // For this sample, we simulate the reboot by writing to the console
        //   and updating the reported properties.
        try
        {
            Console.WriteLine("Rebooting!");
    
            // Update device twin with reboot time. 
            TwinCollection reportedProperties, reboot, lastReboot;
            lastReboot = new TwinCollection();
            reboot = new TwinCollection();
            reportedProperties = new TwinCollection();
            lastReboot["lastReboot"] = DateTime.Now;
            reboot["reboot"] = lastReboot;
            reportedProperties["iothubDM"] = reboot;
            Client.UpdateReportedPropertiesAsync(reportedProperties).Wait();
        }
        catch (Exception ex)
        {
            Console.WriteLine();
            Console.WriteLine("Error in sample: {0}", ex.Message);
        }
    
        string result = @"{""result"":""Reboot started.""}";
        return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200));
    }
    
  9. Finally, add the following code to the Main method to open the connection to your IoT hub and initialize the method listener:

    try
    {
        Console.WriteLine("Connecting to hub");
        Client = DeviceClient.CreateFromConnectionString(DeviceConnectionString, 
          TransportType.Mqtt);
    
        // setup callback for "reboot" method
        Client.SetMethodHandlerAsync("reboot", onReboot, null).Wait();
        Console.WriteLine("Waiting for reboot method\n Press enter to exit.");
        Console.ReadLine();
    
        Console.WriteLine("Exiting...");
    
        // as a good practice, remove the "reboot" handler
        Client.SetMethodHandlerAsync("reboot", null, null).Wait();
        Client.CloseAsync().Wait();
    }
    catch (Exception ex)
    {
        Console.WriteLine();
        Console.WriteLine("Error in sample: {0}", ex.Message);
    }
    
  10. In Solution Explorer, right-click your solution, and then select Set StartUp Projects.

  11. For Common Properties > Startup Project, Select Single startup project, and then select the SimulateManagedDevice project. Select OK to save your changes.

  12. Select Build > Build Solution.

Note

To keep things simple, this article does not implement any retry policy. In production code, you should implement retry policies (such as an exponential backoff), as suggested in Transient fault handling.

Get the IoT hub connection string

In this article, you create a backend service that invokes a direct method on a device. To invoke a direct method on a device through IoT Hub, your service needs the service connect permission. By default, every IoT Hub is created with a shared access policy named service that grants this permission.

To get the IoT Hub connection string for the service policy, follow these steps:

  1. In the Azure portal, select Resource groups. Select the resource group where your hub is located, and then select your hub from the list of resources.

  2. On the left-side pane of your IoT hub, select Shared access policies.

  3. From the list of policies, select the service policy.

  4. Copy the Primary connection string and save the value.

Screenshot that shows how to retrieve the connection string from your IoT Hub in the Azure portal.

For more information about IoT Hub shared access policies and permissions, see Access control and permissions.

Create a service app to trigger a reboot

In this section, you create a .NET console app, using C#, that initiates a remote reboot on a device using a direct method. The app uses device twin queries to discover the last reboot time for that device.

Important

This article includes steps to connect to a service using a shared access signature. This authentication method is convenient for testing and evaluation, but authenticating to a service with Microsoft Entra ID or managed identities is a more secure approach. To learn more, see Security best practices > Cloud security.

  1. Open Visual Studio and select Create a new project.

  2. In Create a new project, find and select the Console App (.NET Framework) project template, and then select Next.

  3. In Configure your new project, name the project TriggerReboot, then select Next.

    Screenshot that shows how to configure a new Visual Studio project.

  4. Accept the default version of the .NET Framework, then select Create to create the project.

  5. In Solution Explorer, right-click the TriggerReboot project, and then select Manage NuGet Packages.

  6. Select Browse, then search for and select Microsoft.Azure.Devices. Select Install to install the Microsoft.Azure.Devices package.

    Screenshot that shows how to install the Microsoft.Azure.Devices package.

    This step downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package and its dependencies.

  7. Add the following using statements at the top of the Program.cs file:

    using Microsoft.Azure.Devices;
    using Microsoft.Azure.Devices.Shared;
    
  8. Add the following fields to the Program class. Replace the {iot hub connection string} placeholder value with the IoT Hub connection string you copied previously in Get the IoT hub connection string.

    static RegistryManager registryManager;
    static string connString = "{iot hub connection string}";
    static ServiceClient client;
    static string targetDevice = "myDeviceId";
    
  9. Add the following method to the Program class. This code gets the device twin for the rebooting device and outputs the reported properties.

    public static async Task QueryTwinRebootReported()
    {
        Twin twin = await registryManager.GetTwinAsync(targetDevice);
        Console.WriteLine(twin.Properties.Reported.ToJson());
    }
    
  10. Add the following method to the Program class. This code initiates the reboot on the device using a direct method.

    public static async Task StartReboot()
    {
        client = ServiceClient.CreateFromConnectionString(connString);
        CloudToDeviceMethod method = new CloudToDeviceMethod("reboot");
        method.ResponseTimeout = TimeSpan.FromSeconds(30);
    
        CloudToDeviceMethodResult result = await 
          client.InvokeDeviceMethodAsync(targetDevice, method);
    
        Console.WriteLine("Invoked firmware update on device.");
    }
    
  11. Finally, add the following lines to the Main method:

    registryManager = RegistryManager.CreateFromConnectionString(connString);
    StartReboot().Wait();
    QueryTwinRebootReported().Wait();
    Console.WriteLine("Press ENTER to exit.");
    Console.ReadLine();
    
  12. Select Build > Build Solution.

Note

This article performs only a single query for the device's reported properties. In production code, we recommend polling to detect changes in the reported properties.

Run the apps

You're now ready to run the apps.

  1. To run the .NET device app SimulateManagedDevice, in Solution Explorer, right-click the SimulateManagedDevice project, select Debug, and then select Start new instance. The app should start listening for method calls from your IoT hub.

  2. After that the device is connected and waiting for method invocations, right-click the TriggerReboot project, select Debug, and then select Start new instance.

    You should see Rebooting written in the SimulatedManagedDevice console and the reported properties of the device, which include the last reboot time, written in the TriggerReboot console.

    Service and device app run

Customize and extend the device management actions

Your IoT solutions can expand the defined set of device management patterns or enable custom patterns by using the device twin and cloud-to-device method primitives. Other examples of device management actions include factory reset, firmware update, software update, power management, network and connectivity management, and data encryption.

Device maintenance windows

Typically, you configure devices to perform actions at a time that minimizes interruptions and downtime. Device maintenance windows are a commonly used pattern to define the time when a device should update its configuration. Your back-end solutions can use the desired properties of the device twin to define and activate a policy on your device that enables a maintenance window. When a device receives the maintenance window policy, it can use the reported property of the device twin to report the status of the policy. The back-end app can then use device twin queries to attest to compliance of devices and each policy.

Next steps

In this article, you used a direct method to trigger a remote reboot on a device. You used the reported properties to report the last reboot time from the device, and queried the device twin to discover the last reboot time of the device from the cloud.

To continue getting started with IoT Hub and device management patterns such as end-to-end image-based update in Device Update for Azure IoT Hub article using the Raspberry Pi 3 B+ Reference Image.

To learn how to extend your IoT solution and schedule method calls on multiple devices, see Schedule and broadcast jobs.