mkn3000
Contributor
Contributor

script to move vms to resource pool based on tags

Jump to solution

I am looking to move vms to resource pool based on tags.

if anyone had similar script that will help me a lot.

0 Kudos
1 Solution

Accepted Solutions
mkn3000
Contributor
Contributor

@LucD Sorry for the lately replying the problem fixed after making changes in Tagcategory as suggested in previous post. 

View solution in original post

0 Kudos
9 Replies
LucD
Leadership
Leadership

What do you already have?
We might help you with filling in the blanks


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

0 Kudos
mkn3000
Contributor
Contributor

I have this script which not working can you please help on this

param (
[Parameter(Mandatory=$true)]
[string]$vCenterName,
[Parameter(Mandatory=$true)]
[string]$logfile
)

function connect-vCenter {
param (
$vCenterName
)

$vCenterObj = Get-VIServer $vCenterName
return $vCenterObj
}

function disconnect-vCenter {
param (
$vc
)
Disconnect-VIServer -Server $vc -Confirm:$false
}

function get-vmlist ($vc, $logfile) {
Write-Log -Level INFO -Message "Get list of VMs"
$tag = get-tag -Category drs -Name NO
$allVms = get-cluster -Server $vc | ? {($_ | Get-Annotation -Server $vc -CustomAttribute GEO).Value -eq "YES"} | get-vm -Server $vc
$vmsNotToAttach = get-cluster -Server $vc | ? {($_ | Get-Annotation -Server $vc -CustomAttribute GEO).Value -eq "YES"} | get-vm -Server $vc -Tag $tag
$vms = $allVms | ? {$_ -notin $vmsNotToAttach}
return $vms
}

function get-datastoreLocation ($vm, $vc) {
$r = [regex] "\[([^\[]*)\]"
$match = $r.match(($vm.ExtensionData.Config.Files.VMPathName))
$VMXdatastoreLocation = (Get-TagAssignment -Server $vc -Entity (Get-Datastore ($match.Groups[1].value)) -Category Datacenter).tag.name
$tier = (Get-TagAssignment -Server $vc -Entity (Get-Datastore ($match.Groups[1].value)) -Category Tier).tag.name
$dsInfo = @{}
$dsInfo.dcLocation = $VMXdatastoreLocation
$dsInfo.tier = $tier
return $dsInfo
}

function add-vmToDrsGroups {
param (
$vm,
$dsLocation,
$cluster,
$vc,
$logfile
)

$vmGroupName = $dsLocation + "_VM_Group"
switch ($dsLocation)
{
"M03" { $otherSite = "M21"}
"M21" { $otherSite = "M03"}
}
$vmGroupNameToRemove = $otherSite + "_VM_Group"

$vmGroup = Get-DrsClusterGroup -Cluster $cluster -Type VMGroup -Name $vmGroupName -Server $vc
$allVmGroup = Get-DrsClusterGroup -Cluster $cluster -Type VMGroup -Name "All_VMs" -Server $vc
$vmGroupToRemove = Get-DrsClusterGroup -Cluster $cluster -Type VMGroup -Name $vmGroupNameToRemove -Server $vc

if (-not ($vmGroup.member.name).contains($vm.name)) {
Write-Log -Level INFO -Message "Adding $($vm.name) to DRS Clustergroup $($vmGroup.Name) on Cluster $($cluster.name)"
Set-DrsClusterGroup -Server $vc -DrsClusterGroup $vmGroup -VM $vm -add -Confirm:$false
}
if (-not ($allVMGroup.member.name).contains($vm.name)) {
Write-Log -Level INFO -Message "Adding $($vm.name) to DRS Clustergroup $($allVmGroup.Name) on Cluster $($cluster.name)"
Set-DrsClusterGroup -Server $vc -DrsClusterGroup $allVmGroup -VM $vm -add -Confirm:$false
}
if (($vmGroupToRemove.member.name).contains($vm.name)) {
Write-Log -Level INFO -Message "Remove $($vm.name) from DRS Clustergroup $($vmGroupToRemove.Name) on Cluster $($cluster.name)"
Set-DrsClusterGroup -Server $vc -DrsClusterGroup $vmGroupToRemove -VM $vm -Remove -Confirm:$false
}
}

function moveVmToResourcePool {
param (
$vm,
$tier,
$vc,
$cluster
)
$vmRsPoolId = ($vm.ExtensionData.ResourcePool).value
$vmRsPool = (Get-ResourcePool -Server $vc -Id ("ResourcePool-" + $vmRsPoolId)).Name
switch ($tier) {
"01" {$rsPoolName = "Platin"}
"02" {$rsPoolName = "Gold"}
"03" {$rsPoolName = "Silver"}
}
if ($vmRsPool -ne $rsPoolName) {
$rsPool = Get-Cluster -Name $cluster -Server $vc | Get-ResourcePool -Name $rsPoolName -Server $vc
Move-VM -vm $vm -Destination $rsPool -Server $vc -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -WarningVariable moveWarning -ErrorVariable moveError
if ($moveWarning -or $moveError) {
Write-Log -Level INFO -Message "$moveWarning $moveError"
} else {
Write-Log -Level INFO -Message "moved $($vm.name) to resourcepool $($rsPool.Name)"
}
}

}

function configureLogging ($logfile, $logLevel) {
Add-LoggingTarget -Name File @{ Path = "$logfile"
RotateAfterAmount = 10
RotateAmount = 1
RotateAfterSize = 10000000
}
Set-LoggingDefaultLevel -Level $logLevel
}

function main ($vCenterName, $logfile) {
configureLogging $logfile INFO
Write-Log -Level INFO -Message "connecting to vcenter $vCenterName"
$vc = connect-vCenter -vCenterName $vCenterName
$vms = get-vmlist $vc $logfile
foreach ($vm in $vms) {
write-host $vm -ForegroundColor Green
Write-Log -Level INFO -Message "processing VM $vm"
$dsInfo = get-datastoreLocation $vm $vc
$cluster = ($vm.VMHost).Parent
moveVmToResourcePool -vm $vm -tier $dsInfo.tier -vc $vc -cluster $cluster
if ($cluster -ne $false) {
add-vmToDrsGroups -vm $vm -dsLocation $dsInfo.dcLocation -cluster $cluster -vc $vc -logfile $logfile
} else {
Write-Log -Level INFO -Message "$($vm.name) not added to a drs group"
}
}
Write-Log -Level INFO -Message "disconnecting from vcenter"
Write-Log -Level INFO -Message "Finished"
Write-Log -Level INFO -Message "---------------------------------------------------------------------------"
}

main $vCenterName $logfile

0 Kudos
LucD
Leadership
Leadership

What exactly is not working?

I'm not going to set up a test environment and debug your script, which is doing a lot more than moving VMs to Resourcepools, in its entirety.


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

0 Kudos
mkn3000
Contributor
Contributor

I am facing errors in this area 

 

$tag = get-tag -Category drs -Name NO

$allVms = get-cluster -Server $vc | ? {($_ | Get-Annotation -Server $vc -CustomAttribute GEO).Value -eq "YES"} | get-vm -Server $vc

$vmsNotToAttach = get-cluster -Server $vc | ? {($_ | Get-Annotation -Server $vc -CustomAttribute GEO).Value -eq "YES"} | get-vm -Server $vc -Tag $tag

$vms = $allVms | ? {$_ -notin $vmsNotToAttach}

return $vms

0 Kudos
LucD
Leadership
Leadership

What errors?


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

0 Kudos
mkn3000
Contributor
Contributor


Here is the multiple errors message


Get-TagAssignment : 11/7/2022 3:11:45 PM Get-TagAssignment Could not find TagCategory with name 'Tier'.
At C:\drsmove.ps1:74 char:14
+ ... $tier = (Get-TagAssignment -Server $vc -Entity (Get-Datastore ($ma ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Tier:String) [Get-TagAssignment], VimException
+ FullyQualifiedErrorId : Core_ObnSelector_SelectObjectByNameCore_ObjectNotFound,VMware.VimAutomation.ViCore.Cmdlets.Commands.Tagging.GetTagAssignment

Get-TagAssignment : 11/7/2022 3:11:45 PM Get-TagAssignment TagCategory parameter: Could not find any of the objects specified by name.
At C:\drsmove.ps1:74 char:14
+ ... $tier = (Get-TagAssignment -Server $vc -Entity (Get-Datastore ($ma ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (VMware.VimAutom...gory[] Category:RuntimePropertyInfo) [Get-TagAssignment], ObnRecordProcessingFailedException
+ FullyQualifiedErrorId : Core_ObnSelector_SetNewParameterValue_ObjectNotFoundCritical,VMware.VimAutomation.ViCore.Cmdlets.Commands.Tagging.GetTagAssignment

Get-ResourcePool : 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 C:\drsmove.ps1:131 char:83
+ ... ame $cluster -Server $vc | Get-ResourcePool -Name $rsPoolName -Server ...
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-ResourcePool], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetResourcePool

Move-VM : Cannot validate argument on parameter 'Destination'. The argument is null or empty. Provide an argument that is not null or empty, and then try the
command again.
At C:\drsmove.ps1:132 char:38
+ Move-VM -vm $vm -Destination $rsPool -Server $vc -WarningActi ...
+ ~~~~~~~
+ CategoryInfo : InvalidData: (:) [Move-VM], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.MoveVM

Get-DrsClusterGroup : 11/7/2022 3:11:46 PM Get-DrsClusterGroup DrsClusterGroup with name '_VM_Group' was not found using the specified filter(s).
At C:\drsmove.ps1:98 char:16
+ ... $vmGroup = Get-DrsClusterGroup -Cluster $cluster -Type VMGroup -Name ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-DrsClusterGroup], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetDrsClusterGroup

Get-DrsClusterGroup : 11/7/2022 3:11:47 PM Get-DrsClusterGroup DrsClusterGroup with name 'All_VMs' was not found using the specified filter(s).
At C:\drsmove.ps1:99 char:19
+ ... llVmGroup = Get-DrsClusterGroup -Cluster $cluster -Type VMGroup -Name ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-DrsClusterGroup], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetDrsClusterGroup

Get-DrsClusterGroup : 11/7/2022 3:11:47 PM Get-DrsClusterGroup DrsClusterGroup with name '_VM_Group' was not found using the specified filter(s).
At C:\drsmove.ps1:100 char:24
+ ... pToRemove = Get-DrsClusterGroup -Cluster $cluster -Type VMGroup -Name ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-DrsClusterGroup], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetDrsClusterGroup

You cannot call a method on a null-valued expression.
At C:\drsmove.ps1:102 char:9
+ if (-not ($vmGroup.member.name).contains($vm.name)) {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression.
At C:\drsmove.ps1:106 char:9
+ if (-not ($allVMGroup.member.name).contains($vm.name)) {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression.
At C:\drsmove.ps1:110 char:9
+ if (($vmGroupToRemove.member.name).contains($vm.name)) {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull

0 Kudos
LucD
Leadership
Leadership

You should always start with the 1st error, the others are most probably a consequence of that one.

I think the error message is quite clear, there is apparently no TagCategory with the name 'Tier' in the environment.


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

0 Kudos
mkn3000
Contributor
Contributor

@LucD Sorry for the lately replying the problem fixed after making changes in Tagcategory as suggested in previous post. 

0 Kudos
LucD
Leadership
Leadership

Not sure why you marked that last reply as the Solution?


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

0 Kudos