Disable/Enable vMotion on a VM

March 19, 2020 1 By Allan Kjaer

I was looking at how to disable vMotion/Storage vMotion on a VM in vCenter 6.7, after a Tweet from Michael Ryom, And I have used a script from William Lam to do this in earlier version of vCenter, and work fine, but it did not work with vCenter 6.7 Update.

I have used William Lams old script at got it to work with vCenter 6.7, the original port from him here, and a huge thanks to William for this.

I have changed some things, so it works with 6.7 Update 3.

Disclaimer: The use of internal APIs are not officially supported by VMware and can change at any time. Please use at your own risk.

27 March 2020: updated the disable script so you can set the “Source ID”, this can be used for select in the Postgres database by “select * from VPX_DISABLED_METHODS where source_id_val = ‘self’;”

Disable script:

$vc_server = "<vCenter name>"
$vc_username = "<user/admin>"
$vc_password = "<password>"
$secpasswd = ConvertTo-SecureString $vc_password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($vc_username, $secpasswd)
$mob_url = "https://$vc_server/mob/?moid=AuthorizationManager&method=disableMethods"
$vm_name = "<vm name>"
$method = "RelocateVM_Task"
$disabled_by = "self"

$vcenter = connect-viserver $vc_server -User $vc_username -Password $vc_password
$vm = Get-VM -Name $vm_name
$vm_moref = (Get-View $vm).MoRef.Value

# Ingore SSL Warnings
add-type -TypeDefinition  @"
        using System.Net;
        using System.Security.Cryptography.X509Certificates;
        public class TrustAllCertsPolicy : ICertificatePolicy {
            public bool CheckValidationResult(
                ServicePoint srvPoint, X509Certificate certificate,
                WebRequest request, int certificateProblem) {
                return true;
            }
        }
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

# Initial login to vSphere MOB using GET and store session using $vmware variable
$results = Invoke-WebRequest -Uri $mob_url -SessionVariable vmware -Credential $credential -Method GET

# Extract hidden vmware-session-nonce which must be included in future requests to prevent CSRF error
# Credit to https://blog.netnerds.net/2013/07/use-powershell-to-keep-a-cookiejar-and-post-to-a-web-form/ for parsing vmware-session-nonce via Powershell

if($results.StatusCode -eq 200) {
    $null = $results -match 'name="vmware-session-nonce" type="hidden" value="?([^\s^"]+)"'
    $sessionnonce = $matches[1]
} else {
    $results
    Write-host "Failed to login to vSphere MOB"
}

# The POST data payload must include the vmware-session-nonce variable + URL-encoded
$body = @"
vmware-session-nonce=$sessionnonce&entity=%3Centity+type%3D%22ManagedEntity%22+xsi%3Atype%3D%22ManagedObjectReference%22%3E$vm_moref%3C%2Fentity%3E%0D%0A%0D%0A&method=%3CDisabledMethodRequest%3E%0D%0A+++%3Cmethod%3E$method%3C%2Fmethod%3E%0D%0A%3C%2FDisabledMethodRequest%3E%0D%0A%0D%0A&sourceId=$disabled_by
"@

# Second request using a POST and specifying our session from initial login + body request
$results = Invoke-WebRequest -Uri $mob_url -WebSession $vmware -Method POST -Body $body

#Logout out of vSphere MOB
$mob_logout_url = "https://$vc_server/mob/logout"
Invoke-WebRequest -Uri $mob_logout_url -WebSession $vmware -Method GET

disconnect-viserver $vcenter -confirm:$false

Enable script:

$vc_server = "<vCenter name>"
$vc_username = "<user/admin>"
$vc_password = "<password>"
$secpasswd = ConvertTo-SecureString $vc_password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($vc_username, $secpasswd)
$mob_url = "https://$vc_server/mob/?moid=AuthorizationManager&method=enableMethods"
$vm_name = "<vm name>"
$method = "RelocateVM_Task"

$vcenter = connect-viserver $vc_server -User $vc_username -Password $vc_password
$vm = Get-VM -Name $vm_name
$vm_moref = (Get-View $vm).MoRef.Value

# Ingore SSL Warnings
add-type -TypeDefinition  @"
        using System.Net;
        using System.Security.Cryptography.X509Certificates;
        public class TrustAllCertsPolicy : ICertificatePolicy {
            public bool CheckValidationResult(
                ServicePoint srvPoint, X509Certificate certificate,
                WebRequest request, int certificateProblem) {
                return true;
            }
        }
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

# Initial login to vSphere MOB using GET and store session using $vmware variable
$results = Invoke-WebRequest -Uri $mob_url -SessionVariable vmware -Credential $credential -Method GET

# Extract hidden vmware-session-nonce which must be included in future requests to prevent CSRF error
# Credit to https://blog.netnerds.net/2013/07/use-powershell-to-keep-a-cookiejar-and-post-to-a-web-form/ for parsing vmware-session-nonce via Powershell

if($results.StatusCode -eq 200) {
    $null = $results -match 'name="vmware-session-nonce" type="hidden" value="?([^\s^"]+)"'
    $sessionnonce = $matches[1]
} else {
    $results
    Write-host "Failed to login to vSphere MOB"
}

# The POST data payload must include the vmware-session-nonce variable + URL-encoded
$body = @"
vmware-session-nonce=$sessionnonce&entity=%3Centity+type%3D%22ManagedEntity%22+xsi%3Atype%3D%22ManagedObjectReference%22%3E$vm_moref%3C%2Fentity%3E%0D%0A&method=%3Cmethod%3E$method%3C%2Fmethod%3E
"@

# Second request using a POST and specifying our session from initial login + body request
$results = Invoke-WebRequest -Uri $mob_url -WebSession $vmware -Method POST -Body $body

#Logout out of vSphere MOB
$mob_logout_url = "https://$vc_server/mob/logout"
Invoke-WebRequest -Uri $mob_logout_url -WebSession $vmware -Method GET

disconnect-viserver $vcenter -confirm:$false

Not sure why the orgional script for William did not work.

Please share this page if you find it usefull: