Lesson Learned #409:Resilient Azure SQL DB: Powering Performance with OpenAsync and ExecuteAsync

This article is contributed. See the original author and article here.

Efficiently managing Azure SQL Database and Managed Instance operations is essential for developers and DBAs seeking high-performing, reliable applications in the cloud. This article introduces a powerful PowerShell script leveraging the OpenAsync technique, designed to optimize these Azure database solutions by implementing a resilient connection policy and enabling asynchronous query execution. Today, I would like to share several topics about OpenAsync and ExecuteAsync learned about several support cases worked on previously.


 


The Script: Harnessing the Power of OpenAsync


 


The provided PowerShell script showcases two fundamental functions: Open-ConnectionAsync and Execute-QueryAsync. These functions capitalize on the OpenAsync technique to revolutionize the way connections are established and queries are executed in Azure SQL Database and Managed Instance environments.


 


1. Open-ConnectionAsync Function


This function establishes an asynchronous connection to the target Azure database and incorporates the following key features:




  • Asynchronous Connection: The use of OpenAsync enables the script to asynchronously establish connections, preventing application blocking and ensuring high responsiveness.




  • Exponential Backoff: The function gracefully handles transient connectivity issues with an exponential backoff strategy, intelligently delaying connection retries and allowing the infrastructure to recover from potential disruptions.




 


2. Execute-QueryAsync Function


This function revolutionizes query execution by leveraging the OpenAsync technique and includes the following essential elements:




  • Asynchronous Query Execution: By utilizing the OpenAsync approach, queries are executed asynchronously, maximizing application performance and responsiveness.




  • Dynamic Timeout Adjustment: The function applies a backoff mechanism to dynamically adjust the CommandTimeout property during query execution retries. This intelligent approach extends query execution time, significantly reducing the likelihood of timeouts due to transient performance fluctuations.




 


Empowering Developers and DBAs


 


The script offers developers and DBAs significant advantages:


1. Resilience in Connectivity: The OpenAsync technique combined with exponential backoff ensures that connection attempts are smartly retried, minimizing the impact of temporary connection issues and promoting application stability.


2. Optimized Query Performance: Asynchronous query execution and dynamic CommandTimeout adjustment guarantee queries have sufficient time to complete successfully, enhancing application performance even during peak database activity.


3. Tailored Customization: The script’s adjustable parameters, including $totalQueries, $maxConnectionAttempts, and $maxQueryAttempts, provide developers and DBAs with the flexibility to tailor the script to their specific use cases.


 


Conclusion


By leveraging the power of OpenAsync, developers and DBAs can unlock the full potential of Azure SQL Database and Managed Instance. Our PowerShell script empowers them to optimize connection handling and query execution, ensuring a resilient and high-performing experience in the Azure cloud.


 


Disclaimer: The PowerShell script is intended for educational purposes only. Prior to applying any script to production systems, developers and DBAs should thoroughly test it in a controlled environment and adhere to security and performance best practices.


 

function Open-ConnectionAsync {
    param (
        [string]$connectionString,
        [int]$maxAttempts
    )

    $attempts = 1

    while ($attempts -le $maxAttempts) {
        try {
            $connection = New-Object System.Data.SqlClient.SqlConnection
            $connection.ConnectionString = $connectionString

            Write-Host "$(Get-Date) - Attempting to establish connection..."
            $openTask = $connection.OpenAsync()

            # Esperar hasta 0.5 segundos (500 milisegundos) para la conexión.
            Start-Sleep -Milliseconds 50

            if ($openTask.IsCompleted) {
             If( -not $openTask.IsFaulted -and -not $openTask.IsCanceled)
              {
                Write-Host "$(Get-Date) - Connection established successfully."
                return $connection
              }
            }
        }
        catch {
            $attempts++
            $backoffTime = [math]::Pow(2, $attempts) * 1000
            Write-Host "$(Get-Date) - Error establishing connection: $_.Exception.Message. Retrying in $backoffTime milliseconds..."
            Start-Sleep -Milliseconds $backoffTime
        }
    }

    Write-Host "$(Get-Date) - Maximum connection attempts reached. Could not establish connection."
    return $null
}

function Execute-QueryAsync {
    param (
        [System.Data.SqlClient.SqlConnection]$connection,
        [string]$query,
        [int]$queryNumber,
        [int]$maxAttempts
    )

    for ($i = 1; $i -le $maxAttempts; $i++) {
        $queryTimer = [System.Diagnostics.Stopwatch]::StartNew()

        try {
            $command = $connection.CreateCommand()
            $command.CommandText = $query

            Write-Host "$(Get-Date) - Attempt $i to execute Query $queryNumber..."
            $command.CommandTimeout = 30 + ([math]::Pow(2, $i) * 10)  # Increase CommandTimeout with backoff value

            $openTask = $command.ExecuteNonQueryAsync()

            # Esperar hasta 0.5 segundos (500 milisegundos) para la ejecución de la consulta.
            Start-Sleep -Milliseconds 50

            if ($openTask.IsCompleted) {
             If( -not $openTask.IsFaulted -and -not $openTask.IsCanceled)
              {
                $queryTimer.Stop()
                Write-Host "$(Get-Date) - Query $queryNumber, attempt $($i + 1) executed successfully. Execution time: $($queryTimer.Elapsed.ToString())"
                return
              }
             else 
             {
                Write-Host "$(Get-Date) - Query $queryNumber, attempt $($i + 1) execution failed. Retrying..."
                throw "- Query $queryNumber, attempt $($i + 1) execution failed. Retrying..."
             }
            }
        }
        catch {
            $queryTimer.Stop()
            Write-Host "$(Get-Date) - Error executing query $queryNumber, attempt $($i + 1): $_.Exception.Message. Execution time: $($queryTimer.Elapsed.ToString())"
            if ($i -lt $maxAttempts - 1) {
                $backoffTime = [math]::Pow(2, $i) * 1000
                Write-Host "$(Get-Date) - Retrying query $queryNumber in $backoffTime milliseconds..."
                Start-Sleep -Milliseconds $backoffTime
            }
            else {
                Write-Host "$(Get-Date) - Maximum query attempts reached. Moving to the next query."
            }
        }
    }
}

$connectionString = "data source=tcp:servername.database.windows.net,1433;initial catalog=DBName;User ID=UserName;Password=Password; ConnectRetryCount = 3; ConnectRetryInterval = 10; Connection Timeout = 30; Max Pool Size = 100; MultipleActiveResultSets = false; Min Pool Size = 1; Application Name = Testing by JMJD -SQL; Pooling = True;Connection Timeout=5" 

$totalQueries = 300
$maxConnectionAttempts = 10
$maxQueryAttempts = 10

for ($i = 1; $i -le $totalQueries; $i++) {
    $connection = Open-ConnectionAsync -connectionString $connectionString -maxAttempts $maxConnectionAttempts

    if ($connection) {
        $query = "SELECT 1"
        Execute-QueryAsync -connection $connection -query $query -queryNumber ($i + 1) -maxAttempts $maxQueryAttempts
        $connection.Close()
    }
}

Write-Host "$(Get-Date) - End of the script."

 

Catch up after your week off with task history in Microsoft Project for the web.

Catch up after your week off with task history in Microsoft Project for the web.

This article is contributed. See the original author and article here.

Introduction


The new task history feature in Microsoft Project for the web helps task owners stay on top of their tasks and quickly identify recent progress that has been made or changes that have impacted the schedule. Edits to tasks such as adding or removing labels, changing the duration, or changes to other tasks that affect the schedule of work all appear in the new Changes pane in Task Details. It is rolling out now, and will be available world-wide over the next few days. 


 


Watch this 2-minute demo for a quick overview. 


 


Getting Started


Task history is available to all users in Project for the web who have a Project Plan 3 or greater license.



  1. First open a project at Project Home or in a Project tab in Microsoft Teams.

  2. Open task details for any task. It can be reached by clicking the task details in the task grid, or by clicking a task card in the board view.


AlexanderLahuerta_0-1690576487378.png


 



  1. In the corner of task details, there is a new task history icon. Click it to open the changes pane.


AlexanderLahuerta_1-1690576487384.png


 


 


Details about the recorded changes


All the changes a user makes to a task are recorded in task history. For each edit, details are shown such as who made the change, when they made it, what property was changed, the previous value, and the new value.


Changes that are recorded include edits such as



  • Adding or removing labels

  • Changing the duration or effort

  • Editing checklists

  • Adding or removing attachments

  • Edits to any custom columns


 


AlexanderLahuerta_2-1690576487458.png


 


Changes made to other tasks that impact the selected task


Project for the web makes it easy to track tasks and identify dependencies. Dependencies between tasks means it is crucial for task owners to understand how changes across the project impacts their work. Task history makes it easy to identify these changes and stay on track. Changes made to other tasks that impact either the start date or finish date of the selected task have a history record that shows high-level information about the edit.


In the example shown below, Allan Smith edited the duration of a related task called “Kick-off budgeting.” This edit impacted the start date of the currently selected task.


 


AlexanderLahuerta_3-1690576487462.png


 


 


Navigating to related task edits


Clicking the task title for these changes takes you to the related task and highlights the relevant edit. In this example, clicking the task title of the previously shown change record opens the “Kick-off budgeting” task and highlights the change in duration.


Pressing the browser back button or pressing the back button in Teams returns to the previously selected task.


AlexanderLahuerta_4-1690576487466.png


 


 


Pro-tip: use task history with task conversations to stay on track


Task history pairs perfectly with task conversations to enable in-context chat about changes to tasks. For projects that have been pinned in Teams channels, the bottom of the task details pane includes a task conversation button. Pressing it opens the conversation pane.


AlexanderLahuerta_5-1690576487487.png


 


 


Chats in this pane automatically include a link to the task to help everyone quickly get to a shared context. More information about task conversations can be found at the Microsoft support page for them.


 


AlexanderLahuerta_6-1690576487499.png


 


Frequently Asked Questions


Why don’t I see the task history button?
Task History is only available to users with a Project Plan 3 or greater license. If the icon doesn’t appear in task details, work with your Administrator to verify the license that is assigned to you.


Will edits made by users without a Project Plan 3 license be shown in the Changes pane?
Yes. Edits made by all users, regardless of their license, will appear in the changes pane. Only users with a Project Plan 3 or greater license will be able to open the changes pane to view these edits.


Is task history available in Planner?
No. Task history -along with other powerful features such as custom columns and the timeline view- helps to give teams with more sophisticated project management requirements the tools they need to keep their projects on track. These features can all be found in Project for the web.


Can my team build Power BI reports using Task History data?
Yes. Task history data is stored in Microsoft Dataverse and can be queried using Power BI. Learn more about the schema by visiting our support page.


Do edits to tasks using the Project scheduling APIs appear in task history?
No. Only edits to tasks made using the grid, board, or timeline views appear in the Changes pane.


My team uses Project in Power Apps, do edits made in that context appear in task history?
Edits made in the grid, board, and timeline views appear in Task History. Any edits to tasks using Power Apps forms as well as any edits to columns added to tables in Dataverse are not shown in task history.


My team has customized Project in Power Apps, will task history work in our environment?


Yes, but your administrator needs to ensure that they are validating their customizations with the latest release, including any customization of security roles in Dataverse.

Updated insight names in Meeting Effectiveness report template

This article is contributed. See the original author and article here.

We are excited to announce some updates to our Viva Insights Meeting effectiveness report template that will enhance your experience and make the insights more actionable! As part of our ongoing commitment to providing valuable tools for our customers, we have reevaluated the insight naming conventions for this template and made some changes.


 


In our quest to enhance meeting effectiveness, we have focused on ensuring insights resonate with users. While the conclusions drawn from the data remain unchanged, you’ll notice a shift from a passive tone to a more actionable sense in our insight framing.


 


To improve clarity and eliminate confusion, we have revisited the names of several insights, making them easier to comprehend. We understand the significance of intuitive and understandable naming conventions, and addressing this issue has been a priority for us.


 

































Existing insight name  New insight name 
Short and small  Large and long 
Advanced meeting notice  Short notice 
Attendee availability  Conflicting 
Joined on time  Joined late 
Ended on time  Ended late 
No multitasking  Multitasked 

 


New name descriptions and actionable takeaways for improved meeting effectiveness


 


1. “Short and small” is now “Large and long”: This insight highlights meetings that have 9 or more invitees and last more than 1 hour.


Action: Foster focused discussions and prevent attendee fatigue to ensure more productive and impactful outcomes.


 


2. “Advanced meeting notice” has been renamed “Short notice”: This change aims to emphasize meetings that have are scheduled with less than 24 hours of notice.


Action: Ensure that important meetings are scheduled with enough lead time to enable employees to feel in control over their days and sufficiently prepare for meetings.


 


3. “Attendee availability” is now “Conflicting”: This insight highlights meetings where scheduling conflicts are present amongst participants, potentially impacting meeting attendance.


Action: Identify and address scheduling conflicts, optimize attendee availability, and facilitate more productive meetings by effectively managing conflict commitments.


 


4. “Joined on time” is now “Joined late”: This insight highlights meetings where attendees were unable to join a Teams meeting within five minutes of the scheduled start time.


Action: This can be caused by back-to-back meetings that make it challenging for employees to take breaks and join the next meeting on time. Use the Shared meeting plan to automatically build in a few minutes between meetings to provide a short break. 


 


5. “Ended on time” is now “Ended late”: This insight focuses on meetings that exceeded their scheduled duration.


Action: Prompt participants to conclude discussions within the allotted time and ensure timely transitions to subsequent tasks.


 


6.”No multitasking” has been changed to “Multitasked”: This insight highlights the instances where attendees are sending chats or emails during meetings.


Action: Encourage attendees to minimize multitasking and prioritize focused engagement, enhancing meeting productivity and outcomes.


 


To see these changes, simply download a new version of the Power BI template from the product and load in data from a Meeting effectiveness query. All your existing Meeting effectiveness queries will be compatible with this new version. Any Meeting effectiveness reports that you have created before this update will also continue to work, however from this point forward, the prior version of the template will not be available to download.


 


We’re committed to continuously improving our products to better serve our customers. The updates to The Meeting effectiveness report template are rooted in research and user feedback, with the aim of providing actionable insights and eliminating confusion. We believe that these changes will significantly enhance your experience with our product and empower you to drive better outcomes in your meetings. We look forward to your feedback and encourage you to explore the newly refined template.

The roadmap to SaaS success: How to adopt the cloud for your SaaS offering

This article is contributed. See the original author and article here.

In this guest blog post, Stig Panduro, Senior Director of Microsoft Alliance at Silk Technologies, explores software as a service (SaaS) and what your business should consider and prepare for as you plan your cloud migration.


 


In the fast-paced world of software development, staying ahead of the competition is vital for success. Simply dominating the market today is no guarantee of continued leadership in the future. To maintain a competitive edge and meet evolving customer demands, software companies must explore new technologies and business models.



One model that has gained significant traction is providing software as a service (SaaS). By adopting SaaS, companies can offer customers seamless access to software without the hassle of physical installations, making it an enticing choice, particularly in today’s remote work environment.


 


Is your product ready for this transformation into a SaaS offering? Achieving this requires migrating your software from traditional on-premises infrastructure to the cloud. If your software relies on databases like Oracle or Microsoft SQL Server, the migration process becomes far more complex.


 


The SaaS phenomenon


 


Migrating to SaaS is the process of transitioning from a conventional on-premises software model to a dynamic software-as-a-service paradigm. Gartner’s extensive market research indicates SaaS is expected to grow 17.9% in 2023. This surge in popularity can be attributed to several factors. SaaS empowers software customers with unparalleled flexibility, allowing them to purchase and install software at their convenience, and providing remote accessibility. No longer must they schedule on-site visits from the vendor for hardware installations. Moreover, SaaS offers subscription-based pricing, replacing hefty upfront costs with a pay-as-you-go model, significantly reducing capital expenditures.


 


Simultaneously, SaaS presents software companies with a wealth of opportunities. By offering a SaaS version of their products, companies can tap into a broader customer base. The subscription-based pricing model enables them to achieve stable, recurring revenue. These factors combine to make the transformation into a SaaS offering an enticing prospect.


 


Challenges you might encounter


 


While the potential rewards of migrating to SaaS are immense, cloud migration itself poses formidable challenges. Moving your applications to the cloud is a complex undertaking. Some applications can be effortlessly lifted and shifted to the cloud, but others require significant refactoring. This process is time-consuming, costly, and inherently risky. If your applications rely on databases, expect additional hurdles during the migration process. These databases demand unparalleled performance levels, which might not be achievable through native cloud infrastructure alone unless you’re willing to pay for additional cloud resources. These challenges frequently surface unexpectedly during the migration process, causing significant complications.


 


Implementing a zero-downtime deployment strategy is another potential stumbling block. SaaS applications are expected to be available around the clock, serving a global user base. Any downtime is met with little tolerance from users, who demand uninterrupted service. By adopting a zero-downtime deployment approach, you can seamlessly update your application without disrupting customer workflows. However, downtime events can occasionally be beyond your control. It becomes crucial to establish a robust disaster recovery plan to minimize the impact of outages on your zero-downtime deployment strategy.


 


As you onboard more customers, achieving seamless and cost-effective scalability becomes paramount. Furthermore, the inherent flexibility of SaaS makes it challenging to calculate an accurate total cost of ownership (TCO) and offer competitive pricing. Questions concerning user capacity, traffic handling capabilities, and storage volume must be thoroughly analyzed during the early stages of SaaS cloud migration to ensure optimized TCO and cost control.


 


Formulating your SaaS migration strategy


 


In the face of these daunting cloud migration obstacles, hope shouldn’t be lost. By bringing together your business analysts, architects, and developers and meticulously outlining business and application requirements, you can begin to simplify your SaaS migration strategy. Careful analysis of your software’s architecture will help identify elements that can be smoothly transitioned to the cloud, as well as areas requiring more extensive adjustments. Significant code optimization will likely be necessary to achieve the desired outcome.


 


If you find yourself at a loss on how to execute a SaaS cloud migration, turn to Silk. The Silk Data Virtualization Platform acts as a bridge between your applications and the underlying infrastructure. By utilizing a higher-performance compute network, Silk connects with compute VMs, surpassing the limited-capacity data network of cloud infrastructure. This empowers Silk to support performance-intensive workloads, eliminating the need for oversized compute VMs to achieve faster performance. Silk’s innovative design decouples performance and capacity, eliminating wasteful spending on unnecessary resources to meet IOPS or throughput targets. By offloading network layer tasks to the compute layer, Silk significantly reduces latency, resulting in highly responsive applications.


 


In addition to performance optimization, Silk offers enhanced resiliency through a self-healing architecture that proactively avoids disruptions and an active-active architecture that eliminates single points of failure by distributing management across cloud zones. The platform also provides critical enterprise data services like zero-footprint snapshots, enabling the creation of data copies for dev/test or disaster recovery purposes without compromising performance or incurring additional storage costs.


 


Scalability is a core pillar of Silk’s value proposition, ensuring seamless and cost-efficient migration of customers and their data as your SaaS platform expands. Leveraging machine learning-based monitoring capabilities, Silk analyzes cloud usage patterns to optimize your cloud experience and achieve the most cost-effective price point.


 


SimCorp’s success story


 


One company that recently made a successful move to SaaS was SimCorp. SimCorp is a leading provider of investment management solutions serving 40 percent of the world’s top financial companies. SimCorp’s flagship product, SimCorp Dimensions, empowers over 200 global clients with efficiency and flexibility in asset management. Initially available solely as an on-premises solution, SimCorp recognized the market was increasingly turning toward SaaS and embarked on transitioning SimCorp Dimensions into a SaaS offering. Considering the time and effort required for a full refactor, it opted for a lift-and-shift approach to Microsoft Azure. However, it needed to ensure the consistent high performance needed for its SaaS offering to be a success.


 


SimCorp turned to Silk and its data virtualization platform that sits between SimCorp Dimensions and the underlying Azure infrastructure. Silk proved ideal for performance-intensive workloads, giving SimCorp the boost it needed while providing dramatic and consistent reductions in latency for maximum application responsiveness. With Silk, SimCorp migrated one of its largest clients from an on-premises setup utilizing expensive compute and storage solutions to its SaaS offering. By leveraging Silk’s capabilities, the client experienced a remarkable 20 percent improvement in performance compared to its previous on-premises setup.


 


Ulrik Elstrup Hansen, VP and Head of SaaS Innovations at SimCorp, attests to the value of Silk: “I would recommend other companies to use Silk because of their ability to provide you with the right level of performance and resiliency. You get a partner that is truly invested in your success. With Silk, we are able to get closer to the promise of the cloud.”


 


Embrace the SaaS revolution with Silk


 


The shift toward SaaS holds immense potential for software companies seeking sustained growth and customer satisfaction. Overcoming the challenges of cloud migration is a prerequisite for unlocking the benefits of this transformative model. And while it might be a mountain to overcome, it is not, in fact, impossible.

Feature Deep Dive: Simplified Sharing Across Microsoft 365

Feature Deep Dive: Simplified Sharing Across Microsoft 365

This article is contributed. See the original author and article here.

Sharing and collaboration are at the heart of Microsoft 365, empowering you to work seamlessly with coworkers and partners on files and documents. Collaboration across Word, Excel, PowerPoint, Teams, Outlook, OneDrive, SharePoint and other applications maximizes your efficiency and productivity at work. We understand the importance of file sharing, and that’s precisely why we’ve focused on refining and improving the experience based on the feedback you have given us. When you click the “Share” button, the Share Dialog box pops up. It’s this experience, used over eight hundred million times each month across Microsoft 365 applications, that we set out to improve. Our goal was to make it easier for you to share and collaborate. Today, we’re thrilled to announce that the Simplified Sharing experience is available across more than fifty Microsoft 365 applications on all platforms: Web, Desktop, and Mobile!


 


Hero_ShareDialog.png


The new Simplified Sharing in Microsoft 365 applications makes file sharing easier and faster than ever before!


 


Simple and fast sharing across Microsoft 365



As part of the Simplified Sharing experience, we’ve refreshed the Share dialog to be streamlined and free of distractions. Let’s take a look at these enhancements and the various ways you can share today:


 



Easily and quickly share a file with your coworkers by sending them an email or copying a link. 



Email a link
: When you want to email someone a link to a file, simply start typing a name, group or email and you’ll be given suggestions based on your most frequent collaborators. You also have the option to add a brief message. Once you hit “Send,” OneDrive will craft an e-mail and send it to your chosen recipients!


 


Copy a link: If you want to send your file in a different application, such as Teams or Outlook, you can always copy a link to your clipboard. We’ve made it easier to create and copy a link with a single click and see a quick confirmation. Once copied you can paste it into a Microsoft Teams chat, document, or email to give others access to the file. If you want more granular control around how others can access your file, such as giving them edit, view, review permissions or if you want to block downloads, just click the gear icon for further customization.


 



It’s now simple to share externally while respecting admin settings and external policies in Microsoft 365.



Share files externally
: You can also share links easily with people external to your organization. The new streamlined experience asks for your confirmation before creating an external share link while respecting admin settings and external policies, making it a lot easier and faster than the previous experience.


 


Granular control when sharing files



We are making it easier to view and control who has access to shared files or folders and what permissions they have.



Manage who has access to shared files and their respective permissions.


 


Manage Access: At the bottom of the Share dialog, you’ll see the people who have access to the shared file. Clicking on the people’s profile pictures or initials will take you to the Manage Access dialog which shows a comprehensive list of people and groups who have access to the file or folder, along with their respective permissions. The Manage Access dialog also lets you grant additional access, stop sharing, or set controls for how recipients access the files and folders you’ve shared with them.


 


Links: Clicking on the “Links” tab will surface a view of all the sharing links that have been created for the file or folder and who has access via each link. From the links view you can fine-tune who has access and what permissions they have.


 


 


SensitivityLabel.png


Easily determine a file’s sensitivity level in Microsoft 365 before sharing it.

Sharing sensitive files – We understand that some organizations want to handle sensitive information with an extra layer of protection. Sensitivity Labels in Microsoft 365 allow you to classify files based on their level of confidentiality, enabling better control over access and distribution. We’ve seamlessly integrated these labels into the Share dialog and Manage Access dialog. These labels, specific to each file, give you at-a-glance understanding of file sensitivity before sharing, helping to ensure security for your sensitive documents.


 


Learn more


 


When you’re ready to try the simplified sharing experience in Microsoft 365, just tap the Share button in the file you are working in to get started. And keep the feedback coming! To give us feedback just tap the feedback icon Ihcene_Cheriet_0-1690299741563.png in any Microsoft 365 app. Your feedback is invaluable in shaping a better experience tailored to your needs. Let’s elevate collaboration in Microsoft 365 together!



Learn more in the following support articles:
Sharing files, folders, and list items – Microsoft Support
Managing access in OneDrive for business – Microsoft Support


 


About the author


Ihcene Cheriet is a Senior Product Manager on the OneDrive team. She joined the team in 2020 where she focused on improving the sharing and collaboration experience across the M365 ecosystem. In her free time, she enjoys learning more about photography and exploring diverse cuisines.