I am trying to find PowerShell cmdlet which can retrieve information about which storage account Azure VM use.
Example, I want to supply name of VM and I would like to see which storage that VM use. Or it will be also good to query specific storage account and see which VMs use this storage account.
I am trying following cmdlets but I cannot see details about storage account:
Select-AzureSubscription -SubscriptionName "name"
Get-AzureVM -Name "name" -ServiceName "name"
The Get-AzureDisk cmdlet may be useful for you. This is the approach that I'm using.
$disk = Get-AzureDisk | Where-Object { $_.AttachedTo.RoleName -eq "YOURVMNAME" }
$mediaLink = $disk.MediaLink
$storageAccountName = $mediaLink.Host.Split('.')[0]
https://msdn.microsoft.com/en-us/library/azure/dn495125.aspx
I am answering the second part of your question. You want list of VM under a particular Storage Account. Suppose your storage account name is "xyz123" and you want to list all vms under this storage account. Then you just need to run the script given below-
$vms = Get-AzureVM
$output = " "
$tgtStorageaccount = "xyz123"
foreach($vm in $vms)
{
$disk = Get-AzureVM -ServiceName $vm.ServiceName –Name $vm.Name | Get-AzureOSDisk
$mediaLink = $disk.MediaLink
$storageAccountName = $mediaLink.Host.Split('.')[0]
if ($storageAccountName -eq $tgtStorageaccount)
{
$output =$output + "`r`n" + $vm.Name
}
}
$output
Hope This one will help you. Thanks.
Yes. Storageaccount can be find for RM based VM.
For OS:
$output = Get-AzureRmVM -ResourceGroupName "xx-RG-xx-DEv" -Name "xx-xx-vm-DEV"
$storageAccountName = $output.StorageProfile.OsDisk.Vhd.Uri.Split("/")[2].Split(".")[0]
Get-AzureRmStorageAccount -StorageAccountName $storageAccountName -ResourceGroupName "xx-RG-xx-DEv"
Each of a vm's disks is going to be stored in a given blob, with the blob's uri containing the storage account name. For example:
https://mystorageaccount.blob.core.windows.net/vhds/myosdisk.vhd
You'd need to retrieve the various os disk and data disk uri's from your vm's and then parse the uri accordingly. Here's a way to get the storage account for each disk by first grabbing the base uri (mystorageaccount.blob.core.windows.net) and then taking the first string segment (separated by dot characters).
For the OS disk:
Get-AzureVM -ServiceName myservice -Name myvmname |
GetAzureOSDisk |
ForEach-Object { $_.MediaLink.Host.split(".")[0] }
And likewise for data disks:
Get-AzureVM -ServiceName myservice -Name myvmname |
GetAzureDataDisk |
ForEach-Object { $_.MediaLink.Host.split(".")[0] }
You'll get duplicate storage account names if you used the same storage account for more than one disk.
Related
I'm currently studying for az-104 azure exam and going through some scripting exercises.
I can confirm the script below works, but I don't understand how...
in the last few lines of the script the variable $vm is defined twice. how is this possible?
also when you define a variable is it actually running the commands that are being defined? i didn't realize that was the case, but it definitely seems to be.. can someone please explain?
$resourcegroup = "2019dc_group"
$machinename = "2019dc"
$location = "east us"
$storagetype = "Standard_LRS"
$name = "newdisk"
$size = 20
$datadiskconfig = new-azdiskconfig -SkuName $storagetype -location $location -createoption empty -DiskSizeGB $size
$datadisk01 = new-azdisk -diskname $name -disk $datadiskconfig -ResourceGroupName $resourcegroup
$vm = Get-AzVM -name $machinename -resourcegroupname $resourcegroup
$vm = add-azvmdatadisk -vm $vm -name $name -createoption attach -ManagedDiskId $datadisk01.id -lun 1
update-azvm -vm $vm -resourcegroupname $resourcegroup
Variable types in PowerShell are dynamic. They are automatically "adjusted" to the type of the object they are assigned to.
Yes, the commands are being executed first and then the object is placed in the variable. This is also why you are able to use the vm variable in the command and assign the result back to that variable. When the "add-azvmdatadisk" command is executed, the type of the variable is still an Azure VM. When the assignment takes places, it is an Azure VM Data Disk
You can use Get-Member to get the type, methods, properties, events etc. for any object.
$a = 1 #System.Int32
$a | Get-Member
$a = "1" #System.String
$a | Get-Member
$a = Get-Service | Select-Object -First 1 #System.ServiceProcess.ServiceController
$a | Get-Member
The $VM variable is not defined twice. It's being assigned a value twice. One doesn't need to define variables in Powershell, assignment will automatically create one.
Let's review the code. First off,
$vm = Get-AzVM -name $machinename -resourcegroupname $resourcegroup
After the Get-AzVM, you'll have its output in $vm. Nothing fancy here. Note that before this statement, $vm didn't exist, and trying to work with it would generate an error about using null value.
$vm = add-azvmdatadisk -vm $vm -name $name -createoption attach -ManagedDiskId $datadisk01.id -lun 1
Here $vm is used twice. The first usage is when you pass it as an argument to Add-AzVmDataDisk. The cmdlet returns a PSVirtualMachine object, so after adding the disk, you'd get an updated version of $vm into the variable. This might or might not be important a difference. If the Azure VM objects are lazy evaluated, the old $vm would contain hardware information without the new disk. This often is the case, as it improves performance. By assigning the output of the later cmdlet into $vm, you are sure to have up-to-date version of your VM.
If you have a lab environment, try printing $vm before the last disk addition cmdlet call and after it. See what's different on the outputs.
I am trying to write a PowerShell script that will look for shutdown VMs in my Resource Group and deallocate them. The output of the below script does not give me the VM name "clean" when I attempt tp assign the below as a variable. The end result is to execute the Stop-AzureRmVM -ResourceGroupName LAB -Name $VM -force
So for more context, lets say AVGJOE-DC1 is in a stopped state and I run the below line in Azure Powershell it will display
Name
----
AVGJOE-DC1
If I then if I tried to use $VM to call AVGJOE-DC1 in the
Stop-AzureRmVM -ResourceGroupName LAB -Name $VM -force
it fails due to the variable being set to a longer string something like
MicroSoftComputerResource\Resourcegroup[#Name=AVGJOE-DC1].
Hopefully that makes sense.
$VM = Get-AzureRmVM -ResourceGroupName LAB | get-azurermvm -Status | ?{$_.statuses.displaystatus -eq "VM stopped"} | select name
Just like #Theo said in the comment, select name gives you an object with property name. If you want the string value of the name property, you can use Select-Object -ExpandProperty name instead of select name.
Currently, I am working in a Powershell to restore the VHD file from a Virtual Machine which is being backed up by Azure Recovery Services Vault.
That being said, my difficulty is how do I get the Config Blob Uri parameter after restoring the VHD using Powershell? Even using Get-AzureRmRecoveryServicesBackupJobDetails -Job $restoreJob I don't see any option that provides this information.
As you can see in the image below, the Azure Portal shows the Config Blob Uri parameter
Once the Powershell completes the restore, then I'd like to retrieve the Config Blob Uri to perform a VM creation based on that specific VHD file, however, without such information, I have to get it manually.
Is there any possibility to get it directly from Powershell?
#get restore job detail
$details = Get-AzureRmRecoveryServicesBackupJobDetails -Job $restorejob
#restored disk properties
$properties = $details.properties
$storageAccountName = $properties["Target Storage Account Name"]
$containerName = $properties["Config Blob Container Name"]
$blobName = $properties["Config Blob Name"]
#Set the Azure storage context and restore the JSON configuration file
Set-AzureRmCurrentStorageAccount -Name $storageAccountName -ResourceGroupName $resourceGroupName
$destination_path = "C:\temp\vmconfig.json"
Get-AzureStorageBlobContent -Container $containerName -Blob $blobName -Destination $destination_path
$obj = ((Get-Content -Path $destination_path -Raw -Encoding Unicode)).TrimEnd([char]0x00) | ConvertFrom-Json
This will download config json file to $destination_path and you can reference your that file when building your VM.
More details at: https://learn.microsoft.com/en-us/azure/backup/backup-azure-vms-automation#restore-an-azure-vm
Also, if you know your Storage Account Name, you can retrieve config uri from there:
$storageAccountName = (Get-AzureRmStorageAccount -ResourceGroupName $resourceGroupName).StorageAccountName
Set-AzureRmCurrentStorageAccount -Name $storageAccountName -ResourceGroupName $resourceGroupName
$storageContainerName = (Get-AzureStorageContainer).Name
$configBlob = Get-AzureStorageBlob -Container $storageContainerName | where {$_.Name -match "json"}
$configName = $configBlob.Name
$configURI = "https://$storageAccountname.blob.core.windows.net/$storageContainerName/$configName"
Hope this helps.
I am trying to create an Azure Automation job to create a new Azure Automation Runbook. I am using the following to try to get it to work.
$Context = New-AzureStorageContext $storageAccountName $storageAccountKey
$Path = Get-AzureStorageFile -ShareName "qdrive" -Path "TestWorkFlow.ps1" -Context $Context |Select-object Name |Out-String
Import-AzureRMAutomationRunbook -ResourceGroupName $ResourceGroupName -AutomationAccountName $AutomationAccountName -Path $Path -Type PowerShellWorkflow -Force -Name $Name -Published
I get an error message of
Import-AzureRMAutomationRunbook:Cannot find path 'C:\Windows\System32\
Name
------
TestWorkFlow.ps1
I need help figuring out how to send the path of the file to the $path variable in a UNC and not a URI.
Thanks!
The cmdlet needs to take a fully qualified path to the runbook .ps1 file, where the local machine has access to that path via normal local file system referencing. It looks like in this case $Path contains “Name ------ TestWorkFlow.ps1” – so therefore you are not storing the path in $Path correctly, hence the failure.
The $path variable for the -Path switch to the cmdlet needs to contain the full path, Including the filename itself. Like, "C:\Users\Johndoe\TestWorkFlow.ps1". Hope this helps.
I have the script, which create vitrual machine, and install google chrome via dsc. I created current storage account, and executed script. But in next time I have error. This is my script:
$SubscriptionName = "subscription_name"
Select-AzureSubscription -SubscriptionName $SubscriptionName
#Replace the variable values as needed
$VMName = "CSETest"
$StorageAccount = 'googleChrome'
$StorageKey = 'key'
$StorageContainer = 'dscarchives'
$ServiceName="ChromeInstaller"
#Get the OS image reference
$arrayWindows=( Get-AzureVMImage | where-object { $_.ImageName -like "*Windows*Server*2012*R2*en.us*" } )
$locationAllow=$arrayWindows[$arrayWindows.Count-1].Location
$locationAllow=$locationAllow.Split(";")
$locationAllow=$locationAllow | where-object { $_ -like "* US*"}
$Localization=(Get-Random -InputObject $locationAllow)
#Create VM Config with last windows update
$vmConfig = New-AzureVMConfig -Name $VMName -ImageName $arrayWindows[$arrayWindows.Count-1].ImageName -InstanceSize Small
#Create Provisioning Configuration
$vmProvisioningConfig = Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername "login" -Password "password"
$StorageContext = New-AzureStorageContext -StorageAccountName $StorageAccount -StorageAccountKey $StorageKey
Publish-AzureVMDscConfiguration -ConfigurationPath .\ChromeInstaller.ps1 -ContainerName $StorageContainer -StorageContext $StorageContext -Force
#Set the Azure VM DSC Extension to run the LCM meta-configuration
$vmAzureExtension = Set-AzureVMDscExtension -VM $vmProvisioningConfig -ConfigurationArchive ChromeInstaller.ps1.zip -ConfigurationName OpenChrome -Verbose -StorageContext $StorageContext -ContainerName $StorageContainer -Force
#Create a VM
New-AzureVM -ServiceName $ServiceName -VMs $vmAzureExtension -Location $Localization -WaitForBoot
In the last line, script throw exception:
New-AzureVM : BadRequest: The location or affinity group Central US of the storage account where the source image
a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-201410.01-en.us-127GB.vhd resides is not in the same location or affinity group as
the specified cloud service. The source image must reside in a storage account that has the same affinity group or location as the cloud
service West US.
So, as you can see, my script generate random location. And I can't link with on location. So, how can I fix this bug?
The source image VHD must exist in the same location as the new virtual machine. Use AzCopy to copy the image to storage accounts in all locations listed in $locationAllow.
The Simple answer is to create your VM in the same location as your storage account. This is telling you that your Azure OS Image in the storage account location does not exist in your cloud service location.
You can also try this
$AzureLocation = (get-azurelocation)
$Localization=(Get-Random -InputObject $AzureLocation)
$WindowsImage=( Get-AzureVMImage | where-object { $_.ImageName -like "*Windows*Server*2012*R2*en.us*" -and $_.Location -Match $Localization.DisplayName } | sort PublishedDate | select -first 1 ).ImageName
#Create VM Config with last windows update
$vmConfig = New-AzureVMConfig -Name $VMName -ImageName $WindowsImage -InstanceSize Small
With this method, we are selecting a location, then an image that resides within that location. Previously you were selecting an image (which may reside in Location West US) then selecting a location .
Alternativly, get the location of your storage account and use that location to get the image and create the cloud service in the same location of the storage account