Example #1
0
        public async Task RunSampleAsync()
        {
            try
            {
                Console.WriteLine($"RegistrationID = {_security.GetRegistrationID()}");
                VerifyRegistrationIdFormat(_security.GetRegistrationID());

                Console.Write("ProvisioningClient RegisterAsync . . . ");
                DeviceRegistrationResult result = await _provClient.RegisterAsync().ConfigureAwait(false);

                Console.WriteLine($"{result.Status}");
                Console.WriteLine($"ProvisioningClient AssignedHub: {result.AssignedHub}; DeviceID: {result.DeviceId}");

                if (result.Status != ProvisioningRegistrationStatusType.Assigned)
                {
                    return;
                }

                Microsoft.Azure.Devices.Client.IAuthenticationMethod auth;
                if (_security is SecurityProviderTpm)
                {
                    Console.WriteLine("Creating TPM DeviceClient authentication.");
                    auth = new DeviceAuthenticationWithTpm(result.DeviceId, _security as SecurityProviderTpm);
                }
                else if (_security is SecurityProviderX509)
                {
                    Console.WriteLine("Creating X509 DeviceClient authentication.");
                    auth = new DeviceAuthenticationWithX509Certificate(result.DeviceId, (_security as SecurityProviderX509).GetAuthenticationCertificate());
                }
                else if (_security is SecurityProviderSymmetricKey)
                {
                    Console.WriteLine("Creating Symmetric Key DeviceClient authenication");
                    auth = new DeviceAuthenticationWithRegistrySymmetricKey(result.DeviceId, (_security as SecurityProviderSymmetricKey).GetPrimaryKey());
                }
                else
                {
                    throw new NotSupportedException("Unknown authentication type.");
                }

                using (DeviceClient iotClient = DeviceClient.Create(result.AssignedHub, auth, Microsoft.Azure.Devices.Client.TransportType.Amqp))
                {
                    Console.WriteLine("DeviceClient OpenAsync.");
                    await iotClient.OpenAsync().ConfigureAwait(false);

                    Console.WriteLine("DeviceClient SendEventAsync.");
                    await iotClient.SendEventAsync(new Microsoft.Azure.Devices.Client.Message(Encoding.UTF8.GetBytes("TestMessage"))).ConfigureAwait(false);

                    Console.WriteLine("DeviceClient CloseAsync.");
                    await iotClient.CloseAsync().ConfigureAwait(false);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
        public static async Task RunAsync(ProvisioningDeviceClient provisioningDeviceClient, SecurityProvider security)
        {
            Console.WriteLine($"RegistrationID = {security.GetRegistrationID()}");

            Console.Write("ProvisioningClient RegisterAsync . . . ");
            DeviceRegistrationResult result = await provisioningDeviceClient.RegisterAsync().ConfigureAwait(false);

            Console.WriteLine($"{result.Status}");
            Console.WriteLine($"ProvisioningClient AssignedHub: {result.AssignedHub}; DeviceID: {result.DeviceId}");

            if (result.Status == ProvisioningRegistrationStatusType.Assigned)
            {
                X509Certificate2 certificate = (security as SecurityProviderX509).GetAuthenticationCertificate();
                Console.WriteLine($"Registration certificate thumbprint: {certificate.Thumbprint}");
                IAuthenticationMethod auth = new DeviceAuthenticationWithX509Certificate(result.DeviceId, certificate);
                using (DeviceClient iotClient = DeviceClient.Create(result.AssignedHub, auth, TransportType.Amqp))
                {
                    Console.WriteLine("DeviceClient OpenAsync.");
                    await iotClient.OpenAsync().ConfigureAwait(false);

                    Console.WriteLine("DeviceClient SendEventAsync.");
                    await iotClient.SendEventAsync(new Message(Encoding.UTF8.GetBytes("TestMessage"))).ConfigureAwait(false);

                    Console.WriteLine("DeviceClient CloseAsync.");
                    await iotClient.CloseAsync().ConfigureAwait(false);
                }
            }
        }
Example #3
0
        public async Task <DeviceClient> RunAsync()
        {
            Console.WriteLine($"RegistrationID = {_security.GetRegistrationID()}");
            VerifyRegistrationIdFormat(_security.GetRegistrationID());

            Console.Write("ProvisioningClient RegisterAsync . . . ");
            DeviceRegistrationResult result = await _provClient.RegisterAsync().ConfigureAwait(false);

            Console.WriteLine($"{result.Status}");
            Console.WriteLine($"ProvisioningClient AssignedHub: {result.AssignedHub}; DeviceID: {result.DeviceId}");

            if (result.Status != ProvisioningRegistrationStatusType.Assigned)
            {
                return(null);
            }

            IAuthenticationMethod auth;

            if (_security is SecurityProviderTpm)
            {
                Console.WriteLine("Creating TPM DeviceClient authentication.");
                auth = new DeviceAuthenticationWithTpm(result.DeviceId, _security as SecurityProviderTpm);
            }
            else if (_security is SecurityProviderX509)
            {
                Console.WriteLine("Creating X509 DeviceClient authentication.");
                auth = new DeviceAuthenticationWithX509Certificate(result.DeviceId, (_security as SecurityProviderX509).GetAuthenticationCertificate());
            }
            else if (_security is SecurityProviderSymmetricKey)
            {
                Console.WriteLine("Creating Symmetric Key DeviceClient authenication");
                auth = new DeviceAuthenticationWithRegistrySymmetricKey(result.DeviceId, (_security as SecurityProviderSymmetricKey).GetPrimaryKey());
            }
            else
            {
                throw new NotSupportedException("Unknown authentication type.");
            }

            DeviceClient iotClient = DeviceClient.Create(result.AssignedHub, auth, TransportType.Amqp);

            return(iotClient);
        }
        public async Task RunAsync()
        {
            Console.WriteLine($"RegistrationID = {security.GetRegistrationID()}");

            // Register the Device with DPS
            Console.Write("ProvisioningClient RegisterAsync . . . ");
            DeviceRegistrationResult result = await provClient.RegisterAsync().ConfigureAwait(false);

            Console.WriteLine($"Device Registration Status: {result.Status}");
            Console.WriteLine($"ProvisioningClient AssignedHub: {result.AssignedHub}; DeviceID: {result.DeviceId}");
            deviceId = result.DeviceId;

            // Verify Device Registration Status
            if (result.Status != ProvisioningRegistrationStatusType.Assigned)
            {
                throw new Exception($"DeviceRegistrationResult.Status is NOT 'Assigned'");
            }

            // Create x509 DeviceClient Authentication
            Console.WriteLine("Creating X509 DeviceClient authentication.");
            var auth = new DeviceAuthenticationWithX509Certificate(result.DeviceId, (security as SecurityProviderX509).GetAuthenticationCertificate());


            Console.WriteLine("Simulated Device. Ctrl-C to exit.");
            using (iotClient = DeviceClient.Create(result.AssignedHub, auth, TransportType.Amqp))
            {
                // Explicitly open DeviceClient to communicate with Azure IoT Hub
                Console.WriteLine("DeviceClient OpenAsync.");
                await iotClient.OpenAsync().ConfigureAwait(false);


                // TODO 1: Setup OnDesiredPropertyChanged Event Handling to receive Desired Properties changes
                Console.WriteLine("Connecting SetDesiredPropertyUpdateCallbackAsync event handler...");
                await iotClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChanged, null).ConfigureAwait(false);


                // TODO 2: Load Device Twin Properties since device is just starting up
                Console.WriteLine("Loading Device Twin Properties...");
                var twin = await iotClient.GetTwinAsync().ConfigureAwait(false);

                // Use OnDesiredPropertyChanged event handler to set the loaded Device Twin Properties (re-use!)
                await OnDesiredPropertyChanged(twin.Properties.Desired, null);


                // Start reading and sending device telemetry
                Console.WriteLine("Start reading and sending device telemetry...");
                await SendDeviceToCloudMessagesAsync(iotClient);

                // Explicitly close DeviceClient
                Console.WriteLine("DeviceClient CloseAsync.");
                await iotClient.CloseAsync().ConfigureAwait(false);
            }
        }
Example #5
0
        public async Task <DeviceClient> ProvisionDeviceAndGetClientAsync()
        {
            Console.WriteLine($"RegistrationID = {_security.GetRegistrationID()}");
            VerifyRegistrationIdFormat(_security.GetRegistrationID());

            Console.Write("ProvisioningClient RegisterAsync . . . ");
            DeviceRegistrationResult result = await _provClient.RegisterAsync().ConfigureAwait(false);

            Console.WriteLine($"{result.Status}");
            Console.WriteLine($"ProvisioningClient AssignedHub: {result.AssignedHub}; DeviceID: {result.DeviceId}");

            if (result.Status != ProvisioningRegistrationStatusType.Assigned)
            {
                Console.WriteLine($"Provisioning failed : Status: {result.Status}");
                return(null);
            }

            Console.WriteLine("Creating X509 DeviceClient authentication.");
            IAuthenticationMethod auth = new DeviceAuthenticationWithX509Certificate(result.DeviceId, (_security as SecurityProviderX509).GetAuthenticationCertificate());

            return(DeviceClient.Create(result.AssignedHub, auth, TransportType.Amqp));
        }
Example #6
0
        public async Task RunAsync()
        {
            colorMessage($"\nRegistrationID = {_security.GetRegistrationID()}", ConsoleColor.Yellow);

            // Register the Device with DPS.
            whiteMessage("ProvisioningClient RegisterAsync . . . ");
            DeviceRegistrationResult result = await _provClient.RegisterAsync().ConfigureAwait(false);

            if (result.Status == ProvisioningRegistrationStatusType.Assigned)
            {
                greenMessage($"Device Registration Status: {result.Status}");
                greenMessage($"ProvisioningClient AssignedHub: {result.AssignedHub}; DeviceID: {result.DeviceId}");
            }
            else
            {
                redMessage($"Device Registration Status: {result.Status}");
                throw new Exception($"DeviceRegistrationResult.Status is NOT 'Assigned'");
            }

            // Create x509 DeviceClient Authentication.
            whiteMessage("Creating X509 DeviceClient authentication.");
            var auth = new DeviceAuthenticationWithX509Certificate(result.DeviceId, (_security as SecurityProviderX509).GetAuthenticationCertificate());

            whiteMessage("Simulated Device. Ctrl-C to exit.");
            using (s_deviceClient = DeviceClient.Create(result.AssignedHub, auth, TransportType.Amqp))
            {
                // Explicitly open DeviceClient to communicate with Azure IoT Hub.
                whiteMessage("DeviceClient OpenAsync.");
                await s_deviceClient.OpenAsync().ConfigureAwait(false);

                // Setup OnDesiredPropertyChanged Event Handling to receive Desired Properties changes.
                whiteMessage("Connecting SetDesiredPropertyUpdateCallbackAsync event handler...");
                await s_deviceClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChanged, null).ConfigureAwait(false);

                // Load Device Twin Properties since device is just starting up.
                whiteMessage("Loading Device Twin Properties...");
                var twin = await s_deviceClient.GetTwinAsync().ConfigureAwait(false);

                // Use OnDesiredPropertyChanged event handler to set the loaded Device Twin properties.
                await OnDesiredPropertyChanged(twin.Properties.Desired, null);

                // Start reading and sending device telemetry.
                colorMessage("\nStart reading and sending device telemetry...\n", ConsoleColor.Yellow);
                await SendDeviceToCloudMessagesAsync2(s_deviceClient);

                // Explicitly close DeviceClient.
                whiteMessage("DeviceClient CloseAsync.");
                await s_deviceClient.CloseAsync().ConfigureAwait(false);
            }
        }
Example #7
0
        public async Task RunSampleAsync()
        {
            Console.WriteLine($"RegistrationID = {_security.GetRegistrationID()}");
            VerifyRegistrationIdFormat(_security.GetRegistrationID());

            Console.Write("ProvisioningClient RegisterAsync . . . ");
            DeviceRegistrationResult result = await _provClient.RegisterAsync().ConfigureAwait(false);

            Console.WriteLine($"{result.Status}");
            Console.WriteLine($"ProvisioningClient AssignedHub: {result.AssignedHub}; DeviceID: {result.DeviceId}");

            if (result.Status != ProvisioningRegistrationStatusType.Assigned)
            {
                return;
            }

            IAuthenticationMethod auth;

            if (_security is SecurityProviderSymmetricKey)
            {
                Console.WriteLine("Creating Symmetric Key DeviceClient authenication");
                auth = new DeviceAuthenticationWithRegistrySymmetricKey(result.DeviceId, (_security as SecurityProviderSymmetricKey).GetPrimaryKey());
            }
            else
            {
                throw new NotSupportedException("Unknown authentication type.");
            }

            deviceClient = DeviceClient.Create(result.AssignedHub, auth, TransportType.Amqp);
            await deviceClient.OpenAsync().ConfigureAwait(false);

#pragma warning disable 4014
            Task.Run(async() => await ListenCommands());
#pragma warning restore 4014

            SendDeviceToCloudMessagesAsync();
        }
Example #8
0
        public async Task RunAsync()
        {
            Console.WriteLine($"RegistrationID = {_security.GetRegistrationID()}");

            Console.Write("ProvisioningClient RegisterAsync . . . ");
            DeviceRegistrationResult result = await _provClient.RegisterAsync().ConfigureAwait(false);

            Console.WriteLine($"Device Registration Status: {result.Status}");
            Console.WriteLine($"ProvisioningClient AssignedHub: {result.AssignedHub}; DeviceID: {result.DeviceId}");

            if (result.Status != ProvisioningRegistrationStatusType.Assigned)
            {
                throw new Exception($"DeviceRegistrationResult.Status is NOT 'Assigned'");
            }

            Console.WriteLine("Creating Symmetric Key DeviceClient authentication");
            IAuthenticationMethod auth = new DeviceAuthenticationWithRegistrySymmetricKey(result.DeviceId, (_security as SecurityProviderSymmetricKey).GetPrimaryKey());


            Console.WriteLine("Simulated Device. Ctrl-C to exit.");
            using (iotClient = DeviceClient.Create(result.AssignedHub, auth, TransportType.Amqp))
            {
                Console.WriteLine("DeviceClient OpenAsync.");
                await iotClient.OpenAsync().ConfigureAwait(false);


                // TODO 1: Setup OnDesiredPropertyChanged Event Handling
                Console.WriteLine("Connecting SetDesiredPropertyUpdateCallbackAsync event handler...");
                await iotClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChanged, null).ConfigureAwait(false);


                // TODO 2: Load Device Twin Properties
                Console.WriteLine("Loading Device Twin Properties...");
                var twin = await iotClient.GetTwinAsync().ConfigureAwait(false);
                await OnDesiredPropertyChanged(twin.Properties.Desired, null);


                // Start reading and sending device telemetry
                Console.WriteLine("Start reading and sending device telemetry...");
                await SendDeviceToCloudMessagesAsync(iotClient);

                //Console.WriteLine("DeviceClient CloseAsync.");
                //await iotClient.CloseAsync().ConfigureAwait(false);
            }
        }
Example #9
0
        public async Task RunAsync()
        {
            colorMessage($"\nRegistrationID = {_security.GetRegistrationID()}", ConsoleColor.Yellow);

            // Register the Device with DPS.
            whiteMessage("ProvisioningClient RegisterAsync . . . ");
            DeviceRegistrationResult result = await _provClient.RegisterAsync().ConfigureAwait(false);

            if (result.Status == ProvisioningRegistrationStatusType.Assigned)
            {
                greenMessage($"Device Registration Status: {result.Status}");
                greenMessage($"ProvisioningClient AssignedHub: {result.AssignedHub}; DeviceID: {result.DeviceId}");
            }
            else
            {
                redMessage($"Device Registration Status: {result.Status}");
                throw new Exception($"DeviceRegistrationResult.Status is NOT 'Assigned'");
            }

            // Create x509 DeviceClient Authentication.
            whiteMessage("Creating X509 DeviceClient authentication.");
            var auth = new DeviceAuthenticationWithX509Certificate(result.DeviceId, (_security as SecurityProviderX509).GetAuthenticationCertificate());

            whiteMessage("Simulated Device. Ctrl-C to exit.");
            using (s_deviceClient = DeviceClient.Create(result.AssignedHub, auth, TransportType.Amqp))
            {
                // Explicitly open DeviceClient to communicate with Azure IoT Hub.
                whiteMessage("DeviceClient OpenAsync.");
                await s_deviceClient.OpenAsync().ConfigureAwait(false);

                // Start reading and sending device telemetry.
                colorMessage("\nStart reading and sending device telemetry...\n", ConsoleColor.Yellow);
                await SendDeviceToCloudMessagesAsync(s_deviceClient);
                await SendDeviceToCloudLogMessagesAsync(s_deviceClient);

                // Explicitly close DeviceClient.
                whiteMessage("DeviceClient CloseAsync.");
                await s_deviceClient.CloseAsync().ConfigureAwait(false);
            }
        }
Example #10
0
        /// <summary>
        /// Update the enrollment under test such that it forces it to reprovision to the hubs within <paramref name="iotHubsToReprovisionTo"/>
        /// </summary>
        private async Task UpdateEnrollmentToForceReprovision(EnrollmentType?enrollmentType, ProvisioningServiceClient provisioningServiceClient, ICollection <String> iotHubsToReprovisionTo, SecurityProvider security, string groupId)
        {
            if (enrollmentType == EnrollmentType.Individual)
            {
                IndividualEnrollment individualEnrollment = await provisioningServiceClient.GetIndividualEnrollmentAsync(security.GetRegistrationID()).ConfigureAwait(false);

                individualEnrollment.IotHubs = iotHubsToReprovisionTo;
                IndividualEnrollment individualEnrollmentResult = await provisioningServiceClient.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false);
            }
            else
            {
                EnrollmentGroup enrollmentGroup = await provisioningServiceClient.GetEnrollmentGroupAsync(groupId).ConfigureAwait(false);

                enrollmentGroup.IotHubs = iotHubsToReprovisionTo;
                EnrollmentGroup enrollmentGroupResult = await provisioningServiceClient.CreateOrUpdateEnrollmentGroupAsync(enrollmentGroup).ConfigureAwait(false);
            }
        }
Example #11
0
        /// <summary>
        /// Update the enrollment under test such that it forces it to reprovision to the hubs within <paramref name="iotHubsToReprovisionTo"/>
        /// </summary>
        private async Task UpdateEnrollmentToForceReprovision(EnrollmentType? enrollmentType, ProvisioningServiceClient provisioningServiceClient, ICollection<String> iotHubsToReprovisionTo, SecurityProvider security, string groupId)
        {
            if (enrollmentType == EnrollmentType.Individual)
            {
                IndividualEnrollment retrievedEnrollment = null;
                await RetryOperationHelper
                            .RetryOperationsAsync(
                                async () =>
                                {
                                    retrievedEnrollment = await provisioningServiceClient.GetIndividualEnrollmentAsync(security.GetRegistrationID()).ConfigureAwait(false);
                                },
                                s_provisioningServiceRetryPolicy,
                                s_retryableExceptions,
                                Logger)
                            .ConfigureAwait(false);

                if (retrievedEnrollment == null)
                {
                    throw new ArgumentException($"The individual enrollment entry with registration Id {security.GetRegistrationID()} could not be retrieved, exiting test.");
                }

                retrievedEnrollment.IotHubs = iotHubsToReprovisionTo;
                IndividualEnrollment updatedEnrollment = null;

                await RetryOperationHelper
                            .RetryOperationsAsync(
                                async () =>
                                {
                                    updatedEnrollment = await provisioningServiceClient.CreateOrUpdateIndividualEnrollmentAsync(retrievedEnrollment).ConfigureAwait(false);
                                },
                                s_provisioningServiceRetryPolicy,
                                s_retryableExceptions,
                                Logger)
                            .ConfigureAwait(false);

                if (updatedEnrollment == null)
                {
                    throw new ArgumentException($"The individual enrollment entry with registration Id {security.GetRegistrationID()} could not be updated, exiting test.");
                }
            }
            else
            {
                EnrollmentGroup retrievedEnrollmentGroup = null;
                await RetryOperationHelper
                            .RetryOperationsAsync(
                                async () =>
                                {
                                    retrievedEnrollmentGroup = await provisioningServiceClient.GetEnrollmentGroupAsync(groupId).ConfigureAwait(false);
                                },
                                s_provisioningServiceRetryPolicy,
                                s_retryableExceptions,
                                Logger)
                            .ConfigureAwait(false);

                if (retrievedEnrollmentGroup == null)
                {
                    throw new ArgumentException($"The enrollment group entry with group Id {groupId} could not be retrieved, exiting test.");
                }

                retrievedEnrollmentGroup.IotHubs = iotHubsToReprovisionTo;
                EnrollmentGroup updatedEnrollmentGroup = null;

                await RetryOperationHelper
                            .RetryOperationsAsync(
                                async () =>
                                {
                                    updatedEnrollmentGroup = await provisioningServiceClient.CreateOrUpdateEnrollmentGroupAsync(retrievedEnrollmentGroup).ConfigureAwait(false);
                                },
                                s_provisioningServiceRetryPolicy,
                                s_retryableExceptions,
                                Logger)
                            .ConfigureAwait(false);

                if (updatedEnrollmentGroup == null)
                {
                    throw new ArgumentException($"The enrollment group entry with group Id {groupId} could not be updated, exiting test.");
                }
            }
        }
Example #12
0
        /// <summary>
        /// Provisions a device to a starting hub, tries to open a connection, send telemetry,
        /// and (if supported by the protocol) send a twin update. Then, this method updates the enrollment
        /// to provision the device to a different hub. Based on the provided reprovisioning settings, this
        /// method then checks that the device was/was not reprovisioned as expected, and that the device
        /// did/did not migrate twin data as expected.
        /// </summary>
        public async Task ProvisioningDeviceClient_ReprovisioningFlow(
            Client.TransportType transportProtocol,
            AttestationMechanismType attestationType,
            EnrollmentType? enrollmentType,
            bool setCustomProxy,
            ReprovisionPolicy reprovisionPolicy,
            AllocationPolicy allocationPolicy,
            CustomAllocationDefinition customAllocationDefinition,
            ICollection<string> iotHubsToStartAt,
            ICollection<string> iotHubsToReprovisionTo,
            string proxyServerAddress = null)
        {
            using ProvisioningServiceClient provisioningServiceClient = CreateProvisioningService(s_proxyServerAddress);

            string groupId = null;
            if (enrollmentType == EnrollmentType.Group)
            {
                if (attestationType == AttestationMechanismType.X509)
                {
                    groupId = TestConfiguration.Provisioning.X509GroupEnrollmentName;
                }
                else
                {
                    groupId = _idPrefix + AttestationTypeToString(attestationType) + "-" + Guid.NewGuid();
                }
            }

            bool transportProtocolSupportsTwinOperations = transportProtocol != Client.TransportType.Http1;

            using ProvisioningTransportHandler transport = CreateTransportHandlerFromName(transportProtocol);
            using SecurityProvider security = await CreateSecurityProviderFromNameAsync(
                    attestationType,
                    enrollmentType,
                    groupId,
                    reprovisionPolicy,
                    allocationPolicy,
                    customAllocationDefinition,
                    iotHubsToStartAt)
                .ConfigureAwait(false);

            //Check basic provisioning
            if (ImplementsWebProxy(transportProtocol) && setCustomProxy)
            {
                transport.Proxy = (proxyServerAddress != null) ? new WebProxy(s_proxyServerAddress) : null;
            }

            var provClient = ProvisioningDeviceClient.Create(
                s_globalDeviceEndpoint,
                TestConfiguration.Provisioning.IdScope,
                security,
                transport);
            using var cts = new CancellationTokenSource(PassingTimeoutMiliseconds);
            DeviceRegistrationResult result = await provClient.RegisterAsync(cts.Token).ConfigureAwait(false);
            ValidateDeviceRegistrationResult(result);

#pragma warning disable CA2000 // Dispose objects before losing scope
            // The certificate instance referenced in the DeviceAuthenticationWithX509Certificate instance is common for all tests in this class. It is disposed during class cleanup.
            Client.IAuthenticationMethod auth = CreateAuthenticationMethodFromSecurityProvider(security, result.DeviceId);
#pragma warning restore CA2000 // Dispose objects before losing scope

            await ConfirmRegisteredDeviceWorks(result, auth, transportProtocol, transportProtocolSupportsTwinOperations).ConfigureAwait(false);

            //Check reprovisioning
            await UpdateEnrollmentToForceReprovision(enrollmentType, provisioningServiceClient, iotHubsToReprovisionTo, security, groupId).ConfigureAwait(false);
            result = await provClient.RegisterAsync(cts.Token).ConfigureAwait(false);
            ConfirmDeviceInExpectedHub(result, reprovisionPolicy, iotHubsToStartAt, iotHubsToReprovisionTo, allocationPolicy);
            await ConfirmDeviceWorksAfterReprovisioning(result, auth, transportProtocol, reprovisionPolicy, transportProtocolSupportsTwinOperations).ConfigureAwait(false);

            if (attestationType == AttestationMechanismType.X509 && enrollmentType == EnrollmentType.Group)
            {
                Logger.Trace($"The test enrollment type {attestationType}-{enrollmentType} with group Id {groupId} is currently hardcoded - do not delete.");
            }
            else
            {
                Logger.Trace($"Deleting test enrollment type {attestationType}-{enrollmentType} with registration Id {security.GetRegistrationID()}.");
                await DeleteCreatedEnrollmentAsync(enrollmentType, security, groupId, Logger).ConfigureAwait(false);
            }

            if (security is SecurityProviderX509 x509Security)
            {
                X509Certificate2 deviceCertificate = x509Security.GetAuthenticationCertificate();
                deviceCertificate?.Dispose();
            }

            if (auth != null && auth is IDisposable disposableAuth)
            {
                disposableAuth?.Dispose();
            }
        }