Tag Archives: powercli

vSphere: Enable/Disable DRS Host rules with PowerCLI

I know that the latest version of PowerCLI already have commandlet to will enable/disable DRS host rules. But when you are in operations, you don’t really get to use the latest version of PowerCLI all the time. Anyway, this is just a placeholder for myself, but if you find it useful great for you.

Disclaimer: This is not my original work, I forgot where I ripped the codes from, but its not my original work. Apologize for the bad formatting.

#Filename = Set-DRSVMHostRules.ps1

$cluster = Get-Cluster 
$ClusName $rule = $cluster | 
  Get-DrsRule -Type VMHostAffinity -Name $RuleName 
$spec = New-Object VMware.Vim.ClusterConfigSpec
$ruleSpec = New-Object VMware.Vim.ClusterRuleSpec 
$ruleSpec.Info = $rule.ExtensionData 
$ruleSpec.Info.Enabled = $Enable 
$ruleSpec.Operation = "edit" 
$spec.rulesSpec += $ruleSpec 

$cluster.ExtensionData.ReconfigureCluster($spec,$true) | Out-Null
$cluster | Get-DrsRule -Type VMHostAffinity -Name $RuleName

get-cluster ClusterABCDC | Get-DrsRule -Type VMHostAffinity | 
% { .\Set-DRSVMHostRules.ps1 -ClusName $_.cluster -RuleName $ -Enable $true}
Leave a comment

Posted by on July 21, 2019 in powershell, vmware


Tags: , ,

PS: One-line create a custom object list

The one-liner challenge for me today:

  • Get a list of random VMs from each ESXi host in a cluster
  • Send the host name, vm name and IP address to a CSV file

Normally, this is straight forward, but because we only need grab 2 VMs from each host, it is not possible to just  pipe the VM objects into a CSV file since the loop breaks between each host. The solution is to store all records into a array of custom objects and then pipe that into a CSV file at the end.

$ListOfVMs = @() ;
get-cluster | ? { $ -match "cluster1" } |
get-vmhost | % { $_ | get-vm | ? { $ -match "dev" } |
select -first 2 |
% { $t = @{} |
    select VMhost,Name,IPAddress ;
    $t.VMHost = $_.VMHost;
    $t.Name = $_.Name ;
    $t.IPAddress = $_.guest.IPAddress[0] ;
    $ListOfVMs += $t }
} ; $ListOfVMs | export-csv .\mylist.csv -NoTypeInformation


Leave a comment

Posted by on April 18, 2018 in powershell


Tags: , , ,

PS+REST: ESXi hosts’ NSX Channel Health check

As part of the daily checks for NSX, we need to ensure that the communication channel on all ESXi hosts are healthy.

The REST API for channel health is straight forward, just feed the list of host IDs into the API and query the hostConnStatus for the XML file. Read the rest of this entry »

Leave a comment

Posted by on February 15, 2018 in powershell, vmware


Tags: , ,

PowerCLI: Script to reboot each ESXi hosts

I realized that having done this for a few year, I never really nailed down a script to do this properly. It is very common as a vSphere admin to have to reboot your ESXi hosts after a configuration change or for patching.

Below is a first draft, not pretty code-wise but its a working operational script. I hope to improve on it over time. The basic flow of the script is as follows:

  • You establish a connection to the vCenter server first before running the script
  • You submit an input file which is list of ESXi host names
  • The script reads the list and does the following for each host
    • Sets the host in maintenance mode and counts down to 30 minutes. If the hosts does not get into maintenance mode by then the script terminates and you need to figure out why.
    • If the host goes into maintenance mode, it then force reboots the hosts and waits for 30 minutes again. Again if the host doesn’t come up by 30 minutes, the script terminates and you need to fix the host issue.
    • Lastly, once the host is back online, it sets the host to connected state and works on the next host in the loop.

Read the rest of this entry »

Leave a comment

Posted by on November 5, 2017 in powershell, vmware


Tags: , ,

PowerCLI: Listing VMs from a bunch of vCenters

I need to grab all the VMs in a list of vCenters, but for each line of VM, I need to know which cluster and ESXi host they sit in. The original script was this;

Get-content .\vc.txt |
% {$vc=$_ ; connect-viserver $vc ; Get-VM |
Select Name, Vmhost, @{Name="Cluster";
Expression={ ((get-vmhost $_.vmhost).parent)}}, Folder,
@{Name="vCenter"; Expression= {$vc}} |
export-csv .\$vc.txt -NoTypeInformation ;
disconnect-viserver $vc –force –confirm:$false }

Even thought the code was straight forward with just a single get-VM execution, it was very slow. The reason was the Cluster field code block, which executes get-vmhost to get the cluster name for each VM, took time to execute.

@{Name="Cluster"; Expression={ ((get-vmhost $_.vmhost).parent)}}

A faster one-line calls each cluster first, then calls each VM in turn.

Get-content .\vc.txt |
% {$vc=$_ ; connect-viserver $vc ; Get-Cluster |
% { $clus=$; Get-VM -Location $Clus |
% { "$($`t$($`t$($_.folder)`t$($_.vmhost)`t$Clus`t$vc" |
out-file .\$vc.txt -append }} ;
disconnect-viserver $vc –force –confirm:$false }
Leave a comment

Posted by on May 19, 2017 in powershell, vmware


Tags: , , ,

PowerCLI: Getting VMHosts, PortGroups and switches info

I needed to extract a list of hosts in vCenter and with them, get all the portgroups and switch info. Unfortunately, there is no one one-liner script that can do this. Mainly because you have standard and distributed switches and their properties are different. In order to do this you need to separate one-liner, both feeding into the same output file.

The first script output the hosts against their VDSwitches. The script creates a tab-delimited text file that you can easy copy and paste onto a spreadsheet. Both scripts output the following:
– Clustername
– Hostname
– virtual network adapter name
– IP
– subnet mask
– port group name
– switch name

Get-VMHostNetworkAdapter -vmkernel | 
% { $vnet=$_ ; get-vdportgroup -vmhostnetworkadapter $vnet | 
$($`t$($_.vdswitch)`t$($_.vlanconfiguration)" | 
out-file .\temp\output.txt -append } }

The second script output the hosts against their standard switch, as you can see the order of the function is very different. The main reason is that VMHostNetworkAdapter object cannot be pipped into the VirtualPortGroup but it works the other way around.

You can also see from the second script the the names for virtualswitch and vlanID different from the above. Actually .vdswitch and .vlanconfiguration are objects themselves, but they are nice enough to output the values I want without needing to specify the actual object, i.e. switch name and VLAN ID.

Get-VirtualPortgroup -standard | 
% { $pg=$_ ; get-vmhostnetworkadapter -portgroup $pg | 
% { "$($_.vmhost.parent)`t$($_.vmhost)`t$($`t
$($`t$($pg.vlanid)" |
 out-file .\temp\output.txt -append }}
Leave a comment

Posted by on March 31, 2017 in powershell, vmware


Tags: , , , ,

PowerCLI VUM 5.5: Get-baseline stackoverflow error

Update: PowerCLI VUM 6.0 seemed to have solved this problem

I ran in the following error when trying to get baseline via PowerCLI VUM

get-baseline -entity "clustername"

Powershell will then crash with stackoverflow error

A bit of search doesn’t reveal any solution or fixed to it, but one post seems to solve the problem for me, even though its talking about Windows 7/8 and I am running powershell on a Windows 2008R2 server. Apparently, this behaviour has been on-going since VUM 5.1.

The solution is to run powershell in version 2 compatible mode. However, if you try to amend the PowerCLI shortcut, you will find that it already has maxed out the number of character allowed and you cannot add anymore parameters. The solution is simply to create a CMD file, copy and paste the PowerCLI launch commands and add “-version 2” to the parameters. Remember to add “-version 2” immediately after the EXE and not at the end of the rest of the parameters.

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -version 2 -psc "C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\vim.psc1" -noe -c ". \"C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts\Initialize-PowerCLIEnvironment.ps1\""

Here is my powershell environment and after running in version 2

I have PowerCLI 5.8 installed with VUM 5.5 U2 PowerCLI.:

  • VMware-UpdateManager-Pscli-5.5.0-1302474.exe
  • VMware-PowerCLI-5.8.0-2057893
Get-PSSnapin | ft
Name                           PSVersion            Description
----                           ---------            -----------
Microsoft.PowerShell.Diagno... 3.0                  This Windows PowerShell sna...
Microsoft.PowerShell.Core      3.0                  This Windows PowerShell sna...
Microsoft.PowerShell.Utility   3.0                  This Windows PowerShell Sna...
Microsoft.PowerShell.Host      3.0                  This Windows PowerShell sna...
Microsoft.PowerShell.Manage... 3.0                  This Windows PowerShell Sna...
Microsoft.PowerShell.Security  3.0                  This Windows PowerShell Sna...
Microsoft.WSMan.Management     3.0                  This Windows PowerShell sna...
VMware.VimAutomation.Core      2.0                  This Windows PowerShell sna...
VMware.VimAutomation.Vds       2.0                  This Windows PowerShell sna...
VMware.VumAutomation           2.0                  This Windows PowerShell sna...
VMware.VimAutomation.License   2.0                  This Windows Powershell sna...
VMware.DeployAutomation        2.0                  Cmdlets for Rule-Based-Depl...
VMware.ImageBuilder            2.0                  This Windows PowerShell sna...
VMware.VimAutomation.Storage   2.0                  This Windows PowerShell sna...

$psversiontable (After running in version 2)

Name                           Value
----                           -----
CLRVersion                     2.0.50727.5485
BuildVersion                   6.1.7601.17514
PSVersion                      2.0
WSManStackVersion              2.0
PSCompatibleVersions           {1.0, 2.0}
PSRemotingProtocolVersion      2.1

$psversiontable (Before running in version 2)

Name                           Value
----                           -----
WSManStackVersion              3.0
PSCompatibleVersions           {1.0, 2.0, 3.0}
BuildVersion                   6.2.9200.16398
PSVersion                      3.0
CLRVersion                     4.0.30319.1026
PSRemotingProtocolVersion      2.2

Leave a comment

Posted by on September 24, 2015 in powershell, Scripts, vmware


Tags: ,

PowerCLI: Managing roles, permissions and privileges in vCenters

The following scripts allows you to add new roles, new permissions and add/remove privileges from existing roles in your vcenters. This is useful if you need to modify the role bases access control (RBAC) of a list of your vCenters. For new permission, I have defaulted to add them at the root folder AKA VC level and set to propagate, since this is the most common requirement. You can modify it for more flexibility as required.

The format of the XML file looks like this.  Do remember that many privileges are related, so setting just one may not be enough, you must test it out first before rollout. For example, to provide privilege for a role to delte alarm you need two privileges, “Remove alarm” & “Set alarm status”. Also notice that privilege ID is used instead of full description this is a less error prone approach.

To get the privilege ID, run “get-viprivilege “privilege name” | ft name, id

<?xml version="1.0" encoding="utf-8" ?>
Role action: valid verbs = AddRole, Add, Remove
   <vCenter Name="vcenter1"></vCenter>
   <Role Name="Role1" Action="Remove">
   <Role Name="Role2" Action="Add">
   <Role Name="TEST2" Action="AddRole">
   <Permission Principal="\user1" Role="TEST2" />

The script is below loops through the xml and does work accordingly. The logging is very basic, you can have more error trapping if you want and better logging functions.


   Script to add roles, permissions and add/remove privileges in vCenters

   This script is used to add new roles, add new permission and update (add/remove) privileges for roles already defined in vCenters. For new permissions, it will default to root folder (i.e. VC level) and propagate.

 .PARAMETER rbacxml
   XML file that contains required updates (read XML file for format)

   # Update roles in XML file
   Update-RBAC.ps1 .\rbac.xml


[string]$ScriptPath = Split-Path -Path $MyInvocation.MyCommand.Path -Parent
[string]$ScriptFile = Split-path -Path $MyInvocation.MyCommand.Path -Leaf
[string]$ScriptName = []::GetFilenameWithoutExtension($ScriptFile)
[string]$LogFileName = "$ScriptName-" + (Get-Date -Format "yyyyMMdd_HHmmss") + ".log"
[string]$LogFile = Join-Path $ScriptPath "$LogFileName"

[xml]$rbac = get-content $rbacxml ;

if ($global:defaultviservers.count -gt 0) { disconnect-viserver * -confirm:$false -force }

foreach ( $vc in $rbac.inventory.vcenters.vcenter) {
  connect-viserver $
  " ***** $($ **** " | out-file $Logfile -append

  foreach ( $role in $rbac.inventory.roles.role) {

    if ($role.action -match "addrole") {

      # Only need to add new role once
      if ((Get-virole $ -ea silentlycontinue).name -ne $ {
        "Role = $($ Adding New role"
        New-VIRole $ -ea silentlycontinue | out-null
        if ($error.count -eq 0) { "SUCCESS: Add Role = $($" | out-file $LogFile -append }
        else { "ERROR Adding New Role: Role = $($" | out-file $LogFile -append }

    # Only apply if the role is valid for this vCenter
    if (get-virole $ -server $ -ea silentlycontinue) { 

      foreach ($privilege in $role.privilege) {
        if ($role.action -match "add") {
          "Role = $($ Adding Privilege = $privilege"
          Set-VIRole -Role $ -AddPrivilege (Get-VIPrivilege -id $privilege) -ea silentlycontinue | out-null
          if ($error.count -eq 0) { "SUCCESS: Role = $($, AddPrivilege = $privilege" | out-file $LogFile -append }
          else { "ERROR Adding privilege: Role = $($, AddPrivilege = $privilege" | out-file $LogFile -append }
        elseif ($role.action -match "remove") {
          "Role = $($ Removing Privilege = $privilege"
          Set-VIRole -Role $ -RemovePrivilege (Get-VIPrivilege -id $privilege) -ea silentlycontinue | out-null
          if ($error.count -eq 0) { "SUCCESS: Role = $($, RemovePrivilege = $privilege" | out-file $LogFile -append }
          else { "ERROR Removing privilege: Role = $($, RemovePrivilege = $privilege" | out-file $LogFile -append }

 foreach ( $perm in $rbac.inventory.permissions.permission) {

   if ($perm.role) {
     "New Permission: Principal = $($perm.principal), Role = $($perm.role)"
     New-VIPermission -role $perm.role -principal $perm.principal -entity (get-folder -NoRecursion) -Propagate $true -ea SilentlyContinue | out-null
     if ($error.count -eq 0) { "SUCCESS: Permission added for: Principal = $($perm.principal), Role = $($perm.role), entity = root, propagate = true" | out-file $LogFile -append }
     else { "ERROR Adding permission: Principal = $($perm.principal), Role = $($perm.role)" | out-file $LogFile -append }

 disconnect-viserver $ -confirm:$false -force


"Please checke $Logfile for complete status"

Leave a comment

Posted by on March 12, 2015 in powershell, Scripts, vmware


Tags: ,

PowerCLI count VMs for each host in each cluster

Need to do a quick inventory of our environment and needed to get a list of clusters, ESX host and VM count per host.

Updated: Ensure that you have a stored credentials first

$cred = get-credential
Get-content .\vc.txt | % {
$vc=$_ ; connect-viserver $vc -credential $cred;
get-vmhost |
select-object name, parent, @{Name="VMCount";
Expression = {(get-vm -location $_ | measure-object).count }} |
export-csv .\$vc.txt ;
disconnect-viserver $vc –force –confirm:$false }


Leave a comment

Posted by on February 14, 2014 in powershell, Scripts, vmware