RSS .92| RSS 2.0| ATOM 0.3
  • Home

    Nutanix and Powershell – Automating Nutanix Cluster Operations

    September 3rd, 2014

    This blog post details the use of the mega awesome Nutanix Powershell cmdlets to conduct, what in essence, are one-time operations to configure a Nutanix cluster.

    We will cover operations to define DNS, NTP and SMTP servers and re-use code from a previous blog post to create a Storage Pool and Container.

    We are going to leverage the following Nutanix Powershell cmdlets:

    • get-NTNXnameServer
    • remove-NTNX-nameServer
    • add-NTNXnameServer
    • get-NTNXntpServer
    • remove-NTNXntpServer
    • add-NTNXntpServer
    • remove-NTNXsmtpServer
    • set-NTNXsmtpServer
    • get-NTNXdisk
    • new-NTNXstoragePool
    • new-NTNXcontainer
    • add-NTNXnfsDatastore
    • set-NTNXcluster

    Pretty easy really.  One option that stands out is the Nutanix Pulse verbosity level.  We can configure the following levels:

    • None
    • All
    • Basic
    • Basic-Coredump

    This defines the levels you, and Nutanix support, will receive describing platform status.

    ### [ Variable Definition ] ###
    # define DNS servers
    $nameServer1 = ""
    $nameServer2 = ""
    # define NTP servers
    $ntpServer1 = ""
    $ntpServer2 = ""
    # define SMTP settings
    $smtpServer = ""
    $smtpPort = "25"
    $smtpFromAddress = "email [at]"
    # define Storage parameters
    $storagePool = "SP1"
    $containerName = "NTNX-container001"
    # Pulse verbosity type
    $pulseLevel = "ALL"
    ### [ Main ] ###
    ## set DNS servers ##
    if( ($nameServer1.length -gt 0) -and ($nameServer2.length -gt 0) ) {
       # clean up old records
       [void](get-NTNXnameServer | remove-NTNXnameServer)
       write-host "Adding DNS servers: "$nameServer1","$nameServer2
       [void](add-NTNXnameServer -input $nameServer1)
       [void](add-NTNXnameServer -input $nameServer2)
    } else {
       write-host "Adding DNS server: "$nameServer1
       [void](add-NTNXnameServer -input $nameServer1)
    ## set NTP servers ##
    if( ($ntpServer1.length -gt 0) -and ($ntpServer2.length -gt 0) ) {
       # clean up old records
       [void](get-NTNXntpServer | remove-NTNXntpServer)
       write-host "Adding NTP servers: "$ntpServer1","$ntpServer2
       [void](add-NTNXntpServer -input $ntpServer1)
       [void](add-NTNXntpServer -input $ntpServer2)
    } else {
    write-host "Adding NTP server: "$ntpServer1
       [void](add-NTNXntpServer -input $ntpServer1)
    ## set SMTP server ##
    if( $smtpServer -gt 0) {
       #clean up old records
       write-host "Adding SMTP server: "$smtpServer
       [void](set-NTNXsmtpServer -address $smtpServer -port $smtpPort -fromEmailAddress $smtpFromAddress)
    ## create Storage ##
    $array [email protected]()
    (get-ntnxdisk) |% {
       $hardware = $_
       write-host "Adding disk "$" to the array"
       $array += $
    write-host "Creating a new storage: $storagePool"
    new-NTNXStoragePool -name $storagePool -disks $array
    write-host "Creating container: $containerName"
    new-NTNXContainer -storagepoolid $ -name $containerName
    sleep 3
    write-host "Adding container $containerName to ESXi hosts"
    add-NTNXnfsDatastore -containerName $containerName
    ## set Pulse verbosity level ##
    write-host "Setting Pulse verbosity level to: "$pulseLevel
    [void](set-NTNXcluster -supportVerbosityType $pulseLevel)

    Nutanix+Powershell – Provision a StoragePool, Container and Mount Datastore in Seconds

    August 19th, 2014

    The Nutanix platform is consistently iterating and adding quality new features with every release.

    Nutanix has released Powershell cmdlets with NOS version 4.0+.  This post will describe using said cmdlets to create a storage pool and container(s).

    A full brain dump of the Nutanix plaform can be found at the Nutanix Bible, and the data structure section in particular.

    Storage Pool

    On the storage side of the Nutanix platform, each node consists of X SSD and Y magnetic spinning disks.  Nutanix best practice states that 1, and only 1, Storage Pool be created per Nutanix cluster.  A Storage Pool encapsulates all disks on each node of the cluster.

    That being said, let’s dig in to what is required to automagically provision a storage pool and container on top!

    A requirement to create a storage pool, as described above, is to list and capture all disks available.  To do that, we leverage the get-ntnxdisk cmdlet:


    The output will be similar to:

    id : 43
    serviceVMId : 4
    lastServiceVMId : 0
    mountPath : /home/nutanix/data/stargate-storage/disks/BTTV333505WZ400HGN
    diskSize : 179289518899
    storageTierName : SSD-SATA
    storagePoolId :
    hostName : <redacted>
    cvmIpAddress : <redacted>
    clusterUuid : <redacted>
    markedForRemoval : False
    dataMigrated : False
    online : True
    diskStatus : NORMAL
    location : 1

    There will obviously be more disks.  We are looking for the value of id, and want to add them to an array:

    $array [email protected]()
    (get-NTNXdisk) |% {
       $hardware = $_
       write-host "Adding disk "$" to the array"
       $array += $

    We want to define a storage pool and container name:

    $storagePool = "SP1"
    $containerName = "NTNX-container001"

    Now let’s have some fun and create the storage pool:

    write-host "Creating a new storage pool: $storagePool"
    new-NTNXStoragePool -name $storagePool -disks $array
    # save the storagePool object for use with Container
    $newStoragePool = get-NTNXStoragePool

    At this point, if you browse to the Prism UI you will see our brand new storage pool called SP1.  You can also evaluate $newStoragePool


    In Nutanix land, a container is a logical segmentation of a Storage Pool, and is represented to the Hypervisor as a datastore.

    write-host "Creating container: $containerName"
    new-NTNXContainer -storagepoolid $ -name $containerName

    We just prepared an object that will be mounted as a datastore on the Hypervisors.  That quickly.  If you stop and think for a second, provisioning storage in a traditional three-tier architecture can take hours (creation of LUN, zoning, etc etc) and is fraught with errors.

    We are now going to mount the newly created container to the Hypervisors:

    write-host "Adding container $containerName to ESXi hosts"
    add-NTNXnfsDatastore -containerName $containerName

    Look at your VI Client.  The datastores are all mounted!  Bang!  That fast.  The Power of the Nutanix platform.


    To put it all together:

    $storagePool = "SP1"
    $containerName = "NTNX-container001"
    $array [email protected]()
    (get-ntnxdisk) |% {
       $hardware = $_
       write-host "Adding disk "$" to the array"
       $array += $
    write-host "Creating a new storage: $storagePool"
    new-NTNXStoragePool -name $storagePool -disks $array
    write-host "Creating container: $containerName"
    new-NTNXContainer -storagepoolid $ -name $containerName
    sleep 3
    write-host "Adding container $containerName to ESXi hosts"
    add-NTNXnfsDatastore -containerName $containerName

    (NOTE) I added a 3 tick sleep to make sure the new-NTNXContainer command had time to complete on the back end.

    Consuming Nutanix PrismAPI with Powershell – Display information about CVM

    March 19th, 2014

    A customer recently asked how to list the IP address of the Nutanix CVM (Controller Virtual Machine).

    I have already blogged how to consume the PrismAPI with vCenter Orchestrator.  This time we will use Powershell.

    PrismAPI exposes a whole bunch of awesome data.  In particular the /hosts/ endpoint is what we need:


    It will respond with:

    “entities”: [
    “serviceVMId”: 10,
    “name”: “NTNX-<redacted>-D”,
    “serviceVMExternalIP”: “192.168.2.”,
    “hypervisorAddress”: “192.168.2.”,

    But in reality, it will be one gigantic string/array blob.

    The following code will connect to your block, query the data and respond with the serviceVMid, CVM name, CVM IP and hypervisor IP.  Note: You will need Powershell 4.0 for the invoke-restmethod.

    Be sure to enter proper data to the <FILL THIS IN> sections.  Have fun!

    add-type @"
    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
    #declare an array to be used later
    $array = @()
    $Uri = "https://:9440/PrismGateway/services/rest/v1/hosts/"
    $username = ""
    $password = ""
    $Header = @{"Authorization" = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($username+":"+$password ))}
    $results = Invoke-RestMethod -Method Get -Uri $Uri -Headers $Header
    # grab the results of the entity section
    ($results.entities) |%{
    # set the output of the foreach to the $array var
    $array = $_
    #iterate through the array
    ($array) | %{
    write-host "`nname:"$ "`n serviceID:"$array.serviceVMid "`n externalIP:"$array.serviceVMExternalIP "`n hypervisorAddress:"$array.hypervisorAddress"`n"

    The Great Road Trip to the Cloud

    December 22nd, 2010

    Cloud computing is one of the new buzz words of the tech industry.  Everyone is jumping on the bandwagon.  The adoption of virtualization in the Enterprise has led to the rise of Cloud.  Cloud has even gone mainstream with Microsoft’s “To the Cloud” add campaign.

    I became interested in Cloud when I worked at a SaaS company.  At the time we had to graft three different environments together due to acquisition.  I started to think of a better way to standardize on an application server, Operating System and platform.  In effect we were dealing with a 3x3x3x3x3x3x3 syndrome.  We had 3 different web servers, 3 application servers, 3 operating systems, 3 database platforms, 3 SAN’s, 3 networks and 3 sets of hardware.  It was painful.

    I stumbled upon the blog of Don MacAskill from a service called SmugMug (  He wrote about his version of SkyNet to elastically extend his environment to Amazon AWS.  Needless to say it was a turning point, sort of like when I heard Led Zeppelin I for the first time.

    A Short History

    Virtualization is not new technology.  In fact, it has its roots in Mainframes.  The tech industry is a circular beast.  Central computing with dumb terminals gave way to distributed computing, client/server, and now a hybrid where data can be found on multiple hubs, and a combination of smart and dumb spokes.  The industry also realized that running a data center is not an easy task.  Running multiple data centers incurs huge expense.  Thus, the rise of co-location.  Business realized it could be a cheaper proposition to pay someone else to do some of the dirty work (space, power, cooling, physically security), all the way up to a managed service.

    Business then realized it was still booking Capital Expense (CapEx) and Operational Expense (OpEx) in the dealing with co-lo.  Servers are not being used as much as expected.  When growth hit unexpectedly, giant road blocks presented themselves in both acquiring gear fast enough, but finding space, and still staying within the original co-lo agreement.

    Virtualization nudges itself in to the equation because people realized that everything shouldn’t be focused on the application and an infrastructure that is a) expensive and b) underutilized.  If you want to focus solely on your application stack, you can now do that.  If you don’t want to go through CapEx to buy infrastructure, you can easily lease CPU time, in effect, from the cloud.


    So now you may ask yourself “what is cloud computing?”  Good question.  A good answer: It all depends on who you ask.

    I’ll give you my opinion on the state of Cloud.

    • Public
    • Private
    • Hybrid
    • SaaS
    • IaaS
    • PaaS
    • AaaS

    Public: The cloud is hosted by a third-party, somewhere on the Internet.

    Private: The cloud is hosted inside the firewalls of the business.

    Hybrid: A grafting of resources from Public and Private clouds, used to augment the infrastructure.  In short, if Public and Private are two circles in a venn diagram, their intersection is Hybrid.

    Saas: It could be argued that Software as a Service (SaaS) was the first of the new generation of infrastructure that begat cloud.  A person or business consumes a resource that is hosted, and possibly sold, by a third-party.  Twitter and Facebook and World of Warcraft all fall in to this category.  The SaaS provider usually built their own web, application and database servers, storage and network.  Most likely at great cost.  The environment may have been self-hosted, or in a co-lo.

    IaaS: I believe technology developed by VMware has led to Infrastructure as a Service (IaaS).  I know IBM, Sun and HP have been doing virtualization for years, but only on high-end gear.  VMware was the mainstream player that rammed it down everyone’s throats.  Turning cheap x86 based servers in to powerhouses.  Servers went from scale out, to scale up/scale out configurations.  We need bigger, but less.  Short provision cycles, and chargeback models all help to turn IaaS in to a business generator, and less a budget black hole.  Amazon AWS is probably the biggest player in Public Cloud IaaS.

    PaaS: PaaS provides an infrastructure as a bundled stack, where infrastructure is abstracted and is presented as a consumable resource.  It seems to me that VMware’s vCloud Director is going to allow business to provision the private cloud, and sell resources to its internal, and external customers.

    AaaS: I count the App as a Service to be a power-play by vendors.  They give application developers a fully abstracted platform, and expose certain pieces by API calls.  The users and developers on top of this platform do not care at all how the plumbing works, only that it does.  Google App Engine, Microsoft Azure and Salesforce are big players in this arena.  VMware and Red Hat are making in-roads with their latest purchases.


    The race to the cloud includes a tipping-point for business when consuming public-cloud resources becomes more expensive than building a private-cloud.  There are always use-cases for all the current cloud types I have listed.  Industry is trying to build partnerships to allow private cloud application stacks to migrate to public, and vice-versa.  The technology is not ready as of the end of 2010, but by mid-2011 I do believe we will see the beginnings of true migration paths to create Hybrid clouds to create active-active infrastructure.

    This blog post will be a living document as things change.  Stay tuned!

    PowerCLI – Generate Count of Running VM’s

    September 8th, 2010

    If you are like me, you have virtual machines in different states in your virtual environment.  Running, paused, or powered-off.  If you have ever been asked “How many VM’s do we have,” and you know the right answer is technically not what vCenter lists as total VM’s, run the following PowerCLI script:

    (get-vm )| %{
      $vm = $_
      if( get-vmguest -VM $vm.Name |where-object {$vm.State -eq &quot;Running&quot;}){
    echo $vcounter

    Let’s break down line 5, where all of the magic happens.  We are running get-vmguest on the current VM pulled from get-vm on line 3, and then determine if it’s state is “Running.”  PowerCLI and vCenter differ in how they display the state of a VM: “Running” or “Not-Running” in PowerCLI vs “Powered On” or “Powered Off” in vCenter.

    Voila, you now have the count of virtual machines that are Powered-On and theoretically doing work.

    PowerCLI – Gather Virtual Machine Network Information

    August 24th, 2010

    Mapping the virtual networking can be troublesome at times.  How often are you asked to provide MAC addresses to determine what switch port a Virtual Machine is using?  This quick PowerCLI script will walk through and display the VM name, Port Group(s), IP(s) and MAC Address.

    (get-vm) | %{
      $vm = $_
      echo $
      $vm.Guest.Nics | %{
        $vminfo = $_
        echo $vminfo.NetworkName $vminfo.IPAddress $vminfo.MacAddress

    In this example, %{ } will conduct a foreach on each virtual machine from get-vm, and then a foreach on each virtual network adapter assigned to the VM.

    PowerCLI – Physical and Virtual CPU statistics

    June 29th, 2010

    I was recently tasked with providing information regarding CPU averages across our production environment, both physical and virtual.  I know there are other PowerCLI scripts floating around, but it was a good way for me to learn more PowerShell.

    Measure-object and getting the average to show two digits was one of the harder problems to solve (along with get-vmhost $_.NumCPU not working correctly with the version of PowerCLI I had installed).  Lines 29, 31, 49 and 51 are highlighted to show the snip-its.

    It will grab the CPU stats between the days you specify (lines 13,14) from your Virtual Center server, at line 10.  It will spit out a count of your physical hosts, CPUs, Virtual Machines and vCPUs.

    # Add in the VI Toolkit goodness
    if ( (Get-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) -eq $null )
     Add-PSsnapin VMware.VimAutomation.Core
    # Connect to the vCenter server(s)
    $vcserver= @()
    $vcserver += connect-VIServer &quot;_Your VC Server_&quot;
    # define our start and finish days
    # define our silly little counters
    $pCounter = 0
    $vCounter = 0
     # print stat dates
     write-host `n --- Statistics for $startdate through $finishdate --- `n
     # ---- grab stats for Physical ----
     foreach ($esx_server in (get-vmhost))
     # grab the cpu.usage.average, days are configurable
     $pStats = (get-stat -entity $esx_server -stat cpu.usage.average -Start $startdate -Finish $finishdate | measure-object -property value -average)
     # we only want two decimal places
     $pAvg = [system.math]::round($pStats.average,2)
     write-host Physical: $ CPU-Average: $pAvg
     # increment physical counter
     # add up the total number of pCPU in cluster
     $pCPU += $esx_server.NumCPU
     write-host `nPhysical Host Count: $pCounter
     write-host Physical CPUs: $pCPU `n
     # ---- grab stats for Virtual ----
     foreach ($vm_server in (get-vm))
     #grab the cpu.usage.average, days are configurable
     $vStats = (get-stat -entity $vm_server -stat cpu.usage.average -Start $startdate -Finish $finishdate | measure-object -property value -average)
     # we only want two decimal places
     $vAvg = [system.math]::round($vStats.average,2)
     write-host Virtual: $ CPU-Average: $vAvg
     # increment virtual cointer
     # add up total number of vCPU in cluster
     $vCPU += $vm_server.NumCPU
     write-host `nVirtual Host Count: $vCounter
     write-host Virtual CPUs: $vCPU `n
    # Disconnect from the vCenter server(s)
    disconnect-viserver $vcserver -Confirm:$False
    # END

    PowerCLI – Get VMware-Tools versions

    June 22nd, 2010

    Imagine this:

    You are sitting in your cube on a Tuesday morning and your boss walks in and says: “I need all of the installed versions of VMware-Tools to report for compliance!”  Your initially reaction is probably: “really?”  And then you say, OK, I can do that.

    And here is how to do it:

    # Add in the VI Toolkit goodness
    if ( (Get-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) -eq $null )
    Add-PSsnapin VMware.VimAutomation.Core
    # Connect to the vCenter server(s)
    $vcserver= @()
    $vcserver += connect-VIServer &quot;&lt;Your vCenter Server&gt;&quot;
    # get the vmware tools version for each VM
    get-vm |% { get-view $ } | select Name, @{ Name=&quot;ToolsVersion&quot;; Expression={$}}
    # Disconnect from the vCenter server(s)
    disconnect-viserver $vcserver -Confirm:$False
    # END


    Your output will be of the form:   200000   0


    Update (3/25/2011): My colleagues found a post on the VMTN page that has to do with my script.  LucD had another idea on how to run the script that would generate so much load on vCenter.  Check it out here.

    PowerCLI Part I

    June 21st, 2010

    Microsoft did a great job with PowerShell.  I take it as 1 part BASH, 2 parts PERL, and probably a few dashes of VB (which I know no dashes).

    VMware blended up their own cmdlets for system automation and reporting.  The useage for the most part is straight-forward, but I have found a few oddities.

    For a few months, I was getting all kids of requests for information from the Management.  Off the top of my head, I can think of:

    • VMware-tools versions installed across the board
    • VM counts across clusters
    • Show VM to LUN mappings

    I leaned heavily on posts by LucD, Virtu-Al, and others, so I’ll post some things I came up with.

    Part I

    I always load in the VI Toolkit PSSnapin at the beginning of every PS1, like so:

    # Add in the VI Toolkit goodness
    if ( (Get-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) -eq $null )
    Add-PSsnapin VMware.VimAutomation.Core