VMware Cloud Community
Knotz
Contributor
Contributor
Jump to solution

Deploying a vm to a Datastore with the least amount of space, but enough for the vm

I have been given this tricky task and i just cant figure out how to put all the pieces together.

I need to create a script that will intelligently decided what datastore to deploy a vm to.  We don't want to deploy to a datastore that has the most space, we want to deploy to the datastore that has the least amount of space but can still accommodate the space for the ( vm+5% ) and still leave 50GB free on the lun after the move.

So for example, if the vm is 40GB, we want the script to select the datastore that has a close to 90GB available without being under.

So my thought for this approach is:

  • Create query to get all pertinent luns.  This excludes all luns with name "local" in it and excludes all proprietary luns (which have a slightly different naming convention then our general shared storage luns)
    • This piece i have partially figured out
      • get-datastore | where-object { ($_.Name -match "PAR0[1-4]_[edp]*disk*") -and ($_.Name -notmatch "local")}
    • Now i need to get all of their total sizes and free space sizes.  maybe export this list to a csv to read against if i have to.
    • Create a variable that contains: the total vm size of the vm that is being deployed before its deployed. 
    • Then subtract vm size against each datastore size and somehow pull out the one that as close to 50GB free on the datastore and still facilitates the deployment of the vm.

I have a few other scripts i scrounged up on the internet that i've been trying to piece together... but i just dont quiet have all the parts...

  • Get-Datastore | Where-Object {$_.ParentFolder -match “Internal”} `| Select-Object -Property Datacenter, FreeSpaceMB, CapacityMB, Name `| Sort-Object -Property FreeSpaceMB
  • Select-Object Name,@{n="CapacityGB";e={[math]::round(($_.CapacityMB/1024))}},@{n="FreeSpaceGB";e={[math]::round(($_.FreeSpaceMB/1024))}},@{n="FreeSpacePercent";e={[math]::round(($_.FreeSpaceMB/$_.CapacityMB*100))}} | Sort-Object FreeSpaceGB

Any help would be greatly appreciated!!!

-Knotz

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Try something like this

# Get all datastores

$ds = Get-Datastore | Where-Object { ($_.Name -match "PAR0[1-4]_[edp]*disk*") -and ($_.Name -notmatch "local")} |

Select-Object Name,

    @{n="CapacityGB";e={[math]::round(($_.CapacityMB/1024))}},

    @{n="FreeSpaceGB";e={[math]::round(($_.FreeSpaceMB/1024))}},

    @{n="FreeSpacePercent";e={[math]::round(($_.FreeSpaceMB/$_.CapacityMB*100))}}

foreach($vm in Get-VM){

# Find possible candidates

    $candidates = $ds | where {($_.FreeSpaceGB - $vm.UsedSpaceGB - 50) -gt 0}

# Find best candidate

    $target = $candidates | Sort-Object -Property FreeSpaceGB -Descending | Select -First 1

    Write-Output "VM $($vm.Name) can go to $($target.Name)"

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
5 Replies
Knotz
Contributor
Contributor
Jump to solution

I was able to combine these to get a good list of Capacity,FreeSpace, and Free space percent on just available/deploy-able luns.

get-datastore | where-object { ($_.Name -match "PAR0[1-4]_[edp]*disk*") -and ($_.Name -notmatch "local")} | Select-Object Name,@{n="CapacityGB";e={[math]::round(($_.CapacityMB/1024))}},@{n="FreeSpaceGB";e={[math]::round(($_.FreeSpaceMB/1024))}},@{n="FreeSpacePercent";e={[math]::round(($_.FreeSpaceMB/$_.CapacityMB*100))}} | Sort-Object FreeSpaceGB

Now i could easily export this to a csv... but then what... <scratches head>

-Knotz

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Try something like this

# Get all datastores

$ds = Get-Datastore | Where-Object { ($_.Name -match "PAR0[1-4]_[edp]*disk*") -and ($_.Name -notmatch "local")} |

Select-Object Name,

    @{n="CapacityGB";e={[math]::round(($_.CapacityMB/1024))}},

    @{n="FreeSpaceGB";e={[math]::round(($_.FreeSpaceMB/1024))}},

    @{n="FreeSpacePercent";e={[math]::round(($_.FreeSpaceMB/$_.CapacityMB*100))}}

foreach($vm in Get-VM){

# Find possible candidates

    $candidates = $ds | where {($_.FreeSpaceGB - $vm.UsedSpaceGB - 50) -gt 0}

# Find best candidate

    $target = $candidates | Sort-Object -Property FreeSpaceGB -Descending | Select -First 1

    Write-Output "VM $($vm.Name) can go to $($target.Name)"

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Wh33ly
Hot Shot
Hot Shot
Jump to solution

After you found your target, you should start to deploy your VM on that target. Depending on how you want to deploy your VM's you should parse the target value to your deployment.

For example you could use New-VM to deploy your VM

New-VM -Name VM2 -Template Template -VMHost $host -datastore $target

Knotz
Contributor
Contributor
Jump to solution

Now i know its ugly, but i got this far on my own...and it seems to pull the right datastore.  I still need to pull just the name as opposed to the @<Name=datastorename> naming format.  anyway.. going to abandon this for a few and try your script above.  looks much cleaner, like someone who knew what they were doing Smiley Happy.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

$vmsizegb=50

$vmsizemb=($vmsizegb*1024)

$datastoreminsizemb=($vmsizemb+51000)

$datastoreminsizegb=($datastoreminsizemb/1024)

get-datastore | where-object { ($_.Name -match "PAR0[1-4]_[edp]*disk*") -and ($_.Name -notmatch "local") -and ($_.FreeSpaceMB -gt $datastoreminsizemb) } | Select-Object Name,@{n="FreeSpaceGB";e={[math]::round(($_.FreeSpaceMB/1024-$datastoreminsizegb))}} | Sort-Object FreeSpaceGB | Select-Object -first 1

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

0 Kudos
Knotz
Contributor
Contributor
Jump to solution

So LucD,

thanks a ton for the help!  i pretty much combined our ideas and came up with this.. which works beautifully!!!

at some point before this, ill figure out that $vmsize variable and assign as such and then run this part.  But this was the hard part imo.

$vmsize=150

$dsminspace=($vmsize+50)

$ds = Get-Datastore | Where-Object { ($_.Name -match "PAR0[1-4]_[edp]*disk*") -and ($_.Name -notmatch "local")} |

Select-Object Name,

    @{n="CapacityGB";e={[math]::round(($_.CapacityMB/1024))}},

    @{n="FreeSpaceGB";e={[math]::round(($_.FreeSpaceMB/1024))}},

    @{n="FreeSpacePercent";e={[math]::round(($_.FreeSpaceMB/$_.CapacityMB*100))}} |

where {($_.FreeSpaceGB - $vm.UsedSpaceGB - $dsminspace) -gt 0} | Sort-Object -Property FreeSpaceGB | Select -First 1

write-output "$($ds.Name)"

then follow that up with something like this....ill also have to figure out some host logic as well...

New-VM -Name VM2 -Template Template -VMHost $host -datastore $ds

Thanks a ton guys.  mucho appreciated.  +1 for vmware communities!

-Knotz

0 Kudos