Importieren und Exportieren von IoT Hub-Geräteidentitäten per Massenvorgang

Jeder IoT-Hub verfügt über eine Identitätsregistrierung, die Sie zum Erstellen von Geräteressourcen im Dienst verwenden können. Außerdem wird mit der Identitätsregistrierung der Zugriff auf geräteseitige Endpunkte ermöglicht. In diesem Artikel wird beschrieben, wie Sie Geräteidentitäten mithilfe des ImportExportDeviceSample-Beispiels, das im Microsoft Azure IoT SDK für .NET enthalten ist, massenweise in und aus einer Identitätsregistrierung importieren und exportieren. Weitere Informationen dazu, wie Sie diese Funktion beim Migrieren eines IoT-Hubs in eine andere Region verwenden können, lesen Sie die Informationen unter Manuelles Migrieren einer Azure IoT-Hub-Instanz mithilfe einer Azure Resource Manager-Vorlage.

Hinweis

Der IoT-Hub hat vor kurzem Unterstützung für virtuelle Netzwerke in einer begrenzten Anzahl von Regionen hinzugefügt. Diese Funktion sichert Import- und Exportvorgänge und macht Hauptschlüssel zur Authentifizierung überflüssig. Derzeit ist die Unterstützung für virtuelle Netzwerke nur in den folgenden Regionen verfügbar: WestUS2, EastUS und SouthCentralUS. Weitere Informationen zur Unterstützung virtueller Netzwerke und den API-Aufrufen zu deren Implementierung finden Sie unter IoT Hub-Unterstützung für virtuelle Netzwerke.

Import- und Exportvorgänge erfolgen im Kontext von Aufträgen, die Ihnen das Ausführen von Dienstvorgängen in großen Mengen auf einem IoT-Hub ermöglichen.

Die RegistryManager-Klasse im SDK enthält die Methoden ExportDevicesAsync und ImportDevicesAsync, die das Job-Framework verwenden. Diese Methoden ermöglichen das Exportieren, Importieren und Synchronisieren der gesamten IoT Hub-Identitätsregistrierung.

In diesem Artikel wird die Verwendung der Klasse RegistryManager und des Auftragssystems zum Ausführen von Massenimport- und -exportvorgängen von Geräten in die bzw. aus der Identitätsregistrierung eines IoT-Hubs erörtert. Sie können den Azure IoT Hub Device Provisioning-Dienst auch dazu verwenden, um eine Just-in-Time-Bereitstellung auf einem oder mehreren IoT-Hubs ohne Benutzereingriff (Zero Touch) zu ermöglichen. Weitere Informationen finden Sie in der Dokumentation zum Bereitstellungsdienst.

Hinweis

Einige der Codeschnipsel in diesem Artikel stammen aus dem ImportExportDevicesSample-Dienstbeispiel, das mit dem Microsoft Azure IoT SDK für .NET bereitgestellt wird. Das Beispiel befindet sich im /iothub/service/samples/how to guides/ImportExportDevicesSample-Ordner des SDK, und Codeschnipsel werden, sofern angegeben, aus der ImportExportDevicesSample.cs-Datei für dieses SDK-Beispiel eingeschlossen. Weitere Informationen zum ImportExportDevicesSample-Beispiel und anderen Dienstbeispielen, die im Azure IoT SDK für.NET enthalten sind, finden Sie unter Azure IoT-Hub-Dienstbeispiele für C#.

Was sind Aufträge?

Identitätsregistrierungsvorgänge verwenden das Auftragssystem, wenn der Vorgang:

  • eine potenziell lange Ausführungsdauer im Vergleich mit standardmäßigen Laufzeitvorgängen hat.

  • eine große Menge von Daten an den Benutzer zurückgibt.

Anstelle eines einzelnen API-Aufrufs, mit dem auf das Ergebnis des Vorgangs gewartet oder mit dem der Vorgang blockiert wird, erstellt der Vorgang asynchron einen Auftrag für diesen IoT-Hub. Für den Vorgang wird dann sofort ein JobProperties-Objekt zurückgegeben.

Wichtig

Dieser Artikel enthält Schritte zum Herstellen einer Verbindung mit einem Dienst mithilfe einer Shared Access Signature. Diese Authentifizierungsmethode eignet sich für Tests und Auswertungen, aber die Authentifizierung bei einem Dienst mit Microsoft Entra ID oder verwalteten Identitäten ist ein sichererer Ansatz. Weitere Informationen finden Sie unter Bewährte Methoden für die Sicherheit von IoT-Lösungen > Cloudsicherheit.

Der folgende C#-Codeausschnitt zeigt, wie ein Exportauftrag erstellt wird:

// Call an export job on the IoT hub to retrieve all devices
JobProperties exportJob = await 
  registryManager.ExportDevicesAsync(containerSasUri, false);

Hinweis

Um die RegistryManager-Klasse in Ihrem C#-Code zu verwenden, fügen Sie das Microsoft.Azure.Devices-NuGet-Paket Ihrem Projekt hinzu. Die RegistryManager-Klasse befindet sich im Microsoft.Azure.Devices-Namespace.

Sie können die RegistryManager-Klasse verwenden, um den Status des Auftrags unter Verwendung der zurückgegebenen JobProperties-Metadaten abzufragen. Verwenden Sie zum Erstellen einer Instanz der RegistryManager-Klasse die CreateFromConnectionString-Methode.

RegistryManager registryManager =
  RegistryManager.CreateFromConnectionString("{your IoT Hub connection string}");

So finden Sie die Verbindungszeichenfolge Ihres IoT-Hubs im Azure-Portal

  1. Navigieren Sie zu Ihrem IoT Hub.

  2. Klicken Sie auf Freigegebene Zugriffsrichtlinien.

  3. Wählen Sie eine Richtlinie aus. Berücksichtigen Sie dabei die benötigten Berechtigungen.

  4. Kopieren Sie die Verbindungszeichenfolge für diese Richtlinie.

Der folgende C#-Codeschnipsel aus der Methode WaitForJobAsync im SDK-Beispiel zeigt, wie alle fünf Sekunden eine Abfrage erfolgt, um festzustellen, ob die Auftragsausführung beendet wurde:

// Wait until job is finished
while (true)
{
    job = await registryManager.GetJobAsync(job.JobId);
    if (job.Status == JobStatus.Completed
        || job.Status == JobStatus.Failed
        || job.Status == JobStatus.Cancelled)
    {
        // Job has finished executing
        break;
    }
    Console.WriteLine($"\tJob status is {job.Status}...");

    await Task.Delay(TimeSpan.FromSeconds(5));
}

Hinweis

Wenn für Ihr Speicherkonto Firewallkonfigurationen vorhanden sind, die die Konnektivität von IoT Hub einschränken, sollten Sie die Verwendung der Ausnahme vertrauenswürdiger Microsoft-Erstanbieter in Erwägung ziehen (in ausgewählten Regionen für IoT-Hubs mit verwalteter Dienstidentität verfügbar).

Grenzwerte bei Geräteimport-/exportaufträgen

Bei allen IoT Hub-Tarifen ist jeweils nur ein aktiver Geräteimport- oder -exportauftrag zulässig. Außerdem gibt es in IoT Hub Grenzwerte für die Rate der Auftragsvorgänge. Weitere Informationen finden Sie unter IoT Hub-Kontingente und Drosselung.

Exportieren von Geräten

Mithilfe der Methode ExportDevicesAsync können Sie die gesamte IoT Hub-Identitätsregistrierung in einen Azure Storage-Blobcontainer exportieren und dazu eine Shared Access Signature (SAS) verwenden. Mit dieser Methode können Sie zuverlässige Sicherungen Ihrer Geräte-Informationen in einem Blobcontainer erstellen, den Sie steuern.

Die ExportDevicesAsync -Methode erfordert zwei Parameter:

  • Eine Zeichenfolge, die einen URI eines Blobcontainers enthält. Dieser URI muss ein SAS-Token enthalten, das Schreibzugriff auf den Container gewährt. Der Auftrag erstellt zum Speichern der serialisierten Exportgerätedaten ein Blockblob in diesem Container. Das SAS-Token muss diese Berechtigungen enthalten:

    SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Read 
       | SharedAccessBlobPermissions.Delete
    
  • Einen booleschen Wert, der angibt, ob Sie Authentifizierungsschlüssel aus Ihren Exportdaten ausschließen möchten. Bei FALSE werden Authentifizierungsschlüssel in die Exportausgabe eingeschlossen. Andernfalls werden Schlüssel als NULL exportiert.

Der folgende C#-Codeausschnitt zeigt, wie Sie einen Exportauftrag initiieren, der Geräteauthentifizierungsschlüssel in die exportierten Daten einbezieht und für den Abschluss eine Umfrage durchführt:

// Call an export job on the IoT Hub to retrieve all devices
JobProperties exportJob = 
  await registryManager.ExportDevicesAsync(containerSasUri, false);

// Wait until job is finished
while(true)
{
    exportJob = await registryManager.GetJobAsync(exportJob.JobId);
    if (exportJob.Status == JobStatus.Completed || 
        exportJob.Status == JobStatus.Failed ||
        exportJob.Status == JobStatus.Cancelled)
    {
    // Job has finished executing
    break;
    }

    await Task.Delay(TimeSpan.FromSeconds(5));
}

Ähnlichen Code finden Sie in der Methode ExportDevicesAsync aus dem SDK-Beispiel. Der Auftrag speichert seine Ausgabe im angegebenen Blobcontainer als Blockblob mit dem Namen devices.txt. Die Ausgabedaten bestehen aus serialisierten JSON-Gerätedaten mit einem Gerät pro Zeile.

Das folgende Beispiel zeigt die Ausgabedaten:

{"id":"Device1","eTag":"MA==","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device2","eTag":"MA==","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device3","eTag":"MA==","status":"disabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device4","eTag":"MA==","status":"disabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device5","eTag":"MA==","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}

Wenn ein Gerät Zwillingsdaten aufweist, werden die Zwillingsdaten ebenfalls zusammen mit den Gerätedaten exportiert. Das folgende Beispiel zeigt dieses Format. Alle Daten ab der Zeile „twinETag“ bis zum Ende sind Zwillingsdaten.

{
   "id":"export-6d84f075-0",
   "eTag":"MQ==",
   "status":"enabled",
   "authentication":null,
   "twinETag":"AAAAAAAAAAI=",
   "tags":{
      "Location":"LivingRoom"
   },
   "properties":{
      "desired":{
         "Thermostat":{
            "Temperature":75.1,
            "Unit":"F"
         },
      },
      "reported":{}
   }
}

Wenn Sie Zugriff auf diese Daten im Code benötigen, können Sie diese Daten mithilfe der Klasse ExportImportDevice deserialisieren. Der folgende C#-Codeschnipsel aus der Methode ReadFromBlobAsync im SDK-Beispiel zeigt, wie Geräteinformationen gelesen werden, die zuvor aus ExportImportDevice in eine BlobClient-Instanz exportiert wurden:

private static async Task<List<string>> ReadFromBlobAsync(BlobClient blobClient)
{
    // Read the blob file of devices, import each row into a list.
    var contents = new List<string>();

    using Stream blobStream = await blobClient.OpenReadAsync();
    using var streamReader = new StreamReader(blobStream, Encoding.UTF8);
    while (streamReader.Peek() != -1)
    {
        string line = await streamReader.ReadLineAsync();
        contents.Add(line);
    }

    return contents;
}

Importieren von Geräten

Die ImportDevicesAsync-Methode in der RegistryManager-Klasse ermöglicht Ihnen das Anwenden von Massenvorgängen (Import/Synchronisierung) auf eine IoT Hub-Identitätsregistrierung. Wie die ExportDevicesAsync-Methode auch, wird für die ImportDevicesAsync-Methode das Job-Framework verwendet.

Nutzen Sie die ImportDevicesAsync-Methode umsichtig, damit mit ihr nicht nur neue Geräte in der Identitätsregistrierung bereitgestellt, sondern auch vorhandene Geräte aktualisiert und gelöscht werden können.

Warnung

Ein Importvorgang kann nicht rückgängig gemacht werden. Sichern Sie vor dem Verwenden der ExportDevicesAsync-Methode stets Ihre vorhandenen Daten in einem anderen Blobcontainer, bevor Sie Massenänderungen an Ihrer Identitätsregistrierung vornehmen.

Die ImportDevicesAsync -Methode erfordert zwei Parameter:

  • Eine Zeichenfolge, die einen URI eines Azure Storage-Blobcontainers enthält, der als Eingabe für den Auftrag verwendet werden soll. Dieser URI muss ein SAS-Token enthalten, das Lesezugriff auf den Container gewährt. Dieser Container muss ein Blob mit dem Namen devices.txt enthalten, das die serialisierten Gerätedaten enthält, die in Ihre Identitätsregistrierung importiert werden sollen. Die importierten Daten müssen Geräteinformationen im gleichen JSON-Format enthalten, das vom ExportImportDevice-Auftrag verwendet wird, wenn er das Blob devices.txt erstellt. Das SAS-Token muss diese Berechtigungen enthalten:

    SharedAccessBlobPermissions.Read
    
  • Eine Zeichenfolge, die einen URI eines Azure Storage-Blobcontainers enthält, der als Ausgabe aus dem Auftrag verwendet werden soll. Der Auftrag erstellt in diesem Container ein Blockblob zum Speichern von Fehlerinformationen aus dem abgeschlossenen Importauftrag. Das SAS-Token muss diese Berechtigungen enthalten:

    SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Read 
       | SharedAccessBlobPermissions.Delete
    

Hinweis

Die beiden Parameter können auf den gleichen Blobcontainer verweisen. Die separaten Parameter ermöglichen einfach mehr Kontrolle über Ihre Daten, da der Ausgabecontainer zusätzliche Berechtigungen erfordert.

Der folgende C#-Codeausschnitt zeigt, wie ein Importauftrag ausgelöst wird:

JobProperties importJob = 
   await registryManager.ImportDevicesAsync(containerSasUri, containerSasUri);

Diese Methode kann auch verwendet werden, um die Daten für den Gerätezwilling zu importieren. Das Format für die Dateneingabe entspricht dem Format wie im Abschnitt für ExportDevicesAsync. Auf diese Weise können Sie die exportierten Daten erneut importieren.

Importverhalten

Sie können die ImportDevicesAsync -Methode zum Anwenden der folgenden Massenvorgänge auf Ihre Identitätsregistrierung verwenden:

  • Massenregistrierung neuer Geräte
  • Massenlöschung vorhandener Geräte
  • Massenstatusänderungen (Aktivieren oder Deaktivieren von Geräten)
  • Massenzuweisung neuer Geräteauthentifizierungsschlüssel
  • Automatische Massenneugenerierung von Geräteauthentifizierungsschlüsseln
  • Massenaktualisierung von Zwillingsdaten

Sie können eine beliebige Kombination der obigen Vorgänge innerhalb eines einzelnen Aufrufs von ImportDevicesAsync ausführen. Sie können beispielsweise gleichzeitig neue Geräte registrieren oder vorhandene Geräte aktualisieren und löschen. Bei Verwendung zusammen mit der ExportDevicesAsync -Methode können Sie alle Ihre Geräte vollständig von einem IoT Hub zu einem anderen migrieren.

Verwenden Sie die optionale importMode-Eigenschaft in den Importserialisierungsdaten für jedes Gerät, um den Importprozess gerätebezogen zu steuern. Die importMode -Eigenschaft hat die folgenden Optionen:

  • Erstellen
  • CreateOrUpdate (Standard)
  • CreateOrUpdateIfMatchETag
  • Delete
  • DeleteIfMatchETag
  • Aktualisieren
  • UpdateIfMatchETag
  • UpdateTwin
  • UpdateTwinIfMatchETag

Ausführliche Informationen zu den Importmodusoptionen finden Sie unter ImportMode

Problembehandlung bei Importaufträgen

Die Verwendung eines Importauftrags zum Erstellen von Geräten schlägt möglicherweise mit einem Kontingentproblem fehl, wenn das Kontingent nahe am Grenzwert der Geräteanzahl für den IoT-Hub liegt. Dieser Fehler kann sogar dann auftreten, wenn die Gesamtanzahl der Geräte noch geringer als die Kontingentgrenze ist. Der Fehler IotHubQuotaExceeded (403002) wird mit der folgenden Meldung zurückgegeben: „Total number of devices on IotHub exceeded the allocated quota.“ (Die Gesamtzahl der Geräte auf IotHub hat das zugeordnete Kontingent überschritten).

Wenn Ihnen dieser Fehler angezeigt wird, können Sie mithilfe der folgenden Abfrage die Gesamtanzahl der Geräte zurückgeben, die auf Ihrem IoT-Hub registriert sind:

SELECT COUNT() as totalNumberOfDevices FROM devices

Informationen zur Gesamtzahl der Geräte, die auf einem IoT-Hub registriert werden können, finden Sie unter IoT Hub-Grenzwerte.

Wenn ein Kontingent weiterhin zur Verfügung steht, können Sie den Auftragsausgabe-Blob für Geräte untersuchen, bei denen der Fehler IotHubQuotaExceeded (403002) aufgetreten ist. Anschließend können Sie versuchen, diese Geräte dem IoT-Hub einzeln hinzuzufügen. Dazu können Sie beispielsweise die Methoden AddDeviceAsync oder AddDeviceWithTwinAsync verwenden. Versuchen Sie nicht, die Geräte mithilfe eines anderen Auftrags hinzuzufügen, weil dann wahrscheinlich derselbe Fehler auftritt.

Beispiel für das Importieren von Geräten – Massengerätebereitstellung

Der folgende C#-Codeschnipsel aus der Methode GenerateDevicesAsync im SDK-Beispiel veranschaulicht, wie mehrere Geräteidentitäten generiert werden:

  • Einfügen von Authentifizierungsschlüsseln
  • Schreiben von Geräteinformationen in ein Blockblob
  • Importieren der Geräte in die Identitätsregistrierung
private async Task GenerateDevicesAsync(RegistryManager registryManager, int numToAdd)
{
    var stopwatch = Stopwatch.StartNew();

    Console.WriteLine($"Creating {numToAdd} devices for the source IoT hub.");
    int interimProgressCount = 0;
    int displayProgressCount = 1000;
    int totalProgressCount = 0;

    // generate reference for list of new devices we're going to add, will write list to this blob
    BlobClient generateDevicesBlob = _blobContainerClient.GetBlobClient(_generateDevicesBlobName);

    // define serializedDevices as a generic list<string>
    var serializedDevices = new List<string>(numToAdd);

    for (int i = 1; i <= numToAdd; i++)
    {
        // Create device name with this format: Hub_00000000 + a new guid.
        // This should be large enough to display the largest number (1 million).
        string deviceName = $"Hub_{i:D8}_{Guid.NewGuid()}";
        Debug.Print($"Adding device '{deviceName}'");

        // Create a new ExportImportDevice.
        var deviceToAdd = new ExportImportDevice
        {
            Id = deviceName,
            Status = DeviceStatus.Enabled,
            Authentication = new AuthenticationMechanism
            {
                SymmetricKey = new SymmetricKey
                {
                    PrimaryKey = GenerateKey(32),
                    SecondaryKey = GenerateKey(32),
                }
            },
            // This indicates that the entry should be added as a new device.
            ImportMode = ImportMode.Create,
        };

        // Add device to the list as a serialized object.
        serializedDevices.Add(JsonConvert.SerializeObject(deviceToAdd));

        // Not real progress as you write the new devices, but will at least show *some* progress.
        interimProgressCount++;
        totalProgressCount++;
        if (interimProgressCount >= displayProgressCount)
        {
            Console.WriteLine($"Added {totalProgressCount}/{numToAdd} devices.");
            interimProgressCount = 0;
        }
    }

    // Now have a list of devices to be added, each one has been serialized.
    // Write the list to the blob.
    var sb = new StringBuilder();
    serializedDevices.ForEach(serializedDevice => sb.AppendLine(serializedDevice));

    // Write list of serialized objects to the blob.
    using Stream stream = await generateDevicesBlob.OpenWriteAsync(overwrite: true);
    byte[] bytes = Encoding.UTF8.GetBytes(sb.ToString());
    for (int i = 0; i < bytes.Length; i += BlobWriteBytes)
    {
        int length = Math.Min(bytes.Length - i, BlobWriteBytes);
        await stream.WriteAsync(bytes.AsMemory(i, length));
    }
    await stream.FlushAsync();

    Console.WriteLine("Running a registry manager job to add the devices.");

    // Should now have a file with all the new devices in it as serialized objects in blob storage.
    // generatedListBlob has the list of devices to be added as serialized objects.
    // Call import using the blob to add the new devices.
    // Log information related to the job is written to the same container.
    // This normally takes 1 minute per 100 devices (according to the docs).

    // First, initiate an import job.
    // This reads in the rows from the text file and writes them to IoT Devices.
    // If you want to add devices from a file, you can create a file and use this to import it.
    //   They have to be in the exact right format.
    try
    {
        // The first URI is the container to import from; the file defaults to devices.txt, but may be specified.
        // The second URI points to the container to write errors to as a blob.
        // This lets you import the devices from any file name. Since we wrote the new
        // devices to [devicesToAdd], need to read the list from there as well.
        var importGeneratedDevicesJob = JobProperties.CreateForImportJob(
            _containerUri,
            _containerUri,
            _generateDevicesBlobName);
        importGeneratedDevicesJob = await registryManager.ImportDevicesAsync(importGeneratedDevicesJob);
        await WaitForJobAsync(registryManager, importGeneratedDevicesJob);
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Adding devices failed due to {ex.Message}");
    }

    stopwatch.Stop();
    Console.WriteLine($"GenerateDevices, time elapsed = {stopwatch.Elapsed}.");
}

Beispiel für das Importieren von Geräten – Massenlöschung

Der folgende C#-Codeschnipsel aus der Methode DeleteFromHubAsync im SDK-Beispiel zeigt, wie Sie alle Geräte aus einem IoT-Hub löschen:

private async Task DeleteFromHubAsync(RegistryManager registryManager, bool includeConfigurations)
{
    var stopwatch = Stopwatch.StartNew();

    Console.WriteLine("Deleting all devices from an IoT hub.");

    Console.WriteLine("Exporting a list of devices from IoT hub to blob storage.");

    // Read from storage, which contains serialized objects.
    // Write each line to the serializedDevices list.
    BlobClient devicesBlobClient = _blobContainerClient.GetBlobClient(_destHubDevicesImportBlobName);

    Console.WriteLine("Reading the list of devices in from blob storage.");
    List<string> serializedDevices = await ReadFromBlobAsync(devicesBlobClient);

    // Step 1: Update each device's ImportMode to be Delete
    Console.WriteLine("Updating ImportMode to be 'Delete' for each device and writing back to the blob.");
    var sb = new StringBuilder();
    serializedDevices.ForEach(serializedEntity =>
    {
        // Deserialize back to an ExportImportDevice and change import mode.
        ExportImportDevice device = JsonConvert.DeserializeObject<ExportImportDevice>(serializedEntity);
        device.ImportMode = ImportMode.Delete;

        // Reserialize the object now that we've updated the property.
        sb.AppendLine(JsonConvert.SerializeObject(device));
    });

    // Step 2: Write the list in memory to the blob.
    BlobClient deleteDevicesBlobClient = _blobContainerClient.GetBlobClient(_hubDevicesCleanupBlobName);
    await WriteToBlobAsync(deleteDevicesBlobClient, sb.ToString());

    // Step 3: Call import using the same blob to delete all devices.
    Console.WriteLine("Running a registry manager job to delete the devices from the IoT hub.");
    var importJob = JobProperties.CreateForImportJob(
        _containerUri,
        _containerUri,
        _hubDevicesCleanupBlobName);
    importJob = await registryManager.ImportDevicesAsync(importJob);
    await WaitForJobAsync(registryManager, importJob);

    // Step 4: delete configurations
    if (includeConfigurations)
    {
        BlobClient configsBlobClient = _blobContainerClient.GetBlobClient(_srcHubConfigsExportBlobName);
        List<string> serializedConfigs = await ReadFromBlobAsync(configsBlobClient);
        foreach (string serializedConfig in serializedConfigs)
        {
            try
            {
                Configuration config = JsonConvert.DeserializeObject<Configuration>(serializedConfig);
                await registryManager.RemoveConfigurationAsync(config.Id);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Failed to deserialize or remove a config.\n\t{serializedConfig}\n\n{ex.Message}");
            }
        }
    }

    stopwatch.Stop();
    Console.WriteLine($"Deleted IoT hub devices and configs: time elapsed = {stopwatch.Elapsed}");
}

Abrufen des SAS-URI des Containers

Das folgende Codebeispiel veranschaulicht das Erstellen eines SAS-URI mit Lese-, Schreib- und Löschberechtigungen für einen Blobcontainer:

static string GetContainerSasUri(CloudBlobContainer container)
{
  // Set the expiry time and permissions for the container.
  // In this case no start time is specified, so the
  // shared access signature becomes valid immediately.
  var sasConstraints = new SharedAccessBlobPolicy();
  sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24);
  sasConstraints.Permissions = 
    SharedAccessBlobPermissions.Write | 
    SharedAccessBlobPermissions.Read | 
    SharedAccessBlobPermissions.Delete;

  // Generate the shared access signature on the container,
  // setting the constraints directly on the signature.
  string sasContainerToken = container.GetSharedAccessSignature(sasConstraints);

  // Return the URI string for the container,
  // including the SAS token.
  return container.Uri + sasContainerToken;
}

Nächste Schritte

In diesem Artikel haben Sie gelernt, wie Massenvorgänge auf die Identitätsregistrierung in einem IoT Hub angewendet werden. Viele dieser Vorgänge, darunter das Verschieben von Geräten von einem Hub zu einem anderen, werden im Artikel Manuelles Migrieren einer Azure IoT-Hub-Instanz mithilfe einer Azure Resource Manager-Vorlage im Abschnitt Verwalten der beim IoT-Hub registrierten Geräte verwendet.