Loading...

Rehosting On-Prem Process Automation when migrating to Azure

Rehosting On-Prem Process Automation when migrating to Azure

Many enterprises seek to migrate on-premises IT infrastructure to cloud for cost optimization, scalability, and enhanced reliability. During modernization, key aspect is to transition automated processes from on-premises environments, where tasks are automated using scripts (PowerShell or Python) and tools like Windows Task Scheduler or System Center Service Management Automation (SMA).

This blog showcases successful transitions of customer automated processes to the cloud with Azure Automation, emphasizing script re-use and modernization through smart integrations with complementing Azure products. Using runbooks in PowerShell or Python, the platform supports PowerShell versions 5.1, and PowerShell 7.2. To learn more, click here.

 

Additionally, Azure Automation provides seamless certificate authentication with managed identity, eliminating the need to manage certificates and credentials while rehosting. Azure Automation safeguards the keys and passwords by wrapping the encryption key with the customer-managed key associated to key vault. Integration with Azure Monitor coupled with Automation’s native job logs equip the customers with advanced monitoring and error/failure management. Azure Automation platform efficiently manages long-running scripts in the cloud or on-premises with resource limits options with Hybrid runbook worker. Hybrid runbook worker also equips you to automate workloads off-Azure while utilizing the goodness of Azure Automation runbooks.

 

Rehosting on-premises operations with minimal effort covers scenarios listed below. Additional efforts involve modernizing scripts for cloud-native management of secrets, certificates, logging, and monitoring. –

  • State configuration management - Monitor state changes in the infrastructure and generate insights/alerts for subsequent actions.
  • Build, deploy and manage resources - Deploy virtual machines across a hybrid environment using runbooks. This is not entirely serverless and requires relatively higher manual effort in rehosting.
  • Periodic maintenance - to execute tasks that need to be performed at set timed intervals like
    1. purging stale data or reindex a SQL database.
    2. Checking for orphaned computer and users in Active Directory
    3. Windows Update notifications
  • Respond to alerts - Orchestrate a response when cost-based (e.g. VM cost consumption), system-based, service-based, and/or resource utilization alerts are generated.

Specifically, here are some of the scenarios of managing state configuration of M365 suite where our customer rehosted the on-premises PowerShell script to cloud with Azure Automation

 

Scenarios for State Configuration Management of M365 Suite

  1. User Permission & access control management
  2. Mailbox alerts configuration
  3. Configuring SharePoint sites availability
  4. Synchronizing Office 365 with internal applications

Example: Rehosting User Permission & access control management in M365 mailboxes

 

Here is how one of the customers rehosted a heavy monolithic PowerShell script to Azure. The objective of the job was to identify –

 

List of shared mailboxes --> list of permissions existing for these mailboxes --> users & groups mapped to the mailboxes --> list of permissions granted (& modified overtime) to these users/groups --> Final output with a view of Mailbox Id, Groups, Users, Permissions provided, Permissions modified (with timestamps).

 

1. Shared mailboxes credentials

 

 

########################################### # Get Shared Mailboxes ########################################### $forSharedMailboxes = @{ Properties = "GrantSendOnBehalfTo" RecipientTypeDetails = "SharedMailbox" ResultSize = "Unlimited" } $sharedMailboxes = Get-EXOMailbox @forSharedMailboxes

 

 

2. Obtain shared Mailbox permissions

 

 

########################################### # Get Shared Mailbox Permissions ########################################### $sharedMailboxesPermissions = foreach ($sharedMailbox in $sharedMailboxes) { # ------------------------------------------------------------------------------------------------------- # Get Send As Permissions # ------------------------------------------------------------------------------------------------------- try { $forTheSharedMailbox = @{ Identity = $sharedMailbox.Identity ResultSize = "Unlimited" } $recipientPermissions = @(Get-EXORecipientPermission @forTheSharedMailbox) $recipientPermissions = $recipientPermissions.Where({ $_.Trustee -ne "NT AUTHORITY\SELF" }) $recipientPermissions = $recipientPermissions.Where({ $_.Trustee -notlike "S-1-5-21*" }) if ($recipientPermissions) { foreach ($recipientPermission in $recipientPermissions) { [SharedMailboxPermission]@{ MailboxDisplayName = $sharedMailbox.DisplayName MailboxEmailAddresses = $sharedMailbox.EmailAddresses MailboxId = $sharedMailbox.Id MailboxUserPrincipalName = $sharedMailbox.UserPrincipalName Permission = $recipientPermission.AccessRights PermissionExchangeObject = $recipientPermission.Trustee } } } } catch { Write-Warning ("Getting send as permissions for $($sharedMailbox.Identity).") continue }

 

 

3. User & groups mapped to the mailboxes 

 

 

########################################### # Get Entra and Exchange User Objects ########################################### $forEntraAndExchangeUserObjects = @{ Connection = $forTheSharedMailboxGovernanceSite Identity = $entraAndExchangeUserObjectListRelativeUrl } $userObjectsList = Get-PnPList @forEntraAndExchangeUserObjects $fromTheEntraAndExchangeUserObjectsList = @{ Connection = $forTheSharedMailboxGovernanceSite List = $userObjectsList PageSize = 5000 } $userObjectsListItems = (Get-PnPListItem @fromTheEntraAndExchangeUserObjectsList).FieldValues ########################################### # Get Entra and Exchange Group Objects ########################################### $forEntraAndExchangeGroupObjects = @{ Connection = $forTheSharedMailboxGovernanceSite Identity = $entraAndExchangeGroupObjectListRelativeUrl } $groupObjectsList = Get-PnPList @forEntraAndExchangeGroupObjects $fromTheEntraAndExchangeGroupObjectsList = @{ Connection = $forTheSharedMailboxGovernanceSite List = $groupObjectsList PageSize = 5000 } $groupObjectsListItems = (Get-PnPListItem @fromTheEntraAndExchangeGroupObjectsList).FieldValues

 

 

4. List of permissions granted (& modified overtime) to these users/groups

 

 

# ---------------------------------------- # Get Full Access Permissions # ------------------------------------- try { $forTheSharedMailbox = @{ Identity = $sharedMailbox.Identity ResultSize = "Unlimited" } $mailboxPermissions = @(Get-EXOMailboxPermission @forTheSharedMailbox) $mailboxPermissions = $mailboxPermissions.Where({ $_.User -ne "NT AUTHORITY\SELF" }) $mailboxPermissions = $mailboxPermissions.Where({ $_.User -notlike "S-1-5-21*" }) if ($mailboxPermissions) { foreach ($mailboxPermission in $mailboxPermissions) { [SharedMailboxPermission]@{ MailboxDisplayName = $sharedMailbox.DisplayName MailboxEmailAddresses = $sharedMailbox.EmailAddresses MailboxId = $sharedMailbox.Id MailboxUserPrincipalName = $sharedMailbox.UserPrincipalName Permission = $mailboxPermission.AccessRights PermissionExchangeObject = $mailboxPermission.User } } } } catch { Write-Warning ("Getting full access permissions for $($sharedMailbox.Identity).") continue } # ------------------------------------------------------------------------------------------------------- # Get Send On Behalf Of Permissions # ------------------------------------------------------------------------------------------------------- $grantSendOnBehalfToPermissions = @($sharedMailbox.GrantSendOnBehalfTo) $grantSendOnBehalfToPermissions = $grantSendOnBehalfToPermissions.Where({ $_ -notlike "S-1-5-21*" }) if ($grantSendOnBehalfToPermissions) { foreach ($grantSendOnBehalfToPermission in $grantSendOnBehalfToPermissions) { [SharedMailboxPermission]@{ MailboxDisplayName = $sharedMailbox.DisplayName MailboxEmailAddresses = $sharedMailbox.EmailAddresses MailboxId = $sharedMailbox.Id MailboxUserPrincipalName = $sharedMailbox.UserPrincipalName Permission = "SendOnBehalfOf" PermissionExchangeObject = $grantSendOnBehalfToPermission } } } }

 

 

 

As the customer modernized from On-premises to Azure via Azure Automation, the following list captures the aspects that have to be updated. The changes were mostly an improvement in terms of experience offered by Azure Automation leveraging smart integrations with other Azure capabilities and little to no reliance on custom scripts.

  1. Setup Logging & Monitoring methods - In On prem setup, customers authored custom scripts for logging, which was no more needed with Azure Automation. Customers utilized in-portal Azure Monitor integration to forward logs to Azure monitor, quey logs, and set up alerts for insights.
  2. Handling certificate authentication Managed Identity based authentication provides improved means to store secrets and passwords without doing regular updates to code credentials. Azure Automation supports both PS script and in-built portal experience to configure Managed Identity
  3. Storing passwords and security keysKey Vault integration with Azure Automation helped the customers to transition this on-prem experience seamlessly. The sample PS script below is recommended to enable Key Vault integration.

 

 

Install-Module -Name Microsoft.PowerShell.SecretManagement -Repository PSGallery -Force Install-Module Az.KeyVault -Repository PSGallery -Force Import-Module Microsoft.PowerShell.SecretManagement Import-Module Az.KeyVault $VaultParameters = @{ AZKVaultName = $vaultName SubscriptionId = $subID } Register-SecretVault -Module Az.KeyVault -Name AzKV -VaultParameters $VaultParameters

 

 

 

If you are currently utilizing Azure Automation for rehosting such light weight environment agnostic operations from on-prem to cloud or want to know more details, please reach out to us on [email protected].

 

 

 

 

 

 

 

 

 

 

 

 

Published on:

Learn more
Azure Governance and Management Blog articles
Azure Governance and Management Blog articles

Azure Governance and Management Blog articles

Share post:

Related posts

Microsoft Purview: Data Lifecycle Management- Azure PST Import

Azure PST Import enables Microsoft 365 admins to import PST files from Azure Blob Storage into Exchange Online mailboxes using PowerShell. The...

22 hours ago

Power Automate: sort Function

Power Automate's sort function arranges arrays in ascending order by value or property. Learn usage tips, the string-vs-number gotcha, and how...

1 day ago

AI-Powered Approval System Using Copilot in Power Apps and Power Automate Flow

Modern approval processes are often slow, manual, and inconsistent, leading to delays, policy violations, and poor decision-making. In this so...

1 day ago

April Patches for Azure DevOps Server

We are releasing patches for our self‑hosted product, Azure DevOps Server. We strongly recommend that all customers remain on the latest, most...

2 days ago

Integration Testing Azure Functions with Reqnroll and C#, Part 5 - Using Corvus.Testing.ReqnRoll in a build pipeline

If you use Azure Functions on a regular basis, you'll likely have grappled with the challenge of testing them. In the final post in this serie...

6 days ago

Integration Testing Azure Functions with Reqnroll and C#, Part 4 - Controlling your functions with additional configuration

If you use Azure Functions on a regular basis, you'll likely have grappled with the challenge of testing them. In the fourth of this series of...

6 days ago
Stay up to date with latest Microsoft Dynamics 365 and Power Platform news!
* Yes, I agree to the privacy policy