Building a working foreach loop on Get-VM
Solution 1
After spending some time with the code over the weekend, I started by removing all the user initiated variables and running a number of Write-Host. What I found was that the foreach and the inner for loops were running successfully, but the naming convention on the path was recycling, thus eliminating it from working 100%. The fix was simply to put the VM name variable in the pathway. Once that was done, it worked like a charm.
Here's the finished code:
Write-Host "This script is set up for quickly creating and initilizing VHDs"
$Path = "E:\Hyper-V\Virtual hard disks\Test Drives\"
$fileName = "target"
$vhdSize = 7GB
$GetVM = Get-VM -ComputerName localhost
Foreach ($vm in $GetVM)
{
$n = $vm.Name
$vmAmount = 4
Write-Host "vm = " $n
For($val = 0; $val -le $vmAmount; $val++)
{
Write-Host "drive = " $val
Write-Host "Path Before = " $Path
$vhdPath = (Join-path $Path ($n + "_" + $fileName + '-' + $val + '.vhdx'))
Write-Host "Path after = " $vhdPath
New-VHD -Path $vhdPath -SizeBytes $vhdSize -Fixed
Mount-VHD -Path $vhdPath
$disk = get-vhd -path $vhdPath
Initialize-Disk $disk.DiskNumber
$partition = New-Partition -AssignDriveLetter -UseMaximumSize -DiskNumber $disk.DiskNumber
$volume = Format-Volume -FileSystem NTFS -Confirm:$false -Force -Partition $partition
Dismount-VHD -Path $vhdPath
Add-VMHardDiskDrive -VMName $n -Path $vhdPath
}
}
Solution 2
Move the $val = 0
to just before the Foreach
loop. Otherwise, although you increment at the end of the loop, at the start of the loop you are zeroing it again, so $val
is always going to be zero.
Gavin_Talyn
I started with Geocities a long time ago. During the course of my career I got side tracked into hardware, networking, databases, and then accounting. Lately I've been wanting to come back to the coding side of things and found things much changed since I left in 2008. I'm attempting to rectify that and make a proper coder out of me.
Updated on June 04, 2022Comments
-
Gavin_Talyn almost 2 years
I'm trying to build a loop that will take the Get-VM cmdlet, put it into an array, and let me run a foreach statement on each VM. When I have that array built, the loop should go to each VM, build the designated amount of VHDs, initialize them, format them, and attach them to the VM.
The logic in the script works. It will build a disk and attach it to the VM. Where I'm failing is that the script will error out saying that the machine it is trying to build is already created (I suspect a scope error in my $val variable). It will also stop and not move to the next object.
I suspect I have scope errors, and also that ForEach-Object might be a better way to go on this script. However at this point I'm lost and need a little help.
As always, thank you and happy coding!
Write-Host "This script is set up for quickly creating and initilizing VHDs" $Path = Read-Host "Please enter the path you want to create the drives to. Use the format in this example <E:\VHDS\>" $fileName = Read-Host "The Drive will be <target>-<number>.vhdx. Please Name the target " $vhdSize = 1GB $vmAmount = 1 $GetVM = Get-VM Foreach ($vm in $GetVM) { $n = $vm.Name.ToString() $val = 0 For($internalCounter = 0; $internalCounter -le $vmAmount; $internalCounter++) { $vhdPath = (Join-path $Path ($fileName + '-' + $val + '.vhdx')) New-VHD -Path $vhdPath -SizeBytes $vhdSize -Fixed Mount-VHD -Path $vhdPath $disk = get-vhd -path $vhdPath Initialize-Disk $disk.DiskNumber $partition = New-Partition -AssignDriveLetter -UseMaximumSize -DiskNumber $disk.DiskNumber $volume = Format-Volume -FileSystem NTFS -Confirm:$false -Force -Partition $partition Dismount-VHD -Path $vhdPath Add-VMHardDiskDrive -VMName $n -Path $vhdPath } $val++ }