IoT Hub cihaz kimliklerinizi toplu olarak içeri ve dışarı aktarma
Her IoT hub'ında, hizmette cihaz kaynakları oluşturmak için kullanabileceğiniz bir kimlik kayıt defteri vardır. Kimlik kayıt defteri cihaza yönelik uç noktalara erişimi denetlemenize de olanak tanır. Bu makalede, .NET için Microsoft Azure IoT SDK'sında bulunan ImportExportDeviceSample örneği kullanılarak cihaz kimliklerinin toplu olarak bir kimlik kayıt defterine nasıl içeri ve dışarı aktarıldığı açıklanır. IoT hub'larını farklı bir bölgeye geçirirken bu özelliği nasıl kullanabileceğiniz hakkında daha fazla bilgi için bkz . Azure Resource Manager şablonu kullanarak Azure IoT hub'larını el ile geçirme.
Not
IoT Hub kısa süre önce sınırlı sayıda bölgeye sanal ağ desteği ekledi. Bu özellik içeri ve dışarı aktarma işlemlerinin güvenliğini sağlar ve kimlik doğrulaması için anahtar geçirme gereksinimini ortadan kaldırır. Şu anda sanal ağ desteği yalnızca şu bölgelerde kullanılabilir: WestUS2, EastUS ve SouthCentralUS. Sanal ağ desteği ve bunu uygulamaya yönelik API çağrıları hakkında daha fazla bilgi edinmek için bkz . Sanal ağlar için IoT Hub Desteği.
İçeri ve dışarı aktarma işlemleri, bir IoT hub'ında toplu hizmet işlemlerini yürütmenizi sağlayan işler bağlamında gerçekleşir.
SDK'daki RegistryManager sınıfı, İş çerçevesini kullanan ExportDevicesAsync ve ImportDevicesAsync yöntemlerini içerir. Bu yöntemler bir IoT hub kimlik kayıt defterini dışarı aktarmanıza, içeri aktarmanıza ve eşitlemenize olanak tanır.
Bu makalede, IoT hub'ının kimlik kayıt defterine ve ioT hub'ından cihazların toplu içeri ve dışarı aktarma işlemlerini gerçekleştirmek için RegistryManager sınıfı ve İş sisteminin kullanılması ele alınmaktadır. Azure IoT Hub Cihaz Sağlama Hizmeti'ni kullanarak bir veya daha fazla IoT hub'ına dokunmadan, tam zamanında sağlamayı etkinleştirebilirsiniz. Daha fazla bilgi edinmek için sağlama hizmeti belgelerine bakın.
Not
Bu makaledeki kod parçacıklarından bazıları, .NET için Microsoft Azure IoT SDK'sı ile sağlanan ImportExportDevicesSample hizmet örneğine eklenmiştir. Örnek, SDK klasöründe bulunur /iothub/service/samples/how to guides/ImportExportDevicesSample
ve burada belirtilen kod parçacıkları söz konusu SDK örneğinin dosyasından ImportExportDevicesSample.cs
eklenir. ImportExportDevicesSample örneği ve Azure IoT SDK for.NET dahil edilen diğer hizmet örnekleri hakkında daha fazla bilgi için bkz . C# için Azure IoT hub hizmeti örnekleri.
İşler nedir?
Kimlik kayıt defteri işlemleri şu işlem sırasında iş sistemini kullanır:
Standart çalışma zamanı işlemleriyle karşılaştırıldığında büyük olasılıkla uzun bir yürütme süresine sahiptir.
Kullanıcıya büyük miktarda veri döndürür.
İşlemin sonucunu bekleyen veya engelleyen tek bir API çağrısı yerine, işlem zaman uyumsuz olarak bu IoT hub'ı için bir iş oluşturur. İşlem hemen bir JobProperties nesnesi döndürür.
Önemli
Bu makale, paylaşılan erişim imzası kullanarak hizmete bağlanma adımlarını içerir. Bu kimlik doğrulama yöntemi test ve değerlendirme için uygundur, ancak Microsoft Entra ID veya yönetilen kimliklerle bir hizmette kimlik doğrulaması yapmak daha güvenli bir yaklaşımdır. Daha fazla bilgi edinmek için bkz . En iyi güvenlik yöntemleri > Bulut güvenliği.
Aşağıdaki C# kod parçacığı, dışarı aktarma işinin nasıl oluşturulacağını gösterir:
// Call an export job on the IoT hub to retrieve all devices
JobProperties exportJob = await
registryManager.ExportDevicesAsync(containerSasUri, false);
Not
C# kodunuzda RegistryManager sınıfını kullanmak için projenize Microsoft.Azure.Devices NuGet paketini ekleyin. RegistryManager sınıfı Microsoft.Azure.Devices ad alanındadır.
Döndürülen JobProperties meta verilerini kullanarak İşin durumunu sorgulamak için RegistryManager sınıfını kullanabilirsiniz. RegistryManager sınıfının bir örneğini oluşturmak için CreateFromConnectionString yöntemini kullanın.
RegistryManager registryManager =
RegistryManager.CreateFromConnectionString("{your IoT Hub connection string}");
IoT hub'ınızın bağlantı dizesi bulmak için Azure portalında:
IoT Hub'ınıza gidin.
Paylaşılan erişim ilkeleri'ni seçin.
İhtiyacınız olan izinleri dikkate alarak bir ilke seçin.
bu ilkenin bağlantı dizesi kopyalayın.
SDK örneğindeki WaitForJobAsync yönteminden alınan aşağıdaki C# kod parçacığı, işin yürütülmesinin tamamlandığını görmek için beş saniyede bir nasıl yoklama yapılacağını gösterir:
// 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));
}
Not
Depolama hesabınızda IoT Hub'ın bağlantısını kısıtlayan güvenlik duvarı yapılandırmaları varsa, Microsoft güvenilen birinci taraf özel durumunu (yönetilen hizmet kimliğine sahip IoT hub'ları için belirli bölgelerde kullanılabilir) kullanmayı göz önünde bulundurun.
Cihaz içeri/dışarı aktarma iş sınırları
Tüm IoT Hub katmanları için aynı anda yalnızca bir etkin cihaz içeri veya dışarı aktarma işine izin verilir. IoT Hub'da iş işlemleri için hız sınırları da vardır. Daha fazla bilgi için bkz. IoT Hub kotaları ve kısıtlamaları.
Cihazları dışarı aktarma
Paylaşılan erişim imzası (SAS) kullanarak IoT hub kimlik kayıt defterinin tamamını bir Azure Depolama blob kapsayıcısına aktarmak için ExportDevicesAsync yöntemini kullanın. Bu yöntem, denetlediğiniz bir blob kapsayıcısında cihaz bilgilerinizin güvenilir yedeklerini oluşturmanıza olanak tanır.
ExportDevicesAsync yöntemi iki parametre gerektirir:
Blob kapsayıcısının URI'sini içeren dize. Bu URI, kapsayıcıya yazma erişimi veren bir SAS belirteci içermelidir. İş, serileştirilmiş dışarı aktarma cihazı verilerini depolamak için bu kapsayıcıda bir blok blobu oluşturur. SAS belirteci şu izinleri içermelidir:
SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Delete
Kimlik doğrulama anahtarlarını dışarı aktarma verilerinizden dışlamak isteyip istemediğinizi gösteren boole değeri. False ise, kimlik doğrulama anahtarları dışarı aktarma çıkışına eklenir. Aksi takdirde anahtarlar null olarak dışarı aktarılır.
Aşağıdaki C# kod parçacığı, dışarı aktarma verilerinde cihaz kimlik doğrulama anahtarlarını içeren bir dışarı aktarma işinin nasıl başlatıldığını ve ardından tamamlanıp tamamlanmadığını gösterir:
// 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));
}
Benzer kodu SDK örneğinden ExportDevicesAsync yönteminde bulabilirsiniz. İş, çıktısını sağlanan blob kapsayıcısında devices.txt adlı bir blok blobu olarak depolar. Çıkış verileri, satır başına bir cihaz içeren JSON serileştirilmiş cihaz verilerinden oluşur.
Aşağıdaki örnekte çıkış verileri gösterilmektedir:
{"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="}}}
Bir cihazda ikiz verileri varsa, ikiz verileri de cihaz verileriyle birlikte dışarı aktarılır. Aşağıdaki örnekte bu biçim gösterilmektedir. "twinETag" satırından sona kadar olan tüm veriler ikiz veridir.
{
"id":"export-6d84f075-0",
"eTag":"MQ==",
"status":"enabled",
"authentication":null,
"twinETag":"AAAAAAAAAAI=",
"tags":{
"Location":"LivingRoom"
},
"properties":{
"desired":{
"Thermostat":{
"Temperature":75.1,
"Unit":"F"
},
},
"reported":{}
}
}
Kodda bu verilere erişmeniz gerekiyorsa ExportImportDevice sınıfını kullanarak bu verilerin seri durumdan çıkarabilirsiniz. SDK örneğindeki ReadFromBlobAsync yönteminden alınan aşağıdaki C# kod parçacığı, daha önce ExportImportDevice'ten BlobClient örneğine aktarılmış olan cihaz bilgilerinin nasıl okunduğunu gösterir:
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;
}
Cihazları içeri aktarma
RegistryManager sınıfındaki ImportDevicesAsync yöntemi, IoT hub kimlik kayıt defterinde toplu içeri aktarma ve eşitleme işlemleri gerçekleştirmenizi sağlar. ExportDevicesAsync yöntemi gibi ImportDevicesAsync yöntemi de İş çerçevesini kullanır.
ImportDevicesAsync yöntemini kullanmaya dikkat edin çünkü kimlik kayıt defterinizde yeni cihazlar sağlamaya ek olarak mevcut cihazları da güncelleştirebilir ve silebilir.
Uyarı
İçeri aktarma işlemi geri alınamaz. Kimlik kayıt defterinizde toplu değişiklikler yapmanızdan önce ExportDevicesAsync yöntemini kullanarak mevcut verilerinizi her zaman başka bir blob kapsayıcısına yedekleyin.
ImportDevicesAsync yöntemi iki parametre alır:
İşe giriş olarak kullanılacak bir Azure Depolama blob kapsayıcısının URI'sini içeren dize. Bu URI, kapsayıcıya okuma erişimi veren bir SAS belirteci içermelidir. Bu kapsayıcı, kimlik kayıt defterinize aktarılacağınız serileştirilmiş cihaz verilerini içeren devices.txt adlı bir blob içermelidir. İçeri aktarma verileri, ExportImportDevice işinin bir devices.txt blob oluştururken kullandığı JSON biçiminde cihaz bilgilerini içermelidir. SAS belirteci şu izinleri içermelidir:
SharedAccessBlobPermissions.Read
İşin çıktısı olarak kullanılacak bir Azure Depolama blob kapsayıcısının URI'sini içeren dize. İş, tamamlanan içeri aktarma işinden hata bilgilerini depolamak için bu kapsayıcıda bir blok blobu oluşturur. SAS belirteci şu izinleri içermelidir:
SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Delete
Not
İki parametre aynı blob kapsayıcısını işaret edebilir. Çıkış kapsayıcısı ek izinler gerektirdiğinden, ayrı parametreler verileriniz üzerinde daha fazla denetime olanak tanır.
Aşağıdaki C# kod parçacığı, içeri aktarma işinin nasıl başlatılacağını gösterir:
JobProperties importJob =
await registryManager.ImportDevicesAsync(containerSasUri, containerSasUri);
Bu yöntem, cihaz ikizinin verilerini içeri aktarmak için de kullanılabilir. Veri girişinin biçimi ExportDevicesAsync bölümünde gösterilen biçimle aynıdır. Bu şekilde, dışarı aktarılan verileri yeniden içeri aktarabilirsiniz.
İçeri aktarma davranışı
Kimlik kayıt defterinizde aşağıdaki toplu işlemleri gerçekleştirmek için ImportDevicesAsync yöntemini kullanabilirsiniz:
- Yeni cihazların toplu kaydı
- Mevcut cihazların toplu silme işlemleri
- Toplu durum değişiklikleri (cihazları etkinleştirme veya devre dışı bırakma)
- Yeni cihaz kimlik doğrulama anahtarlarını toplu atama
- Cihaz kimlik doğrulama anahtarlarının toplu otomatik olarak yeniden yenilenmesi
- İkiz verilerini toplu güncelleştirme
Önceki işlemlerin herhangi bir bileşimini tek bir ImportDevicesAsync çağrısı içinde gerçekleştirebilirsiniz. Örneğin, yeni cihazları kaydedebilir ve mevcut cihazları aynı anda silebilir veya güncelleştirebilirsiniz. ExportDevicesAsync yöntemiyle birlikte kullanıldığında, tüm cihazlarınızı bir IoT hub'ından diğerine tamamen geçirebilirsiniz.
Cihaz başına içeri aktarma işlemini denetlemek için her cihaz için içeri aktarma serileştirme verilerinde isteğe bağlı importMode özelliğini kullanın. importMode özelliği aşağıdaki seçeneklere sahiptir:
- Oluştur
- CreateOrUpdate (varsayılan)
- CreateOrUpdateIfMatchETag
- Delete
- DeleteIfMatchETag
- Güncelleştirme
- UpdateIfMatchETag
- UpdateTwin
- UpdateTwinIfMatchETag
Bu içeri aktarma modu seçeneklerinin her biri hakkında ayrıntılı bilgi için bkz . ImportMode
İçeri aktarma işlerinin sorunlarını giderme
Cihaz oluşturmak için içeri aktarma işi kullanmak, IoT hub'ının cihaz sayısı sınırına yaklaştığında kota sorunuyla başarısız olabilir. Toplam cihaz sayısı kota sınırından daha düşük olsa bile bu hata oluşabilir. IotHubQuotaExceeded (403002) hatası şu hata iletisiyle döndürülür: "IotHub'da toplam cihaz sayısı ayrılan kotayı aştı."
Bu hatayı alırsanız, IoT hub'ınıza kayıtlı toplam cihaz sayısını döndürmek için aşağıdaki sorguyu kullanabilirsiniz:
SELECT COUNT() as totalNumberOfDevices FROM devices
IoT hub'ına kaydedilebilecek toplam cihaz sayısı hakkında bilgi için bkz . IoT Hub sınırları.
Hala kullanılabilir kota varsa, IotHubQuotaExceeded (403002) hatasıyla başarısız olan cihazlar için iş çıktı blobunu inceleyebilirsiniz. Ardından bu cihazları IoT hub'ına tek tek eklemeyi deneyebilirsiniz. Örneğin, AddDeviceAsync veya AddDeviceWithTwinAsync yöntemlerini kullanabilirsiniz. Aynı hatayla karşılaşabileceğiniz için cihazları başka bir iş kullanarak eklemeyi denemeyin.
Cihazları içeri aktarma örneği – toplu cihaz sağlama
SDK örneğindeki GenerateDevicesAsync yönteminden alınan aşağıdaki C# kod parçacığında birden çok cihaz kimliğinin nasıl oluşturulacağı gösterilmektedir:
- Kimlik doğrulama anahtarlarını dahil edin.
- Bu cihaz bilgilerini bir blok bloba yazın.
- Cihazları kimlik kayıt defterine aktarın.
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}.");
}
Cihazları içeri aktarma örneği – toplu silme
AŞAĞıDAKI C# kod parçacığı, SDK örneğindeki DeleteFromHubAsync yönteminden ioT hub'ından tüm cihazların nasıl silineceği gösterilmektedir:
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}");
}
Kapsayıcı SAS URI'sini alma
Aşağıdaki kod örneği, bir blob kapsayıcısı için okuma, yazma ve silme izinlerine sahip bir SAS URI'sinin nasıl oluşturulacağı gösterilmektedir:
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;
}
Sonraki adımlar
Bu makalede, ioT hub'ında kimlik kayıt defterinde toplu işlemler gerçekleştirmeyi öğrendiniz. Cihazları bir hub'dan diğerine taşıma da dahil olmak üzere bu işlemlerin çoğu, Azure Resource Manager şablonu kullanarak Azure IoT hub'ını el ile geçirme bölümünün IoT hub'ına kayıtlı cihazları yönetme bölümünde kullanılır.