Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon What are the steps to automate VM shutdowns using Azure Functions and PowerShell


What are the steps to automate VM shutdowns using Azure Functions and PowerShell


To automate VM shutdowns using Azure Functions and PowerShell, follow these steps:

1. Create an Azure Function:
- Navigate to the Azure portal and create a new Azure Function App.
- Choose the runtime stack as PowerShell (if available) or use a C# function with PowerShell scripts executed via the `Process` class.
- Set up a timer trigger to run your function at the desired shutdown time.

2. Authenticate with Azure:
- In your Azure Function, you need to authenticate with Azure to manage VMs. You can use a managed identity for this purpose.
- Enable the managed identity in the Azure Function configuration and assign the necessary permissions to manage VMs.

3. Write PowerShell Script:
- Within your Azure Function, write a PowerShell script to stop the VMs. You can use the `Stop-AzVM` cmdlet for this.
- Ensure the script is executed in the context of the managed identity.

4. Implement Logic for Shutdown:
- Use Azure tags or other metadata to identify which VMs should be shut down.
- Implement logic to check the current time and compare it with the desired shutdown time stored in tags or another data source.

5. Test and Deploy:
- Test your function in a non-production environment to ensure it works as expected.
- Once tested, deploy it to your production environment.

Here's a simplified example of how you might implement this in a C# Azure Function that runs a PowerShell script:

csharp
using System;
using System.Diagnostics;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

public class VMShutdownFunction
{
    [Function("VMShutdown")]
    public void Run([TimerTrigger("0 0 17 * * *")] MyInfo myTimer, ILogger logger)
    {
        logger.LogInformation($"C# Timer trigger function executed at {DateTime.Now}");
        
        // Authenticate and run PowerShell script
        var process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "powershell.exe",
                Arguments = "-NoProfile -ExecutionPolicy Bypass -Command \"Stop-AzVM -Name 'YourVMName' -ResourceGroupName 'YourResourceGroupName'\"",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                CreateNoWindow = true
            }
        };
        process.Start();
        process.WaitForExit();
    }
}

public class MyInfo
{
    public MySchedule Schedule { get; set; }

    public bool IsPastDue { get; set; }
}

public class MySchedule
{
    public string Frequency { get; set; }
    public int Interval { get; set; }
    public string Schedule { get; set; }
}

For a PowerShell-based Azure Function (if supported), you would directly write the PowerShell script to stop the VMs:

powershell
# Authenticate with Azure (using managed identity or other means)
Connect-AzAccount -Identity

# Define VMs to shutdown
$vmName = "YourVMName"
$resourceGroupName = "YourResourceGroupName"

# Stop the VM
Stop-AzVM -Name $vmName -ResourceGroupName $resourceGroupName -Confirm:$false -NoWait -Force

**Note: Ensure you have the necessary permissions and authentication set up for your Azure Function to manage VMs. Also, the availability of PowerShell as a runtime for Azure Functions might vary, so you may need to use a C# function to execute PowerShell scripts.

Citations:
[1] https://serverfault.com/questions/747712/azure-script-to-start-or-shut-down-multiple-vms
[2] https://learn.microsoft.com/en-us/azure/virtual-machines/auto-shutdown-vm
[3] https://techcommunity.microsoft.com/blog/coreinfrastructureandsecurityblog/switch-off-virtual-machines-on-a-schedule-using-an-azure-tag/4207182
[4] https://stackoverflow.com/questions/71391125/is-it-possible-to-automate-shutdown-in-azure-vms-to-save-costs
[5] https://www.reddit.com/r/AZURE/comments/xtdaa4/automating_stopping_vms/
[6] https://stackoverflow.com/questions/37204782/is-it-possible-to-stop-start-an-azure-arm-virtual-machine-from-an-azure-function
[7] https://charbelnemnom.com/schedule-azure-vm-using-azure-function/
[8] https://www.joelverhagen.com/blog/2022/05/azure-functions-on-vmss