You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: articles/iot-hub/iot-hub-bulk-identity-mgmt.md
+35-64Lines changed: 35 additions & 64 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,45 +1,46 @@
1
1
---
2
-
title: Import and export Azure IoT Hub device identities
3
-
description: How to use the Azure IoT service SDK to run bulk operations against the identity registry to import and export device identities. Import operations enable you to create, update, and delete device identities in bulk.
2
+
title: Import and export device identities
3
+
titleSuffix: Azure IoT Hub
4
+
description: Use the Azure IoT service SDK to import and export device identities so that you can create, update, and delete device identities in bulk.
4
5
author: kgremban
5
6
6
7
ms.author: kgremban
7
8
ms.service: iot-hub
8
9
ms.topic: how-to
9
-
ms.date: 06/16/2023
10
+
ms.date: 01/25/2024
10
11
ms.custom: devx-track-csharp, references_regions
11
12
---
12
13
13
14
# Import and export IoT Hub device identities in bulk
14
15
15
-
Each IoT hub has an identity registry you can use to create per-device resources in the service. The identity registry also enables you to control access to the device-facing endpoints. This article describes how to import and export device identities in bulk to and from an identity registry, using the ImportExportDeviceSample sample included with the [Microsoft Azure IoT SDK for .NET](https://github.com/Azure/azure-iot-sdk-csharp/tree/main). For more information about how you can use this capability when migrating an IoT hub to a different region, see [How to manually migrate an Azure IoT hub using an Azure Resource Manager template](migrate-hub-arm.md).
16
+
Each IoT hub has an identity registry that you can use to create device resources in the service. The identity registry also enables you to control access to the device-facing endpoints. This article describes how to import and export device identities in bulk to and from an identity registry, using the ImportExportDeviceSample sample included with the [Microsoft Azure IoT SDK for .NET](https://github.com/Azure/azure-iot-sdk-csharp/tree/main). For more information about how you can use this capability when migrating an IoT hub to a different region, see [How to manually migrate an Azure IoT hub using an Azure Resource Manager template](migrate-hub-arm.md).
16
17
17
18
> [!NOTE]
18
-
> IoT Hub has recently added virtual network support in a limited number of regions. This feature secures import and export operations and eliminates the need to pass keys for authentication. Initially, virtual network support is available only in these regions: *WestUS2*, *EastUS*, and *SouthCentralUS*. To learn more about virtual network support and the API calls to implement it, see [IoT Hub Support for virtual networks](virtual-network-support.md).
19
+
> IoT Hub recently added virtual network support in a limited number of regions. This feature secures import and export operations and eliminates the need to pass keys for authentication. Currently, virtual network support is available only in these regions: *WestUS2*, *EastUS*, and *SouthCentralUS*. To learn more about virtual network support and the API calls to implement it, see [IoT Hub Support for virtual networks](virtual-network-support.md).
19
20
20
-
Import and export operations take place in the context of *Jobs* that enable you to execute bulk service operations against an IoT hub.
21
+
Import and export operations take place in the context of *jobs* that enable you to execute bulk service operations against an IoT hub.
21
22
22
23
The **RegistryManager** class in the SDK includes the **ExportDevicesAsync** and **ImportDevicesAsync** methods that use the **Job** framework. These methods enable you to export, import, and synchronize the entirety of an IoT hub identity registry.
23
24
24
-
This topic discusses using the **RegistryManager** class and **Job** system to perform bulk imports and exports of devices to and from an IoT hub's identity registry. You can also use the Azure IoT Hub Device Provisioning Service to enable zero-touch, just-in-time provisioning to one or more IoT hubs without requiring human intervention. To learn more, see the [provisioning service documentation](../iot-dps/index.yml).
25
+
This article discusses using the **RegistryManager** class and **Job** system to perform bulk imports and exports of devices to and from an IoT hub's identity registry. You can also use the Azure IoT Hub Device Provisioning Service to enable zero-touch, just-in-time provisioning to one or more IoT hubs. To learn more, see the [provisioning service documentation](../iot-dps/index.yml).
25
26
26
27
> [!NOTE]
27
28
> Some of the code snippets in this article are included from the ImportExportDevicesSample service sample provided with the [Microsoft Azure IoT SDK for .NET](https://github.com/Azure/azure-iot-sdk-csharp/tree/main). The sample is located in the `/iothub/service/samples/how to guides/ImportExportDevicesSample` folder of the SDK and, where specified, code snippets are included from the `ImportExportDevicesSample.cs` file for that SDK sample. For more information about the ImportExportDevicesSample sample and other service samples included in the Azure IoT SDK for.NET, see [Azure IoT hub service samples for C#](https://github.com/Azure/azure-iot-sdk-csharp/tree/main/iothub/service/samples/how%20to%20guides).
28
29
29
30
## What are jobs?
30
31
31
-
Identity registry operations use the **Job** system when the operation:
32
+
Identity registry operations use the job system when the operation:
32
33
33
34
* Has a potentially long execution time compared to standard run-time operations.
34
35
35
36
* Returns a large amount of data to the user.
36
37
37
-
Instead of a single API call waiting or blocking on the result of the operation, the operation asynchronously creates a **Job** for that IoT hub. The operation then immediately returns a **JobProperties** object.
38
+
Instead of a single API call waiting or blocking on the result of the operation, the operation asynchronously creates a job for that IoT hub. The operation then immediately returns a **JobProperties** object.
38
39
39
40
The following C# code snippet shows how to create an export job:
40
41
41
42
```csharp
42
-
// Call an export job on the IoT Hub to retrieve all devices
43
+
// Call an export job on the IoT hub to retrieve all devices
To find the connection string for your IoT hub, in the Azure portal:
58
59
59
-
- Navigate to your IoT hub.
60
+
1. Navigate to your IoT hub.
60
61
61
-
- Select **Shared access policies**.
62
+
1. Select **Shared access policies**.
62
63
63
-
- Select a policy, taking into account the permissions you need.
64
+
1. Select a policy, taking into account the permissions you need.
64
65
65
-
- Copy the connection string from the panel on the right-hand side of the screen.
66
+
1. Copy the connection string for that policy.
66
67
67
68
The following C# code snippet, from the **WaitForJobAsync** method in the SDK sample, shows how to poll every five seconds to see if the job has finished executing:
68
69
@@ -93,9 +94,7 @@ Only one active device import or export job is allowed at a time for all IoT Hub
93
94
94
95
## Export devices
95
96
96
-
Use the **ExportDevicesAsync** method to export the entirety of an IoT hub identity registry to an Azure Storage blob container using a shared access signature (SAS). For more information about shared access signatures, see [Grant limited access to Azure Storage resources using shared access signatures (SAS)](../storage/common/storage-sas-overview.md).
97
-
98
-
This method enables you to create reliable backups of your device information in a blob container that you control.
97
+
Use the **ExportDevicesAsync** method to export the entirety of an IoT hub identity registry to an Azure Storage blob container using a shared access signature (SAS). This method enables you to create reliable backups of your device information in a blob container that you control.
99
98
100
99
The **ExportDevicesAsync** method requires two parameters:
101
100
@@ -150,7 +149,6 @@ If a device has twin data, then the twin data is also exported together with the
150
149
"id":"export-6d84f075-0",
151
150
"eTag":"MQ==",
152
151
"status":"enabled",
153
-
"statusReason":"firstUpdate",
154
152
"authentication":null,
155
153
"twinETag":"AAAAAAAAAAI=",
156
154
"tags":{
@@ -162,35 +160,13 @@ If a device has twin data, then the twin data is also exported together with the
162
160
"Temperature":75.1,
163
161
"Unit":"F"
164
162
},
165
-
"$metadata":{
166
-
"$lastUpdated":"2017-03-09T18:30:52.3167248Z",
167
-
"$lastUpdatedVersion":2,
168
-
"Thermostat":{
169
-
"$lastUpdated":"2017-03-09T18:30:52.3167248Z",
170
-
"$lastUpdatedVersion":2,
171
-
"Temperature":{
172
-
"$lastUpdated":"2017-03-09T18:30:52.3167248Z",
173
-
"$lastUpdatedVersion":2
174
-
},
175
-
"Unit":{
176
-
"$lastUpdated":"2017-03-09T18:30:52.3167248Z",
177
-
"$lastUpdatedVersion":2
178
-
}
179
-
}
180
-
},
181
-
"$version":2
182
163
},
183
-
"reported":{
184
-
"$metadata":{
185
-
"$lastUpdated":"2017-03-09T18:30:51.1309437Z"
186
-
},
187
-
"$version":1
188
-
}
164
+
"reported":{}
189
165
}
190
166
}
191
167
```
192
168
193
-
If you need access to this data in code, you can easily deserialize this data using the **ExportImportDevice** class. The following C# code snippet, from the **ReadFromBlobAsync** method in the SDK sample, shows how to read device information that was previously exported from **ExportImportDevice** into a **BlobClient** instance:
169
+
If you need access to this data in code, you can deserialize this data using the **ExportImportDevice** class. The following C# code snippet, from the **ReadFromBlobAsync** method in the SDK sample, shows how to read device information that was previously exported from **ExportImportDevice** into a **BlobClient** instance:
@@ -221,13 +197,13 @@ Take care using the **ImportDevicesAsync** method because in addition to provisi
221
197
222
198
The **ImportDevicesAsync** method takes two parameters:
223
199
224
-
* A *string* that contains a URI of an [Azure Storage](../storage/index.yml) blob container to use as *input* to the job. This URI must contain a SAS token that grants read access to the container. This container must contain a blob with the name **devices.txt** that contains the serialized device data to import into your identity registry. The import data must contain device information in the same JSON format that the **ExportImportDevice** job uses when it creates a **devices.txt** blob. The SAS token must include these permissions:
200
+
* A *string* that contains a URI of an Azure Storage blob container to use as *input* to the job. This URI must contain a SAS token that grants read access to the container. This container must contain a blob with the name **devices.txt** that contains the serialized device data to import into your identity registry. The import data must contain device information in the same JSON format that the **ExportImportDevice** job uses when it creates a **devices.txt** blob. The SAS token must include these permissions:
225
201
226
202
```csharp
227
203
SharedAccessBlobPermissions.Read
228
204
```
229
205
230
-
* A *string* that contains a URI of an [Azure Storage](../storage/index.yml) blob container to use as *output* from the job. The job creates a block blob in this container to store any error information from the completed import **Job**. The SAS token must include these permissions:
206
+
* A *string* that contains a URI of an Azure Storage blob container to use as *output* from the job. The job creates a block blob in this container to store any error information from the completed import job. The SAS token must include these permissions:
This method can also be used to import the data for the device twin. The format for the data input is the same as the format shown in the **ExportDevicesAsync** section. In this way, you can reimport the exported data. The **$metadata** is optional.
223
+
This method can also be used to import the data for the device twin. The format for the data input is the same as the format shown in the **ExportDevicesAsync** section. In this way, you can reimport the exported data.
248
224
249
225
## Import behavior
250
226
@@ -259,28 +235,23 @@ You can use the **ImportDevicesAsync** method to perform the following bulk oper
259
235
260
236
You can perform any combination of the preceding operations within a single **ImportDevicesAsync** call. For example, you can register new devices and delete or update existing devices at the same time. When used along with the **ExportDevicesAsync** method, you can completely migrate all your devices from one IoT hub to another.
261
237
262
-
If the import file includes twin metadata, then this metadata overwrites the existing twin metadata. If the import file doesn't include twin metadata, then only the `lastUpdateTime` metadata is updated using the current time.
263
-
264
238
Use the optional **importMode** property in the import serialization data for each device to control the import process per-device. The **importMode** property has the following options:
265
239
266
-
| importMode | Description |
267
-
| --- | --- |
268
-
|**Create**|If a device doesn't exist with the specified **ID**, it's newly registered. If the device already exists, an error is written to the log file. |
269
-
|**CreateOrUpdate**|If a device doesn't exist with the specified **ID**, it's newly registered. If the device already exists, existing information is overwritten with the provided input data without regard to the **ETag** value. |
270
-
|**CreateOrUpdateIfMatchETag**|If a device doesn't exist with the specified **ID**, it's newly registered. If the device already exists, existing information is overwritten with the provided input data only if there's an **ETag** match. If there's an **ETag** mismatch, an error is written to the log file. |
271
-
|**Delete**|If a device already exists with the specified **ID**, it's deleted without regard to the **ETag** value. If the device doesn't exist, an error is written to the log file. |
272
-
|**DeleteIfMatchETag**|If a device already exists with the specified **ID**, it's deleted only if there's an **ETag** match. If the device doesn't exist, an error is written to the log file. If there's an ETag mismatch, an error is written to the log file. |
273
-
|**Update**|If a device already exists with the specified **ID**, existing information is overwritten with the provided input data without regard to the **ETag** value. If the device doesn't exist, an error is written to the log file. |
274
-
|**UpdateIfMatchETag**|If a device already exists with the specified **ID**, existing information is overwritten with the provided input data only if there's an **ETag** match. If the device doesn't exist or there's an **ETag** mismatch, an error is written to the log file. |
275
-
|**UpdateTwin**|If a twin already exists with the specified **ID**, existing information is overwritten with the provided input data without regard to the twin's **ETag** value. |
276
-
|**UpdateTwinIfMatchETag**|If a twin already exists with the specified **ID**, existing information is overwritten with the provided input data only if there's a match on the twin's **ETag** value. The twin's **ETag** is processed independently from the device's **ETag**. If there's a mismatch with the existing twin's **ETag**, an error is written to the log file. |
240
+
***Create**
241
+
***CreateOrUpdate** (default)
242
+
***CreateOrUpdateIfMatchETag**
243
+
***Delete**
244
+
***DeleteIfMatchETag**
245
+
***Update**
246
+
***UpdateIfMatchETag**
247
+
***UpdateTwin**
248
+
***UpdateTwinIfMatchETag**
277
249
278
-
> [!NOTE]
279
-
> If the serialization data doesn't explicitly define an **importMode** flag for a device, it defaults to **createOrUpdate** during the import operation.
250
+
For details about each of these import mode options, see [ImportMode](/dotnet/api/microsoft.azure.devices.importmode)
280
251
281
-
## Import troubleshooting
252
+
## Troubleshoot import jobs
282
253
283
-
Using an import job to create devices may fail with a quota issue when it's close to the device count limit of the IoT hub. This failure can happen even if the total device count is still lower than the quota limit. The **IotHubQuotaExceeded (403002)** error is returned with the following error message: "Total number of devices on IotHub exceeded the allocated quota.”
254
+
Using an import job to create devices might fail with a quota issue when it's close to the device count limit of the IoT hub. This failure can happen even if the total device count is still lower than the quota limit. The **IotHubQuotaExceeded (403002)** error is returned with the following error message: "Total number of devices on IotHub exceeded the allocated quota.”
284
255
285
256
If you get this error, you can use the following query to return the total number of devices registered on your IoT hub:
286
257
@@ -290,7 +261,7 @@ SELECT COUNT() as totalNumberOfDevices FROM devices
290
261
291
262
For information about the total number of devices that can be registered to an IoT hub, see [IoT Hub limits](iot-hub-devguide-quotas-throttling.md#other-limits).
292
263
293
-
If there's still quota available, you can examine the job output blob for devices that failed with the **IotHubQuotaExceeded (403002)** error. You can then try adding these devices individually to the IoT hub. For example, you can use the **AddDeviceAsync** or **AddDeviceWithTwinAsync** methods. Don't try to add the devices using another job as you may likely encounter the same error.
264
+
If there's still quota available, you can examine the job output blob for devices that failed with the **IotHubQuotaExceeded (403002)** error. You can then try adding these devices individually to the IoT hub. For example, you can use the **AddDeviceAsync** or **AddDeviceWithTwinAsync** methods. Don't try to add the devices using another job as you might encounter the same error.
294
265
295
266
## Import devices example – bulk device provisioning
296
267
@@ -402,7 +373,7 @@ private async Task GenerateDevicesAsync(RegistryManager registryManager, int num
402
373
Console.WriteLine($"GenerateDevices, time elapsed = {stopwatch.Elapsed}.");
403
374
}
404
375
```
405
-
376
+
406
377
## Import devices example – bulk deletion
407
378
408
379
The following C# code snippet, from the **DeleteFromHubAsync** method in the SDK sample, shows you how to delete all of the devices from an IoT hub:
Copy file name to clipboardExpand all lines: articles/iot-hub/troubleshoot-error-codes.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -76,7 +76,7 @@ This error typically occurs when the daily message quota for the IoT hub is exce
76
76
* To understand how operations are counted toward the quota, such as twin queries and direct methods, see [Understand IoT Hub pricing](iot-hub-devguide-pricing.md#charges-per-operation).
77
77
* To set up monitoring for daily quota usage, set up an alert with the metric *Total number of messages used*. For step-by-step instructions, see [Set up metrics and alerts with IoT Hub](tutorial-use-metrics-and-diags.md#set-up-metrics).
78
78
79
-
This error may also be returned by a bulk import job when the number of devices registered to your IoT hub approaches or exceeds the quota limit for an IoT hub. To learn more, see [Troubleshoot import jobs](iot-hub-bulk-identity-mgmt.md#import-troubleshooting).
79
+
This error may also be returned by a bulk import job when the number of devices registered to your IoT hub approaches or exceeds the quota limit for an IoT hub. To learn more, see [Troubleshoot import jobs](iot-hub-bulk-identity-mgmt.md#troubleshoot-import-jobs).
0 commit comments