Skip to main content

PowerShell : Use Case for MutEx

This post is to give you context on a practical use case of using MutEx in PowerShell.

From the MSDN documentation for the MutEx class , MutEx is :


"A synchronization primitive that can also be used for interprocess synchronization."


Mut - Mutually 
Ex - Exclusive


Recently while deploying AzureStack, I saw multiple failed deployments, partly because of me not paying attention. 


But since it failed, I had to go and look at the code in an effort to see what went wrong.

AzureStack runs all the deployment tasks for creating a POC by using scheduled tasks (runs in System context) heavily.

Also the status of the deployment  is tracked by using XML files (these are placed under C:\ProgramData\Microsoft\AzureStack\), so they have to avoid conflicts in reading and writing of these XML files from these tasks which are separate PowerShell processes.

Now this is a simple but very important part of the whole process. So while going through the code being used,
I saw this little neat function in the AzureStakDeploymentStatus.psm1 file :


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
## Lock the status reads\writes with a mutex to avoid conlicts
function Invoke-ActionWithMutex
{
    param(
        [ScriptBlock]$Action
    )

    $mutex = $null

    try
    {
        $createdNew = $fasle # Typo here but this evaluates to False

        $mutex = New-Object System.Threading.Mutex($true, "Global\AzureStackDeploymentStatus", [ref]$createdNew)

        if (-not $createdNew)
        {
            try
            {
               $mutex.WaitOne() | Out-Null
            }
            catch [System.Threading.AbandonedMutexException]
            {
                #AbandonedMutexException means another thread exit without releasing the mutex, and this thread has acquired the mutext, therefore, it can be ignored
            }
        }

        Invoke-Command -ScriptBlock $Action -NoNewScope
    }
    finally
    {
        if ($mutex -ne $null)
        {
            $mutex.ReleaseMutex()
            $mutex.Dispose()
        }
    }

}

This function piqued my interest on the subject of MutEx. In the same .psm1 file this function is being used within the functions Get-AzureStackDeploymentStatus and Update-AzureStackDeploymentStatus.

Below is the Get-AzureStackDeploymentStatus defintion :


001
002
003
004
005
006
007
008
009
010
011
012
function Get-AzureStackDeploymentStatus
{
    [CmdletBinding()]
    param()
    if (-not (Test-Path $statusFilePath)) {
        Update-AzureStackDeploymentStatus $StatusTemplate | Out-Null
    }

    Invoke-ActionWithMutex -Action {
        [xml](Get-Content $statusFilePath)
    }
}

and the Update-AzureStackDeploymentStatus definition is below:


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
function Update-AzureStackDeploymentStatus
{
    [CmdletBinding()]
    param(
        [Xml]$Status
    )

    Invoke-ActionWithMutex -Action {
        if (-not (Test-Path $statusFileFolder))
        {
            New-Item -Path $statusFileFolder -ItemType Directory | Out-Null
        }
        $Status.Save($statusFilePath)
    }
}


Now this is powerful stuff and since my first exposure to it, I have been reading up a lot on this topic and how to use this in my Scripts.

This post will soon follow a series of post on this particular topic.

Popular posts from this blog

Test connectivity via a specific network interface

Recently while working on a Private cloud implementation, I came across a scenario where I needed to test connectivity of a node to the AD/DNS via multiple network adapters.  Many of us would know that having multiple network routes is usually done to take care of redundancy. So that if a network adapter goes down, one can use the other network interface to reach out to the node. In order to make it easy for everyone to follow along, below is an analogy for the above scenario: My laptop has multiple network adapters (say Wi-Fi and Ethernet) connected to the same network. Now how do I test connectivity to a Server on the network only over say Wi-Fi network adapter?

PowerShell + SCCM : Run CM cmdlets remotely

Today I saw a tweet about using implicit remoting to load the Configuration Manager on my machine by Justin Mathews . It caught my eye as I have never really tried it, but theoretically it can be done. Note - The second tweet says "Cannot find a provider with the name CMSite", resolution to which is in the Troubleshooting section at the end.

Azure DevOps Tips & Tricks - Find private REST APIs

Original source -  Azure DevOps Tip - Find private APIs Often working with Azure DevOps, I hit a wall trying to automate some tasks but there are no REST API's made public yet. It was one of those task of automating creation of Environments in multi-stage YAML based pipelines in AzDO. Quick research reveals that this has been requested in uservoice  (please upvote). Let's see one of the very simple ways to discover some of these APIs.