VMware Cloud Community
jondercik2020
Contributor
Contributor
Jump to solution

Remove Storage DRS override

I am trying to remove Storage DRS overrides programmatically for some VMs, but I cannot seem to get it right.  Here is the function that I wrote that doesn't quite work right:

Any help is appreciated.

 

Function Local:Set-SDRSForSmallVM
{
param($vm)

$datastoreClusterList = $vm | Get-DatastoreCluster
if ( $datastoreClusterList )
{
foreach($datastoreCluster in $datastoreClusterList)
{
$dscName = $datastoreCluster.Name
# The first thing that must be done is to see if the VM has an override set, and if so remove it
# Copied some of this code from https://ryanjan.uk/2018/07/30/storage-drs-and-powercli-part-1-get-vm-overrides/
$StoragePod = Get-View -ViewType "StoragePod" -Filter @{"Name" = "$dscName"}
if ( $StoragePod)
{
$podVMConfig = $StoragePod.PodStorageDrsEntry.StorageDrsConfig.VmConfig
$vmID = $vm.id
$filteredList = $podVMConfig | Where-Object {$_.vm -eq $vmID}
if ( $filteredList)
{
$pod = New-Object VMware.Vim.ManagedObjectReference
$pod.Type = 'StoragePod'
$pod.Value = $datastoreCluster.ExtensionData.MoRef.value
$spec = New-Object VMware.Vim.StorageDrsConfigSpec
$spec.VmConfigSpec = New-Object VMware.Vim.StorageDrsVmConfigSpec[] (1)
$spec.VmConfigSpec[0] = New-Object VMware.Vim.StorageDrsVmConfigSpec
$spec.VmConfigSpec[0].Operation = 'remove'
$spec.VmConfigSpec[0].Info = New-Object VMware.Vim.StorageDrsVmConfigInfo
$spec.VmConfigSpec[0].Info.IntraVmAffinity = $true
$spec.VmConfigSpec[0].Info.Vm = New-Object VMware.Vim.ManagedObjectReference
$spec.VmConfigSpec[0].Info.Vm.Type = 'VirtualMachine'
$spec.VmConfigSpec[0].Info.Vm.Value = $vm.ExtensionData.MoRef.Value
# The definition of this type is located here:
#https://vdc-repo.vmware.com/vmwb-repository/dcr-public/3325c370-b58c-4799-99ff-58ae3baac1bd/45789cc5...

$spec.VmConfigSpec[0].Info.Behavior = 'automated'
$spec.VmConfigSpec[0].Info.Enabled = $true
$modify = $true
$_this = Get-View -Id 'StorageResourceManager-StorageResourceManager'
try
{
$_this.ConfigureStorageDrsForPod_Task($pod, $spec, $modify) | Out-Null
Start-sleep -seconds .1
}
catch
{
Start-sleep -seconds .1
}

$vmName = $vm.Name
#Start-Sleep -seconds .1
}
#Start-Sleep -Seconds .1
}


}
}

}

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Ok, I think I understand what causes the confusion.

With CodeCapture you get the code the Web Client runs when a user performs an action.
In my experience, the code used by the Web CLient is not always the most logical.
But that is probably since the Web Client coders know vSphere much better than me.

In your case, removing a VM from the SDRS overrides is done by 'adding' the VM with no properties set.
So in fact, the Enabled property is $null.
I suspect the SDRS code interprets this by removing the VM from the visible entries in the Web Client.
But the VM, or better said it's MoRef, is still there.
Just check for example $dsc.ExtensionData.PodStorageDrsEntry.StorageDrsConfig.VmConfig, and you'll notice that there is still an entry with the VM's MoRef in there. But none of the properties, like Enabled for example, is set. 

To really remove a VM from that list, you need to use indeed the 'remove' operation.
Something like this

$dscName = 'MyDSC'
$vmName = 'MyVM'

$dsc = Get-DatastoreCluster -Name $dscName
$vm = Get-VM -Name $vmName

$StorResMgr = Get-View StorageResourceManager

$spec = New-Object -TypeName VMware.Vim.StorageDrsConfigSpec

$vmSpec = New-Object -TypeName VMware.Vim.StorageDrsVmConfigSpec

$vmSpec.Operation = [VMware.Vim.ArrayUpdateOperation]::remove
$vmSpec.RemoveKey = $vm.ExtensionData.MoRef

$spec.VmConfigSpec += $vmSPec

$StorResMgr.ConfigureStorageDrsForPod($dsc.ExtensionData.MoRef,$spec,$true)


Long story short, using CodeCapture doesn't always produce the 'logical' code, but gives you the Web Client implementation 😁


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

View solution in original post

15 Replies
LucD
Leadership
Leadership
Jump to solution

How did you call the Set-DRSForSmallVM function?
How did you pass the parameter?
Are you getting any error messages?


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

0 Kudos
jondercik2020
Contributor
Contributor
Jump to solution

I call it from the main body of my script passing a virtual machine object parameter. 

 Set-SDRSForSmallVM -VM $vm
 
The error I am getting is:

A specified parameter was not correct: spec.vmConfigSpec[0]

In the GUI, nothing is being output in the Powershell Window as far as errors go.

0 Kudos
jondercik2020
Contributor
Contributor
Jump to solution

I will update the function to be a more correct advanced Powershell function when it works, and I have feeling I know what is causing the error, it just doesn't make sense to me.

$spec.VmConfigSpec[0].Operation = 'remove'

is supposed to be

$spec.VmConfigSpec[0].Operation = 'add'
if I use Developer Center but why would it be add when I want to remove the override?
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Now I'm confused.
You used CodeCapture to capture the methods called by the Web Client.
But what did you do in the Web Client?
Add or remove settings for a specific VM?


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

0 Kudos
jondercik2020
Contributor
Contributor
Jump to solution

Sorry for the confusion LucD.

In a datastore cluster I removed a VM that I no longer wanted to have an override and clicked remove.  That gave me the code and it included the operation

$spec.VmConfigSpec[0].Operation = 'add'

In my code I changed add to remove because I want to remove the rule.  Why would removing a SDRS override call the add operation and not the remove operation.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ok, I think I understand what causes the confusion.

With CodeCapture you get the code the Web Client runs when a user performs an action.
In my experience, the code used by the Web CLient is not always the most logical.
But that is probably since the Web Client coders know vSphere much better than me.

In your case, removing a VM from the SDRS overrides is done by 'adding' the VM with no properties set.
So in fact, the Enabled property is $null.
I suspect the SDRS code interprets this by removing the VM from the visible entries in the Web Client.
But the VM, or better said it's MoRef, is still there.
Just check for example $dsc.ExtensionData.PodStorageDrsEntry.StorageDrsConfig.VmConfig, and you'll notice that there is still an entry with the VM's MoRef in there. But none of the properties, like Enabled for example, is set. 

To really remove a VM from that list, you need to use indeed the 'remove' operation.
Something like this

$dscName = 'MyDSC'
$vmName = 'MyVM'

$dsc = Get-DatastoreCluster -Name $dscName
$vm = Get-VM -Name $vmName

$StorResMgr = Get-View StorageResourceManager

$spec = New-Object -TypeName VMware.Vim.StorageDrsConfigSpec

$vmSpec = New-Object -TypeName VMware.Vim.StorageDrsVmConfigSpec

$vmSpec.Operation = [VMware.Vim.ArrayUpdateOperation]::remove
$vmSpec.RemoveKey = $vm.ExtensionData.MoRef

$spec.VmConfigSpec += $vmSPec

$StorResMgr.ConfigureStorageDrsForPod($dsc.ExtensionData.MoRef,$spec,$true)


Long story short, using CodeCapture doesn't always produce the 'logical' code, but gives you the Web Client implementation 😁


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

jondercik2020
Contributor
Contributor
Jump to solution

Got it. Thanks a lot.  Some of these more complicated things are a ton more difficult to figure out.

0 Kudos
henketh
Contributor
Contributor
Jump to solution

Hi,

How do I remove all VMs from the Datastore Cluster VM Overrides list? I tried the script in another post (How to disable or remove VM from VMoverrides), but I got an error, and I believe that script targeted a Host Cluster and not a Datastore Cluster?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

And does the script in this thread not work for you?
Have you read the info I added to my reply?


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

0 Kudos
henketh
Contributor
Contributor
Jump to solution

Thanks for answering!
I haven't tried the script in this post, since it seems to target only a specific VM, or am I wrong?
I want to remove ALL VMs from the VM Override list for my datastore clusters.

0 Kudos
henketh
Contributor
Contributor
Jump to solution

Now I have tried the script, and it works fine for a specific VM.
How do I remove ALL VMs in the VM Overrides list?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Can you try with

$dscName = 'MyDSC'

$dsc = Get-DatastoreCluster -Name $dscName
$StorResMgr = Get-View StorageResourceManager

$spec = New-Object -TypeName VMware.Vim.StorageDrsConfigSpec
$vmSpec = New-Object -TypeName VMware.Vim.StorageDrsVmConfigSpec
$spec.VmConfigSpec += $vmSPec

$StorResMgr.ConfigureStorageDrsForPod($dsc.ExtensionData.MoRef,$spec,$true)


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

0 Kudos
henketh
Contributor
Contributor
Jump to solution

Resulted in an error:

Exception calling "ConfigureStorageDrsForPod" with "3" argument(s): "A specified parameter was not correct: spec.vmConfigSpec[0]"
At C:\Users\hentho\Desktop\removeAllVMfromOverride.ps1:9 char:1
+ $StorResMgr.ConfigureStorageDrsForPod($dsc.ExtensionData.MoRef,$spec, ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : VimException

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Then try like this

$dscName = 'MyDSC'

$dsc = Get-DatastoreCluster -Name $dscName
$StorResMgr = Get-View StorageResourceManager

$spec = New-Object -TypeName VMware.Vim.StorageDrsConfigSpec

$dsc.ExtensionData.PodStorageDrsEntry.StorageDrsConfig.VmConfig |
ForEach-Object -Process {
  $vm = New-Object -TypeName VMware.Vim.StorageDrsVmConfigSpec
  $vm.Operation = [VMware.Vim.ArrayUpdateOperation]::remove
  $vm.RemoveKey = $_.Vm
  $spec.VmConfigSpec += $vm
}

$StorResMgr.ConfigureStorageDrsForPod($dsc.ExtensionData.MoRef, $spec, $true)


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

henketh
Contributor
Contributor
Jump to solution

It worked like a dream, many thanks!

0 Kudos