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
}
}
}
}
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
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
I call it from the main body of my script passing a virtual machine object parameter.
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.
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
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
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.
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
Got it. Thanks a lot. Some of these more complicated things are a ton more difficult to figure out.
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?
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
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.
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?
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
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
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
It worked like a dream, many thanks!