How does one convert PSVirtualMachineObjects? - powershell

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
}
}
}

Related

New-AzureRmVM : Parameter set cannot be resolved using the specified named parameters

I am new to Powershell, I am running following script and getting the error as mentioned in the subject line:
$LocationName = "West Europe"
$VNet_ResourceGroupName = "Mydeveloper_resource_group"
$VM_ResourceGroupName = "MyDeveloperResourceGroup"
$PublicIpAddress = "[]"
$PrivateIpAddress = "10.199.120.30"
$VirtualNetworkName = "developer_vnet"
$SubnetName = "MySubnet"
$SubnetId = "/subscriptions/....../resourceGroups/developer_resource_group/providers/Microsoft.Network/virtualNetworks/developer_vnet/subnets/MySubnet"
$VMName = "AWE4DVM022"
$VMSize = "Standard_D4s_v3"
$AllocationMethod = "Static"
$ImageId = "/subscriptions/................................./resourceGroups/MyIMAGELIBRARY/providers/Microsoft.Compute/images/developer-desktop-image-...................."
$cred = Get-Credential -Message "Type the name and password of the local administrator account."
$nic = New-AzureRmNetworkInterface -Name TestNIC -ResourceGroupName $VM_ResourceGroupName -Location $LocationName -SubnetId $SubnetId -PrivateIpAddress $PrivateIpAddress
$vm = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize
$vm = Set-AzureRmVMOperatingSystem -VM $vm -Linux -ComputerName $VMName -Credential $cred
$vm = Add-AzureRmVMNetworkInterface -VM $vm -Id $nic.Id
New-AzureRmVM -ResourceGroupName $VM_ResourceGroupName -ImageName $ImageId -VM $vm
Powershell has this concept of parameter sets. When you call a script, function, or commandlet that uses parameter sets (like New-AzureRMVM does), you can't pass parameters for arguments in different sets. For example, New-AzureRmVM has three parameters sets. ResourceGroupName is in parameter sets 1, 2, and 3. ImageName is in parameter set 1, and VM is in parameter set 2. Powershell can't figure out what set to use because ImageName is on one set while VM is in another.

Set-AzureRmVMCustomScriptExtension before Creating VM

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

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

Import VMware Image to Azure - Credentials?

I try to create a Virtual Computer in Azure Portal from VMWare Image. I worked with this tutorials:
https://azure.microsoft.com/de-de/documentation/articles/virtual-machines-windows-upload-image/#uploadvm
(german)
https://buildwindows.wordpress.com/2015/12/20/how-to-add-a-nic-to-an-azure-virtual-machine-arm/
(english)
In the german tutorial you´ll find
$vm = Set-AzureRmVMOperatingSystem -VM $vmConfig -Windows -ComputerName $computerName -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
To get $cred i used:
$cred = Get-Credentials
a login windows will appear to enter credentials
What kind of credentials i have to enter here? The credentials of the Image or Azure? In what format i have to enter it? I tried Computername\User and password (e.g. ARES\Administrator and the password.
EDIT 1
with the machine credentials MyMachineName\Administrator i got the following error:
PS C:\WINDOWS\system32> $cred = Get-Credential
Cmdlet Get-Credential an der Befehlspipelineposition 1
Geben Sie Werte für die folgenden Parameter an:
Credential
PS C:\WINDOWS\system32> $vm = Set-AzureRmVMOperatingSystem -VM $vmConfig -Windows -ComputerName $computerName -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
PS C:\WINDOWS\system32> $result = New-AzureRmVM -ResourceGroupName $rgName -Location $location -VM $vm
New-AzureRmVM : Windows admin user name cannot be more than 20 characters long, end with a period(.), or contain the following characters: \ / " [ ] : | < > + = ; , ? * #.
StatusCode: 400
ReasonPhrase: Bad Request
OperationID : ''
In Zeile:1 Zeichen:11
+ $result = New-AzureRmVM -ResourceGroupName $rgName -Location $locatio ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [New-AzureRmVM], ComputeCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Compute.NewAzureVMCommand
Edit 2
After the tip to read the example of https://msdn.microsoft.com/en-us/library/mt603843.aspx i got this one. My user is Administrator, but i got the message, ist no allowed?!
PS C:\WINDOWS\system32> $SecurePassword = ConvertTo-SecureString "mypassword" -AsPlainText -Force
PS C:\WINDOWS\system32> $Credential = New-Object System.Management.Automation.PSCredential ("Administrator", $SecurePassword);
PS C:\WINDOWS\system32> $AvailabilitySet = Get-AzureRmAvailabilitySet -ResourceGroupName "KGSCloud"
PS C:\WINDOWS\system32> $vmName = "titan"
PS C:\WINDOWS\system32> $computerName = "TITAN"
PS C:\WINDOWS\system32> $vm = Set-AzureRmVMOperatingSystem -VM $vmConfig -Windows -ComputerName $computerName -Credential $Credential -ProvisionVMAgent -EnableAutoUpdate
PS C:\WINDOWS\system32> $result = New-AzureRmVM -ResourceGroupName $rgName -Location $location -VM $vm
New-AzureRmVM : The Admin Username specified is not allowed.
StatusCode: 400
ReasonPhrase: Bad Request
OperationID : ''
In Zeile:1 Zeichen:11
+ $result = New-AzureRmVM -ResourceGroupName $rgName -Location $locatio ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [New-AzureRmVM], ComputeCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Compute.NewAzureVMCommand
Can someone help me?
Kind Regards
For Set-AzureRmVMOperatingSystem you will need to enter the credentials of the virtual machine. So the format would be the local administrator account and password at this stage.

Add-Computer fails by not finding the domain

I'm working an a script to autoconfigure my VMs. The idea is, that the VM automatic configures its netadapter and the joins a domain via default credentials. It's supposed to work with 2012r2, so PoShv4 is in use.
It works perfect until it comes to the point of working with Add-Computer
$vmName = (Get-ItemProperty –path 'HKLM:\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters').VirtualMachineName
$vmName = $vmName -replace '\w+\s+(.+)' , '$1'
$ip = $vmName -replace '\D+(\d+)' , '$1'
switch -Regex ($vmName) {
'dc' {$Ip = '10.18.0.{0}0' -f $ip}
'srv' {$Ip = '10.18.1.{0}0' -f $ip}
'CL' {$Ip = '10.18.2.{0}0' -f $ip}
}
#Configure IP-Settings
$netadapter = Get-NetAdapter -Name Ethernet
$netadapter | Set-NetIPInterface -DHCP Disabled | Out-Null
$netadapter | New-NetIPAddress -IPAddress $ip -PrefixLength 16 -DefaultGateway 10.18.0.10 | Out-Null
Set-DnsClientServerAddress -InterfaceAlias Ethernet -ServerAddresses 10.18.0.10 | Out-Null
#Create Credentials for Domainjoin
$username = 'domain\administrator'
$password = ConvertTo-SecureString 'Passw0rd' -AsPlainText -Force
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
Start-Sleep -Seconds 5
#Check if Domainjoin possible
if ($vmName -eq 'DC1')
{
Install-WindowsFeature AD-Domain-services -IncludeAllSubFeature -IncludeManagementTools
Rename-Computer $vmName -Restart
}
elseif ($vmName -match 'DC')
{
Install-WindowsFeature AD-Domain-services -IncludeAllSubFeature -IncludeManagementTools
-DomainCredential $cred -NewName $vmName -Restart
}
else
{
$null = [net.dns]::Resolve('domain.tld')
Add-Computer -DomainName 'domain.tld' -DomainCredential $cred -NewName $vmName -Restart -Server 'dc1.domain.tld'
}
Add-Computer fails with the following error:
Add-Computer : Der angegebene Servername "dc1.domain.tld" kann nicht aufgelöst werden.
In C:\VMAutoConfig.ps1:42 Zeichen:5
+ Add-Computer -DomainName 'domain.tld' -DomainCredential $cred -NewName $ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (dc1.domain.tld:String) [Add-Computer], InvalidOperationException
+ FullyQualifiedErrorId : AddressResolutionException,Microsoft.PowerShell.Commands.AddComputerCommand
Any known issues with that?
Timedelay of up to 5 secs between netadapter config and Add-Computer does not help at all.
If I run the script a second time, everthing's ok and works.