Azure Powershell Scripting parameters - azure

Good Day
I have been tasked to gather a list of all the VMs in our different subscriptions, and I have a script that gathers: Mode, Name, ResourceGroupName, location, VMSize, and Status. There are two empty columns: subscription and availability set.
A bit of a backstory, the company I am contracted to hired a vendor to deploy the resources and now they don't know if the vendor did what they were suppose to.
What I am trying to figure out:
How to list the ASG the resource is in
The NSG the resource is in
The vCPUs and RAM
Storage account
I have been scouring google to find the PSObjects I need to define. Any assistance would be greatly appreciated

1.How to list the ASG the resource is in
If you want to list all the ASGs in the VM, you need to list them via all the NICs, you could refer to the command below, the $asgnames is the list of all ASGs, note if different NICs have the same ASG, it will output several times.
$nics = (Get-AzureRmVM -ResourceGroupName "<ResourceGroupName>" -Name "<VM Name>").NetworkProfile.NetworkInterfaces
$nicnames = #()
$asgnames = #()
foreach($nic in $nics){
$a = $nic.Id -split"/"
$nicname = $a[8]
$nicnames += $nicname
$ipconfig = Get-AzureRmResource -ResourceGroupName <ResourceGroupName> -ResourceType Microsoft.Network/networkInterfaces/ipConfigurations -ResourceName "$nicname/ipconfig1" -ApiVersion 2018-07-01
$asgids = $ipconfig.Properties.applicationSecurityGroups.id
foreach ($asgid in $asgids){
$a = $asgid -split"/"
$asganme = $a[8]
$asgnames += $asganme
}
}
2.The NSG the resource is in
If you want to get NSGs in the VM, you need to get them via all NICs and VNET Subnet.
Get the NSG of the NIC, the $nsgnic is the NSG:
$nic = Get-AzureRmResource -ResourceGroupName <ResourceGroupName> -ResourceType Microsoft.Network/networkInterfaces -ResourceName "<NIC name>" -ApiVersion 2018-07-01
$a = $nic.properties.networkSecurityGroup.id -split"/"
$nsgnic = $a[8]
Get the NSG of subnet, the $nsgsub is the NSG:
$subnet = Get-AzureRmResource -ResourceGroupName <ResourceGroupName> -ResourceType Microsoft.Network/virtualNetworks/subnets -ResourceName "<Vnet name>/<Subnet name>" -ApiVersion 2018-07-01
$b = $subnet.properties.networkSecurityGroup.id -split"/"
$nsgsub = $a[8]
Then the NSGs of the VM will be the sum of $nsgnic and $nsgsub.
3.The vCPUs and RAM
Try the command below, NumberOfCores is the vCPUs , MemoryInMB is the RAM, note the RAM in result is in MB, you could convert it to GB if necessary.
Get-AzureRmVMSize -ResourceGroupName "<ResourceGroupName>" -VMName "<VMName>"
4.Storage account
If I do not misunderstand, the storage account here you mean the Diagnostics storage account, try the command below, $storage is the storage account uri.
$a = Get-AzureRmResource -ResourceGroupName <ResourceGroupName> -ResourceType Microsoft.Compute/virtualMachines -ResourceName "<VM Name>" -ApiVersion 2018-06-01
$storage = $a.properties.diagnosticsProfile.bootDiagnostics.storageUri

Related

Need help spiting Azure snapshots into another tenant/subscription

I have a script which snapshots all my disks in a certain RG.
However when I do the snapshotting, I need them to be spat out into another tenant/subscription for a migration project!
I've got as far as snapshotting everything and spitting them into a different RG but I need to take it a step further and spit them into the same named RG but in a different tenant/sub.
My script is below:
Login-AzureRmAccount -Credential $psCred –SubscriptionId $SubscriptionId -ErrorAction Stop | out-null
Connect-AzureRmAccount
Get-AzureRmSubscription -SubscriptionId $SubscriptionId | Select-AzureRmSubscription
$tagResList = Get-AzureRmResource -TagName Environment -TagValue Staging
#$tagResList = Find-AzureRmResource -ResourceGroupNameEquals testrs
#$tagRsList[0].ResourceId.Split("//")
#subscriptions
#<SubscriptionId>
#resourceGroups
#<ResourceGroupName>
#providers
#Microsoft.Compute
#virtualMachines
#<vmName>
foreach($tagRes in $tagResList) {
if($tagRes.ResourceId -match "Microsoft.Compute")
{
$vmInfo = Get-AzureRmVM sandbox207478603000 #$tagRes.ResourceId.Split("//")[4] -Name $tagRes.ResourceId.Split("//")[8]
#Set local variables
$location = $vmInfo.Location
$resourceGroupName = $vmInfo.ResourceGroupName
$timestamp = Get-Date -f MM-dd-yyyy_HH_mm_ss
#Snapshot name of OS data disk
$snapshotName = $vmInfo.Name + $timestamp
#Create snapshot configuration
$snapshot = New-AzureRmSnapshotConfig -SourceUri $vmInfo.StorageProfile.OsDisk.ManagedDisk.Id -Location $location -CreateOption copy
#Take snapshot
New-AzureRmSnapshot -Snapshot $snapshot -SnapshotName $snapshotName snapshots $resourceGroupName
if($vmInfo.StorageProfile.DataDisks.Count -ge 1){
#Condition with more than one data disks
for($i=0; $i -le $vmInfo.StorageProfile.DataDisks.Count - 1; $i++){
#Snapshot name of OS data disk
$snapshotName = $vmInfo.StorageProfile.DataDisks[$i].Name + $timestamp
#Create snapshot configuration
$snapshot = New-AzureRmSnapshotConfig -SourceUri $vmInfo.StorageProfile.DataDisks[$i].ManagedDisk.Id -Location $location -CreateOption copy
#Take snapshot
New-AzureRmSnapshot -Snapshot $snapshot -SnapshotName $snapshotName snapshots $ResourceGroupName
}
}
else{
Write-Host $vmInfo.Name + " doesn't have any additional data disk."
}
}
else{
$tagRes.ResourceId + " is not a compute instance"
}
}
$tagRgList = Get-AzureRmResourceGroup -Tag #{ Environment = "Staging" }
I am not sure if you can save snapshot in another tenant in one command as you'd need to be authenticated there.
I would suggest using azcopy tool to move snapshot files between storage accounts
#######################################
Reviewed your comment and found that indeed you can't use azcopy on vm images.
But you may create access to the snapshot
#Generate the SAS for the snapshot
$sas = Grant-AzSnapshotAccess -ResourceGroupName $ResourceGroupName -SnapshotName $SnapshotName -DurationInSecond $sasExpiryDuration -Access Read
and save it to the destination storage account:
#Copy the snapshot to the storage account
Start-AzStorageBlobCopy -AbsoluteUri $sas.AccessSAS -DestContainer $storageContainerName -DestContext $destinationContext -DestBlob $destinationVHDFileName
More details canbe found here

Validate Azure Resource Group Exist or not

I am trying to write to a powershell script to validate the Resource Group is exist or not.
Conditions-
Check the resource group (myrg) is already exist in azure subscription.
If "condition 1" is FALSE then Create a Resource Group (myrg) Else append 2 digits to the Resource Group name. e.g. (myrg01)
Check the (myrg01)resource group exist in azure subscription.
If "condition 3" is FALSE then Create a Resource Group (myrg01) Else increment the last digit by one for Resource Group name. e.g. (myrg02)
Check the (myrg02) resource group exist in azure subscription.
If "condition 5" is FALSE then Create a Resource Group (myrg02) Else increment the last digit by one for Resource Group name. e.g. (myrg03)
and so on.........
Below is the code which i have written so far and unable to create a desired loop.
$rgname= "myrg"
Get-AzResourceGroup -Name $rgname -ErrorVariable notPresent -ErrorAction SilentlyContinue
if ($notPresent){
Write-Host "ResourceGroup doesn't exist, Creating resource group"
$createRG= New-AzResourceGroup -Name $rgname -Location $region -Tag $tag
Write-Host $rgname
}
else{
$countcontent = $countcontent + 1
$counter = [int]$countcontent
++$counter
$countString = "{0:d2}" -f ($counter)
Write-Host "ResourceGroup $rgname already exist, Generating a new name for Resource Group"
$rgname= $rgname + $countString
Get-AzResourceGroup -Name $rgname -ErrorVariable notPresent -ErrorAction SilentlyContinue
if ($notpresent){
$createRG= New-AzResourceGroup -Name $rgname -Location $region -Tag $tag
Write-Host $rgname
Clear-Variable countcontent
Clear-Variable counter
Clear-Variable countString
}
}
Got a workaround
$rg="myrg"
$Subscriptions = Get-AzSubscription
$Rglist=#()
foreach ($Subscription in $Subscriptions){
$Rglist +=(Get-AzResourceGroup).ResourceGroupName
}
$rgfinal=$rg
$i=1
while($rgfinal -in $Rglist){
$rgfinal=$rg +"0" + $i++
}
Write-Output $rgfinal
Set-AzContext -Subscription "Subscription Name"
$createrg= New-AzResourceGroup -Name $rgfinal -Location "location"

How to initialize a disk after I append a data disk to VM automatucally?

Based on this doc :
https://learn.microsoft.com/en-us/azure/virtual-machines/windows/attach-managed-disk-portal I can append a data disk to my windows Azure VMs and initialize the disk manually by login to the VM. Everything works for me.
BUT it is not enough as I want to make the whole process automatually by code. Could you please give me some code sample or guide about it ? Thanks!
#ShirazBhaiji provided a helpful doc that will meet your requirement, but there is a new feature that you can run commands on Azure VMs directly, no need to enable WinRM.
Just try the Powershell below :
This is the command to init a data disk in windows :
$disks = Get-Disk | Where partitionstyle -eq 'raw' | sort number
$letters = 70..89 | ForEach-Object { [char]$_ }
$count = 0
$labels = "data1","data2"
foreach ($disk in $disks) {
$driveLetter = $letters[$count].ToString()
$disk |
Initialize-Disk -PartitionStyle MBR -PassThru |
New-Partition -UseMaximumSize -DriveLetter $driveLetter |
Format-Volume -FileSystem NTFS -NewFileSystemLabel $labels[$count] -Confirm:$false -Force
$count++
}
Save it as a .ps1 file.
Use this command to append a disk and run the above command directly :
$vm = Get-AzVM -Name <your VM name> -ResourceGroupName <your vm resource group name>
$dataDiskName = $vm.Name + '_datadisk1'
$diskConfig = New-AzDiskConfig -SkuName 'Premium_LRS' -Location $vm.Location -CreateOption Empty -DiskSizeGB 128 -Zone 1
$dataDisk1 = New-AzDisk -DiskName $dataDiskName -Disk $diskConfig -ResourceGroupName $vm.ResourceGroupName
Add-AzVMDataDisk -VM $vm -Name $dataDiskName -CreateOption Attach -ManagedDiskId $dataDisk1.Id -Lun 1
Update-AzVM -VM $vm -ResourceGroupName $vm.ResourceGroupName
Invoke-AzVMRunCommand -VM $vm -CommandId 'RunPowerShellScript' -ScriptPath "<path of the previous .ps1 file>"
Result :
Hope it helps!
You can do this using powershell, you need to have windows remote management enabled on the VM.
Example scripts can be found here:
https://learn.microsoft.com/en-us/azure/virtual-machines/windows/attach-disk-ps

Auto sql of azure SQL based on DTU consumption alert

I have to scale my Azure SQL if DTU utilization is high at any moment and scale down if consumption is low for a certain duration.
I know this can be done by setting alert rule and web hook but looking for some redimate stuff which i can refer and utilize it....
Scale up and down takes time and sometimes it takes more than expected. It usually takes 5-10 minutes but sometimes it takes 25-30 minutes. The busier the database is at the time of the scale, the more time it takes to scale up or down. The size of the database also matters.
Remember also that transactions are rolled back when a scale is in progress.
My suggestion is to use the following query to identify patterns in resource consumption and then automate the scale up and down of the database.
SELECT *
FROM sys.dm_db_resource_stats
ORDER BY end_time
Tabulate that data on hours and days of the week to facilitate the pattern identification. After that use Azure Automation and parts of the following PowerShell to automate the scale up/down of the database. The following PowerShell does all what you want, it monitors DTU usage and then based on consumption triggers a scale process.
# Login-AzureRmAccount
# Set the resource group name and location for your server
$resourcegroupname = "myResourceGroup-$(Get-Random)"
$location = "southcentralus"
# Set an admin login and password for your server
$adminlogin = "ServerAdmin"
$password = "ChangeYourAdminPassword1"
# The logical server name has to be unique in the system
$servername = "server-$(Get-Random)"
# The sample database name
$databasename = "mySampleDatabase"
# The ip address range that you want to allow to access your server
$startip = "0.0.0.0"
$endip = "0.0.0.0"
# Create a new resource group
$resourcegroup = New-AzureRmResourceGroup -Name $resourcegroupname -Location $location
# Create a new server with a system wide unique server name
$server = New-AzureRmSqlServer -ResourceGroupName $resourcegroupname `
-ServerName $servername `
-Location $location `
-SqlAdministratorCredentials $(New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminlogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force))
# Create a server firewall rule that allows access from the specified IP range
$serverfirewallrule = New-AzureRmSqlServerFirewallRule -ResourceGroupName $resourcegroupname `
-ServerName $servername `
-FirewallRuleName "AllowedIPs" -StartIpAddress $startip -EndIpAddress $endip
# Create a blank database with S0 performance level
$database = New-AzureRmSqlDatabase -ResourceGroupName $resourcegroupname `
-ServerName $servername `
-DatabaseName $databasename -RequestedServiceObjectiveName "S0"
# Monitor the DTU consumption on the imported database in 5 minute intervals
$MonitorParameters = #{
ResourceId = "/subscriptions/$($(Get-AzureRMContext).Subscription.Id)/resourceGroups/$resourcegroupname/providers/Microsoft.Sql/servers/$servername/databases/$databasename"
TimeGrain = [TimeSpan]::Parse("00:05:00")
MetricNames = "dtu_consumption_percent"
}
(Get-AzureRmMetric #MonitorParameters -DetailedOutput).MetricValues
# Scale the database performance to Standard S1
$database = Set-AzureRmSqlDatabase -ResourceGroupName $resourcegroupname `
-ServerName $servername `
-DatabaseName $databasename `
-Edition "Standard" `
-RequestedServiceObjectiveName "S1"
# Set an alert rule to automatically monitor DTU in the future
Add-AzureRMMetricAlertRule -ResourceGroup $resourcegroupname `
-Name "MySampleAlertRule" `
-Location $location `
-TargetResourceId "/subscriptions/$($(Get-AzureRMContext).Subscription.Id)/resourceGroups/$resourcegroupname/providers/Microsoft.Sql/servers/$servername/databases/$databasename" `
-MetricName "dtu_consumption_percent" `
-Operator "GreaterThan" `
-Threshold 90 `
-WindowSize $([TimeSpan]::Parse("00:05:00")) `
-TimeAggregationOperator "Average" `
-Actions $(New-AzureRmAlertRuleEmail -SendToServiceOwners)
# Clean up deployment
# Remove-AzureRmResourceGroup -ResourceGroupName $resourcegroupname

How to move an azure VM image to a different location

I have an azure VM image with a managed disk in east US and I want to move/copy it to West Europe.
Is there an easy way to do it?
I saw that there's an azure cli extension called az-image-copy but it doesn't work for me because it outputs an error which says that it can't find the OS disk (even though the resource ID is correct and I can see it in the azure portal)
ERROR: Resource ServerLinux_OsDisk_1_c208679747734937b10a1525aa84a7d7 is not found
So is there any other way to do it?
You could use azure powershell to copy the managed images, create a snapshot and copy it to anther region, then create the image. Here is a similar issue.
Create a snapshot:
<# -- Create a snapshot of the OS (and optionally data disks) from the generalized VM -- #>
$vm = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $vmName
$disk = Get-AzureRmDisk -ResourceGroupName $resourceGroupName -DiskName $vm.StorageProfile.OsDisk.Name
$snapshot = New-AzureRmSnapshotConfig -SourceUri $disk.Id -CreateOption Copy -Location $region
$snapshotName = $imageName + "-" + $region + "-snap"
New-AzureRmSnapshot -ResourceGroupName $resourceGroupName -Snapshot $snapshot -SnapshotName $snapshotName
Copy the snapshot:
# Create the name of the snapshot, using the current region in the name.
$snapshotName = $imageName + "-" + $region + "-snap"
# Get the source snapshot
$snap = Get-AzureRmSnapshot -ResourceGroupName $resourceGroupName -SnapshotName $snapshotName
# Create a Shared Access Signature (SAS) for the source snapshot
$snapSasUrl = Grant-AzureRmSnapshotAccess -ResourceGroupName $resourceGroupName -SnapshotName $snapshotName -DurationInSecond 3600 -Access Read
# Set up the target storage account in the other region
$targetStorageContext = (Get-AzureRmStorageAccount -ResourceGroupName $resourceGroupName -Name $storageAccountName).Context
New-AzureStorageContainer -Name $imageContainerName -Context $targetStorageContext -Permission Container
# Use the SAS URL to copy the blob to the target storage account (and thus region)
Start-AzureStorageBlobCopy -AbsoluteUri $snapSasUrl.AccessSAS -DestContainer $imageContainerName -DestContext $targetStorageContext -DestBlob $imageBlobName
Get-AzureStorageBlobCopyState -Container $imageContainerName -Blob $imageBlobName -Context $targetStorageContext -WaitForComplete
# Get the full URI to the blob
$osDiskVhdUri = ($targetStorageContext.BlobEndPoint + $imageContainerName + "/" + $imageBlobName)
# Build up the snapshot configuration, using the target storage account's resource ID
$snapshotConfig = New-AzureRmSnapshotConfig -AccountType StandardLRS `
-OsType Windows `
-Location $targetRegionName `
-CreateOption Import `
-SourceUri $osDiskVhdUri `
-StorageAccountId "/subscriptions/${sourceSubscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.Storage/storageAccounts/${storageAccountName}"
# Create the new snapshot in the target region
$snapshotName = $imageName + "-" + $targetRegionName + "-snap"
$snap2 = New-AzureRmSnapshot -ResourceGroupName $resourceGroupName -SnapshotName $snapshotName -Snapshot $snapshotConfig
Create the image:
<# -- In the second subscription, create a new Image from the copied snapshot --#>
Select-AzureRmSubscription -SubscriptionId $targetSubscriptionId
$snap = Get-AzureRmSnapshot -ResourceGroupName $resourceGroupName -SnapshotName $snapshotName
$imageConfig = New-AzureRmImageConfig -Location $destinationRegion
Set-AzureRmImageOsDisk -Image $imageConfig `
-OsType Windows `
-OsState Generalized `
-SnapshotId $snap.Id
New-AzureRmImage -ResourceGroupName $resourceGroupName `
-ImageName $imageName `
-Image $imageConfig
For more details, refer to this link.
If the resources are under the same subscription then you can get move resources to from the Resource Group 01 (East Us) to the Resource Group 02 (West Europe).
For your help you can check these documents:
Move Managed Disks and VMs
Move resources to new resource group or subscription
Copy managed disks in the same subscription or different subscription with PowerShell
Migrating Azure IaaS solutions using MigAz
The last link is about the MigAz tool, which allow to migrate resources on Azure.

Resources