Skip to content

Instantly share code, notes, and snippets.

@jeffpatton1971
Last active April 1, 2017 16:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeffpatton1971/7dc49a60bf655ef3dbbeddeac0255222 to your computer and use it in GitHub Desktop.
Save jeffpatton1971/7dc49a60bf655ef3dbbeddeac0255222 to your computer and use it in GitHub Desktop.
This script is designed to either start or stop a group of VM's in a Resource Group in Azure.

UpdatePowerState

This script and workflow is designed to either start or stop a group of VM's in a Resource Group in Azure. The script/workflow has 3 parameters:

  • AzureConnectionAssetName
  • ResourceGroupName
  • PowerState

AzureConnectionAssetName

This defaults to AzureRunAsConnection which is the default connection name Azure creates when running through the Azure Automation Account wizard.

ResourceGroupName

This parameter is mandatory, and is the name of the ResourceGroup you wish to have the runbook run against.

PowerState

This is going to be one of two values PowerState/running or PowerState/deallocated. This will be the state that we want to enforce on the vm's in the Resource Group.

  • PowerState/running, will start stopped vm's.
  • PowerState/deallocated will stop running vm's.
Create Azure Run As account

This is a toggle, leaving it at the default will create the SPN in the Azure AD that will allow the PowerShell scripts/workflows to use.

After the automation account is created it will show up in the Portal. If you open it up and click Assets, and then Connections you will see two connections the SPN connection for ARM deployments and a Certificate for Classic (v1) deployments. The scripts/workflows will use the default name for SPN as most of these will be targeted at ARM deployments.

If you have an Automation Account already, you can create the SPN yourself in the Portal. You will need the TenantID and SubscriptionID, and the ApplicationID and Certificate Thumbprint are generated for you by Azure when you create the SPN.

Now that the Automation Account is setup all that's left is to create your runbooks. Back in your Automation Account blade, you can click on Runbooks and then click Add a runbook. At this point you can either import a runbook, or create a new runbook. We will walk through creating a new runbook, you will need to provide a Name, a Description and then choose a Runbook Type.

param
(
[Parameter(Mandatory=$false)]
[string]$AzureConnectionAssetName = 'AzureRunAsConnection',
[Parameter(Mandatory=$false)]
[string]$ResourceGroupName,
[Parameter(Mandatory=$true)]
[ValidateSet('PowerState/running','PowerState/deallocated')]
[string]$PowerState
)
try
{
$ErrorActionPreference = 'Stop';
$Error.Clear();
$AutomationConnection = Get-AutomationConnection -Name $AzureConnectionAssetName;
$AzureAccount = Add-AzureRmAccount -ServicePrincipal -TenantId $AutomationConnection.TenantId -ApplicationId $AutomationConnection.ApplicationId -CertificateThumbprint $AutomationConnection.CertificateThumbprint;
}
catch
{
if (!($AutomationConnection))
{
throw "Azure Automation Connection $($AzureConnectionAssetName) not found.";
}
else
{
throw $Error.Exception;
}
}
if ($ResourceGroupName)
{
$VMs = Get-AzureRmVM -ResourceGroupName $ResourceGroupName;
}
else
{
$VMs = Get-AzureRmVM;
}
foreach ($VM in $VMs)
{
#
# Check PowerState
#
$VmStatus = Get-AzureRmVM -ResourceGroupname $VM.ResourceGroupname -Name $VM.Name -Status;
#
# Check if ProvisioningState -eq updating, if so check powerstate
# PowerState/deallocating vm is going down
# There is no PowerState on a vm that is off, as it's coming on there are the following states
# PowerState/stopped this is different from PowerState/deallocated (perhaps if the machine is powered off from the OS side)
# PowerState/starting vm is starting up
# PowerState/running vm is running
#
if (($VmStatus.Statuses |Select-Object -Property Code) -match 'ProvisioningState/updating')
{
#
# VM is updating
#
$Status = ($VmStatus.Statuses |Where-Object -Property Code -Like 'PowerState*' |Select-Object -ExpandProperty Code);
Write-Output "$($VM.Name) is updating current status is $($Status).";
}
else
{
switch ($PowerState)
{
'PowerState/running'
{
#
# This VM needs to be running
#
if (!(($VmStatus.Statuses |Select-Object -Property Code) -match $PowerState))
{
$Result = Start-AzureRmVM -Name $VM.Name -ResourceGroupName $VM.ResourceGroupName;
}
}
'PowerState/deallocated'
{
#
# This VM needs to be stopped
#
if (!(($VmStatus.Statuses |Select-Object -Property Code) -match $PowerState))
{
$Result = Stop-AzureRmVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name -Force;
}
}
}
}
if (!($Result.IsSuccessStatusCode))
{
Write-Output "$($VM.Name) PowerState ($($PowerState)) operation failed ($($Result.Error)) at $($Result.StartTime).";
}
else
{
Write-Output "$($VM.Name) PowerState ($($PowerState)) operation succeeded.";
}
}
@deviaSteve
Copy link

That IsSuccessStatusCode doesn't work running locally. I had to use: $Result.Status -eq "Succeeded"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment