static async Task <string> selfRegisterAndSetConnString(string DeviceId) { Task <string> deviceConnString = null; try { registryManager = RegistryManager.CreateFromConnectionString(iotHubConnString); Device newDevice = new Device(DeviceId); await registryManager.AddDeviceAsync(newDevice); newDevice = await registryManager.GetDeviceAsync(DeviceId); newDevice.Authentication.SymmetricKey.PrimaryKey = CryptoKeyGenerator.GenerateKey(32); newDevice.Authentication.SymmetricKey.SecondaryKey = CryptoKeyGenerator.GenerateKey(32); newDevice = await registryManager.UpdateDeviceAsync(newDevice); string deviceInfo = String.Format("ID={0}\nPrimaryKey={1}\nSecondaryKey={2}", newDevice.Id, newDevice.Authentication.SymmetricKey.PrimaryKey, newDevice.Authentication.SymmetricKey.SecondaryKey); deviceConnString = Task.FromResult(string.Format("HostName={0};DeviceId={1};SharedAccessKey={2}", iotHubName, newDevice.Id, newDevice.Authentication.SymmetricKey.PrimaryKey)); } catch (Exception ex) { Console.WriteLine("An error occured creating device:{0}", ex.ToString()); } return(deviceConnString.Result); }
// POST: api/Device public async Task <IHttpActionResult> Post([FromBody] string Id) { //TODO: Validate deviceID string! var rm = DeviceStuff.DevicesManagementSingleton.GlobalRegistryManager; var olddev = await rm.GetDeviceAsync(Id); if (null != olddev) { return(Unauthorized()); } var dev = new Device(Id); await rm.AddDeviceAsync(dev); dev = await rm.GetDeviceAsync(dev.Id); dev.Authentication.SymmetricKey.PrimaryKey = CryptoKeyGenerator.GenerateKey(32); dev.Authentication.SymmetricKey.SecondaryKey = CryptoKeyGenerator.GenerateKey(32); dev = await rm.UpdateDeviceAsync(dev); var devda = new DeviceStuff.DeviceDataAuth(dev); devda.SetDeviceConnectionString(ConfigurationManager.ConnectionStrings["IotHub"].ConnectionString); return(Ok(devda)); }
public static async Task<EnrollmentGroup> CreateEnrollmentGroup(ProvisioningServiceClient provisioningServiceClient, AttestationMechanismType attestationType, string groupId, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection<string> iothubs, DeviceCapabilities capabilities) { Attestation attestation; switch (attestationType) { case AttestationMechanismType.Tpm: throw new NotSupportedException("Group enrollments do not support tpm attestation"); case AttestationMechanismType.SymmetricKey: string primaryKey = CryptoKeyGenerator.GenerateKey(32); string secondaryKey = CryptoKeyGenerator.GenerateKey(32); attestation = new SymmetricKeyAttestation(primaryKey, secondaryKey); break; case AttestationMechanismType.X509: default: throw new NotSupportedException("Test code has not been written for testing this attestation type yet"); } var enrollmentGroup = new EnrollmentGroup(groupId, attestation) { Capabilities = capabilities, ReprovisionPolicy = reprovisionPolicy, AllocationPolicy = allocationPolicy, CustomAllocationDefinition = customAllocationDefinition, IotHubs = iothubs, }; return await provisioningServiceClient.CreateOrUpdateEnrollmentGroupAsync(enrollmentGroup).ConfigureAwait(false); }
/// <inheritdoc /> public ExportImportDevice CreateNewIoTHubDevice(JToken externalDevice) { var newDevice = new ExportImportDevice() { Id = externalDevice["name"].ToString(), ImportMode = ImportMode.Create, Status = DeviceStatus.Enabled, Authentication = new AuthenticationMechanism() { SymmetricKey = new SymmetricKey() { PrimaryKey = CryptoKeyGenerator.GenerateKey(32), SecondaryKey = CryptoKeyGenerator.GenerateKey(32) } }, Tags = new Microsoft.Azure.Devices.Shared.TwinCollection(), }; foreach (var prop in GetRequiredTwinProperties()) { var sourcePropertyValue = externalDevice[prop]; if (sourcePropertyValue != null) { newDevice.Tags[prop] = sourcePropertyValue.ToString(); } } newDevice.Tags["ref"] = externalDevice["ref"].ToString(); return(newDevice); }
public async Task DeviceAuthenticationBadAuthConfigTest7() { var deviceBadAuthConfig = new Device("123") { ConnectionState = DeviceConnectionState.Connected, Authentication = new AuthenticationMechanism() { SymmetricKey = new SymmetricKey() { PrimaryKey = CryptoKeyGenerator.GenerateKey(32), SecondaryKey = null }, X509Thumbprint = null } }; var restOpMock = new Mock <IHttpClientHelper>(); restOpMock.Setup( restOp => restOp.PutAsync(It.IsAny <Uri>(), It.IsAny <Device>(), It.IsAny <PutOperationType>(), It.IsAny <IDictionary <HttpStatusCode, Func <HttpResponseMessage, Task <Exception> > > >(), It.IsAny <CancellationToken>())).ReturnsAsync(deviceBadAuthConfig); var registryManager = new HttpRegistryManager(restOpMock.Object, IotHubName); await registryManager.AddDeviceAsync(deviceBadAuthConfig); }
public static async Task <EnrollmentGroup> CreateEnrollmentGroupAsync( ProvisioningServiceClient provisioningServiceClient, AttestationMechanismType attestationType, string groupId, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection <string> iothubs, DeviceCapabilities capabilities, MsTestLogger logger) { Attestation attestation; switch (attestationType) { case AttestationMechanismType.Tpm: throw new NotSupportedException("Group enrollments do not support tpm attestation"); case AttestationMechanismType.SymmetricKey: string primaryKey = CryptoKeyGenerator.GenerateKey(32); string secondaryKey = CryptoKeyGenerator.GenerateKey(32); attestation = new SymmetricKeyAttestation(primaryKey, secondaryKey); break; case AttestationMechanismType.X509: default: throw new NotSupportedException("Test code has not been written for testing this attestation type yet"); } var enrollmentGroup = new EnrollmentGroup(groupId, attestation) { Capabilities = capabilities, ReprovisionPolicy = reprovisionPolicy, AllocationPolicy = allocationPolicy, CustomAllocationDefinition = customAllocationDefinition, IotHubs = iothubs, }; EnrollmentGroup createdEnrollmentGroup = null; await RetryOperationHelper .RetryOperationsAsync( async() => { createdEnrollmentGroup = await provisioningServiceClient.CreateOrUpdateEnrollmentGroupAsync(enrollmentGroup).ConfigureAwait(false); }, s_provisioningServiceRetryPolicy, s_retryableExceptions, logger) .ConfigureAwait(false); if (createdEnrollmentGroup == null) { throw new ArgumentException($"The enrollment entry with group Id {groupId} could not be created, exiting test."); } return(createdEnrollmentGroup); }
static void Main(string[] args) { var key = CryptoKeyGenerator.GenerateKey(40); Console.WriteLine("This is your SAS generation and validation key:"); Console.WriteLine(); Console.WriteLine(key); Console.WriteLine(); Console.WriteLine("Put the following line in appsettings.json of the client program"); Console.WriteLine(); Console.WriteLine("\"validationKey\": \"" + key + "\""); Console.WriteLine(); Console.WriteLine("and as an application setting in your azure function app"); }
public static async Task <IndividualEnrollment> CreateIndividualEnrollment(ProvisioningServiceClient provisioningServiceClient, AttestationType attestationType, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection <string> iotHubsToProvisionTo, DeviceCapabilities capabilities) { string registrationId = AttestationTypeToString(attestationType) + "-registration-id-" + Guid.NewGuid(); Attestation attestation; IndividualEnrollment individualEnrollment; switch (attestationType) { case AttestationType.Tpm: using (var tpmSim = new SecurityProviderTpmSimulator(registrationId)) { string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey()); var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { Capabilities = capabilities, AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, CustomAllocationDefinition = customAllocationDefinition, IotHubs = iotHubsToProvisionTo }; IndividualEnrollment enrollment = await provisioningService.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false); attestation = new TpmAttestation(base64Ek); enrollment.Attestation = attestation; return(await provisioningService.CreateOrUpdateIndividualEnrollmentAsync(enrollment).ConfigureAwait(false)); } case AttestationType.SymmetricKey: string primaryKey = CryptoKeyGenerator.GenerateKey(32); string secondaryKey = CryptoKeyGenerator.GenerateKey(32); attestation = new SymmetricKeyAttestation(primaryKey, secondaryKey); break; case AttestationType.x509: default: throw new NotSupportedException("Test code has not been written for testing this attestation type yet"); } individualEnrollment = new IndividualEnrollment(registrationId, attestation); individualEnrollment.Capabilities = capabilities; individualEnrollment.CustomAllocationDefinition = customAllocationDefinition; individualEnrollment.ReprovisionPolicy = reprovisionPolicy; individualEnrollment.IotHubs = iotHubsToProvisionTo; individualEnrollment.AllocationPolicy = allocationPolicy; return(await provisioningServiceClient.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false)); }
static async Task <Device> CreateDevice(RegistryManager registryManager, string hostName, string deviceName) { string primaryKey = CryptoKeyGenerator.GenerateKey(32); string secondaryKey = CryptoKeyGenerator.GenerateKey(32); Device device = new Device(deviceName); device.Authentication = new AuthenticationMechanism(); device.Authentication.SymmetricKey.PrimaryKey = primaryKey; device.Authentication.SymmetricKey.SecondaryKey = secondaryKey; await registryManager.AddDeviceAsync(device); string deviceConnectionString = "HostName=" + hostName + ";DeviceId=" + deviceName + ";SharedAccessKey=" + primaryKey; Logger.Log(Logger.LogLevel.Minimal, "ConnectionString=" + deviceConnectionString); return(device); }
public async Task ExecuteAsync(OperationParameters parameters) { try { var deviceId = parameters.Arguments["deviceid"].ToString(); if (string.IsNullOrWhiteSpace(deviceId)) { throw new ArgumentNullException("deviceid"); } var autoGenerateDevicekey = Convert.ToBoolean(parameters.Arguments["auto"]); if (autoGenerateDevicekey) { var device = new Microsoft.Azure.Devices.Device(deviceId); device.Authentication = new Microsoft.Azure.Devices.AuthenticationMechanism(); device.Authentication.SymmetricKey.PrimaryKey = CryptoKeyGenerator.GenerateKey(32); device.Authentication.SymmetricKey.SecondaryKey = CryptoKeyGenerator.GenerateKey(32); var devices = await this.IoTHubContext.RegistryManager.AddDeviceAsync(device); } else { var deviceKey = parameters.Arguments["deviceKey"].ToString(); if (string.IsNullOrWhiteSpace(deviceKey)) { throw new ArgumentNullException("devicekey"); } var device = new Microsoft.Azure.Devices.Device(deviceId); device.Authentication = new Microsoft.Azure.Devices.AuthenticationMechanism(); device.Authentication.SymmetricKey.PrimaryKey = deviceKey; device.Authentication.SymmetricKey.SecondaryKey = deviceKey; var devices = await this.IoTHubContext.RegistryManager.AddDeviceAsync(device); } } catch (Exception exception) { // return Task.FromResult(true); } }
public async void RegisterDevice(string deviceId, string deviceDescription) { var tags = "{\"tags\":" + deviceDescription + "}"; var primaryKey = CryptoKeyGenerator.GenerateKey(32); var secondaryKey = CryptoKeyGenerator.GenerateKey(32); var newDevice = new Device(deviceId); newDevice.Authentication = new AuthenticationMechanism(); newDevice.Authentication.SymmetricKey.PrimaryKey = primaryKey; newDevice.Authentication.SymmetricKey.SecondaryKey = secondaryKey; var device = await registryManager.AddDeviceAsync(newDevice); Type twinType = typeof(Twin); var deviceTwin = await registryManager.GetTwinAsync(deviceId); dynamic dp = JsonConvert.DeserializeObject(tags, twinType); dp.DeviceId = deviceId; dp.ETag = deviceTwin.ETag; await registryManager.UpdateTwinAsync(dp.DeviceId, dp, dp.ETag); }
public static async Task <IndividualEnrollment> CreateIndividualEnrollmentAsync( ProvisioningServiceClient provisioningServiceClient, string registrationId, AttestationMechanismType attestationType, X509Certificate2 authenticationCertificate, ReprovisionPolicy reprovisionPolicy, AllocationPolicy allocationPolicy, CustomAllocationDefinition customAllocationDefinition, ICollection <string> iotHubsToProvisionTo, DeviceCapabilities capabilities, MsTestLogger logger) { Attestation attestation; IndividualEnrollment individualEnrollment; IndividualEnrollment createdEnrollment = null; switch (attestationType) { case AttestationMechanismType.Tpm: using (var tpmSim = new SecurityProviderTpmSimulator(registrationId)) { string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey()); individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { Capabilities = capabilities, AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, CustomAllocationDefinition = customAllocationDefinition, IotHubs = iotHubsToProvisionTo }; IndividualEnrollment temporaryCreatedEnrollment = null; await RetryOperationHelper .RetryOperationsAsync( async() => { temporaryCreatedEnrollment = await provisioningServiceClient.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false); }, s_provisioningServiceRetryPolicy, s_retryableExceptions, logger) .ConfigureAwait(false); if (temporaryCreatedEnrollment == null) { throw new ArgumentException($"The enrollment entry with registration Id {registrationId} could not be created, exiting test."); } attestation = new TpmAttestation(base64Ek); temporaryCreatedEnrollment.Attestation = attestation; await RetryOperationHelper .RetryOperationsAsync( async() => { createdEnrollment = await provisioningServiceClient.CreateOrUpdateIndividualEnrollmentAsync(temporaryCreatedEnrollment).ConfigureAwait(false); }, s_provisioningServiceRetryPolicy, s_retryableExceptions, logger) .ConfigureAwait(false); if (createdEnrollment == null) { throw new ArgumentException($"The enrollment entry with registration Id {registrationId} could not be updated, exiting test."); } return(createdEnrollment); } case AttestationMechanismType.SymmetricKey: string primaryKey = CryptoKeyGenerator.GenerateKey(32); string secondaryKey = CryptoKeyGenerator.GenerateKey(32); attestation = new SymmetricKeyAttestation(primaryKey, secondaryKey); break; case AttestationMechanismType.X509: attestation = X509Attestation.CreateFromClientCertificates(authenticationCertificate); break; default: throw new NotSupportedException("Test code has not been written for testing this attestation type yet"); } individualEnrollment = new IndividualEnrollment(registrationId, attestation) { Capabilities = capabilities, AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, CustomAllocationDefinition = customAllocationDefinition, IotHubs = iotHubsToProvisionTo, }; await RetryOperationHelper .RetryOperationsAsync( async() => { createdEnrollment = await provisioningServiceClient.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false); }, s_provisioningServiceRetryPolicy, s_retryableExceptions, logger) .ConfigureAwait(false); if (createdEnrollment == null) { throw new ArgumentException($"The enrollment entry with registration Id {registrationId} could not be created, exiting test."); } return(createdEnrollment); }
private void autoGenerateDeviceKeys() { primaryKeyTextBox.Text = CryptoKeyGenerator.GenerateKey(32); secondaryKeyTextBox.Text = CryptoKeyGenerator.GenerateKey(32); }
public static string GenerateSymmetricKey() { return(CryptoKeyGenerator.GenerateKey(32)); }
public DeviceKeys() { this._primaryKey = CryptoKeyGenerator.GenerateKey(32); this._secondaryKey = CryptoKeyGenerator.GenerateKey(32); }
public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestMessage req, TraceWriter log) { log.Info("C# HTTP trigger function processed a request."); var IoTHubConnectionString = ConfigurationManager.AppSettings["IoTHub"]; var validationKey = ConfigurationManager.AppSettings["validationKey"]; RegistryManager rm; try { rm = RegistryManager.CreateFromConnectionString(IoTHubConnectionString); } catch (Exception ex) { log.Info("Cannot access IoT Hub"); return(req.CreateResponse(HttpStatusCode.InternalServerError, "Cannot access IoT Hub")); } // Parsing and validating function arguments // parse query parameter string SerialNumber = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "SerialNumber", true) == 0) .Value; if (SerialNumber == null) { // Get request body dynamic data = await req.Content.ReadAsAsync <object>(); SerialNumber = data?.SerialNumber; } if (SerialNumber == null) { log.Info("No serial number given"); return(req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a SerialNumber on the query string or in the request body")); } log.Info("Creating device for serial number \"" + SerialNumber + "\""); string sr = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "sr", true) == 0) .Value; if (sr == null) { // Get request body dynamic data = await req.Content.ReadAsAsync <object>(); sr = data?.sr; } if (sr == null) { log.Info("No sr given"); return(req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a Shared Access Signature on the query string or in the request body")); } string sig = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "sig", true) == 0) .Value; if (sig == null) { // Get request body dynamic data = await req.Content.ReadAsAsync <object>(); sig = data?.sig; } if (sig == null) { log.Info("No sig given"); return(req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a Shared Access Signature on the query string or in the request body")); } string se = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "se", true) == 0) .Value; if (se == null) { // Get request body dynamic data = await req.Content.ReadAsAsync <object>(); se = data?.se; } if (se == null) { log.Info("No se given"); return(req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a Shared Access Signature on the query string or in the request body")); } int intserial = 0; if (!int.TryParse(SerialNumber, out intserial)) { log.Info("noninteger SerialNumber"); return(req.CreateResponse(HttpStatusCode.BadRequest, "This is not a number")); } string requestString = "https://" + req.RequestUri.Authority + req.RequestUri.LocalPath; log.Info("URL is " + requestString); if (!validateSasToken(sr, sig, se, requestString, validationKey, SerialNumber, log)) { log.Info("Invalid Token"); return(req.CreateResponse(HttpStatusCode.BadRequest, "This is not a valid token")); } log.Info("SAS validation successful!"); //the validation of the serial number happens after the SAS validation so no one can try out valid serial numbers without an SAS if (intserial % 7 != 0) { log.Info("not divisable by 7"); return(req.CreateResponse(HttpStatusCode.BadRequest, "This is not a valid number")); } if (null != await rm.GetDeviceAsync(SerialNumber)) { log.Info("Device already created"); return(req.CreateResponse(HttpStatusCode.BadRequest, "This device already exists")); } Device device = new Device(SerialNumber); try { device = await rm.AddDeviceAsync(device); } catch (Exception ex) { log.Info("Create Device Failed"); return(req.CreateResponse(HttpStatusCode.InternalServerError, "Create Device Failed")); } device.Authentication.SymmetricKey.PrimaryKey = CryptoKeyGenerator.GenerateKey(32); device.Authentication.SymmetricKey.SecondaryKey = CryptoKeyGenerator.GenerateKey(32); try { await rm.UpdateDeviceAsync(device); } catch (Exception ex) { log.Info("Setting Security Information failed"); return(req.CreateResponse(HttpStatusCode.InternalServerError, "Setting Security Information failed")); } StringBuilder deviceConnectionStringBuilder = new StringBuilder(); var hostName = String.Empty; var tokenArray = IoTHubConnectionString.Split(';'); for (int i = 0; i < tokenArray.Length; i++) { var keyValueArray = tokenArray[i].Split('='); if (keyValueArray[0] == "HostName") { hostName = tokenArray[i] + ';'; break; } } if (!String.IsNullOrWhiteSpace(hostName)) { deviceConnectionStringBuilder.Append(hostName); deviceConnectionStringBuilder.AppendFormat("DeviceId={0}", device.Id); deviceConnectionStringBuilder.AppendFormat(";SharedAccessKey={0}", device.Authentication.SymmetricKey.PrimaryKey); } else { log.Info("Creating Connection String Failed"); return(req.CreateResponse(HttpStatusCode.InternalServerError, "Creating Connection String failed")); } var deviceConnectionString = deviceConnectionStringBuilder.ToString(); return(req.CreateResponse(HttpStatusCode.OK, deviceConnectionString)); }
/// <summary>c /// Generate NumToAdd devices and add them to the hub. /// To do this, generate each identity. /// Include authentication keys. /// Write the device info to a block blob. /// Import the devices into the identity registry by calling the import job. /// </summary> private async Task GenerateAndAddDevices(string hubConnectionString, string containerURI, int NumToAdd, string devicesToAdd) { int interimProgressCount = 0; int displayProgressCount = 1000; int totalProgressCount = 0; //generate reference for list of new devices you're going to add, will write list to this blob CloudBlockBlob generatedListBlob = _cloudBlobContainer.GetBlockBlobReference(devicesToAdd); // define serializedDevices as a generic list<string> List <string> serializedDevices = new List <string>(); for (var 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.ToString("D8") + "-" + Guid.NewGuid().ToString(); string deviceName = $"Hub_{i.ToString("D8")}-{Guid.NewGuid().ToString()}"; Debug.Print($"device = '{deviceName}'\n"); // Create a new ExportImportDevice. // CryptoKeyGenerator is in the Microsoft.Azure.Devices.Common namespace. var deviceToAdd = new ExportImportDevice() { Id = deviceName, Status = DeviceStatus.Enabled, Authentication = new AuthenticationMechanism { SymmetricKey = new SymmetricKey { PrimaryKey = CryptoKeyGenerator.GenerateKey(32), SecondaryKey = CryptoKeyGenerator.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 {0} messages.", totalProgressCount); 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)); // Before writing the new file, make sure there's not already one there. await generatedListBlob.DeleteIfExistsAsync().ConfigureAwait(false); // Write list of serialized objects to the blob. using (CloudBlobStream stream = await generatedListBlob.OpenWriteAsync().ConfigureAwait(false)) { byte[] bytes = Encoding.UTF8.GetBytes(sb.ToString()); for (var i = 0; i < bytes.Length; i += 500) { int length = Math.Min(bytes.Length - i, 500); await stream.WriteAsync(bytes, i, length).ConfigureAwait(false); } } Console.WriteLine("Creating and running registry manager job to write the new 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. JobProperties importJob = new JobProperties(); RegistryManager registryManager = RegistryManager.CreateFromConnectionString(hubConnectionString); try { // First URL is the container to import from; the file must be called devices.txt // Second URL points to the container to write errors to as a block 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. importJob = await registryManager.ImportDevicesAsync(containerURI, containerURI, devicesToAdd).ConfigureAwait(false); // This will catch any errors if something bad happens to interrupt the job. while (true) { importJob = await registryManager.GetJobAsync(importJob.JobId).ConfigureAwait(false); if (importJob.Status == JobStatus.Completed || importJob.Status == JobStatus.Failed || importJob.Status == JobStatus.Cancelled) { // Job has finished executing break; } await Task.Delay(TimeSpan.FromSeconds(5)).ConfigureAwait(false); } } catch (Exception ex) { Debug.Print("exception message {0}", ex.Message); } }