Set-AzureRmVMCustomScriptExtension before Creating VM - powershell

When running the below Azure Powershell, I get error:
Set-AzureRmVMCustomScriptExtension : Can not perform requested
operation on nested resource. Parent resource 'mycomputer' not found.
$vm = New-AzureRmVMConfig -VMName $vmName -VMSize $vmSize
$vm = Set-AzureRmVMSourceImage -VM $vm -Id $image.Id
$vm = Set-AzureRmVMOSDisk -VM $vm -StorageAccountType $vmStorageType -DiskSizeInGB $vmDiskSize -CreateOption FromImage -Caching ReadWrite
$vm = Set-AzureRmVMOperatingSystem -VM $vm -Windows -ComputerName $vmName -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm = Add-AzureRmVMNetworkInterface -VM $vm -Id $nic.Id
$vm = Add-AzureRmVMSecret -VM $vm -SourceVaultId $vaultId -CertificateStore "My" -CertificateUrl $certURL
$vm = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $rsgName -VMName $vmName -Name $extenstionName -Location $location -StorageAccountName $storageName -StorageAccountKey $storageKey -FileName $fileName -ContainerName $containerName -Run $fileName
$vm = New-AzureRmVM -VM $vm -ResourceGroupName $rsgName -Location $location
Can I not set the CustomScriptExtension as part of building the New VM?

The Set-AzureRmVMCustomScriptExtension command can be used to add the Custom Script extension to an existing virtual machine. Existing VM. so no, you cannot do that before creating a VM.
https://learn.microsoft.com/en-us/azure/virtual-machines/windows/extensions-customscript#powershell-deployment

VM custom script extension is a separate task that need create VM firstly. So, just adjust the execution order of your script.
##create a VM, no need $vm
New-AzureRmVM -VM $vm -ResourceGroupName $rsgName -Location $location
##create custom script extension
Set-AzureRmVMCustomScriptExtension -ResourceGroupName $rsgName -VMName $vmName -Name $extenstionName -Location $location -StorageAccountName $storageName -StorageAccountKey $storageKey -FileName $fileName -ContainerName

Related

Trying to create Palo Alto VM with Azure Powershell

I'm currently trying to create a Palo Alto VM-Series firewall with Azure Powershell to later incorporate some changes.
I have the following relevant code
$VM = Set-AzureRmVMSourceImage -VM $vm -PublisherName $pubName -Offer $offerName -Skus $skuName -Version "latest"
$VM = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize
Set-AzureRmVMPlan -VM $VM -Publisher paloaltonetworks -Product vmseries1 -Name "bundle2"
# Specify the OS disk name and create the VM
$DiskName='OSDisk-'+$VMName
$SA = Get-AzureRmStorageAccount -Name $SAName -ResourceGroupName $RGName
$OSDiskUri = $SA.PrimaryEndpoints.Blob.ToString() + "vhds/" + $VMName+".vhd"
$VM = Set-AzureRmVMOSDisk -VM $VM -Name $DiskName -VhdUri $OSDiskUri -CreateOption fromImage
$VM = Add-AzureRmVMNetworkInterface -VM $VM -Id $VNIC01.Id -Primary
New-AzureRmVM -ResourceGroupName $RGName -Location $Region -VM $VM -Verbose
I get the error
New-AzureRmVM : Changing property 'osDisk.createOption' is not allowed.
ErrorCode: PropertyChangeNotAllowed
ErrorMessage: Changing property 'osDisk.createOption' is not allowed.
StatusCode: 409
ReasonPhrase: Conflict
OperationID : 882848ca-7053-4098-9599-d25d58b4b3fe
At C:\Users\IEUser\Desktop\DeployMultipleNicPANWv0.2.ps1:192 char:1
+ New-AzureRmVM -ResourceGroupName $RGName -Location $Region -VM $VM -V ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [New-AzureRmVM], ComputeCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Compute.NewAzureVMCommand
I had previously tried some changes since it tells me the origin vhd was created with Premium Storage and I have a Standard Storage.
Could someone point me to the right direction?
Thanks
According to your code, I found it the scripts contain
“$VM = Set-AzureRmVMOSDisk -VM $VM -Name $DiskName -VhdUri $OSDiskUri -CreateOption fromImage”.
And the error code is 409. This issue may caused by this :VM created from Image cannot have blob based disks. All disks have to be managed disks.
So, you should decide what source do you want to use to create VM. If you just want to use image to create VM, you should not add -VhdUri $OSDiskUri
More about how to use image to create a new VM with Powershell, refer to this document.
Also, you can use templates to create Palo Alto VM easily. More about how to create Palo Alto VM with templates, refer to this link.
----------Update----------
Ensure your image and other requirements had properly been configured ,and then you can use following Powershell scripts to create:
$VM = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize
$VM = Set-AzureRmVMSourceImage -VM $vm -PublisherName $pubName -Offer $offerName -Skus $skuName -Version "latest"
Set-AzureRmVMPlan -VM $VM -Publisher paloaltonetworks -Product vmseries1 -Name "bundle2"
$VM = Set-AzureRmVMOSDisk -VM $VM -CreateOption fromImage -Caching ReadWrite
$VM = Add-AzureRmVMNetworkInterface -VM $VM -Id $VNIC01.Id -Primary
New-AzureRmVM -ResourceGroupName $RGName -Location $Region -VM $VM -Verbose
NOTE: With managed disk, we cannot change OSdiskname when we use image or vdi to create VM. If you still cannot create it, I suggest you use the templates to create it. Just click deploy on Azure and then supply required information.

How does one convert PSVirtualMachineObjects?

I'm trying to deploy Azure VM's thru a workflow so it could be done in parallel. The code works fine outside of a workflow. But getting this error when trying to do it thru a workflow.
I'm importing the VM parameters thru a csv file.
Are there additional considerations for deploying Azure VM's thru a Workflow?
Workflow Deploy-VMs {
$cred1= New-Object System.Management.Automation.PSCredential "User",$(ConvertTo-SecureString "Password" -asplaintext -force)
$b=Import-Csv Y:\NLG\vms1.csv -Verbose|? type -eq 'VM'
foreach ($c in $b) {
AzureRM.Resources\Login-AzureRmAccount -Credential $cred1 -SubscriptionId subscription id
$nic = New-AzureRmNetworkInterface -Name $c.Name -ResourceGroupName nlg -Location $c.Location -SubnetId $c.SubnetID
$cred= New-Object System.Management.Automation.PSCredential "nladmin",$(ConvertTo-SecureString $c.Password -asplaintext -force)
$vmConfig = New-AzureRmVMConfig -VMName $c.Name -VMSize "Standard_D1"
$vmConfig = Set-AzureRmVMOperatingSystem -VM $vmConfig -Windows -ComputerName $c.Name -Credential $cred
$vmConfig = Set-AzureRmVMSourceImage -VM $vmConfig -PublisherName "MicrosoftWindowsServer" -Offer "WindowsServer" -Skus "2012-R2-Datacenter-smalldisk" -Version "latest"
$vmConfig = Add-AzureRmVMNetworkInterface -VM $vmConfig -Id $nic.Id
$vmConfig = Set-AzureRmVMOSDisk -VM $vmConfig -Name $c.Name -CreateOption FromImage
New-AzureRmVM -ResourceGroupName $c.RG -Location $c.Location -VM $vmConfig
}
}
and getting this error
Cannot bind parameter 'VM'. Cannot convert value
"Microsoft.Azure.Commands.Compute.Models.PSVirtualMachine" to type
"Microsoft.Azure.Commands.Compute.Models.PSVirtualMachine". Error:
"Cannot convert the
"Microsoft.Azure.Commands.Compute.Models.PSVirtualMachine" value of
type
"Deserialized.Microsoft.Azure.Commands.Compute.Models.PSVirtualMachine"
to type "Microsoft.Azure.Commands.Compute.Models.PSVirtualMachine"."
+ CategoryInfo : InvalidArgument: (:) [Set-AzureRmVMOperatingSystem], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.Azure.Commands.Compute.SetAzureVMOperatingSystemCommand
+ PSComputerName : [localhost]
Resolved using inline script for the incompatible cmdlets.
Workflow Deploy-VMs {
$cred1 = New-Object System.Management.Automation.PSCredential "User", $(ConvertTo-SecureString "Password" -AsPlainText -Force)
$b = Import-Csv Y:\NLG\vms1.csv -Verbose|? type -eq 'VM'
foreach -Parallel ($c in $b) {
AzureRM.Resources\Login-AzureRmAccount -Credential $cred1 -SubscriptionId c2d7e81b-ed6a-4de9-a4cd-36e679ec4259
$nic = New-AzureRmNetworkInterface -Name $c.Name -ResourceGroupName nlg -Location $c.Location -SubnetId $c.SubnetID
$cred = New-Object System.Management.Automation.PSCredential "nladmin", $(ConvertTo-SecureString $c.Password -AsPlainText -Force)
InlineScript {
$vmConfig = New-AzureRmVMConfig -VMName $using:c.Name -VMSize "Standard_D1"
$vmConfig = Set-AzureRmVMOperatingSystem -VM $vmConfig -Windows -ComputerName $using:c.Name -Credential $using:cred
$vmConfig = Set-AzureRmVMSourceImage -VM $vmConfig -PublisherName "MicrosoftWindowsServer" -Offer "WindowsServer" -Skus "2012-R2-Datacenter-smalldisk" -Version "latest"
$vmConfig = Add-AzureRmVMNetworkInterface -VM $vmConfig -Id $using:nic.Id
$vmConfig = Set-AzureRmVMOSDisk -VM $vmConfig -Name $using:c.Name -CreateOption FromImage
New-AzureRmVM -ResourceGroupName $using:c.RG -Location $using:c.Location -VM $vmConfig
}
}
}

How to assign a network interface to a newly created VM with ARM Powershell?

I'm getting started with ARM in our Azure tenancy...
Firstly, I created a resource group, TEST-RG.
I've created a Network Interface in my resource group using the Portal. Let's call it TEST-NIC in resource group TEST-RG.
I've also created a DS2_V2 VM called TEST-VM, running Windows 2012 R2 and also in TEST-RG.
How do I associate TEST-NIC with TEST-VM? I can't see a way of doing that in the Portal, nor can I see a way in the Portal of creating a VM with no network interface, such that I can add TEST-NIC later.
So, I assume this can only be done in PS, but I'm not at all clear how...
Have I lost the plot? Any guidance would be appreciated.
Thanks
For now, Azure does not support add a NIC to an existing VM.
can I see a way in the Portal of creating a VM with no network
interface, such that I can add TEST-NIC later
We can't create a VM without NIC, but we can use PowerShell to create a new VM with this NIC.
Here is my script to create a new VM with existing NIC.
$ResourceGroupName = "nic"
$Location = "Eastus"
$StorageName = "jasondisk321"
$StorageType = "Standard_LRS"
$VMName = "myvm"
$VMSize = "Standard_DS2_v2"
$OSDiskName = $VMName + "OSDisk"
$StorageAccount = New-AzureRmStorageAccount -ResourceGroupName $ResourceGroupName -Name $StorageName -Type $StorageType -Location $Location
$nic = Get-AzureRmNetworkInterface -Name jasonnic -ResourceGroupName $rgname
$nicId = $nic.Id
$Credential = Get-Credential
$vm = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize
$vm = Set-AzureRmVMOperatingSystem -VM $vm -ComputerName $VMName -Windows -Credential $Credential
$vm = Set-AzureRmVMSourceImage -VM $vm -PublisherName "MicrosoftWindowsServer" -Offer "WindowsServer" -Skus "2012-R2-Datacenter" -Version "latest"
$vm = Add-AzureRmVMNetworkInterface -VM $vm -Id $nic.Id
$OSDiskUri = $StorageAccount.PrimaryEndpoints.Blob.ToString() + "vhds/" + $OSDiskName + ".vhd"
$vm = Set-AzureRmVMOSDisk -VM $vm -Name $OSDiskName -VhdUri $OSDiskUri -CreateOption FromImage
New-AzureRmVM -ResourceGroupName $ResourceGroupName -Location $Location -VM $vm
Firstly, you can't deploy an ARM VM without a NIC.
If you look at this script
It has the lines
$Interface = New-AzureRmNetworkInterface -Name $InterfaceName `
-ResourceGroupName $ResourceGroupName `
-Location $Location `
-SubnetId $VNet.Subnets[0].Id `
-PublicIpAddressId $PIp.Id
Which is later used by
$VirtualMachine = Add-AzureRmVMNetworkInterface `
-VM $VirtualMachine `
-Id $Interface.Id
So if you want to use an existing NIC you just need to pass the $interface.id (from Get-AzureRmVMNetworkInterface)
When you wrap those two around the rest of a VM deployment script you'll build a VM with a NIC

Azure InvalidParameter: StorageProfile.dataDisks.lun does not have required value(s) for image in storage profile

I have a script to create VMs on Azure using DS Series storage. I am trying to create a VM using one of the SQL Server optimized images. When I change the Publisher, Offer, and SKU to match the SQL Server image I keep getting an error:
InvalidParameter: StorageProfile.dataDisks.lun does not have required value(s) for image in storage profile
Does anyone know how I should modify the following script so that I can use one of the pre-defined image templates for SQL Server?
Switch-AzureMode AzureResourceManager
Add-AzureAccount
$subscr="subscription"
Select-AzureSubscription -SubscriptionName $subscr
$rgName="test-resource-group"
$locName="East US 2"
New-AzureResourceGroup -Name $rgName -Location $locName
$saName="testpremiumstorage"
$saType="Premium_LRS"
New-AzureStorageAccount -Name $saName -ResourceGroupName $rgName –Type $saType -Location $locName
$frontendSubnet=New-AzureVirtualNetworkSubnetConfig -Name "testfrontendSubnet" -AddressPrefix 10.3.3.0/24
$backendSubnet=New-AzureVirtualNetworkSubnetConfig -Name "testbackendSubnet" -AddressPrefix 10.3.2.0/24
New-AzurevirtualNetwork -Name "testVNet" -ResourceGroupName $rgName -Location $locName -AddressPrefix 10.3.0.0/16 -Subnet $frontendSubnet,$backendSubnet
$publicIP = New-AzurePublicIpAddress -Name "testPublicIp" -ResourceGroupName $rgName -Location $locName –AllocationMethod Static -DomainNameLabel "test-public-ip"
$frontendIP = New-AzureLoadBalancerFrontendIpConfig -Name "test-LB-Frontend" -PublicIpAddress $publicIP
$beaddresspool= New-AzureLoadBalancerBackendAddressPoolConfig -Name "test-LB-backend"
$inboundNATRule1= New-AzureLoadBalancerInboundNatRuleConfig -Name "RDP1" -FrontendIpConfiguration $frontendIP -Protocol TCP -FrontendPort 3441 -BackendPort 3389
$inboundNATRule2= New-AzureLoadBalancerInboundNatRuleConfig -Name "RDP2" -FrontendIpConfiguration $frontendIP -Protocol TCP -FrontendPort 3442 -BackendPort 3389
$healthProbe = New-AzureLoadBalancerProbeConfig -Name "HealthProbe" -RequestPath "HealthProbe.aspx" -Protocol http -Port 80 -IntervalInSeconds 15 -ProbeCount 2
$lbrule = New-AzureLoadBalancerRuleConfig -Name "HTTP" -FrontendIpConfiguration $frontendIP -BackendAddressPool $beAddressPool -Protocol Tcp -FrontendPort 80 -BackendPort 80
$NRPLB = New-AzureLoadBalancer -ResourceGroupName $rgName -Name "test-LB" -Location $locName -FrontendIpConfiguration $frontendIP -InboundNatRule $inboundNATRule1,$inboundNatRule2 -LoadBalancingRule $lbrule -BackendAddressPool $beAddressPool -Probe $healthProbe
$nicName="test-NIC"
$lbName="test-LB"
$bePoolIndex=0
$vnetName="testVNet"
$subnetIndex=0
$natRuleIndex=0
$vnet=Get-AzurevirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$lb=Get-AzureLoadBalancer -Name $lbName -ResourceGroupName $rgName
$backendSubnet = Get-AzureVirtualNetworkSubnetConfig -Name "testbackendSubnet" -VirtualNetwork $vnet
$nic=New-AzureNetworkInterface -Name $nicName -ResourceGroupName $rgName -Location $locName -Subnet $backendSubnet -LoadBalancerBackendAddressPool $lb.BackendAddressPools[$bePoolIndex] -LoadBalancerInboundNatRule $lb.InboundNatRules[$natRuleIndex]
$vmName="test"
$vmSize="Standard_DS2"
$vm=New-AzureVMConfig -VMName $vmName -VMSize $vmSize
#This is where the error occurs. If it is switched to the commented image everything will work fine but not when
# trying to create the SQL Server based image
#$pubName="MicrosoftWindowsServer"
#$offerName="WindowsServer"
#$skuName="2012-R2-Datacenter"
$pubName="MicrosoftSQLServer"
$offerName="SQL2014SP1-WS2012R2"
$skuName="Enterprise-Optimized-for-OLTP"
$cred=Get-Credential -Message "Type the name and password of the local administrator account."
$vm=Set-AzureVMOperatingSystem -VM $vm -Windows -ComputerName $vmName -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm=Set-AzureVMSourceImage -VM $vm -PublisherName $pubName -Offer $offerName -Skus $skuName -Version "latest"
$vm=Add-AzureVMNetworkInterface -VM $vm -Id $nic.Id
$diskName="test-OSDisk"
$storageAcc=Get-AzureStorageAccount -ResourceGroupName $rgName -Name $saName
$osDiskUri=$storageAcc.PrimaryEndpoints.Blob.ToString() + "vhds/" + $diskName + ".vhd"
$vm=Set-AzureVMOSDisk -VM $vm -Name $diskName -VhdUri $osDiskUri -CreateOption fromImage
New-AzureVM -ResourceGroupName $rgName -Location $locName -VM $vm
As noted in the script there is a section where the Publisher, Offer, and SKU are defined. When those are switched to the SQL Server related items the script fails with the error but if they use the basic Windows Server 2012 items the script will run fine. Could the item names be different if using premium storage or is there a different way to create the VM?
Some steps that helped me to solve similar issues:
Check if you indeed have the right name - see #theadriangreen's link link and the listing commands behind az vm image --help
Check if you added plan information to the spin-up
Check if you have accepted the terms with az vm image accept-terms --help

Create Azure VM with Premium Storage and Public Static IP Using Powershell

I am trying to create a DS Series VM in Azure using premium storage and assign it a static public IP. From what I have read you can no longer assign a public static IP to a resource group (it only works with the older service groups). I have created a Powershell script that attempts to create a load balancer and assign a new VM to the load balancer. In theory the load balancer can get assigned the public static IP and traffic would get routed to the VM. The script appears to run and the VM is created but it will not Start. The status of the VM is listed as Failed. Can someone please tell me what I am doing wrong in this script?
Switch-AzureMode AzureResourceManager
Add-AzureAccount
$subscr="mysubscription" Select-AzureSubscription -SubscriptionName $subscr
$rgName="testRG" $locName="West US" New-AzureResourceGroup -Name $rgName -Location $locName
$saName="teststorage" $saType="Premium_LRS" New-AzureStorageAccount
-Name $saName -ResourceGroupName $rgName –Type $saType -Location $locName
$frontendSubnet=New-AzureVirtualNetworkSubnetConfig -Name "testfrontendSubnet" -AddressPrefix 10.0.1.0/24 $backendSubnet=New-AzureVirtualNetworkSubnetConfig -Name "testbackendSubnet" -AddressPrefix 10.0.2.0/24 New-AzurevirtualNetwork
-Name "testVNet" -ResourceGroupName $rgName -Location $locName -AddressPrefix 10.0.0.0/16 -Subnet $frontendSubnet,$backendSubnet
$publicIP = New-AzurePublicIpAddress -Name "testPublicIp"
-ResourceGroupName $rgName -Location $locName –AllocationMethod Static -DomainNameLabel "testIP" $frontendIP = New-AzureLoadBalancerFrontendIpConfig -Name "test-LB-Frontend"
-PublicIpAddress $publicIP $beaddresspool= New-AzureLoadBalancerBackendAddressPoolConfig -Name "test-LB-backend" $lbrule = New-AzureLoadBalancerRuleConfig -Name "HTTP"
-FrontendIpConfiguration $frontendIP -BackendAddressPool $beAddressPool -Protocol Tcp -FrontendPort 80 -BackendPort 80 $NRPLB = New-AzureLoadBalancer -ResourceGroupName $rgName -Name "test-LB"
-Location $locName -FrontendIpConfiguration $frontendIP -LoadBalancingRule $lbrule -BackendAddressPool $beAddressPool
$nicName="test-NIC" $lbName="test-LB" $bePoolIndex=0 $vnetName="testVNet" $subnetIndex=0 $natRuleIndex=0 $vnet=Get-AzurevirtualNetwork -Name $vnetName -ResourceGroupName $rgName $lb=Get-AzureLoadBalancer -Name $lbName -ResourceGroupName $rgName
$backendSubnet = Get-AzureVirtualNetworkSubnetConfig -Name "testbackendSubnet" -VirtualNetwork $vnet $nic=New-AzureNetworkInterface -Name $nicName -ResourceGroupName $rgName -Location $locName -Subnet $backendSubnet
-LoadBalancerBackendAddressPool $lb.BackendAddressPools[$bePoolIndex] -LoadBalancerInboundNatRule $lb.InboundNatRules[$natRuleIndex]
# TWO OTHERS I'VE TRIED WITHOUT SUCCESS
# $nic=New-AzureNetworkInterface -Name $nicName -ResourceGroupName $rgName -Location $locName -Subnet $backendSubnet
-LoadBalancerBackendAddressPool $lb.BackendAddressPools[$bePoolIndex]
# $nic=New-AzureNetworkInterface -Name $nicName -ResourceGroupName $rgName -Location $locName -Subnet $vnet.Subnets[$subnetIndex].Id
-LoadBalancerBackendAddressPool $lb.BackendAddressPools[$bePoolIndex]
$vmName="test" $vmSize="Standard_DS2" $vm=New-AzureVMConfig -VMName $vmName -VMSize $vmSize
$pubName="MicrosoftWindowsServer" $offerName="WindowsServer" $skuName="2012-R2-Datacenter" $cred=Get-Credential -Message "Type the name and password of the local administrator account." $vm=Set-AzureVMOperatingSystem -VM $vm -Windows -ComputerName $vmName
-Credential $cred -ProvisionVMAgent -EnableAutoUpdate $vm=Set-AzureVMSourceImage -VM $vm -PublisherName $pubName -Offer $offerName -Skus $skuName -Version "latest" $vm=Add-AzureVMNetworkInterface -VM $vm -Id $nic.Id
$diskName="test-OSDisk" $storageAcc=Get-AzureStorageAccount
-ResourceGroupName $rgName -Name $saName $osDiskUri=$storageAcc.PrimaryEndpoints.Blob.ToString() + "vhds/" + $diskName + ".vhd" $vm=Set-AzureVMOSDisk -VM $vm -Name $diskName
-VhdUri $osDiskUri -CreateOption fromImage New-AzureVM -ResourceGroupName $rgName -Location $locName -VM $vm
You are using the location West US and Azure is having severe capacity issues with DS series VMs using Premium storage in East US 2 and West US since a couple of days.
Sadly this problem have not been mentioned the Azure status page.
Try to use another location that support Premium storage, like West Europe and your VM should create and start normally.