Reputation: 3
I am trying to write a script that automatically start or stop Azure VMs in a resource group by finding their tags with the authentication part done by a managed identity. Also, as a VM starts the script will take a snapshot of its OS disk. Everything worked fine until I added everything linked to the snapshot part.
You will find below the entire script that I used :
Param(
[Parameter(Mandatory=$true)]
[Boolean]
$Shutdown,
[Parameter(Mandatory=$true)]
[String]
$ResourceGroup,
[Parameter(Mandatory=$true)]
[String]
$TagName,
[Parameter(Mandatory=$true)]
[String]
$TagValue,
[Parameter(Mandatory=$true)]
[String]
$ManagedIdentityId
)
$location = 'West Europe'
$datetime = Get-Date -Format "dd-MM-yyyy"
try
{
# Logging into Azure using Managed Identity
Connect-AzAccount -Identity -AccountId $ManagedIdentityId
}
catch
{
Write-Error -Message $_.Exception
throw $_.Exception
}
"Getting VMs with appropriate tags"
# We get all azure resources inside a specific resource group having a specific tag (Key and value). After that we apply a filter to get only virtual machines.
$vms = Get-AzResource -ResourceGroupName $ResourceGroup -TagName $TagName -TagValue $TagValue | where {$_.ResourceType -like "Microsoft.Compute/virtualMachines"}
# Test if the script has to stop or start these virtual machines that we previously got. This test is based on the parameter Shutdown ( Shutdown == true -> Stop VMs | Shutdown == false -> start VMs)
foreach ($vm in $vms) {
if($Shutdown){
Write-Output "Stopping $($vm.Name)";
Stop-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Force;
}
else {
$snapshotConfig = New-AzSnapshotConfig -SourceUri $vm.StorageProfile.OsDisk.ManagedDisk.Id -Location $location -CreateOption copy -SkuName Standard_LRS
$snapshotName = $vm.Name + 'OsDisk_snapshot_' + $datetime"
Write-Output "Taking Snapshots of the $($vm.Name) OS disk";
New-AzSnapshot `
-SnapshotName $snapshotName `
-Snapshot $snapshotConfig `
-ResourceGroupName $ResourceGroup
Write-Output "Starting $($vm.Name)";
Start-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name;
}
}
As I try to launch the script I get the following error :
At line:44 char:66 + $snapshotName = $vm.Name + 'OsDisk_snapshot_' + $datetime" + ~ Unexpected token '" Write-Output "' in expression or statement. At line:45 char:23 + Write-Output "Taking Snapshots of the $($vm.Name) OS disk"; + ~~~~~~ Unexpected token 'Taking' in expression or statement. At line:50 char:43 + Write-Output "Starting $($vm.Name)"; + ~~ The string is missing the terminator: ". At line:42 char:10 + else { + ~ Missing closing '}' in statement block or type definition. At line:37 char:23 + foreach ($vm in $vms) { + ~ Missing closing '}' in statement block or type definition.
I don't quite understand these errors as it worked fine (the VMs could start and stop without problem) before I added this block of code :
$snapshotConfig = New-AzSnapshotConfig -SourceUri $vm.StorageProfile.OsDisk.ManagedDisk.Id -Location $location -CreateOption copy -SkuName Standard_LRS
$snapshotName = $vm.Name + 'OsDisk_snapshot_' + $datetime"
Write-Output "Taking Snapshots of the $($vm.Name) OS disk";
New-AzSnapshot `
-SnapshotName $snapshotName `
-Snapshot $snapshotConfig `
-ResourceGroupName $ResourceGroup
Am I missing something here ?
I tried deleting the Write-Output commands but as I did it I got other Exception errors with missing characters of unexpected token for other lines of code that I didn't change so I'm don't really understand.
Upvotes: 0
Views: 173
Reputation: 7838
Error is related to the extra double quotes (") added after $datetime
in the provided code.
Remove the double quote at the end of below line and execute it as shown below.
$snapshotName = $vm.Name + 'OsDisk_snapshot_' + $datetime
Modified PS script:
Param(
[Parameter(Mandatory=$true)]
[Boolean]
$Shutdown,
[Parameter(Mandatory=$true)]
[String]
$ResourceGroup,
[Parameter(Mandatory=$true)]
[String]
$TagName,
[Parameter(Mandatory=$true)]
[String]
$TagValue
)
$location = 'eastus'
$datetime = Get-Date -Format "dd-MM-yyyy"
$vms = Get-AzResource -ResourceGroupName $ResourceGroup -TagName $TagName -TagValue $TagValue | where {$_.ResourceType -like "Microsoft.Compute/virtualMachines"}
foreach ($vm in $vms) {
if($Shutdown){
Write-Output "Stopping $($vm.Name)";
Stop-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Force
}
else{
$snapshotConfig = New-AzSnapshotConfig -SourceUri $vm.StorageProfile.OsDisk.ManagedDisk.Id -Location $location -CreateOption copy -SkuName Standard_LRS
$snapshotName = $vm.Name + 'OsDisk_snapshot_' + $datetime
Write-Output "Taking Snapshots of the $($vm.Name) OS disk"
New-AzSnapshot `
-SnapshotName $snapshotName `
-Snapshot $snapshotConfig `
-ResourceGroupName $ResourceGroup
Write-Output "Starting $($vm.Name)"
Start-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name
}
}
Output:
Updated code:
$VMs = Get-AzVM
foreach ($VM in $VMs)
{
[Hashtable]$VMTags = (Get-AzVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name).Tags
foreach ($hash in $VMTag.GetEnumerator()) {
if (($hash.Name -eq "Reason") -and ($hash.value -eq "Repro"))
{
Write-host "VM with given tags are" $VM.Name
}
}
}
Upvotes: 0