current azure storage doesn't allow create new VM - powershell

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

Related

Get location value of Resource Group in a variable Powershell

I have a powershell script to deploy a service bus namespace
This is the command i use to deploy it .
New-AzureRmServiceBusNamespace -ResourceGroup $ResourceGroupName -NamespaceName $ServiceBusNamespace -Location $Location
The above command expects a location parameter to be entered. I want that location value as the Location where my resource group is located . How do i extract the Location value of my resource Group ?
I tried various methods and failed. it shows #{location=west us} , when i tried this
$location = Set-AzureRmResourceGroup -Name $ResourceGroupName -Tag #{} | Select-Object Location
Write-Host $location
Need help . Thanks !
$loc = Get-AzureRMResourceGroup -Name $ResourceGroupName | select-object -expandproperty location
Well, if you want to GET something use appropriate verb.
or like this:
$rg = Get-AzureRMResourceGroup -Name $ResourceGroupName
$rg.location
The below code works with Az powershell module.
$loc= Get-AzResourceGroup -Name $resourceGroupName #Gets the resource group details and stores in $loc variable
$location= $loc.location #Gets the location name from resource group properties and stores in $location variable
Write-Host $location #outputs the resource group location

GCE Windows startup scripts & naming

Linux admin pulling out what hair I have left trying to figure out startup scripts for Windows on GCE.
The way I've approached it is the following;
Create a "runonce" script by editing the registry on the "master" image.
Said script does the following;
-
Does a reverse DNS lookup of it's own IP to get the hostname DNS thinks it is and then sets the local hostname to that
Joins the domain
Adds a domain user as autologin (I need this for various reasons)
I GCESysprep the machine
Take an image of the machine after sysprep and make a group template from that
My main issue I'm having is that it's not working at all :) The machines come up, run the script and reboot but god knows what state they're in after they come back, I can't login, reset the password/do anything.
I think ideally what I'd like to do is figure out the best way of doing this, do I host the script in GCE Storage and mark it a startup script in the GCE Console opposed to the registry setting? Is there a better way of renaming the machines?
Here's the script if you're interested;
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}
$ipAddresses = (get-netadapter | get-netipaddress | ? addressfamily -
eq 'IPv4').ipaddress
# Filter out any 192.168 172. 10. IP addresses
$ipAddress = $ipAddresses -like "123*"
# Retrieve the hostname from the ??? DNS Server
$fqdn = (nslookup $ipAddresses | sls name | select -last
1).toString().split(":")[1].trim()
# We only need the hostname without the domain info so split it up
$fqdn_items = $fqdn.split(".")
$newComputerName = $fqdn_items[0]
Write-Host "New Computer Name: $newComputerName"
# Get a WMI object representing the current computer
$currentComputer = Get-WmiObject Win32_ComputerSystem
Write-Host "Attempting to change computer name to $newComputerName"
# Set the Computer Name to the hostname found via DNS Lookup to DNS
Server
# This can only be performed before joining the domain otherwise you
get return code 1326
$currentComputer.Rename($newComputerName)
#SET CREDENTIALS
$domain = “mydomain”
$password = “password” | ConvertTo-SecureString -asPlainText -Force
$username = "$domain\joinuser”
$credential = New-Object
System.Management.Automation.PSCredential($username,$password)
# RENAME THE COMPUTER
Rename-Computer -ComputerName (hostname) -NewName $newComputerName -
LocalCredential $credentiallocal
sleep 100
# JOIN THE DOMAIN
Add-Computer -DomainName $domain -Credential $credential -force
# CONFIGURE AUTOLOGIN
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\Winlogon' -Name AutoAdminLogon -Value 1
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\Winlogon' -Name DefaultUserName -Value
“mydomain\dr-worker"
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\Winlogon' -Name DefaultPassword -Value mypassword
restart

How to get the Config Blob Uri parameter from restored VHD from Azure Recovery Services Vault in Powershell?

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.

Import Azure Automation RunBook using Azure Automation

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.

Get storage account of Azure VM

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.