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