/// <summary> /// Starts the migration batch in Exchange Online. /// </summary> /// <param name="entity">An instance of <see cref="MigrationBatchEntity"/> that represents the migration batch to start.</param> /// <returns>An instance of <see cref="Task"/> that represents the asynchronous operation.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="entity"/> is null. /// </exception> public async Task MigrationBatchStartAsync(MigrationBatchEntity entity) { Command command; CommandParameterCollection parameters; EnvironmentEntity environment; PSCredential credential; Uri connectionUri; WSManConnectionInfo connectionInfo; entity.AssertNotNull(nameof(entity)); try { credential = new PSCredential( service.Configuration.ExchangeOnlineUsername, service.Configuration.ExchangeOnlinePassword.ToSecureString()); environment = await service.Storage.GetEntityAsync <EnvironmentEntity>( MigrationConstants.EnvironmentTableName, entity.CustomerId, entity.PartitionKey); connectionUri = new Uri($"{MigrationConstants.ExchangeOnlineEndpoint}{environment.Organization}"); connectionInfo = GetConnectionInfo(connectionUri, MigrationConstants.SchemaUri, credential); command = new Command("Start-MigrationBatch"); parameters = new CommandParameterCollection { { "Identity", entity.Name } }; using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo)) { scriptManager.InvokeCommand(runspace, command, parameters); } entity.Started = true; await service.Storage.WriteToTableAsync(MigrationConstants.MigrationBatchTable, entity); } finally { connectionInfo = null; connectionUri = null; credential = null; parameters = null; } }
/// <summary> /// Get statistics for the specified migration batch. /// </summary> /// <param name="entity">An instance of <see cref="MigrationBatchEntity"/> that represents the migration batch</param> /// <returns>An instance of <see cref="Task"/> that represents the asynchronous operation.</returns> public async Task MigrationBatchStatisticsAsync(MigrationBatchEntity entity) { Command command; List <Command> commands; EnvironmentEntity environment; PSCredential credential; Uri connectionUri; WSManConnectionInfo connectionInfo; entity.AssertNotNull(nameof(entity)); try { credential = new PSCredential( service.Configuration.ExchangeOnlineUsername, service.Configuration.ExchangeOnlinePassword.ToSecureString()); environment = await service.Storage.GetEntityAsync <EnvironmentEntity>( MigrationConstants.EnvironmentTableName, entity.CustomerId, entity.PartitionKey); connectionUri = new Uri($"{MigrationConstants.ExchangeOnlineEndpoint}{environment.Organization}"); connectionInfo = GetConnectionInfo(connectionUri, MigrationConstants.SchemaUri, credential); commands = new List <Command>(); command = new Command("Get-MigrationUser"); command.Parameters.Add("BatchId", entity.Name); commands.Add(command); command = new Command("Get-MigrationUserStatistics"); commands.Add(command); using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo)) { scriptManager.InvokeCommand(runspace, commands); } } finally { commands = null; connectionInfo = null; connectionUri = null; credential = null; } }
public async Task <MigrationBatchViewModel> CreateBatchAsync([FromBody] MigrationBatchViewModel batch) { Customer customer; CustomerPrincipal principal; DateTime startTime; Dictionary <string, double> eventMetrics; Dictionary <string, string> eventProperties; List <MailboxEntity> entries; MigrationBatchEntity entity; string targetDeliveryDomain; batch.AssertNotNull(nameof(batch)); try { startTime = DateTime.Now; principal = (CustomerPrincipal)HttpContext.Current.User; if (string.IsNullOrEmpty(batch.Id)) { batch.Id = Guid.NewGuid().ToString(); } customer = await operations.GetCustomerAsync(principal.CustomerId); targetDeliveryDomain = $"{customer.CompanyProfile.Domain.Split('.')[0]}.{MigrationConstants.TargetDeliveryDomainSuffix}"; entity = new MigrationBatchEntity(batch.EnvironmentId, batch.Id) { CustomerId = principal.CustomerId, ETag = "*", Name = batch.Name, StartTime = DateTime.Parse(batch.StartTime), Started = false, TargetDeliveryDomain = targetDeliveryDomain }; entries = batch.Mailboxes.Select(m => new MailboxEntity(batch.EnvironmentId, m.Guid) { DisplayName = m.DisplayName, ETag = "*", Name = m.Name, MigrationBatchId = batch.Id, PrimarySmtpAddress = m.PrimarySmtpAddress, SamAccountName = m.SamAccountName, UserPrincipalName = m.UserPrincipalName }).ToList(); await Service.Storage.WriteToTableAsync(MigrationConstants.MigrationBatchTable, entity); await Service.Storage.WriteBatchToTableAsync(MigrationConstants.MailboxTableName, entries); await Service.ServiceBus.WriteToQueueAsync(MigrationConstants.MigrationBatchQueueName, entity); // Capture the request for the customer summary for analysis. eventProperties = new Dictionary <string, string> { { "Email", principal.Email }, { "EnvironmentId", batch.EnvironmentId }, { "MigrationBatchName", batch.Name }, { "PrincipalCustomerId", principal.CustomerId } }; // Track the event measurements for analysis. eventMetrics = new Dictionary <string, double> { { "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds }, { "NumberOfMailboxes", batch.Mailboxes.Count } }; Service.Telemetry.TrackEvent("/api/migrationbatch/create", eventProperties, eventMetrics); return(batch); } finally { entity = null; eventMetrics = null; eventProperties = null; principal = null; } }
/// <summary> /// Creates a new migration batch in Exchange Online. /// </summary> /// <param name="entity">An instance of <see cref="MigrationBatchEntity"/> that represents the new migration batch.</param> /// <returns>An instance of <see cref="Task"/> that represents the asynchronous operation.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="entity"/> is null. /// </exception> public async Task CreateMigrationBatchAsync(MigrationBatchEntity entity) { Command command; CommandParameterCollection parameters; EnvironmentEntity environment; List <MailboxEntity> entites;; PSCredential credential; Uri connectionUri; WSManConnectionInfo connectionInfo; string csvData; entity.AssertNotNull(nameof(entity)); try { credential = new PSCredential( service.Configuration.ExchangeOnlineUsername, service.Configuration.ExchangeOnlinePassword.ToSecureString()); environment = await service.Storage.GetEntityAsync <EnvironmentEntity>( MigrationConstants.EnvironmentTableName, entity.CustomerId, entity.PartitionKey); connectionUri = new Uri($"{MigrationConstants.ExchangeOnlineEndpoint}{environment.Organization}"); connectionInfo = GetConnectionInfo(connectionUri, MigrationConstants.SchemaUri, credential); entites = await service.Storage.GetEntitiesAsync <MailboxEntity>( MigrationConstants.MailboxTableName, m => m.PartitionKey.Equals(environment.RowKey) && !string.IsNullOrEmpty(m.MigrationBatchId) && m.MigrationBatchId.Equals(entity.RowKey)); csvData = entites.Aggregate(new StringBuilder("EmailAddress\n"), (sb, v) => sb.Append(v.PrimarySmtpAddress).Append("\n"), sb => { if (0 < sb.Length) { sb.Length--; } return(sb.ToString()); }); command = new Command("New-MigrationBatch"); parameters = new CommandParameterCollection { { "CSVData", Encoding.ASCII.GetBytes(csvData) }, { "Name", entity.Name }, { "SourceEndpoint", environment.Name }, { "TargetDeliveryDomain", entity.TargetDeliveryDomain } }; using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo)) { scriptManager.InvokeCommand(runspace, command, parameters); } } finally { connectionInfo = null; connectionUri = null; credential = null; parameters = null; } }