{"id":697,"date":"2021-06-24T23:44:14","date_gmt":"2021-06-24T22:44:14","guid":{"rendered":"http:\/\/192.168.8.14\/?p=697"},"modified":"2021-06-24T23:44:54","modified_gmt":"2021-06-24T22:44:54","slug":"mapping-vms-to-aggregates","status":"publish","type":"post","link":"https:\/\/www.jasonstreet.com\/?p=697","title":{"rendered":"Mapping VMs to Aggregates"},"content":{"rendered":"\n<p>Recently I was in a situation where an aggregate in a multi HA pair cluster was low on space. While working to avert the impending disaster I was asked by an incident manager what VMs are on the aggregate that is low on space. Now there where alot of volumes\/LUNs on that aggregate. Stopping to do that analysis would have been bad so we didn&#8217;t. But it was a valid question.<\/p>\n\n\n\n<p>If you have your LUN names the same as your Datastore names then you could quickly(ish) get an answer. But what if you have allot of LUNs or the LUN name is not always the same name as the Datastore name.<\/p>\n\n\n\n<p>So I put this script together.  It will get all the LUNs on an aggregate and then find the VMWare datastores. then get all the VMs on those datastores.<\/p>\n\n\n\n<p>The script uses the VMWare and DataONTAP modules.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\n# import needed modules\nimport-module VMware.VimAutomation.Core\nimport-module VMware.VimAutomation.Common\nimport-module DataONTAP\n\n# FAS and vCenter locations\n$FASName = &quot;NetApp-FAS-Name or IP&quot;\n$vCenterName = &quot;vCenter URL or IP&quot;\n\n# Prompt the user for creds\n$FASCred = Get-Credential -Message &quot;NetApp FAS&quot;\n$VCSACred = Get-Credential -Message &quot;VMWare vCenter&quot;\n\n# connect to FAS and vCenter\nconnect-viserver $vCenterName -cred $VCSACred\nConnect-NcController $FASName -Credential $FASCred\n\n# used to convert the netapp sireal number to vmware NAA number\nfunction ConvertTo-HexString(&#x5B;string]$iinput)\n{\n    write-host $iinput -ForegroundColor Gray\n    &#x5B;byte&#x5B;]]$bytes = $iinput.ToCharArray()\n    $hexBytes = $bytes | % {$_.ToString(&quot;X2&quot;)}\n    $hexBytes -join &#039;&#039;\n}\n\n# get a lookup table of DS names, canonical names (naa number) \n$DSlist1 = Get-Datastore |\nSelect Name,CapacityGB,\n    @{N=&#039;CanonicalName&#039;;E={$_.ExtensionData.Info.Vmfs.Extent&#x5B;0].DiskName}},\n    @{N=&#039;LUN&#039;;E={\n        $esx = Get-View -Id $_.ExtensionData.Host&#x5B;0].Key -Property Name\n        $dev = $_.ExtensionData.Info.Vmfs.Extent&#x5B;0].DiskName\n        $esxcli = Get-EsxCli -VMHost $esx.Name -V2\n        $esxcli.storage.nmp.path.list.Invoke(@{&#039;device&#039;=$dev}).RuntimeName.Split(&#039;:&#039;)&#x5B;-1].TrimStart(&#039;L&#039;)}\n     } \n\n# display the non root aggregates\nGet-NcAggr | where{$_.name -notmatch &quot;aggr0&quot;}\n\n# prompt for the user to enter an aggregate name \n$bob = read-host &quot;enter the name of an aggregate&quot;\n\n# get the aggregate object, no user input checking (thats bad)\n$aggToList = get-ncaggr $bob\n\n# get the LUNs on the Volumes on that aggregate\n$LUNsOnAgg = get-nclun -Volume (get-ncvol -Aggregate $aggToList)\n\n$VMs = @()\n# loop through each LUN\nforeach ($LUNOnAgg in $LUNsOnAgg)\n{\n    # Get the LUN serial number and convert (Hex to ASCII) it to the NAA name in VMWare\n    $LunSN = ConvertTo-HexString $LUNOnAgg.SerialNumber\n    $DS = $DSlist1 | where{$_.CanonicalName -match $LunSN} | sort name -Unique\n\n    # get Datastore object and VMs on the Datastore\n    $DSObj = get-datastore $DS.name\n    $VMsOnDS = get-vm -Datastore $DSobj\n\n    # Loop though the VMs\n    foreach ($VMOnDS in $VMsOnDS)\n    {\n        # Create the tmp VM outpou object\n        # get the VM name, DS name, VM sizes in GB and PowerState\n        $tmpVM = &#039;&#039; | select VM,DataStore,SizeGB,PSizeGB,PowerState\n        $tmpVM.VM = $VMOnDS.name\n        $tmpVM.DataStore = $DSObj.name \n        $tmpVM.SizeGB = &#x5B;int]($VMOnDS.UsedSpaceGB)\n        $tmpVM.PSizeGB = &#x5B;int]($VMOnDS.ProvisionedSpaceGB)\n        $tmpVM.PowerState = $VMOnDS.PowerState\n\n        # Add this VM to the VMs array\n        $VMs += $tmpVM\n    }\n\n}\n$VMs | ft -AutoSize\n\n\n<\/pre><\/div>\n\n\n<p>There you go. a quick script to get VMs on an aggregate.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"435\" height=\"108\" src=\"http:\/\/192.168.8.14\/wp-content\/uploads\/2021\/06\/agg2VM-output.png\" alt=\"\" class=\"wp-image-700\" srcset=\"https:\/\/www.jasonstreet.com\/wp-content\/uploads\/2021\/06\/agg2VM-output.png 435w, https:\/\/www.jasonstreet.com\/wp-content\/uploads\/2021\/06\/agg2VM-output-300x74.png 300w\" sizes=\"auto, (max-width: 435px) 100vw, 435px\" \/><figcaption>test output showing some Tiny Lunix VMs<\/figcaption><\/figure>\n\n\n\n<p>This was knocked up quite quickly, it could use some code to check the user input (the aggregate name) and maybe a little more details of the VMs.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently I was in a situation where an aggregate in a multi HA pair cluster was low on space. While working to avert the impending disaster I was asked by an incident manager what VMs are on the aggregate that is low on space. Now there where alot of volumes\/LUNs on that aggregate. Stopping to&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[59,5,132],"tags":[146,123,144,147,60,8,145],"class_list":["post-697","post","type-post","status-publish","format-standard","hentry","category-ontap","category-powercli","category-reporting","tag-aggregate","tag-datastore","tag-lun-2","tag-mapping","tag-netapp","tag-vm","tag-volume"],"_links":{"self":[{"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/posts\/697","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=697"}],"version-history":[{"count":5,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/posts\/697\/revisions"}],"predecessor-version":[{"id":703,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/posts\/697\/revisions\/703"}],"wp:attachment":[{"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=697"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=697"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=697"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}