Author Posts

August 11, 2015 at 12:17 pm

$newvm.vmwareNEW.newvm | foreach {New-VM -Name $_.name -Template $_.Tmp -StorageFormat $_.SF -Datastore $_.DS -VMHost $_.VMH | set-vm -memorygb $_.RAM -numcpu $_.CPU -Confirm:$false | get-harddisk | set-harddisk -Datastore $_.DS -StorageFormat $_.SF -CapacityGB $_.HD -Confirm:$false | new-harddisk -Datastore $_.DS -StorageFormat $_.SF -CapacityGB $_.NHD -Confirm:$false | new-harddisk -Datastore $_.DS -StorageFormat $_.SF -CapacityGB $_.NNHD -Confirm:$false | new-harddisk -Datastore $_.DS -StorageFormat $_.SF -CapacityGB $_.NNNHD -Confirm:$false | new-harddisk -Datastore $_.DS -StorageFormat $_.SF -CapacityGB $_.NNNNHD -Confirm:$false }

This is the error message I get:
WHY is the name argument empty???
I have an example of the xml file below the error. I don't understand....

New-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not
null or empty, and then try the command again.
At line:1 char:48
+ $newvm.vmwareNEW.newvm | foreach {New-VM -Name $_.Name -Template $_.Tmp -Storage ...
+ ~~~~~~~
+ CategoryInfo : InvalidData: (:) [New-VM], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewVM

Example of XML file:

August 11, 2015 at 12:19 pm

xml:

August 11, 2015 at 12:21 pm

You can't past XML into an HTML forum :). Use Gist to save your XML and then paste the gist URL here. It'll display properly.

August 11, 2015 at 12:25 pm

Ahh many thanks DON!!!

August 13, 2015 at 7:43 am

I'm not sure why your xml query isn't working, but I would like to recommend a cleaner approach to what you are attempting to do. What I'm doing below is converting the XML into a PSObject using Select-Object. Once you have a standard object, it's a normal for loop to enumerate each node versus using XPath. When you look at your command it's very long and complicated to see what variable is doing what, so I HIGHLY recommend the use of splatting. Take a look at this:

[xml]$xml = Get-Content C:\Test\test.xml

$vmsToCreate = $xml.SelectNodes("vmwareNEW/newvm") | Select Name, Tmp, VMH, RP, HD, DS, SF, RAM, CPU, PG

foreach ($newVM in $vmsToCreate) {

    $newVMParams = @{
      Name =          $newVM.name
      Template =      $newVM.Tmp
      StorageFormat = $newVM.SF
      Datastore =     $newVM.DS
      VMHost =        $newVM.VMH   
    }

    $setVMParams = @{
     MemoryGb = $newVM.RAM
     NumCPU =   $newVM.CPU
     Confirm =  $false
    }

    $setHDParams = @{
        Datastore =     $newVM.DS
        StorageFormat = $newVM.SF
        CapacityGB =    $newVM.HD
        Confirm =       $false
    }

    $newHDParams = @{
        Datastore =     $newVM.DS
        StorageFormat = $newVM.SF
        Confirm =       $false
    }

    New-VM  @newVMParams | 
    Set-VM  @setCMParams | 
    Get-Harddisk |
    Set-Harddisk @setHDParams | 
    New-Harddisk @newHDParams -CapacityGB = $new.NHD | 
    New-Harddisk @newHDParams -CapacityGB $_.NNHD |
    New-Harddisk @newHDParams -CapacityGB $_.NNNHD |
    New-Harddisk @newHDParams -CapacityGB $_.NNNNHD 

}

Much cleaner and easier to read. You could also dynamically add and remove parameters

if ($newVM.Name -eq "Foo") {$newVMParams.Add("WhatIf", $true}

Before you test this, you should really consider doing a -WhatIf on your commands step-by-step to ensure the xml properties are mapped properly to the command. So, test New-VM first with WhatIf and slowly step through each phase of your pipeline to validate it's doing what you expect. You can also just remark out the commands and look at the parameters like so:

[xml]$xml = Get-Content C:\test\test.xml

$vmsToCreate = $xml.SelectNodes("vmwareNEW/newvm") | Select Name, Tmp, VMH, RP, HD, DS, SF, RAM, CPU, PG

foreach ($newVM in $vmsToCreate) {

    $newVMParams = @{
      Name =          $newVM.name
      Template =      $newVM.Tmp
      StorageFormat = $newVM.SF
      Datastore =     $newVM.DS
      VMHost =        $newVM.VMH   
    }

    $setVMParams = @{
     MemoryGb = $newVM.RAM
     NumCPU =   $newVM.CPU
     Confirm =  $false
    }

    $setHDParams = @{
        Datastore =     $newVM.DS
        StorageFormat = $newVM.SF
        CapacityGB =    $newVM.HD
        Confirm =       $false
    }

    $newHDParams = @{
        Datastore =     $newVM.DS
        StorageFormat = $newVM.SF
        Confirm =       $false
    }

    #New-VM  @newVMParams | 
    #Set-VM  @setCMParams | 
    #Get-Harddisk |
    #Set-Harddisk @setHDParams | 
    #New-Harddisk @newHDParams -CapacityGB = $new.NHD | 
    #New-Harddisk @newHDParams -CapacityGB $_.NNHD |
    #New-Harddisk @newHDParams -CapacityGB $_.NNNHD |
    #New-Harddisk @newHDParams -CapacityGB $_.NNNNHD 

    $newVMParams
}

August 16, 2015 at 6:14 pm

@Rob Simmers

Thank you for all the help! I really am still in learning mode reading your script is helping me understand how to begin to instruct the shell to do what i want. I really have something to build from thanks to you.

I have already taken your example and added domain and oscustomization.