title | description | author | ms.author | ms.date | ms.topic | ms.service | services | zone_pivot_groups | ms.custom |
---|---|---|---|---|---|---|---|---|---|
Quickstart - Provision a simulated TPM device to Microsoft Azure IoT Hub |
Quickstart - Learn how to provision a TPM simulated device to the Azure IoT Hub Device Provisioning Service |
kgremban |
kgremban |
12/14/2021 |
quickstart |
iot-dps |
iot-dps |
iot-dps-set1 |
mvc, amqp, mqtt, mode-other |
In this quickstart, you'll create a simulated device on your Windows machine. The simulated device will be configured to use a Trusted Platform Module (TPM) attestation mechanism for authentication. After you've configured your device, you'll provision it to your IoT hub using the Azure IoT Hub Device Provisioning Service. Sample code will then be used to help enroll the device with a Device Provisioning Service instance.
If you're unfamiliar with the process of provisioning, review the provisioning overview. Also make sure you've completed the steps in Set up IoT Hub Device Provisioning Service with the Azure portal before continuing.
The Azure IoT Device Provisioning Service supports two types of enrollments:
-
Enrollment groups that are used to enroll multiple related devices.
-
Individual Enrollments that are used to enroll a single device.
This article demonstrates individual enrollments.
-
If you don't have an Azure subscription, create a free account before you begin.
-
Complete the steps in Set up IoT Hub Device Provisioning Service with the Azure portal.
The following prerequisites are for a Windows development environment. For Linux or macOS, see the appropriate section in Prepare your development environment in the SDK documentation.
::: zone pivot="programming-language-ansi-c"
- Visual Studio 2019 with the 'Desktop development with C++' workload enabled. Visual Studio 2015 and Visual Studio 2017 are also supported.
::: zone-end
::: zone pivot="programming-language-csharp"
-
A TPM 2.0 hardware security module on your Windows-based machine.
-
Install .NET Core SDK 6.0 or later on your Windows-based machine. You can use the following command to check your version.
dotnet --info
::: zone-end
::: zone pivot="programming-language-nodejs"
- Install Node.js v4.0+.
::: zone-end
::: zone pivot="programming-language-python"
-
Install Python 2.x or 3.x. Make sure to use the 32-bit or 64-bit installation as required by your setup. When prompted during the installation, make sure to add Python to your platform-specific environment variables.
-
If you're using Windows OS, install the Visual C++ redistributable package to allow the use of native DLLs from Python.
-
Visual Studio 2019 with the 'Desktop development with C++' workload enabled. Visual Studio 2015 and Visual Studio 2017 are also supported.
::: zone-end
::: zone pivot="programming-language-java"
-
Install Java SE Development Kit 8 or later installed on your machine.
-
Download and install Maven.
::: zone-end
- Install the latest version of Git. Make sure that Git is added to the environment variables accessible to the command window. See Software Freedom Conservancy's Git client tools for the latest version of
git
tools to install, which includes Git Bash, the command-line app that you can use to interact with your local Git repository.
::: zone pivot="programming-language-ansi-c"
In this section, you'll prepare a development environment used to build the Azure IoT C SDK and the TPM device simulator sample.
-
Download the latest CMake build system.
[!IMPORTANT] Confirm that the Visual Studio prerequisites (Visual Studio and the 'Desktop development with C++' workload) are installed on your machine, before starting the
CMake
installation. Once the prerequisites are in place, and the download is verified, install the CMake build system. Also, be aware that older versions of the CMake build system fail to generate the solution file used in this article. Make sure to use the latest version of CMake. -
Open a web browser, and go to the Release page of the Azure IoT C SDK.
-
Select the Tags tab at the top of the page.
-
Copy the tag name for the latest release of the Azure IoT C SDK.
-
Open a command prompt or Git Bash shell. Run the following commands to clone the latest release of the Azure IoT C SDK GitHub repository. (replace
<release-tag>
with the tag you copied in the previous step).git clone -b <release-tag> https://github.com/Azure/azure-iot-sdk-c.git cd azure-iot-sdk-c git submodule update --init
This operation could take several minutes to complete.
-
When the operation is complete, run the following commands from the
azure-iot-sdk-c
directory:mkdir cmake cd cmake
::: zone-end
::: zone pivot="programming-language-csharp"
-
Open a Git CMD or Git Bash command-line environment.
-
Clone the Azure IoT Samples for C# GitHub repository using the following command:
git clone https://github.com/Azure-Samples/azure-iot-samples-csharp.git
::: zone-end
::: zone pivot="programming-language-nodejs"
-
Open a Git CMD or Git Bash command-line environment.
-
Clone the azure-utpm-c GitHub repository using the following command:
git clone https://github.com/Azure/azure-utpm-c.git --recursive
::: zone-end
::: zone pivot="programming-language-python"
-
Open a Git CMD or Git Bash command-line environment.
-
Clone the Python GitHub repository using the following command:
git clone --single-branch --branch v1-deprecated https://github.com/Azure/azure-iot-sdk-python.git --recursive
-
Create a folder in your local copy of this GitHub repo for the CMake build process.
cd azure-iot-sdk-python/c mkdir cmake cd cmake
-
Follow these instructions to build the Python packages.
[!NOTE] If running the
build_client.cmd
make sure to use the--use-tpm-simulator
flag.[!NOTE] If using
pip
make sure to also install theazure-iot-provisioning-device-client
package. Note that the released PIP packages are using the real TPM, not the simulator. To use the simulator you need to compile from the source using the--use-tpm-simulator
flag.
::: zone-end
::: zone pivot="programming-language-java"
-
Open a Git CMD or Git Bash command-line environment.
-
Clone the Java GitHub repository using the following command:
git clone https://github.com/Azure/azure-iot-sdk-java.git --recursive
::: zone-end
::: zone pivot="programming-language-ansi-c, programming-language-nodejs, programming-language-python, programming-language-java"
In this section, you'll build and run the TPM simulator. This simulator listens over a socket on ports 2321 and 2322. Do not close the command window. You'll need to keep this simulator running until the end of this quickstart.
::: zone-end
::: zone pivot="programming-language-ansi-c"
-
Run the following command to build Azure IoT C SDK that includes the TPM device simulator sample code. A Visual Studio solution for the simulated device is generated in the
cmake
directory. This sample provides a TPM attestation mechanism via Shared Access Signature (SAS) Token authentication.cmake -Duse_prov_client:BOOL=ON -Duse_tpm_simulator:BOOL=ON ..
[!TIP] If
cmake
does not find your C++ compiler, you may get build errors while running the above command. If that happens, try running the command in the Visual Studio command prompt. -
When the build succeeds, the last few output lines look similar to the following output:
$ cmake -Duse_prov_client:BOOL=ON .. -- Building for: Visual Studio 16 2019 -- The C compiler identification is MSVC 19.23.28107.0 -- The CXX compiler identification is MSVC 19.23.28107.0 ... -- Configuring done -- Generating done -- Build files have been written to: C:/code/azure-iot-sdk-c/cmake
-
Go to the root folder of the git repository you cloned.
-
Run the TPM simulator using the path shown below.
cd .. .\provisioning_client\deps\utpm\tools\tpm_simulator\Simulator.exe
The simulator doesn't display any output. Let it continue to run as it simulates a TPM device.
::: zone-end
::: zone pivot="programming-language-nodejs"
-
Go to the GitHub root folder.
-
Run the TPM simulator to be the HSM for the simulated device.
.\azure-utpm-c\tools\tpm_simulator\Simulator.exe
-
Create a new empty folder called registerdevice. In the registerdevice folder, create a package.json file using the following command at your command prompt(make sure to answer all questions asked by
npm
or accept the defaults if they suit you):npm init
-
Install the following precursor packages:
npm install node-gyp -g npm install ffi -g
[!NOTE] There are some known issues to installing the above packages. To resolve these issues, run
npm install --global --production windows-build-tools
using a command prompt in Run as administrator mode, runSET VCTargetsPath=C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140
after replacing the path with your installed version, and then rerun the above installation commands. -
Install all required packages running the following command at your command prompt in the registerdevice folder:
npm install --save azure-iot-device azure-iot-device-mqtt azure-iot-security-tpm azure-iot-provisioning-device-http azure-iot-provisioning-device
The command installs the following packages:
-
A security client that works with TPM:
azure-iot-security-tpm
-
A transport for the device to connect to the Device Provisioning Service: either
azure-iot-provisioning-device-http
orazure-iot-provisioning-device-amqp
-
A client to use the transport and security client:
azure-iot-provisioning-device
-
The device client:
azure-iot-device
-
A transport: any of
azure-iot-device-amqp
,azure-iot-device-mqtt
, orazure-iot-device-http
-
The security client that you already installed:
azure-iot-security-tpm
[!NOTE] The samples in this quickstart use the
azure-iot-provisioning-device-http
andazure-iot-device-mqtt
transports.
-
-
Open a text editor of your choices.
-
In the registerdevice folder, create a new ExtractDevice.js file.
-
Add the following
require
statements at the start of the ExtractDevice.js file:'use strict'; var tpmSecurity = require('azure-iot-security-tpm'); var tssJs = require("tss.js"); var myTpm = new tpmSecurity.TpmSecurityClient(undefined, new tssJs.Tpm(true));
-
Add the following function to implement the method:
myTpm.getEndorsementKey(function(err, endorsementKey) { if (err) { console.log('The error returned from get key is: ' + err); } else { console.log('the endorsement key is: ' + endorsementKey.toString('base64')); myTpm.getRegistrationId((getRegistrationIdError, registrationId) => { if (getRegistrationIdError) { console.log('The error returned from get registration id is: ' + getRegistrationIdError); } else { console.log('The Registration Id is: ' + registrationId); process.exit(); } }); } });
-
Save and close the ExtractDevice.js file.
node ExtractDevice.js
-
Run the sample.
-
The output window displays the Endorsement key and the Registration ID needed for device enrollment. Copy these values.
::: zone-end
::: zone pivot="programming-language-python"
-
Run the following command to enable the SAS token authentication (the command also generates a Visual Studio solution for the simulated device):
cmake -Duse_prov_client:BOOL=ON -Duse_tpm_simulator:BOOL=ON ..
-
Open a second command prompt.
-
In the second command prompt, navigate to the TPM simulator folder.
-
Run the TPM simulator to be the HSM for the simulated device.
-
Select Allow Access. The simulator listens over a socket on ports 2321 and 2322. Do not close this command window; you will need to keep this simulator running until the end of this quickstart guide.
.\azure-iot-sdk-python\c\provisioning_client\deps\utpm\tools\tpm_simulator\Simulator.exe
::: zone-end
::: zone pivot="programming-language-java"
-
Run the TPM simulator to be the HSM for the simulated device.
-
Select Allow Access. The simulator listens over a socket on ports 2321 and 2322. Do not close this command window; you will need to keep this simulator running until the end of this quickstart guide.
.\azure-iot-sdk-java\provisioning\provisioning-tools\tpm-simulator\Simulator.exe
-
Open a second command prompt.
-
In the second command prompt, navigate to the root folder and build the sample dependencies.
cd azure-iot-sdk-java mvn install -DskipTests=true
-
Navigate to the sample folder.
cd provisioning/provisioning-samples/provisioning-tpm-sample
::: zone-end
::: zone pivot="programming-language-ansi-c, programming-language-csharp, programming-language-python, programming-language-java"
::: zone-end
::: zone pivot="programming-language-ansi-c, programming-language-python, programming-language-java"
In this section, you'll build and execute a sample that reads the endorsement key and registration ID from the TPM simulator you left running, and is still listening over ports 2321 and 2322. These values will be used for device enrollment with your Device Provisioning Service instance.
::: zone-end
::: zone pivot="programming-language-ansi-c"
-
Launch Visual Studio.
-
Open the solution generated in the cmake folder named
azure_iot_sdks.sln
. -
On the Visual Studio menu, select Build > Build Solution to build all projects in the solution.
-
In Visual Studio's Solution Explorer window, navigate to the Provision_Tools folder. Right-click the tpm_device_provision project and select Set as Startup Project.
-
On the Visual Studio menu, select Debug > Start without debugging to run the solution. The app reads and displays a Registration ID and an Endorsement key. Note or copy these values. These will be used in the next section for device enrollment.
::: zone-end
::: zone pivot="programming-language-python"
-
Launch Visual Studio.
-
Open the solution generated in the cmake folder named
azure_iot_sdks.sln
. -
On the Visual Studio menu, select Build > Build Solution to build all projects in the solution.
-
Right-click the tpm_device_provision project and select Set as Startup Project.
-
Run the solution. The output window displays the Endorsement key and the Registration ID needed for device enrollment. Copy these values.
::: zone-end
::: zone pivot="programming-language-java"
-
Sign in to the Azure portal, select the All resources button on the left-hand menu and open your Device Provisioning Service. Note your ID Scope and Provisioning Service Global Endpoint.
-
Edit
src/main/java/samples/com/microsoft/azure/sdk/iot/ProvisioningTpmSample.java
to include your ID Scope and Provisioning Service Global Endpoint as noted before.private static final String idScope = "[Your ID scope here]"; private static final String globalEndpoint = "[Your Provisioning Service Global Endpoint here]"; private static final ProvisioningDeviceClientTransportProtocol PROVISIONING_DEVICE_CLIENT_TRANSPORT_PROTOCOL = ProvisioningDeviceClientTransportProtocol.HTTPS;
-
Save the file.
-
Use the following commands to build the project, navigate to the target folder, and execute the created .jar file (replace
{version}
with your version of Java):mvn clean install cd target java -jar ./provisioning-tpm-sample-{version}-with-deps.jar
-
When the program begins running, it will display the Endorsement key and Registration ID. Copy these values for the next section. Make sure to leave the program running.
::: zone-end
::: zone pivot="programming-language-csharp"
In this section, you'll build and execute a sample that reads the endorsement key from your TPM 2.0 hardware security module. This value will be used for device enrollment with your Device Provisioning Service instance.
-
In a command prompt, change directories to the project directory for the TPM device provisioning sample.
cd .\azure-iot-samples-csharp\provisioning\Samples\device\TpmSample
-
Type the following command to build and run the TPM device provisioning sample. Copy the endorsement key returned from your TPM 2.0 hardware security module to use later when enrolling your device.
dotnet run -- -e
::: zone-end
::: zone pivot="programming-language-ansi-c, programming-language-nodejs, programming-language-python, programming-language-java"
-
Sign in to the Azure portal.
-
On the left-hand menu or on the portal page, select All resources.
-
Select your Device Provisioning Service.
-
In the Settings menu, select Manage enrollments.
-
At the top of the page, select + Add individual enrollment.
-
In the Add Enrollment panel, enter the following information:
-
Select TPM as the identity attestation Mechanism.
-
Enter the Registration ID and Endorsement key for your TPM device from the values you noted previously.
-
Select an IoT hub linked with your provisioning service.
-
Optionally, you may provide the following information:
- Enter a unique Device ID (you can use the suggested test-docs-device or provide your own). Make sure to avoid sensitive data while naming your device. If you choose not to provide one, the registration ID will be used to identify the device instead.
- Update the Initial device twin state with the desired initial configuration for the device.
-
Once complete, press the Save button.
-
-
Select Save.
::: zone-end
::: zone pivot="programming-language-csharp"
-
Sign in to the Azure portal.
-
On the left-hand menu or on the portal page, select All resources.
-
Select your Device Provisioning Service.
-
In the Settings menu, select Manage enrollments.
-
At the top of the page, select + Add individual enrollment.
-
In the Add Enrollment panel, enter the following information:
-
Select TPM as the identity attestation Mechanism.
-
Enter the Endorsement key you retrieved earlier from your HSM.
-
Enter a unique Registration ID for your device. You will also use this registration ID when registering your device, so make a note of it for later.
-
Select an IoT hub linked with your provisioning service.
-
Optionally, you may provide the following information:
- Enter a unique Device ID (you can use the suggested test-docs-device or provide your own). Make sure to avoid sensitive data while naming your device. If you choose not to provide one, the registration ID will be used to identify the device instead.
- Update the Initial device twin state with the desired initial configuration for the device.
-
Once complete, press the Save button.
-
-
Select Save.
::: zone-end
In this section, you'll configure sample code to use the Advanced Message Queuing Protocol (AMQP) to send the device's boot sequence to your Device Provisioning Service instance. This boot sequence causes the device to be registered to an IoT hub linked to the Device Provisioning Service instance.
::: zone pivot="programming-language-ansi-c"
-
In the Azure portal, select the Overview tab for your Device Provisioning Service.
-
Copy the ID Scope value.
-
In Visual Studio's Solution Explorer window, navigate to the Provision_Samples folder. Expand the sample project named prov_dev_client_sample. Expand Source Files, and open prov_dev_client_sample.c.
-
Near the top of the file, find the
#define
statements for each device protocol as shown below. Make sure onlySAMPLE_AMQP
is uncommented.Currently, the MQTT protocol is not supported for TPM Individual Enrollment.
// // The protocol you wish to use should be uncommented // //#define SAMPLE_MQTT //#define SAMPLE_MQTT_OVER_WEBSOCKETS #define SAMPLE_AMQP //#define SAMPLE_AMQP_OVER_WEBSOCKETS //#define SAMPLE_HTTP
-
Find the
id_scope
constant, and replace the value with your ID Scope value that you copied earlier.static const char* id_scope = "0ne00002193";
-
Find the definition for the
main()
function in the same file. Make sure thehsm_type
variable is set toSECURE_DEVICE_TYPE_TPM
as shown below.SECURE_DEVICE_TYPE hsm_type; hsm_type = SECURE_DEVICE_TYPE_TPM; //hsm_type = SECURE_DEVICE_TYPE_X509; //hsm_type = SECURE_DEVICE_TYPE_SYMMETRIC_KEY;
-
Right-click the prov_dev_client_sample project and select Set as Startup Project.
-
On the Visual Studio menu, select Debug > Start without debugging to run the solution. In the prompt to rebuild the project, select Yes, to rebuild the project before running.
The following output is an example of the provisioning device client sample successfully booting up, and connecting to a Device Provisioning Service instance to get IoT hub information and registering:
Provisioning API Version: 1.2.7 Registering... Press enter key to interrupt. Provisioning Status: PROV_DEVICE_REG_STATUS_CONNECTED Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING Registration Information received from service: test-docs-hub.azure-devices.net, deviceId: test-docs-cert-device
::: zone-end
::: zone pivot="programming-language-csharp"
-
In the Azure portal, select the Overview tab for your Device Provisioning Service.
-
Copy the ID Scope value.
-
In a command prompt, change directories to the project directory for the TPM device provisioning sample.
cd .\azure-iot-samples-csharp\provisioning\Samples\device\TpmSample
-
Run the following command to register your device. Replace
<IdScope>
with the value for the DPS you just copied and<RegistrationId>
with the value you used when creating the device enrollment.dotnet run -- -s <IdScope> -r <RegistrationId>
If the device registration was successful, you'll see the following messages:
Initializing security using the local TPM... Initializing the device provisioning client... Initialized for registration Id <RegistrationId>. Registering with the device provisioning service... Registration status: Assigned. Device <RegistrationId> registered to <HubName>.azure-devices.net. Creating TPM authentication for IoT Hub... Testing the provisioned device with IoT Hub... Sending a telemetry message... Finished.
::: zone-end
::: zone pivot="programming-language-nodejs"
-
In the Azure portal, select the Overview tab for your Device Provisioning Service.
-
Copy the ID Scope value.
-
Open a text editor of your choice.
-
In the registerdevice folder, create a new RegisterDevice.js file.
-
Add the following
require
statements at the start of the RegisterDevice.js file:'use strict'; var ProvisioningTransport = require('azure-iot-provisioning-device-http').Http; var iotHubTransport = require('azure-iot-device-mqtt').Mqtt; var Client = require('azure-iot-device').Client; var Message = require('azure-iot-device').Message; var tpmSecurity = require('azure-iot-security-tpm'); var ProvisioningDeviceClient = require('azure-iot-provisioning-device').ProvisioningDeviceClient;
[!NOTE] The Azure IoT SDK for Node.js supports additional protocols like AMQP, AMQP WS, and MQTT WS. For more examples, see Device Provisioning Service SDK for Node.js samples.
-
Add globalDeviceEndpoint and idScope variables and use them to create a ProvisioningDeviceClient instance. Replace {globalDeviceEndpoint} and {idScope} with the Global Device Endpoint and ID Scope values from Step 1:
var provisioningHost = '{globalDeviceEndpoint}'; var idScope = '{idScope}'; var tssJs = require("tss.js"); var securityClient = new tpmSecurity.TpmSecurityClient('', new tssJs.Tpm(true)); // if using non-simulated device, replace the above line with following: //var securityClient = new tpmSecurity.TpmSecurityClient(); var provisioningClient = ProvisioningDeviceClient.create(provisioningHost, idScope, new ProvisioningTransport(), securityClient);
-
Add the following function to implement the method on the device:
provisioningClient.register(function(err, result) { if (err) { console.log("error registering device: " + err); } else { console.log('registration succeeded'); console.log('assigned hub=' + result.registrationState.assignedHub); console.log('deviceId=' + result.registrationState.deviceId); var tpmAuthenticationProvider = tpmSecurity.TpmAuthenticationProvider.fromTpmSecurityClient(result.registrationState.deviceId, result.registrationState.assignedHub, securityClient); var hubClient = Client.fromAuthenticationProvider(tpmAuthenticationProvider, iotHubTransport); var connectCallback = function (err) { if (err) { console.error('Could not connect: ' + err.message); } else { console.log('Client connected'); var message = new Message('Hello world'); hubClient.sendEvent(message, printResultFor('send')); } }; hubClient.open(connectCallback); function printResultFor(op) { return function printResult(err, res) { if (err) console.log(op + ' error: ' + err.toString()); if (res) console.log(op + ' status: ' + res.constructor.name); process.exit(1); }; } } });
-
Save and close the RegisterDevice.js file.
-
Run the following command:
node RegisterDevice.js
-
Notice the messages that simulate the device booting and connecting to the Device Provisioning Service to get your IoT hub information.
::: zone-end
::: zone pivot="programming-language-python"
-
Navigate to the samples folder of the Git repository.
cd azure-iot-sdk-python/provisioning_device_client/samples
-
Using your Python IDE, edit the Python script named provisioning_device_client_sample.py (replace
{globalServiceEndpoint}
and{idScope}
to the values that you previously copied). Also, make sure SECURITY_DEVICE_TYPE is set toProvisioningSecurityDeviceType.TPM
.GLOBAL_PROV_URI = "{globalServiceEndpoint}" ID_SCOPE = "{idScope}" SECURITY_DEVICE_TYPE = ProvisioningSecurityDeviceType.TPM PROTOCOL = ProvisioningTransportProvider.HTTP
-
Run the sample.
python provisioning_device_client_sample.py
-
Notice the messages that simulate the device booting and connecting to the Device Provisioning Service to get your IoT hub information.
::: zone-end
::: zone pivot="programming-language-java"
-
In the command window running the Java sample code on your machine, press Enter to continue running the application. Notice the messages that simulate the device booting and connecting to the Device Provisioning Service to get your IoT hub information.
::: zone-end
-
Go to the Azure portal.
-
On the left-hand menu or on the portal page, select All resources.
-
Select the IoT hub to which your device was assigned.
-
In the Explorers menu, select IoT Devices.
-
If your device was provisioned successfully, the device ID should appear in the list, with Status set as enabled. If you don't see your device, select Refresh at the top of the page.
:::zone pivot="programming-language-ansi-c"
:::zone-end
:::zone pivot="programming-language-csharp"
::: zone-end
::: zone pivot="programming-language-nodejs"
::: zone-end
::: zone pivot="programming-language-python"
::: zone-end
::: zone pivot="programming-language-java"
::: zone-end
Note
If you changed the initial device twin state from the default value in the enrollment entry for your device, it can pull the desired twin state from the hub and act accordingly. For more information, see Understand and use device twins in IoT Hub.
If you plan to continue working on and exploring the device client sample, don't clean up the resources created in this quickstart. If you don't plan to continue, use the following steps to delete all resources created by this quickstart.
-
Close the device client sample output window on your machine.
-
From the left-hand menu in the Azure portal, select All resources.
-
Select your Device Provisioning Service.
-
In the Settings menu, select Manage enrollments.
-
Select the Individual Enrollments tab.
-
Select the check box next to the REGISTRATION ID of the device you enrolled in this quickstart.
-
At the top of the page, select Delete.
-
From the left-hand menu in the Azure portal, select All resources.
-
Select your IoT hub.
-
In the Explorers menu, select IoT devices.
-
Select the check box next to the DEVICE ID of the device you registered in this quickstart.
-
At the top of the page, select Delete.
In this quickstart, you've created a TPM simulated device on your machine and provisioned it to your IoT hub using the IoT Hub Device Provisioning Service. To learn how to enroll your TPM device programmatically, continue to the quickstart for programmatic enrollment of a TPM device.
[!div class="nextstepaction"] Quickstart - Enroll TPM device to Azure IoT Hub Device Provisioning Service