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

Fixing “Flow Client Error: BadRequest” in Power Automate Unbound Actions

In this blog, we’ll cover why the “Flow Client Error: BadRequest” error while working with Power Automate occurs and guide you thr...

2 days ago

Summer 2025 Dynamics 365 Maps Release: Smarter Routing, Azure Maps, Canvas Apps & More!

Technology never stands still, and neither does Team Maplytics! With our latest March 2025 updates, your geo-mapping experience within Dynamic...

3 days ago

Vector Search with Azure SQL, Semantic Kernel and Entity Framework Core

Vector databases like Qdrant and Milvus are specifically designed to efficiently store, manage, and retrieve embeddings. However, many applica...

4 days ago

Power Automate | Unable to Resubmit Flow Runs

If you are troubleshooting a failed flow run and are unable to Resubmit it with the following error : This flow run was started by someone els...

4 days ago

Power Automate – Enable dark mode in Power Automate for desktop

We are launching the ability Enable dark mode in Power Automate for desktop for Power Automate. With this feature, you can switch between defa...

4 days ago

Power Automate Flow | Activation Error | InvalidPaginationPolicy

One of the users reported an issue where they encountered an InvalidPaginationPolicy error while trying to turn on a flow {“error”...

5 days ago

Upcoming Updates for Azure Pipelines Agents Images

To ensure our hosted agents in Azure Pipelines are operating in the most secure and up-to-date environments, we continuously update the suppor...

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