tag:blogger.com,1999:blog-22695163279504908472024-03-13T04:43:09.720-04:00vNuggletsLooking for virtual nugglets? Then you've come to the right place.AC (@allen_crawford)http://www.blogger.com/profile/05360032132878174436noreply@blogger.comBlogger43125tag:blogger.com,1999:blog-2269516327950490847.post-20819527836975093052019-07-31T18:31:00.000-04:002019-08-21T21:17:46.573-04:00Even More Efficient PowerShelling with PowerCLI Argument Completers!<a href="https://static.vnugglets.com/imgs/vnPSModule.png" imageanchor="1" style="clear: left; float: left; margin-right: 15px; margin-top: 5px;"><img alt="Updated vNugglets PowerShell Module!" border="0" src="https://static.vnugglets.com/imgs/vnPSModule.png" title="Updated vNugglets PowerShell Module!" /></a>
Ya-hoo -- tab-completion for several parameters' values and for many VMware PowerCLI cmdlets! We all are accustomed to being super fast on the command line by leveraging tab-completion of, well, most things: paths, cmdlet names, process names, service names, etc.. We also doit in things like editors that have IntelliSense. But, while we may also want to have that same experience with inventory objects in our virtual infrastructures, we do not yet have such capabilities.<br />
<br />
So, we here at vN took the time to hammer out some goodness for enabling tab-completion of parameter values on VMware PowerCLI cmdlets -- now we can tab-complete values of actual inventory objects in a snap!<br />
<br />
<span style="background-color: lime; font-weight: bold;">* Update 23 Aug 2019:</span><BR />
We added a Getting Started section in the Docs in the GitHub repo. See <a href="https://github.com/vNugglets/PowerShellArgumentCompleters/tree/master/docs">https://github.com/vNugglets/PowerShellArgumentCompleters/tree/master/docs</a> for such information, to get going straight away!
<br />
<span style="background-color: lime; font-weight: bold;">* end of 23 Aug 2019 update</span><BR />
What:
<br />
<ul>
<li>This comes in the form of an argument completer add script, soon to be in PowerShellGallery, and with code already at <a href="https://github.com/vNugglets/PowerShellArgumentCompleters">https://github.com/vNugglets/PowerShellArgumentCompleters</a></li>
<li>Initially, for the <span class="VN_codeFace">VMware.PowerCLI</span> module, this adds 301 tab-completion capabilities across 240+ cmdlets and a dozen different parameters</li>
</ul>
<div>
How:</div>
<ul>
<li>You register the argument completers in a PowerShell session by first importing any/all VMware PS modules you'll be using, and then running the Register-VMwarePowerCLIArgumentCompleter script from said repo above (again, this will eventaully be available in the PowerShell gallery for easier consumption/updates)</li>
</ul>
<div>
Example:</div>
<ul>
<li>The following would result in the user being able to tab through all of the completions for the given parameter after which they pressed the Tab key</li>
<ul>
<li disc="" list-style-type:=""><span class="VN_codeFace">Get-VM -Name matt<tab></span></li>
<li disc="" list-style-type:=""><span class="VN_codeFace">Get-VMHost myho<tab></span></li>
<li disc="" list-style-type:=""><span class="VN_codeFace">Get-Datastore -VM myvm0<tab></span></li>
<li disc="" list-style-type:=""><span class="VN_codeFace">Get-VDSwitch -VMHost <tab></span></li>
</ul>
</ul>
<div>
Further Reading:</div>
<ul>
<li>For more detail/background as this pertains to the <span class="VN_codeFace">VMware.PowerCLI</span> module, see the corresponding <a href="https://powercli.ideas.aha.io/ideas/PCLI-I-77">Support Natural PowerShell Interactive Behavior: tab completion</a> idea at powercli.ideas.aha.io</li>
<li>To be clear (and to acknowledge others before): others have written about such things on small scale (adding tab-completion for the <span class="VN_codeFace">-Name</span> parameter for something like <span class="VN_codeFace">Get-VM</span>, for example), but this current goodness is an effort to add far more tab-completions to some of our favorite modules</li>
<li>and, for when you want to <span class="VN_codeFace">Get-ArgumentCompleter</span>, Chris Dent made the excellent (and deep) <span class="VN_codeFace">Get-ArgumentCompleter.ps1</span> script with which we can see the registered argument completers in our PowerShell session. See his GitHub gist at <a href="https://gist.github.com/indented-automation/26c637fb530c4b168e62c72582534f5b">https://gist.github.com/indented-automation/26c637fb530c4b168e62c72582534f5b</a></li>
</ul>
<div>
Time to get tabbin'! And, for when you have stellar ideas for more completers, either let us know, or collaborate with us on GitHub -- we'll make great things together!</div>
MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com0tag:blogger.com,1999:blog-2269516327950490847.post-58533793741054710432018-07-15T15:08:00.000-04:002018-07-15T15:12:29.428-04:00Updated vNugglets.VDNetworking PowerShell module<a href="http://static.vnugglets.com/imgs/vnPSModule.png" imageanchor="1" style="clear: left; float: left; margin-right: 15px; margin-top: 5px;"><img alt="Updated vNugglets PowerShell Module!" border="0" src="http://static.vnugglets.com/imgs/vnPSModule.png" title="Updated vNugglets PowerShell Module!" /></a>Hurray -- the <span class="VN_codeFace">vNugglets.VDNetworking</span> PowerShell module is now updated (with updates available on the PowerShellGallery)! This module has cmdlets for helping manage your VMware virtual distributed networking infrastructure, like reporting on and configuring traffic filtering/marking configurations. The <a href="https://github.com/vNugglets/vNuggletsPSMod_vDNetworking/blob/master/ChangeLog.md">ChangeLog</a> has all of the juicy details, but the big news with this update:<br />
<br />
The <span class="VN_codeFace">Set-VNVMHostNetworkAdapterVDUplink</span> cmdlet provides the ability to manage the VDSwitch Uplink for a VMHost physical NIC ("VMNIC") on the VDSwitch of which the VMNIC is already a part -- finally! (this is not yet available in a native cmdlet in PowerCLI, but I'm sure that VMware has it on their list).<br />
<br />
The copious <a href="https://vnugglets.github.io/vNuggletsPSMod_vDNetworking/examples.html">examples</a> show all kinds of ways to use this module. Grab the module from the PowerShellGallery with the standard<br />
<span class="VN_codeFace">Find-Module vNugglets.VDNetworking | Install-Module</span><br />
that we all know and love (or, use <span class="VN_codeFace">Update-Module</span> instead of <span class="VN_codeFace">Install-Module</span> to update a previously installed version to current, of course).<br />
<br />
Enjoy!MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com0tag:blogger.com,1999:blog-2269516327950490847.post-9466543250113729442018-07-15T15:05:00.000-04:002018-07-15T15:05:54.012-04:00Updated DRSRule PowerShell module, now on PSGallery!A quick blurb on the DRSRule PowerShell module for managing VMware DRS rules via PowerShell/PowerCLI: the module is updated with several bugfixes and enhancements.<br />
<br />
Possibly as exciting of news: the module is now available on the official PowerShellGallery, so it is a snap to install/update the module on your machine!<br />
<br />
As with any module on the PowerShellGallery, you save the module with the <span class="VN_codeFace">Save-Module</span> cmdlet (so that you can inspect the code and ensure that things are good -- security first!). And, you install the module with the <span class="VN_codeFace">Install-Module</span> cmdlet.<br />
<br />
The straightforward and memorable instructions for saving- and/or installation of a module are available by default on each module's Gallery page. For this module, see <a href="https://www.powershellgallery.com/packages/DRSRule">https://www.powershellgallery.com/packages/DRSRule</a>.<br />
<br />
Enjoy!MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com0tag:blogger.com,1999:blog-2269516327950490847.post-74430029761221874202017-06-18T21:03:00.000-04:002017-06-18T21:04:55.630-04:00Updated vNugglets.Utility PowerShell module: v1.2!<a href="http://static.vnugglets.com/imgs/vnPSModule.png" imageanchor="1" style="clear: left; float: left; margin-right: 15px; margin-top: 5px;"><img alt="Updated vNugglets PowerShell Module!" border="0" src="http://static.vnugglets.com/imgs/vnPSModule.png" title="Updated vNugglets PowerShell Module!" /></a>Quick post about some great news -- we have updated the vNugglets.Utility PowerShell module, improving speed, flexibility, and usability of some functions! Additionally, the module is now available in the PowerShell Gallery -- hurray!<br />
<br />
As for the easier means by which to get the module: now you can grab
the vNugglets.Utility module in the same way that you get everything
else from the PowerShell Gallery. You save the module with the <span class="VN_codeFace">Save-Module</span> cmdlet (so that you can inspect the code and ensure that things are good -- security first!). And, you install the module with the, you guessed it, the <span class="VN_codeFace">Install-Module</span> cmdlet. Also, you can see the straightforward instructions for this saving- and installation of the module at <a href="https://www.powershellgallery.com/packages/vNugglets.Utility">https://www.powershellgallery.com/packages/vNugglets.Utility</a>.<br />
<br />
And, the details about the updates in the latest version are chronicled in the <a href="https://github.com/vNugglets/vNuggletsPSMod/blob/master/ChangeLog.md">ChangeLog</a> (which is in the module's repo at the vNugglets GitHub project <a href="https://github.com/vNugglets/vNuggletsPSMod">vNuggletsPSMod</a>). Enjoy the new goodness, and, as always, let us know how it can be better (or, collaborate with us on GitHub)!<br />
<br />MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com0tag:blogger.com,1999:blog-2269516327950490847.post-13713495939831211212016-12-05T20:59:00.001-05:002016-12-05T21:15:14.431-05:00vNugglets PowerShell module release!<a href="http://static.vnugglets.com/imgs/vnPSModule.png" imageanchor="1" style="clear: left; float: left; margin-right: 15px; margin-top: 5px;"><img alt="vNugglets PowerShell Module!" border="0" src="http://static.vnugglets.com/imgs/vnPSModule.png" title="vNugglets PowerShell Module!" /></a>While we have amassed a healthy stack of useful, VMware vSphere-related functions and code snippets here at vNugglets, the code management/interaction can certainly become tedious in more than one way: consumption of the snippets is not the most straight forward, finding snippets/functions is a bit tedious, maintenance and updates to code does not necessarily show when the code is in some older post.<br />
<br />
So, why not make what the people want: a vNugglets PowerShell module? Why not indeed. So, we did. This initial module release not only focused on function-ifying snippets, standardizing parameters, fleshing out comment-based help (many of the hallmarks of a legitimate PowerShell module), but also set about improving on several of the vNugglets snippets/functions from across the years -- hurray! It also captured ideas on several improvements to make in the near future.<br />
<br />
For now the module will live at the vNugglets GitHub project <a href="https://github.com/vNugglets/vNuggletsPSMod">vNuggletsPSMod</a>. It has all kinds of informative supporting docs, like the <a href="https://github.com/vNugglets/vNuggletsPSMod/blob/master/ReadMe.md">ReadMe</a> (with a QuickStart section) and the <a href="https://github.com/vNugglets/vNuggletsPSMod/blob/master/ChangeLog.md">ChangeLog</a>, that will fill you in on all of the nitty-gritty details.
<br />
<h4>
Examples</h4>
We also made a <a href="https://vnugglets.github.io/vNuggletsPSMod">vNugglets.Utility Example page</a> so that you can see straight away what are some of the exciting capabilities of this module.<br />
<br />
As for getting the module itself, check out the <a href="https://github.com/vNugglets/vNuggletsPSMod/releases">vNuggletsPSMod Releases</a> page, which has the .zip file of just the PowerShell module (see the QuickStart mentioned above for getting started with the module). The future fate of the module may be that it is housed in the PowerShell Gallery, but we have not invested the time to work on that just yet.<br />
<br />
So check out the docs, grab the module, and let the good times roll with a newly born module that will surely be near and dear to all of our hearts. And, now that we have the project on GitHub, please feel free to help us out in making it even mo better!<br />
<br />
MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com0tag:blogger.com,1999:blog-2269516327950490847.post-88694841493931069272016-11-16T18:24:00.002-05:002017-08-08T20:27:18.526-04:00Updated PowerShell Module for Sortable HTML Reporting -- NewHtmlReport v1.2<div class="separator" style="clear: both; margin-top: 10px; text-align: center;">
<a href="http://static.vnugglets.com/imgs/NewHtmlReport_snippet.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="NewHtmlReport Snippet" src="http://static.vnugglets.com/imgs/NewHtmlReport_snippet.png" style="border: 1px solid rgb(204, 204, 204);" title="NewHtmlReport Snippet" /></a></div>
Great news -- we've updated the NewHtmlReport PowerShell module -- v1.2! Refresher: this is a module to "easily create functional, somewhat styled HTML reports from data, providing additional functionality to what the base <span class="VN_codeFace">ConvertTo-Html</span> cmdlet provides".<br />
<br />
The <a href="https://github.com/mtboren/NewHtmlReport">NewHtmlReport GitHub repo</a> has the whole project, and the <a href="https://github.com/mtboren/NewHtmlReport/releases">Releases page</a> has the link to the .zip file with just the PowerShell module code itself.<br />
<br />
The module is now a bit more modern, as we have added things like:<br />
<ul>
<li>support for accepting objects from pipeline in the <span class="VN_codeFace">New-HtmlReport</span> function</li>
<li>cmdlet-based module configuration </li>
<li>JSON-based module configuration storage</li>
<li>CDN-based resource usage for the jQuery and TableSorter JS libraries by default, for ease of "getting up and going" right out of the box</li>
</ul>
The are some examples of the output up at the GitHub Pages page for this repository at <a href="http://mtboren.github.io/NewHtmlReport/">http://mtboren.github.io/NewHtmlReport/</a>.<br />
<br />
Also, the <a href="https://github.com/mtboren/NewHtmlReport/blob/master/readme.md">ReadMe</a> has good info about the module, including the Quick Start steps, and the <a href="https://github.com/mtboren/NewHtmlReport/blob/master/changelog.md">ChangeLog</a> has more detail on what things changed and how.<br />
<br />
Enjoy!MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com0tag:blogger.com,1999:blog-2269516327950490847.post-37485923957555491872016-01-12T20:55:00.000-05:002016-01-12T20:55:19.253-05:00XtremIO PowerShell Module Updated -- v0.9.5 available<a href="http://static.vnugglets.com/imgs/xioPlusPShellIcon.png" imageanchor="1" style="clear: left; float: left; margin-right: 25px; margin-top: 5px;"><img alt="XtremIO + PowerShell!" border="0" src="http://static.vnugglets.com/imgs/xioPlusPShellIcon.png" title="XtremIO + PowerShell!" /></a>Even more updates and improvements! Version 0.9.5 of the XtremIO.Utils PowerShell module is now available at <a href="https://github.com/mtboren/XtremIO.Utils/releases">https://github.com/mtboren/XtremIO.Utils/releases</a> (starting with the 0.8.x line, this module has been on GitHub). There are a vast number of update, improvements, bugfixes, and even some new features in this release. From supporting several improvements that came in v2 of the XtremIO REST API (which help with cmdlet speed) to further standardization in the object model (property-availability across types) to now having the somewhat overdue <span class="VN_codeFace">New-XIOSnapshot</span> cmdlet (supporting new snapshots in the XIOS v2 API). See the <a href="https://github.com/mtboren/XtremIO.Utils/blob/master/changelog.md">changelog</a> for the exciting details.<br />
<br />
Oh, and, while the cmdlets all have built-in help with examples (like every cmdlet should), there is now a GitHub Pages page with a whole slew of examples with output. See <a href="https://mtboren.github.io/XtremIO.Utils/">https://mtboren.github.io/XtremIO.Utils/</a> for a load of such examples. The <a href="https://github.com/mtboren/XtremIO.Utils/blob/master/readme.md">readme</a> has a link to that page, but sometimes people don't read the <a href="https://github.com/mtboren/XtremIO.Utils/blob/master/readme.md">readme</a>. Yes, really.<br />
<br />
While you've probably already gone to the <a href="https://github.com/mtboren/XtremIO.Utils/blob/master/changelog.md">changelog</a> to see all of the gorey details, one other tidbit about this version: the amount of change in this release probably warranted incrementing the "minor" version number of the module, but "0.10.0" seems odd, and it's not time for v1.0 yet. So, v0.9.5 it is. Enjoy!MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com1tag:blogger.com,1999:blog-2269516327950490847.post-88470738764717718522015-12-13T20:02:00.002-05:002015-12-13T20:02:44.028-05:00New PowerShell Module for Sortable HTML Reporting -- NewHtmlReportA couple of years ago, after wanting to make some HTML reports to present tabular data that included a bit of style and interactivity, we created a PowerShell module for such things. While there are some posts/scripts on the web that address this need in various ways, we wanted an easy to use, straight forward, flexible way.<br />
<br />
Now we've added a GitHub repository to house this <a href="https://github.com/mtboren/NewHtmlReport">NewHtmlReport Powershell module project</a>. The module uses many of the features of <span class="VN_codeFace">ConvertTo-Html</span>, but goes further by adding things like:<br />
<ul>
<li><a href="https://jquery.com/">jQuery</a> and <a href="http://tablesorter.com/">TableSorter</a> support for HTML tables</li>
<li>centralized style and script configuration, for uniform results across reports</li>
<li>"hightlighting" of rows' values (to bring focus to rows whose values might be of concern, like a datastore usage value that is over a desired threshold)</li>
<li>number formatting so as to make report generation even quicker and easier (you can pass your raw data in, and the cmdlets can handle rounding for you)</li>
</ul>
The are some examples of the output up at the <a href="https://pages.github.com/">GitHub Pages</a> page for this repository at <a href="http://mtboren.github.io/NewHtmlReport/">http://mtboren.github.io/NewHtmlReport/</a>.<br />
<br />
Also, check out the <a href="https://github.com/mtboren/NewHtmlReport/blob/master/readme.md">ReadMe</a> and the <a href="https://github.com/mtboren/NewHtmlReport/blob/master/NewHtmlReport/en-us/about_NewHtmlReport.help.txt">help</a> at the GitHub repo. And, for the next feature/fix that you desire: fork it!MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com1tag:blogger.com,1999:blog-2269516327950490847.post-78327059848813903742015-11-15T20:13:00.000-05:002015-11-15T20:13:08.414-05:00XtremIO PowerShell Module Updated and on GitHub -- v0.9.0 available<a href="http://static.vnugglets.com/imgs/xioPlusPShellIcon.png" imageanchor="1" style="clear: left; float: left; margin-right: 25px; margin-top: 5px;"><img alt="XtremIO + PowerShell!" border="0" src="http://static.vnugglets.com/imgs/xioPlusPShellIcon.png" title="XtremIO + PowerShell!" /></a>Updates and improvements! Version 0.9.0 of the XtremIO.Utils PowerShell module is now available at <a href="https://github.com/mtboren/XtremIO.Utils/releases">https://github.com/mtboren/XtremIO.Utils/releases</a> (starting with the 0.8.x line, this module has been on GitHub). The main focus of version 0.9.0: providing support for the new object types that came with the XIOS v4 release and its extended API. See the <a href="https://github.com/mtboren/XtremIO.Utils/blob/master/changelog.md">changelog</a> for the exciting details. <br />
<br />
And, if you missed it, the previous v0.8.x releases focused on implementing some PowerShell-y features/functionality, with some great strides in pipelining capabilities of several of the cmdlets.<br />
<br />
Note about the changelog and whatnot: we will be using GitHub as the official home for the module's code, and, so, the changelog available there will be the authoritative source, instead of the copies that we previously hosted at vNugglets.com. The module's <a href="http://www.vnugglets.com/2014/11/xtremioutils-powershell-module-general.html">general info page</a> here at vNugglets now holds links to this new home.MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com0tag:blogger.com,1999:blog-2269516327950490847.post-5456483745588716322015-01-22T10:00:00.000-05:002015-01-22T17:27:49.463-05:00DRSRule - New PowerShell Module for DRS Rule and Group Management<div class="separator" style="clear: both; margin-top: 10px; text-align: center;">
<a href="http://static.vnugglets.com/imgs/DrsGroupAndRuleSnippet.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="DRS Things" src="http://static.vnugglets.com/imgs/DrsGroupAndRuleSnippet.png" style="border: 1px solid rgb(204, 204, 204);" title="DRS Things" /></a></div>
There's a new PowerShell module out, and it is for handling your DRS rule- and group needs! "Hello, DRS rule/group export and import? It's me, the new DRSRule module!" The "why" and the "hows" about the module are further below in this post. <br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><vNugglets_note></span> I got to work with the PowerCLI master, <a href="https://twitter.com/LucD22">Luc Dekens</a>, on this module -- what a treat! (Check out his post about the new module at <a href="http://lucd.info/drsrule-drs-rules-and-groups-module" target="_blank">http://lucd.info/drsrule-drs-<wbr></wbr>rules-and-groups-module</a>) It was a great learning experience for me, not only on the PowerShell/PowerCLI tip, but also on topics like collaborative/concurrent development, GitHub features (organizations, releases, etc.), and more.<br />
<br />
The cmdlets from the module are solid as one would expect: pipeline support, value by object or name, WhatIf support, and so on. As for using some of the cool features of PowerShell, the module includes things like advanced/custom type support (including enabling tab-completion of properties later in the pipeline; handy), XML-based external help as manufactured by <a href="https://pscmdlethelpeditor.codeplex.com/">https://pscmdlethelpeditor.codeplex.com/</a>, and leveraging other object storage formats so as to simplify handling/export/import of rich objects (via JSON) -- just a few of the great features/bonuses by Mr. Dekens. <span style="font-family: "Courier New",Courier,monospace;"></vNugglets_note></span><br />
<br />
Now, more about the module.<br />
<h2>
Why the DRSRule module?</h2>
The core PowerCLI PSSnapin from VMware allows for many of the DRS rule operations that one might want to perform. There have been questions over the years in the VMware Communities PowerCLI forum about how to export DRS rules and groups, and, on how to then import such items.<br />
<br />
While there are several posts on the web about how to get/export such things, importing/recreating DRS rules/groups from such exported data has not received much focus. This was the spark for this DRSRule module: to allow for easy export/import of such rules/groups. As part of making a module to handle these actions, other cmdlets were born, like the Get-/New-/Remove-/Set-* cmdlet sets for DRS VM groups and VMHost groups, along with sets for DRS VM to VM rules and VM to VMHost rules.<br />
<br />
<h2>
How to use the DRSRule module?</h2>
The DRSRule module comes with an <a href="https://raw.githubusercontent.com/PowerCLIGoodies/DRSRule/master/About_DRSRule.help.txt"><b>about_DRSRule</b></a>.
<br />
Once the module is installed, use that help topic to get a general introduction to the use of the DRSRule module:<br />
<span class="VN_codeFace">Get-Help about_DRSRule</span><br />
<br />
<h2>
How to get the DRSRule module?</h2>
The source for this PowerShell module is hosted on <a href="http://github.com/">GitHub.com</a>.
<br />
The repository is managed by the GitHub organization "<a href="http://github.com/PowerCLIGoodies" target="_blank">PowerCLIGoodies</a>", and the repo itself is at <a href="https://github.com/PowerCLIGoodies/DRSRule">https://github.com/PowerCLIGoodies/DRSRule</a>.<br />
<br />
There are a few ways to get the module, and use it in your PowerShell session:<br />
<ol start="0">
<h3>
Automated</h3>
<b>Via a script</b><br />Use a PowerShell script to perform the download and the extract.
<br />The script is included in the repository as file <a href="https://raw.githubusercontent.com/PowerCLIGoodies/DRSRule/master/DownloadLatest.ps1" target="_blank">DownloadLatest.ps1</a>. <br /><br /><b>Via PsGet</b><br />
If you have the <a href="http://psget.net/" target="_blank">PsGet</a> module loaded in your PowerShell session, then installing this DRSRule module is as simple as updating PsGet and then installing DRSRule:<br />
<span class="VN_codeFace">Update-Module -Verbose -Module PsGet<br />Install-Module DRSRule</span><br />
<h3>
Manual</h3>
Grab the .zip file of the <a href="https://github.com/PowerCLIGoodies/DRSRule/releases/download/Latest/DRSRule.zip" target="_blank">latest release</a> from the GitHub repository.<br />
Extract the content to a suitable folder.
<br /><br />You can go for the Modules folder linked to the Windows account you are using. To find this path, run:<br /><span class="VN_codeFace">Join-Path ${env:\userprofile} "Documents\WindowsPowerShell\Modules"</span>
<br /><br />Or, you can select any other folder you desire.<br /><br />
Either way you will end up with a folder named <span class="VN_codeFace">[PathToModule]\DRSRule</span>, in which the PowerShell files for the DRSRule module reside.
<br />
<br />Then, load the DRSRule module into your session:<br />If you selected one of the folders in <span class="VN_codeFace">$env:PSModulePath</span> (your PSModule path), you can do this with
<br /><span class="VN_codeFace">Import-Module DRSRule</span>
<br /><br />If you picked another folder, you should use the full path to the folder that contains the module's files, like:<br /><span class="VN_codeFace">Import-Module [PathToModule]\DRSRule</span>
<br />
<br />Please also read the note below about using <span class="VN_codeFace">Unblock-File</span>, since this module is not Authenticode signed</ol>
<br />
<h2>
Note on Unblock-File</h2>
This section pertains to using the Manual method above to get the DRSRule module (downloading .zip file). Since there is no Authenticode certificate supplied for this module, and, assuming that one's PowerShell ExecutionPolicy is at least RemoteSigned, below is a quick/easy
way to unblock files. But, this should only be done when you
trust the code in the files that you are unblocking -- inspecting the
files is for your own good.<br />
<span class="VN_codeFace">Get-ChildItem [PathToModule]\DRSRule | Unblock-File</span><br />
<br />MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com12tag:blogger.com,1999:blog-2269516327950490847.post-24435001955036542712014-12-06T19:53:00.002-05:002014-12-08T20:48:41.641-05:00Get VMs' Current EVC Mode via PowerCLI<div class="separator" style="clear: both; text-align: center;">
<a href="http://static.vnugglets.com/imgs/evcmodeSnippet.png" imageanchor="1" style="clear: right; float: right; margin-left: 15px; margin-top: 5px; margin-bottom: 0px"><img alt="EVC Mode" src="http://static.vnugglets.com/imgs/evcmodeSnippet.png" style="border: 1px solid rgb(204, 204, 204);" title="EVC Mode" /></a></div>
Need to report on what is the current EVC mode in which some VMs are running? We recently did, and out popped a bit of PowerShell/PowerCLI code to do it, of course.
<span style="clear: both; display: block;">As part of some migrations and retirements, we were moving VMs from clusters at one EVC mode (lower) to clusters with higher- or no EVC mode, but were not scheduling power-cycles for the VMs at migration time, so as to keep smaller the scope of work for that event. Rather than have to keep track of "here are the X number of VMs that are at EVC mode [low]", which would need power-cycled at some later date to bring them up to the EVC mode of their new cluster, PowerCLI is there for us.</span>
<br />
It is pretty straightforward, but is handy for identifying those VMs that are, say, at a different EVC mode than is configured on the cluster. So, the code:<br />
<pre class="brush: powershell" title="'Get-VMEVCMode':">function Get-VMEVCMode {
<# .Description
Code to get VMs' EVC mode and that of the cluster in which the VMs reside. May 2014, vNugglets.com
.Example
Get-VMEVCMode -Cluster myCluster | ?{$_.VMEVCMode -ne $_.ClusterEVCMode}
Get all VMs in given clusters and return, for each, an object with the VM's- and its cluster's EVC mode, if any
.Outputs
PSCustomObject
#>
param(
## Cluster name pattern (regex) to use for getting the clusters whose VMs to get
[string]$Cluster_str = ".+"
)
process {
## get the matching cluster View objects
Get-View -ViewType ClusterComputeResource -Property Name,Summary -Filter @{"Name" = $Cluster_str} | Foreach-Object {
$viewThisCluster = $_
## get the VMs Views in this cluster
Get-View -ViewType VirtualMachine -Property Name,Runtime.PowerState,Summary.Runtime.MinRequiredEVCModeKey -SearchRoot $viewThisCluster.MoRef | Foreach-Object {
## create new PSObject with some nice info
New-Object -Type PSObject -Property ([ordered]@{
Name = $_.Name
PowerState = $_.Runtime.PowerState
VMEVCMode = $_.Summary.Runtime.MinRequiredEVCModeKey
ClusterEVCMode = $viewThisCluster.Summary.CurrentEVCModeKey
ClusterName = $viewThisCluster.Name
})
} ## end foreach-object
} ## end foreach-object
} ## end process
} ## end function
</pre>
<br />
And, some examples: Get EVC mode info for all of the VMs in this cluster:<br />
<pre class="PowershellSession">PS vN:\> Get-VMEVCMode -Cluster myCluster
Name PowerState VMEVCMode ClusterEVCMode ClusterName
---- ---------- --------- -------------- -----------
somesvr01.dom.com poweredOn intel-westmere intel-westmere OurCluster
somesvrlm1.dom.com poweredOn intel-penryn intel-westmere OurCluster
somesvrbs03.dom.com poweredOff intel-westmere OurCluster
somesvrxp.dom.com poweredOn intel-penryn intel-westmere OurCluster
...
</pre>
<br />
For all of the VMs in this cluster where their EVC mode does not match the config'd cluster EVC mode, return their info:<br />
<pre class="PowershellSession">PS vN:\> Get-VMEVCMode -Cluster myCluster | ?{($_.VMEVCMode -ne $_.ClusterEVCMode) -and ($_.PowerState -eq "poweredOn")}
Name PowerState VMEVCMode ClusterEVCMode ClusterName
---- ---------- --------- -------------- -----------
somesvrlm1.dom.com poweredOn intel-penryn intel-westmere OurCluster
somesvrp83.dom.com poweredOn intel-penryn intel-westmere OurCluster
somesvra.dom.com poweredOn intel-merom intel-westmere OurCluster
...
</pre>
<br />
<b>Note:</b> The function does expect that you are using at least PowerShell v3, which surely everyone is well beyond by now, anyway. But, if not, the "[ordered]" cast should be the only thing one would need to take out in order to use in older PowerShell versions.<br />
<br />
Straightforward, and uses everyone's favorite PowerCLI cmdlet, <span class="VN_codeFace">Get-View</span>, so you know that it is FaF! Enjoy.<BR /><BR />MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com0tag:blogger.com,1999:blog-2269516327950490847.post-8615262102343279052014-11-30T19:27:00.003-05:002023-07-23T15:46:43.561-04:00XtremIO PowerShell Module Updated -- v0.7.0 available<a href="http://static.vnugglets.com/imgs/xioPlusPShellIcon.png" imageanchor="1" style="clear: left; float: left; margin-right: 25px; margin-top: 5px;"><img alt="XtremIO + PowerShell!" border="0" src="http://static.vnugglets.com/imgs/xioPlusPShellIcon.png" title="XtremIO + PowerShell!" /></a>Even more updates! Version 0.7.0 of the XtremIO.Utils PowerShell module is now available. This release brings some great new features, like superior handling of credentials (via new <span class="VN_codeFace">Connect-XIOServer</span> and <span class="VN_codeFace">Disconnect-XIOServer</span> cmdlets), the rest of the <span class="VN_codeFace">New-XIO*</span> cmdlets for creating items in the XtremIO configuration, and new performance-related cmdlets for focusing in on XtremIO performance reporting from several different aspects.<br />
<br />
<span style="clear: both; display: block;">You can read about the new features available in each updated release in the docs in the repo at <a href="https://github.com/mtboren/XtremIO.Utils">https://github.com/mtboren/XtremIO.Utils</a>. We have also made a new <a href="http://www.vnugglets.com/2014/11/xtremioutils-powershell-module-general.html" target="_blank">general information page</a> for this PowerShell module (like how to get it, how to install it, credentials handling). One can find this info page in the Sticky Posts section at the right, too. Or, if you just want at the module immediately, you can download it from <a href="https://github.com/mtboren/XtremIO.Utils/releases/download/Latest/XtremIO.Utils.zip">https://github.com/mtboren/XtremIO.Utils/releases/download/Latest/XtremIO.Utils.zip</a>.</span><br />
Once you have read those items, let us get to some examples!<br />
<br />
<b>Connect to a couple of XMS servers:</b>
<br />
<pre class="PowershellSession">PS vN:\> Connect-XIOServer -Credential $credMe -ComputerName somexms01.dom.com,somexms02.dom.com -TrustAllCert
ComputerName ConnectDatetime Port
------------ --------------- ----
somexms01.dom.com 11/30/2014 1:54:02 PM 443
somexms02.dom.com 11/30/2014 1:54:02 PM 443
</pre>
Note: this allows for the rest of the subsequent XIO cmdlet calls to be used without presenting credentials again to the cmdlet -- the cmdlets will use the given XIO connection(s) and corresponding connection credentials! Yes, that also means that you need not supply the XMS name each subsequent call: the default, connected XMS servers will be used, unless otherwise specified by the user.<br />
<br />
<b>Get the cluster performance information for all XIO clusters managed by the XMS servers:</b>
<br />
<pre class="PowershellSession">PS vN:\> Get-XIOClusterPerformance
Name WriteBW_MBps WriteIOPS ReadBW_MBps ReadIOPS BW_MBps IOPS TotWriteIOs TotReadIOs
---- ------------ --------- ----------- -------- ------- ---- ----------- ----------
somexms01 6.057 771 41.768 531 47.824 1302 4664182545 3886061537
somexms02 67.480 2783 238.808 5286 306.288 8069 31163303937 81948491968
</pre>
<b>Create a new initiator in initiator group "myserver0" on array managed by "somexms02":</b>
<br />
<pre class="PowershellSession">PS vN:\> New-XIOInitiator -Name myserver0-hba2 -InitiatorGroup myserver0 -PortAddress 0x100000000000ab56 -ComputerName somexms02.dom.com
Name PortAddress PortType IOPS
---- ----------- -------- ----
myserver0-hba2 10:00:00:00:00:00:ab:56 fc 0
</pre>
<b>Create a new LUN maps on array managed by "somexms02":</b>
<br />
<pre class="PowershellSession">PS vN:\> New-XIOLunMap -Volume myVolume02 -InitiatorGroup myserver0,myserver1 -HostLunId 50 -ComputerName somexms02.dom.com
VolumeName LunId InitiatorGroup tg-name
---------- ----- -------------- -------
myVolume02 50 myserver0 Default
myVolume02 50 myserver1 Default
</pre>
<b>A couple of Get-XIOEvent examples:</b>
<br />
<pre class="PowershellSession">PS vN:\> Get-XIOEvent
EventID DateTime Severity EntityDetails Description
------- -------- -------- ------------- -----------
2267 11/30/2014 10:39:29 PM information myVolume02 [1] Mapped LUN 50 to Volume myVolume02 TG Defa...
2266 11/30/2014 10:39:29 PM information User: vNuggsUser, Command: maplun, Argumen...
...
27672 11/30/2014 1:37:41 PM information someVolume03 Small block (blocks smaller than 4KB) IO r...
27671 11/30/2014 1:17:05 PM information External user 'vNuggsUser' authenticated w...
...
PS vN:\> Get-XIOEvent -Category activity -Severity information -EntityType BatteryBackupUnit -Start "11 oct 2014" -End "14 nov 2014 8am"
EventID DateTime Severity EntityDetails Description
------- -------- -------- ------------- -----------
195 11/11/2014 9:29:30 PM information X2-BBU [2] Added new Battery Backup Unit - UPS[2] "X2-BB...
193 11/11/2014 9:29:30 PM information X1-BBU [1] Added new Battery Backup Unit - UPS[1] "X1-BB...
</pre>
While it was quite a bit of doing to make this release happen, the new features are well worth it, and it was quite fun along the way. Now to keep the creativity flowing: on to the next update, in which better pipeline support is one of the targets. Until then, enjoy!
<br />
<br />MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com4tag:blogger.com,1999:blog-2269516327950490847.post-4709483737831884122014-11-30T19:15:00.002-05:002015-11-15T19:39:45.466-05:00XtremIO.Utils PowerShell Module General Info<a href="http://static.vnugglets.com/imgs/xioPlusPShellIcon.png" imageanchor="1" style="clear: left; float: left; margin-right: 25px; margin-top: 5px;"><img alt="XtremIO + PowerShell!" border="0" src="http://static.vnugglets.com/imgs/xioPlusPShellIcon.png" title="XtremIO + PowerShell!" /></a>Herein lies much of the supporting/side information about this PowerShell module that has been written throughout the related vNugglets posts. The intention, however, is to create this more central spot for this info, instead of people having to sift through the previous posts to get all of these tidbits. To read about the latest additions and changes, one can refer to the <a href="https://github.com/mtboren/XtremIO.Utils/blob/Latest/changelog.md">change log</a> and the <a href="https://github.com/mtboren/XtremIO.Utils/blob/Latest/readme.md">ReadMe</a> (which are available in the module itself, too).<br />
<span style="background-color: lime; font-weight: bold;">* Update 15 Nov 2015:</span><br />
Updated links to changelog and readme to be to GitHub, as well as the link to the PowerShell module itself<br />
<span style="background-color: lime; font-weight: bold;">* end of 15 Nov 2015 update</span><br />
<h3>
Module availability:</h3>
One can get the XtremIO.Utils module in a couple of ways:
<br />
<ul>
<li>
via the supercool module <a href="http://psget.net/" target="_blank">PsGet</a>, so installing/updating the module becomes a snap for PsGet module users. The quick how-to on using PsGet to install the XtremIO.Utils module:<br />
<pre class="PowershellSession">PS vN:\> Install-Module -Verbose -Module XtremIO.Utils
</pre>
Or, to update the existing version you may already have:
<br />
<pre class="PowershellSession">PS vN:\> Update-Module -Verbose -Module XtremIO.Utils
</pre>
</li>
<li>
Or, if you like the "old fashioned" module management route (of manually handling the module grab), you can always follow the steps:
<ol start="0">
<li>download from <a href="https://github.com/mtboren/XtremIO.Utils/releases/download/Latest/XtremIO.Utils.zip"><img alt="latest and greatest!" border="0" src="http://static.vnugglets.com/imgs/zipfileicon0.png" title="latest and greatest!" /></a> <a href="https://github.com/mtboren/XtremIO.Utils/releases/download/Latest/XtremIO.Utils.zip">https://github.com/mtboren/XtremIO.Utils/releases/download/Latest/XtremIO.Utils.zip</a></li>
<li>unzip somewhere you like (like, say, in <span class="VN_codeFace">Join-Path ${env:\userprofile} "Documents\WindowsPowerShell\Modules"</span>)</li>
<li>you should now have a folder named <span class="VN_codeFace"><pathToModules>\XtremIO.Utils</span>, in which the PowerShell files reside (see note below about using <span class="VN_codeFace">Unblock-File</span>, since this module is not yet Authenticode signed)</li>
<li><span class="VN_codeFace">Import-Module <pathToModules>\XtremIO.Utils</span></li>
</ol>
</li>
</ul>
<br />
<h3>
<span class="VN_codeFace">Unblock-File</span> discussion:</h3>
One of the other "features" of this module: we have not yet set the Authenticode signature for it. That is, it is unsigned. We went back and forth on the solution:<br />
<ul style="margin-top: 5px;">
<li>buy a legit cert for code signing (best solution, but $$$)</li>
<li>sign it with a self-signed cert (which still leads to a prompt of 'Do you want to run software from this untrusted publisher?' when you try to import the module, since everyone is security-minded and has at least the <span class="VN_codeFace">RemoteSigned</span> execution policy set on their machines)</li>
<li>✔ do not add a signature, and make mention that you will need to <span class="VN_codeFace">Unblock-File</span> the files in the module (after careful inspection of the files to make sure that there is nothing dangerous in there; but, we're talking about vNugglets, here -- you can trust us, right?! a: No. Trust no one)</li>
</ul>
So, since we went with the last option there, below is the quick/easy way to unblock files. But, again, this should only be done when you trust the code in the files that you are unblocking -- inspecting the files is for your own good. Anyway, the unblock command:<br />
<pre class="PowershellSession">PS vN:\> Get-ChildItem <pathToModules>\XtremIOInfo | Unblock-File
</pre>
<br />
<h3>
Credentials discussion:</h3>
<div>
Credentials come into play in a couple of ways in this module. One can use the <span class="VN_codeFace">New-XIOStoredCred</span> cmdlet to store one credential persistently on disk. And, the use of the <span class="VN_codeFace">Connect-XIOServer</span> cmdlet holds credentials in a variable, only for the duration of the PowerShell session (and, only while connected to any XIO servers).<br />
<br />
Stored credentials are encrypted using the Windows Data Protection API, via a derivative of <a href="http://poshcode.org/474" target="_blank">HalR9000's Export-PSCredential</a>. If the encrypted credential file is found at runtime of any of the module's functions that require credentials, the credentials will be imported from said file transparently.</div>
<div>
<br /></div>
<div>
Decryption of the encrypted credentials can only be performed by the user account that performed the encryption, and on the same computer on which the encryption was performed. This module stores the credential file in the <span class="VN_codeFace">${env:temp}</span> directory by default, and this location is configurable as desired.<br />
<br />
If no credentials are specified to the functions of this module, the given function will look for the credential file in the configured location. If none exists, the functions behave as before: they will prompt for credentials as necessary. And, you can get the stored credential with <span class="VN_codeFace">Get-XIOStoredCred</span>, and remove it from disk, if you would like, with <span class="VN_codeFace">Remove-XIOStoredCred</span>.<br />
<br /></div>
MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com0tag:blogger.com,1999:blog-2269516327950490847.post-9687122774912968042014-10-30T09:41:00.001-04:002023-07-23T15:48:12.156-04:00XtremIO PowerShell Module Updated -- v0.6.0 available!<a href="http://static.vnugglets.com/imgs/xioPlusPShellIcon.png" imageanchor="1" style="clear: left; float: left; margin-right: 25px; margin-top: 5px;"><img alt="XtremIO + PowerShell!" border="0" src="http://static.vnugglets.com/imgs/xioPlusPShellIcon.png" title="XtremIO + PowerShell!" /></a>Oh, boy -- more updates! I committed the module at version 0.6.0 on 24 Sep 2014, and am just now making the time to post about it. Plenty of good stuff in this release, with some preparation for changes to come.
<span style="clear: both; display: block;">The release notes and change log are in the repo, of course, at <a href="https://github.com/mtboren/XtremIO.Utils">https://github.com/mtboren/XtremIO.Utils</a>, but some of the highlights:</span>
<ul>
<li>added explicit <span class="VN_codeFace">Get-XIO*</span> cmdlets for object types, in place of using -ItemType on the <span class="VN_codeFace">Get-XIOItemInfo</span> cmdlet, so as to make things more PowerShell-y</li>
<li>more properties available, including loads of performance-related items in a new PerformanceInfo property for many objects</li>
<li>added support for new things available in the XIOS v3.0 release (properties, object types)</li>
</ul>
And, I recently added XtremIO.Utils as a module available via <a href="http://psget.net/" target="_blank">PsGet</a>, so installing/updating the module becomes a snap for PsGet module users. The quick how-to on using PsGet to install the XtremIO.Utils module:<br />
<pre class="PowershellSession">PS vN:\> Install-Module -Verbose -Module XtremIO.Utils
</pre>
Or, to update the existing version you may already have:
<br />
<pre class="PowershellSession">PS vN:\> Update-Module -Verbose -Module XtremIO.Utils
</pre>
Or, if you like the "old fashioned" module management route (of manually handling the module grab), you can always follow the steps outlined in <a href="http://www.vnugglets.com/2014/07/xtremio-powershell-module-updated-now.html" target="_blank">our previous XtremIO post here</a>.<br />
<br />
And, a couple of futures, in development for the next version of this module:<br />
<ul>
<li><span class="VN_codeFace">Connect-XIOServer</span> / <span class="VN_codeFace">Disconnect-XIOServer</span>, so as to handle credentials at a connection level instead of a per-call for every cmdlet</li>
<li>more <span class="VN_codeFace">New-XIO*</span> cmdlets</li>
</ul>
In the meantime, enjoy!
<br />
<br />MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com0tag:blogger.com,1999:blog-2269516327950490847.post-69294671034863688252014-07-30T18:09:00.001-04:002023-07-23T15:31:15.617-04:00XtremIO PowerShell Module Updated -- Now with New-XIO* Functions!<a href="http://static.vnugglets.com/imgs/xioPlusPShellIcon.png" imageanchor="1" style="clear: left; float: left; margin-right: 25px; margin-top: 5px;"><img alt="XtremIO + PowerShell!" border="0" src="http://static.vnugglets.com/imgs/xioPlusPShellIcon.png" title="XtremIO + PowerShell!" /></a>Since releasing the XtremIO PowerShell module that had "Get" capabilities (about which you can read in our <a href="http://www.vnugglets.com/2014/04/xtremio-powershell-module-report-on.html" target="_blank">previous XtremIO + PowerShell post</a>, if you missed it), we've been working to improve the module! Some such improvements:<br />
<ul>
<li>added functions to cover <span class="VN_codeFace">New-XIO*</span> activities, for things like volumes and initiator groups (yes, with <span class="VN_codeFace">-WhatIf</span>)</li>
<li>added credential storing, so that you need not specify credentials for every call</li>
<li>expanded <span class="VN_codeFace">Get-XIOItemInfo</span> to support more object types (as the API has expanded), like volume folders, initiator group folders, target groups, and bricks</li>
<li>updated numeric properties on return objects to actually be numeric (were returned as strings, previously)</li>
<li>added function to open the Java GUI (most of the time, "yuck", but, sometimes useful)</li>
<li>changed the module name to XtremIO.Utils, as it now does more than reporting information</li>
</ul>
<div>
In the works: making module available via <a href="http://psget.net/" target="_blank">PsGet</a>, so that it is that much easier to get. I shall update this post once this is done.<br />
<br />
<span style="background-color: lime; font-weight: bold;">* Update 28 Oct 2014:</span><br />
Made the time to make this module available via the extra-cool PsGet. In order to install the XtremIO.Utils module via PsGet's <span class="VN_codeFace">Install-Module</span>:<br />
<pre class="PowershellSession">PS vN:\> Install-Module -Verbose -Module XtremIO.Utils
</pre>
That's it -- no muss, no fuss! And, have a look at the <a href="http://psget.net/" target="_blank">PsGet page</a> to see the easy, one-line install of the PsGet module itself if you do not already use it.<br />
<span style="background-color: lime; font-weight: bold;">End of update - 28 Oct 2014</span><br />
<br />
Now, how about some examples? Sure!</div>
<br />
<div>
<b>Create an encrypted, stored credential</b>, that the functions in this module will use by default (so you need not specify credentials for every command):</div>
<pre class="PowershellSession">PS vN:\> New-XIOStoredCred
Windows PowerShell credential request.
Enter credentials to use for XtremIO access
User: mattXio
Password for user mattXio: *********************
<span class="PSWarning">VERBOSE: Credentials encrypted (via Windows Data Protection API) and saved to:
'C:\Users\Matt\AppData\Local\Temp\xioCred_by_Matt_on_VM-MattDesktop-002.enc.xml'</span>
</pre>
<div>
<b>Create a new volume:</b></div>
<pre class="PowershellSession">PS vN:\> New-XIOVolume -ComputerName myxms0.dom.com -Name testvol3 -SizeGB 5120 -ParentFolder "/testVols"
Name NaaName VolSizeTB IOPS
---- ------- --------- ----
testvol3 5.00 0
</pre>
<i>Note: there is no <span class="VN_codeFace">NaaName</span> value at this piont, as the <span class="VN_codeFace">NaaName</span> property does not get populated in the volume object until the volume has been mapped to an initiator group for the first time
</i><br />
<div>
<br />
<b>Create a new initiator group:</b></div>
<pre class="PowershellSession">PS vN:\> New-XIOInitiatorGroup -ComputerName myxms0.dom.com -Name testIG0 -ParentFolder "/testIGs" -InitiatorList @{"myserver-hba2" = "10:00:00:00:00:00:00:F4"; "myserver-hba3" = "10:00:00:00:00:00:00:F5"}
Name Index NumInitiator NumVol IOPS
---- ----- ------------ ------ ----
testIG0 21 2 0 0
</pre>
<div>
<b>Create a new initiator group for each host in a cluster:</b></div>
<pre class="PowershellSession">PS vN:\> ## general params to use for each New-XIOInitiatorGroup call
PS vN:\> $hshGeneralParamsForNewXioIG = @{
Computer = "myxms0.dom.com"
TrustAllCert = $true
Port = 443
WhatIf = $true
} ## end hashtable
PS vN:\> ## get the HBA WWNs for the VMHosts in the given cluster, and for each VMHost, create a new XtremIO initiator group with initiators for each HBA
PS vN:\> Get-Cluster -Name myCluster0 -PipelineVariable cluThisOne | Get-VMHostHBAWWN | Group-Object -Property @{e={$_.VMHostName.Split(".")[0]}} | Foreach-Object{
$strVMHostShortname = $_.Name
## make a hashtable of key/value pairs that are initiator-name => HBA WWN; initiator names will be like "myhost0-hba2"
$_.Group | Foreach-Object -begin {$hshInitList = @{}} {$hshInitList["${strVMHostShortname}-$($_.DeviceName.Replace("vmhba","hba"))"] = $_.HBAPortWWN}
## make a hashtable of parameters specific to this new initiator group to make
$hshParamForNewXioIG = @{
Name = $strVMHostShortname
InitiatorList = $hshInitList
ParentFolder = "/$($cluThisOne.Name)"
} ## end hashtable
## create the new initiator group via the given params
New-XIOInitiatorGroup @hshGeneralParamsForNewXioIG @hshParamForNewXioIG
} ## end foreach-object
Name Index NumInitiator NumVol IOPS
---- ----- ------------ ------ ----
myhost0 21 2 0 0
myhost1 22 2 0 0
...
</pre>
<div>
This creates an initiator group for each VMHost in the given cluster, each group with an initiator for each of the VMHost's HBAs. Utilizes the vNugglets function <span class="VN_codeFace">Get-VMHostHBAWWN</span> that we posted in <a href="http://www.vnugglets.com/2014/07/get-vmhost-fc-hba-wwn-info-most-quickly.html" target="_blank">Get VMHost FC HBA WWN Info Most Quickly</a>. These initiator groups are created in the existing initiator-group folder that is defined for this cluster (of the same name as the cluster).<br />
<br /></div>
<div>
<b>Open the management console (Java GUI):</b></div>
<pre class="PowershellSession">PS vN:\> Open-XIOMgmtConsole myxms0.dom.com
</pre>
<div>
<br /></div>
<div>
Credentials discussion:</div>
<div>
Stored credentials are encrypted using the Windows Data Protection API, via a derivative of <a href="http://poshcode.org/474" target="_blank">HalR9000's Export-PSCredential</a>. If the encrypted credential file is found at runtime of any of the module's functions that require credentials, the credentials will be imported from said file transparently.</div>
<div>
<br /></div>
<div>
Decryption of the encrypted credentials can only be performed by the user account that performed the encryption, and on the same computer on which the encryption was performed. This module stores the credential file in the <span class="VN_codeFace">${env:temp}</span> directory by default, and this location is configurable as desired.<br />
<br />
If no credentials are specified to the functions of this module, the given function will look for the credential file in the configured location. If none exists, the functions behave as before: they will prompt for credentials as necessary. And, you can get the stored credential with <span class="VN_codeFace">Get-XIOStoredCred</span>, and remove it from disk, if you would like, with <span class="VN_codeFace">Remove-XIOStoredCred</span>.<br />
<br />
To use the module, just: (also, updated above: install this module via PsGet. See update at top of post)<br />
<ol start="0">
<li>download from <a href="https://github.com/mtboren/XtremIO.Utils/releases/download/Latest/XtremIO.Utils.zip"><img alt="latest and greatest!" border="0" src="http://static.vnugglets.com/imgs/zipfileicon0.png" title="latest and greatest!" /></a> <a href="https://github.com/mtboren/XtremIO.Utils/releases/download/Latest/XtremIO.Utils.zip">https://github.com/mtboren/XtremIO.Utils/releases/download/Latest/XtremIO.Utils.zip</a></li>
<li>unzip somewhere you like (like, say, in <span class="VN_codeFace">Join-Path ${env:\userprofile} "Documents\WindowsPowerShell\Modules"</span>)</li>
<li>you should now have a folder named <span class="VN_codeFace"><pathToModules>\XtremIO.Utils</span>, in which the PowerShell files reside (see note in <a href="http://www.vnugglets.com/2014/04/xtremio-powershell-module-report-on.html" target="_blank">previous XtremIO + PowerShell post</a> about using <span class="VN_codeFace">Unblock-File</span>, since this module is not yet Authenticode signed)</li>
<li><span class="VN_codeFace">Import-Module <pathToModules>\XtremIO.Utils</span></li>
</ol>
<br />
Other upcoming changes:<br />
<ul>
<li>add the other <span class="VN_codeFace">New-XIO*</span> functions for things like folders, single initiators, lun-maps, more</li>
<li>expand <span class="VN_codeFace">Get-XIOItemInfo</span> to support even more object types (as the API continues to expand), like volume snapshots, events, dataprotection-groups</li>
<li>actually get the project on GitHub</li>
</ul>
Enjoy, and let us know what features would be best to add the soonest!<br />
<br />
* Update 06 Aug 2014: included the MIT License file in the .zip file.</div>
<br />MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com2tag:blogger.com,1999:blog-2269516327950490847.post-85772353406116909542014-07-17T22:00:00.000-04:002014-07-17T22:10:17.503-04:00Get VMHost FC HBA WWN Info Most Quickly with PowerCLI<div class="separator" style="clear: both; text-align: center;">
<a href="http://static.vnugglets.com/imgs/vmhbaWwnViaClient.gif" imageanchor="1" style="clear: right; float: right; margin-left: 15px; margin-top: 5px;"><img alt="VMHba WWN Info" src="http://static.vnugglets.com/imgs/vmhbaWwnViaClient.gif" style="border: 1px solid rgb(204, 204, 204);" title="VMHba WWN Info" /></a></div>
People know about getting VMHost HBA info via PowerCLI -- there are plenty of posts about doing so, generally via <span class="VN_codeFace">Get-VMHostHba</span>. Since that works great, there is barely a reason to write something else to do the same thing, save one reason that is near and dear to our vNugglets hearts: speed. We made this a couple of years ago, have tweaked it a few times, and now it seems like time to post it (like, maybe it will be helpful in an upcoming post, or something? So exciting).<br />
<br />
This function uses everybody's favorite PowerCLI cmdlet <span class="VN_codeFace">Get-View</span>. The speed reward: well worth it. For example:<br />
<div dir="ltr" style="margin-left: 0pt;">
<table style="border-collapse: collapse; border: none;"><colgroup><col width="188"></col><col width="129"></col><col width="134"></col></colgroup><tbody>
<tr style="height: 0px;"><td style="background-color: #cfe2f3; border-color: rgb(111, 168, 220); border-style: solid; border-width: 1px; padding: 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline;">Technique</span></div>
</td><td style="background-color: #cfe2f3; border-color: rgb(111, 168, 220); border-style: solid; border-width: 1px; padding: 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline;">Time, 28 hosts</span></div>
</td><td style="background-color: #cfe2f3; border-color: rgb(111, 168, 220); border-style: solid; border-width: 1px; padding: 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline;">Time, 270 hosts</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-color: rgb(111, 168, 220); border-style: solid; border-width: 1px; padding: 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline;"><span class="VN_codeFace">Get-VMHostHba</span></span></div>
</td><td style="border-color: rgb(111, 168, 220); border-style: solid; border-width: 1px; padding: 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline;">61.9s</span></div>
</td><td style="border-color: rgb(111, 168, 220); border-style: solid; border-width: 1px; padding: 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline;">720s</span></div>
</td></tr>
<tr style="background-color: #f0f0f0; height: 0px;"><td style="border-color: rgb(111, 168, 220); border-style: solid; border-width: 1px; padding: 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline;"><span class="VN_codeFace">Get-VMHostHBAWWN</span></span></div>
</td><td style="border-color: rgb(111, 168, 220); border-style: solid; border-width: 1px; padding: 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline;">1.32s</span></div>
</td><td style="border-color: rgb(111, 168, 220); border-style: solid; border-width: 1px; padding: 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline;">14.1s</span></div>
</td></tr>
<tr style="background-color: #d9ead3; height: 0px;"><td style="border-color: rgb(111, 168, 220); border-style: solid; border-width: 1px; padding: 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt; text-align: right;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline;">improvement:</span></div>
</td><td style="border-color: rgb(111, 168, 220); border-style: solid; border-width: 1px; padding: 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt; text-align: center;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline;">46x</span></div>
</td><td style="border-color: rgb(111, 168, 220); border-style: solid; border-width: 1px; padding: 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt; text-align: center;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline;">51x</span></div>
</td></tr>
</tbody></table>
</div>
<br />
More than 45 times faster? I'm in. Now for the function, complete with examples in comment-based help: <i><span style="font-size: small;">(double-click anywhere in the code to Select All)</span></i><br />
<pre class="brush: powershell" title="'Get-VMHostHBAWWN':">function Get-VMHostHBAWWN {
<# .Description
Get the Port- and Node WWN(s) for HBA(s) in host(s). Feb 2012, vNugglets
.Example
Get-VMHostHBAWWN -VMHost myhost0.dom.com
VMHostName DeviceName HBAPortWWN HBANodeWWN HBAStatus
---------- ---------- ---------- ---------- ---------
myhost0.dom.com vmhba1 10:00:00:00:00:00:00:ca 20:00:00:00:00:00:00:ca online
myhost0.dom.com vmhba2 10:00:00:00:00:00:00:83 20:00:00:00:00:00:00:83 online
Get the HBA WWNs for hosts whose name match the pattern myhost0.dom.com
.Example
Get-VMHostHBAWWN -VMHost ^my.+
VMHostName DeviceName HBAPortWWN HBANodeWWN HBAStatus
---------- ---------- ---------- ---------- ---------
myhost0.dom.com vmhba1 10:00:00:00:00:00:00:ca 20:00:00:00:00:00:00:ca online
myhost0.dom.com vmhba2 10:00:00:00:00:00:00:83 20:00:00:00:00:00:00:83 online
mytest1.dom.com vmhba1 10:00:00:00:00:00:00:da 20:00:00:00:00:00:00:da online
mytest0.dom.com vmhba2 10:00:00:00:00:00:00:93 20:00:00:00:00:00:00:93 online
Get the HBA WWNs for hosts whose name match the pattern ^my.+
.Example
Get-Cluster mycluster | Get-VMHostHBAWWN
...
Get the HBA WWNs for hosts in the cluster "mycluster"
.Outputs
PSCustomObject
#>
[CmdletBinding()]param(
## Name pattern of the host for which to get HBA info (accepts regex patterns)
[parameter(Mandatory=$true,ParameterSetName="SearchByHostName")][string]$VMHostName_str,
## Name pattern of the cluster for whose hosts to get HBA info (accepts regex patterns)
[parameter(Mandatory=$true,ParameterSetName="SearchByCluster",ValueFromPipelineByPropertyName)][Alias("Name")][string]$ClusterName_str
) ## end param
Begin {
## helper function for formatting WWN as hex string with colon-separators
function _Format-AsHexWWNString {
param([parameter(Mandatory=$true)][long]$WWN_long)
(("{0:x}" -f $WWN_long) -split "(\w{2})" | ?{$_ -ne ""}) -join ":"
} ## end function
}
Process {
## params for the Get-View expression for getting the View objects
$hshGetViewParams = @{
ViewType = "HostSystem"
Property = "Name", "Config.StorageDevice.HostBusAdapter"
} ## end hashtable
Switch ($PSCmdlet.ParameterSetName) {
## if host name pattern was provided, filter on it in the Get-View expression
"SearchByHostName" {$hshGetViewParams["Filter"] = @{"Name" = $VMHostName_str}; break;} ## end case
## if cluster name pattern was provided, set it as the search root for the Get-View expression
"SearchByCluster" {$hshGetViewParams["SearchRoot"] = (Get-Cluster $ClusterName_str).Id; break;}
} ## end switch
Get-View @hshGetViewParams | Foreach-Object {
$viewHost = $_
$viewHost.Config.StorageDevice.HostBusAdapter | Where-Object {$_ -is [VMware.Vim.HostFibreChannelHba]} | Foreach-Object {
New-Object -TypeName PSObject -Property ([ordered]@{
VMHostName = $viewHost.Name
DeviceName = $_.Device
HBAPortWWN = _Format-AsHexWWNString -WWN $_.PortWorldWideName
HBANodeWWN = _Format-AsHexWWNString -WWN $_.NodeWorldWideName
HBAStatus = $_.Status
}) ## end new-object
} ## end foreach-object
} ## end foreach-object
} ## end process
} ## end function</pre>
<br />
Not terribly fancy, but something to get it done more quickly (FaF, in fact). And, handy for other things down the road. Like, oh, using the WWN info when creating some initiator groups on your XtremIO array? What a good idea.<br />
<br />
Oh, and if you have not yet seen/used parameter <a href="http://technet.microsoft.com/en-us/library/jj672955.aspx" target="_blank">splatting</a>, this provides a decent example of that, too -- the hashtable of parameters used on line 54. Enjoy!<br />
<br />MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com6tag:blogger.com,1999:blog-2269516327950490847.post-31988837713354833142014-04-24T22:48:00.000-04:002015-11-15T20:10:06.883-05:00XtremIO PowerShell module -- Report on your all-flash arrays!<div class="separator" style="clear: both; text-align: center;">
<a href="http://static.vnugglets.com/imgs/xioPlusPShellIcon.png" imageanchor="1" style="clear: left; float: left; margin-right: 25px; margin-top: 5px;"><img alt="XtremIO + PowerShell!" border="0" src="http://static.vnugglets.com/imgs/xioPlusPShellIcon.png" title="XtremIO + PowerShell!" /></a></div>
All-flash arrays -- if you do not have any, get some. If you have XtremIO, you are likely ecstatic with the performance, ease of setup, low maintenance, etc. You are potentially also fairly sad about the Java-based management GUI for when you want to report, especially when you want to report in bulk (say, across ten XtremIO arrays), as it is a separate interface to launch for each array.<br />
<br />
How to turn that frown upside-down? Hello, RESTful API! After a bit of exploring the API, I have created a module for reading info from the XMS (XtremIO Management Server) appliances (the appliances that are used to manage the XtremIO arrays). While the APIs provide support for nearly all management activities (create/delete/modify/read config), this module is starting out with just the configuration/stats-reading types of actions.<br />
<br />
The XtremIO RESTful API provides item types upon which to report, like <span class="VN_codeFace">volumes</span>, <span class="VN_codeFace">lun-maps</span>, <span class="VN_codeFace">clusters</span>, and <span class="VN_codeFace">initiators</span>. Newer releases of the XMS appliances add item types of <span class="VN_codeFace">bricks</span>, <span class="VN_codeFace">snapshots</span>, <span class="VN_codeFace">ssds</span>, <span class="VN_codeFace">storage-controllers</span>, and <span class="VN_codeFace">xenvs</span>. At the end of this post, after the examples, is more info on the differences between the appliance versions and how those difference affect the way one uses this module.<br />
<br />
As for the module itself, it is linked below, it is still being improved upon, and the intentions are to [eventually]:<br />
<ol start="0">
<li>house it on GitHub or the likes</li>
<li>add the rest of the supported item types</li>
<li>add functionality beyond read-only reporting (think config/manage)</li>
<li>finish error handling for some scenarios (invalid item types for given API version, for example)</li>
</ol>
To use the module, just<br />
<ol start="0">
<li>download from <a href="https://github.com/mtboren/XtremIO.Utils/releases/download/Latest/XtremIO.Utils.zip"><img alt="https://github.com/mtboren/XtremIO.Utils/releases/download/Latest/XtremIO.Utils.zip" border="0" src="http://static.vnugglets.com/imgs/zipfileicon0.png" /></a> <a href="https://github.com/mtboren/XtremIO.Utils/releases/download/Latest/XtremIO.Utils.zip">https://github.com/mtboren/XtremIO.Utils/releases/download/Latest/XtremIO.Utils.zip</a> </li>
<li>unzip somewhere you like (like, say, in <span class="VN_codeFace">Join-Path ${env:\userprofile} "Documents\WindowsPowerShell\Modules"</span>)</li>
<li>you should now have a folder named <span class="VN_codeFace"><pathToModules>\XtremIOInfo</span>, in which the PowerShell files reside (see note below about using <span class="VN_codeFace">Unblock-File</span>, since this module is not yet Authenticode signed)</li>
<li><span class="VN_codeFace">Import-Module <pathToModules>\XtremIOInfo</span></li>
</ol>
<br />
You can use <span class="VN_codeFace">Get-Command -Module XtremIOInfo</span> and <span class="VN_codeFace">Get-Help</span> to find out all about the functionality provided by the module and its currently one (1) exported function, including examples. You will also find the ItemType values currently supported by the module (more to come).<br />
<br />
And, some quick examples to whet appetites:<br />
<pre class="PowershellSession">PS vN:\> Get-XIOItemInfo -Computer somexms01.dom.com, somexms02.dom.com, somexms03.dom.com -Credential $credMyAcct -ItemType clusters
Name TotSSDTB UsedSSDTB FreeSSDTB UsedLogicalTB TotProvTB DedupeRatio IOPS
---- -------- --------- --------- ------------- --------- ----------- ----
xio01 7.47 4.03 3.44 12.17 50 3.0 7886
xio02 7.47 1.13 6.34 3.17 50 2.8 2821
xio03 7.47 5.23 2.24 17.79 50 3.4 28363
PS vN:\> Get-XIOItemInfo -Computer somexms04.dom.com -Credential $credMyAcct -TrustAllCert -Port 443 | Format-List
Name : xio04
TotSSDTB : 7.47
UsedSSDTB : 2.43
FreeSSDTB : 5.04
FreespaceLevel : healthy
UsedLogicalTB : 8.02
TotProvTB : 50
OverallEfficiency : 21:1
DedupeRatio : 3.3
ThinProvSavingsPct : 76
IOPS : 18160
SWVersion : 2.2.3-25
SystemSN : APM00000000004
ComputerName : somexms04.dom.com
</pre>
<b>Various notes</b>:<br />
While the module has the ability to connect to different versions of the XMS appliances (v2.2.2 listens on a different port for API requests than does v2.2.3+), not all items are available on the older versions. For example, one can retrieve info on the item type <span class="VN_codeFace">ssds</span> only from from the newer version of the appliances.<br />
<br />
When connecting to an appliance of the newer version, one might save a bit of time by specifying the port on which to communicate -- port 443. The function tries the default port of the old appliances first (42503), and, if that port is not found to be responsive, tries the default port of the new appliances. Also, if you did not put "legitimate" SSL certificate on the appliance (as opposed to the self-signed cert that is on it by default), _and_ you are sure that the address to which you are connecting in the appliance, you can use the <span class="VN_codeFace">-TrustAllCert</span> switch parameter. This is to allow the PowerShell session to establish the SSL connection by not stopping at a "self-signed cert found" error.<br />
<br />
One of the other "features" of this module: we have not yet set the authenticode signature for it. That is, it is unsigned. We went back and forth on the solution:<br />
<ul style="margin-top: 5px;">
<li>buy a legit cert for code signing (best solution, but $$$)</li>
<li>sign it with a self-signed cert (which still leads to a prompt of 'Do you want to run software from this untrusted publisher?' when you try in import the module, since everyone is security-minded and has at least the <span class="VN_codeFace">RemoteSigned</span> execution policy set on their machines)</li>
<li>✔ do not add a signature, and make mention that you will need to <span class="VN_codeFace">Unblock-File</span> the files in the module (after careful inspection of the files to make sure that there is nothing dangerous in there; but, we're talking about vNugglets, here -- you can trust us, right?! a: No. Trust no one)</li>
</ul>
So, since we went with the last option there, below is the quick/easy way to unblock files. But, again, this should only be done when you trust the code in the files that you are unblocking -- inspecting the files is for your own good. Anyway, the unblock command:<br />
<span class="VN_codeFace">Get-ChildItem <pathToModules>\XtremIOInfo | Unblock-File</span><br />
<br />
Alright, enough with the notes, for now. XtremIO storage arrays: awesome. Now, the ability to start interacting with management appliances via PowerShell: excellanté!<br />
<br />MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com3tag:blogger.com,1999:blog-2269516327950490847.post-26820029299757116192013-12-29T13:25:00.000-05:002013-12-29T13:25:38.000-05:00Get VM Disks and RDMs via PowerCLINeed to get info about a VM's hard disks? Like, "regular" virtual disks <i>and</i> RDMs, in a handy and fast manner? We need to, occasionally, and so wrote a function to do so (a while ago -- just finally posting it). It gets things like the hard disk name, the SCSI ID, the storage device display name, the disk size, the SCSI canonical name, and [optionally] the full datastore path for the disk files. Here again, not the first bit of code around to retrieve such things, but a version that is written to do things most quickly.<br />
<br />
The script:
<br />
<pre class="brush: powershell" title="'Get-VMDiskAndRDM':"><# .Description
Function to get a VM's hard disk and RDM info
Originally from Sep 2011, updated Dec 2013 -- vNugglets.com
.Example
Get-VMDiskAndRDM -vmName someVM -ShowVMDKDatastorePath | ft -a
VMName HardDiskName ScsiId DeviceDisplayName SizeGB ScsiCanonicalName VMDKDStorePath
------ ------------ ------ ----------------- ------ ----------------- --------------
someVM Hard disk 1 0:0 50 [dstore0] someVM/someVM.vmdk
someVM Hard disk 2 1:0 someVM-/log_dir 20 naa.60000945618415615641111111111111 [dstore0] someVM/someVM_1.vmdk
Get the disks (including RDMs) for "someVM", and include the datastore path for each VMDK
#>
function Get-VMDiskAndRDM {
param(
## name pattern of the VM guest for which to get info
[parameter(Mandatory=$true)][string]$vmName_str = "myVM",
## switch to specify that VMDK's datastore path should also be returned
[switch]$ShowVMDKDatastorePath_sw
)
## the cool, FaF way (using .NET View objects)
## get the VM object(s)
$arrVMViewsForStorageInfo = Get-View -Viewtype VirtualMachine -Property Name, Config.Hardware.Device, Runtime.Host -Filter @{"Name" = "$vmName_str"}
if (($arrVMViewsForStorageInfo | Measure-Object).Count -eq 0) {Write-Warning "No VirtualMachine objects found matching name pattern '$vmName_str'"; exit} ## end if
$arrVMViewsForStorageInfo | %{
$viewVMForStorageInfo = $_
## get the view of the host on which the VM currently resides
$viewHostWithStorage = Get-View -Id $viewVMForStorageInfo.Runtime.Host -Property Config.StorageDevice.ScsiLun
$viewVMForStorageInfo.Config.Hardware.Device | ?{$_ -is [VMware.Vim.VirtualDisk]} | %{
$hdThisDisk = $_
$oScsiLun = $viewHostWithStorage.Config.StorageDevice.ScsiLun | ?{$_.UUID -eq $hdThisDisk.Backing.LunUuid}
## the properties to return in new object
$hshThisVMProperties = @{
VMName = $viewVMForStorageInfo.Name
## the disk's "name", like "Hard disk 1"
HardDiskName = $hdThisDisk.DeviceInfo.Label
## get device's SCSI controller and Unit numbers (1:0, 1:3, etc)
ScsiId = &{$strControllerKey = $_.ControllerKey.ToString(); "{0}`:{1}" -f $strControllerKey[$strControllerKey.Length - 1], $_.Unitnumber}
DeviceDisplayName = $oScsiLun.DisplayName
SizeGB = [Math]::Round($_.CapacityInKB / 1MB, 0)
ScsiCanonicalName = $oScsiLun.CanonicalName
} ## end hsh
## the array of items to select for output
$arrPropertiesToSelect = "VMName,HardDiskName,ScsiId,DeviceDisplayName,SizeGB,ScsiCanonicalName".Split(",")
## add property for VMDKDStorePath if desired
if ($ShowVMDKDatastorePath_sw -eq $true) {$hshThisVMProperties["VMDKDStorePath"] = $hdThisDisk.Backing.Filename; $arrPropertiesToSelect += "VMDKDStorePath"}
New-Object -Type PSObject -Property $hshThisVMProperties | Select $arrPropertiesToSelect
} ## end foreach-object
} ## end foreach-object
} ## end function
</pre>
<br />
Some example usage:<br />
<pre class="PowershellSession">PS vN:\> Get-VMDiskAndRDM -vmName myVM01 -ShowVMDKDatastorePath | ft -a
VMName HardDiskName ScsiId DeviceDisplayName SizeGB ScsiCanonicalName VMDKDStorePath
------ ------------ ------ ----------------- ------ ----------------- --------------
myVM01 Hard disk 1 0:0 50 [dstore0] myVM01/myVM01.vmdk
myVM01 Hard disk 2 1:0 myVM01-/data001 660 naa.60000946665554443331111111111111 [dstore0] myVM01/myVM01_1.vmdk
</pre>
<br />
The disks with no values for the <span class="VN_codeFace">DeviceDisplayName</span> or <span class="VN_codeFace">ScsiCanonicalName</span> properties are the "regular" virtual disks, and the others are RDMs. And, this VM has hard disks on two separate SCSI controllers.<br />
<br />
<b>Note</b>: the <span class="VN_codeFace">vmName</span> parameter is used as a regular expression when getting the .NET View object of the given VM. As such, one can use a pattern, and can get info on multiple VMs that share the same name pattern.<br />
<br />
And, that is that: some juicy disk/RDM info for VMs, and on the quick! Thanks, <span class="VN_codeFace">Get-View</span>, for keeping things FaF! Enjoy<br />
<br />
BTW: related post, <a href="http://www.vnugglets.com/2013/12/get-vm-by-rdm-with-powercli.html" target="_blank">Get VM by RDM with PowerCLI</a>: how to get the VM that is using a particular SAN storage device as an RDM.
<br />
<br />MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com24tag:blogger.com,1999:blog-2269516327950490847.post-40518485112181379402013-12-24T14:24:00.000-05:002013-12-29T13:26:01.761-05:00Get VM By RDM with PowerCLISometimes one needs to find a VM by RDM. This is not a new thought, and there are plenty of spots on the internet that give ways to achieve this. When this need arose for us a couple of years ago, we found no spot that gave a way to achieve this <i>quickly</i>. So, with vNugglets' focus on speed, I put together a function to do just that: quickly find the VM that is using a given SAN device as an RDM.<br />
<br />
Then, just recently, a VMware Communities forum post made me realize that we had not yet shared this function with the world. So, here we go:<br />
<pre class="brush: powershell" title="'Get-VMWithGivenRDM':"><# .Description
Function to find what VM (if any) is using a LUN as an RDM, based on the LUN's SCSI canonical name. Assumes that the best practice of all hosts in a cluster seeing the same LUNs is followed.
vNugglets, originally from Nov 2011
.Example
Get-VMWithGivenRDM -CanonicalName naa.60000970000192602222333031314444 -Cluster myCluster0 | ft -a
Find a VM using the given LUN as an RDM, formatting output in auto-sized table. Output would be something like:
VMName VMDiskName DeviceDisplayName CanonicalName
------ ---------- ----------------- -------------
myvm033.dom.com Hard disk 10 myvm033-data3FS naa.60000970000192602222333031314444
.Outputs
Zero or more PSObjects with info about the VM and its RDM
#>
function Get-VMWithGivenRDM {
param(
## Canonical name of the LUN in question
[parameter(Mandatory=$true)][string[]]$CanonicalNameOfRDMToFind_arr,
## Cluster whose hosts see this LUN
[parameter(Mandatory=$true)][string]$ClusterName_str
) ## end param
## get the View object of the cluster in question
$viewCluster = Get-View -ViewType ClusterComputeResource -Property Name -Filter @{"Name" = "^$([RegEx]::escape($ClusterName_str))$"}
## get the View of a host in the given cluster (presumably all hosts in the cluster see the same storage)
$viewHostInGivenCluster = Get-View -ViewType HostSystem -Property Name -SearchRoot $viewCluster.MoRef | Get-Random
## get the Config.StorageDevice.ScsiLun property of the host (retrieved _after_ getting the View object for speed, as this property is only retrieved for this object, not all hosts' View objects)
$viewHostInGivenCluster.UpdateViewData("Config.StorageDevice.ScsiLun")
## if matching device(s) found, store some info for later use
$arrMatchingDisk = &{
## get the View objects for all VMs in the given cluster
Get-View -ViewType VirtualMachine -Property Name, Config.Hardware.Device -SearchRoot $viewCluster.MoRef | %{$viewThisVM = $_
## for all of the RDM devices on this VM, see if the canonical name matches the canonical name in question
$viewThisVM.Config.Hardware.Device | ?{($_ -is [VMware.Vim.VirtualDisk]) -and ("physicalMode","virtualMode" -contains $_.Backing.CompatibilityMode)} | %{
$hdThisDisk = $_
$lunScsiLunOfThisDisk = $viewHostInGivenCluster.Config.StorageDevice.ScsiLun | ?{$_.UUID -eq $hdThisDisk.Backing.LunUuid}
## if the canonical names match, create a new PSObject with some info about the VirtualDisk and the VM using it
if ($CanonicalNameOfRDMToFind_arr -contains $lunScsiLunOfThisDisk.CanonicalName) {
New-Object -TypeName PSObject -Property @{
VMName = $viewThisVM.Name
VMDiskName = $hdThisDisk.DeviceInfo.Label
CanonicalName = $lunScsiLunOfThisDisk.CanonicalName
DeviceDisplayName = $lunScsiLunOfThisDisk.DisplayName
} ## end new-object
} ## end if
} ## end foreach-object
} ## end foreach-object
} ## end scriptblock
## if a matching device was found, output its info
if ($arrMatchingDisk) {$arrMatchingDisk | Select VMName, VMDiskName, DeviceDisplayName, CanonicalName}
## else, say so
else {Write-Verbose -Verbose "Booo. No matching disk device with canonical name in '$CanonicalNameOfRDMToFind_arr' found attached to a VM as an RDM in cluster '$ClusterName_str'"}
} ## end fn</pre>
Some example usage:<br />
<pre class="PowershellSession">PS vN:\> Get-VMWithGivenRDM -CanonicalName naa.60000123412342602222333031314444 -Cluster myMegaCluster
VMName VMDiskName DeviceDisplayName CanonicalName
------ ---------- ----------------- -------------
myvm002.dom.com Hard disk 13 myvm002-dataFS_7 naa.60000123412342602222333031314444
...
</pre>
<br />
The point of having a Cluster param is to focus the scope of the search (one generally knows to what set of hosts a particular LUN has been presented).<br />
<br />
And, some thoughts on how to make this function even better:
<br />
<ul>
<li>take cluster input from pipeline</li>
<li>add ability to check entire vCenter inventory, but keep things fast by first narrowing scope to only the VMHosts that see given device, then check those hosts' clusters for a VM with RDM using said device (removes need for "Cluster" param)</li>
<li>maybe: add other info to output object, if there are other things that would be useful/valuable</li>
</ul>
<div>
So, how does this do -- FaF for you, too? Yeah, just as we thought!</div>
<br />MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com0tag:blogger.com,1999:blog-2269516327950490847.post-91331768841579922962013-11-21T15:42:00.001-05:002013-11-21T15:42:41.381-05:00Get VMs by Virtual Port Group with PowerCLIHow to find out what VMs use a particular virtual port group, and quickly? Well, we have just the thing. And, it also helps to illustrate the practical use of <span class="VN_codeFace">LinkedViews</span> and the <span class="VN_codeFace">UpdateViewData()</span> method of .NET View objects (about which we posted a while back in <a href="http://www.vnugglets.com/2012/08/even-faster-powercli-code-with-get-view.html" target="_blank">Even Faster PowerCLI Code with Get-View, UpdateViewData() and LinkedViews</a>), along with the kind of speed increase that said method brings.<br />
<br />
So, the function:<br />
<pre class="brush: powershell" title="'Get-VMOnNetworkPortGroup':"><# .Description
Function to get info about what VMs are on a virtual portgroup. vNugglets, Oct 2013
Highlights the use of the UpdateViewData() method of a .NET View object
.Outputs
PSObject
#>
function Get-VMOnNetworkPortGroup {
param(
## name of network to get; regex pattern
[parameter(Mandatory=$true)][string]$NetworkName_str
) ## end param
## get the .NET View objects for the network port groups whose label match the given name
$arrNetworkViews = Get-View -ViewType Network -Property Name -Filter @{"Name" = $NetworkName_str}
if (($arrNetworkViews | Measure-Object).Count -eq 0) {Write-Warning "No networks found matching name '$NetworkName_str'"; exit}
## get the networks' VMs' names, along with the name of the corresponding VMHost and cluster
$arrNetworkViews | %{$_.UpdateViewData("Vm.Name","Vm.Runtime.Host.Name","Vm.Runtime.Host.Parent.Name")}
## create a new object for each VM on this network
$arrNetworkViews | %{
$viewNetwk = $_
$viewNetwk.LinkedView.Vm | %{
New-Object -TypeName PSObject -Property @{
VMName = $_.Name
NetworkName = $viewNetwk.Name
VMHost = $_.Runtime.LinkedView.Host.Name
Cluster = $_.Runtime.LinkedView.Host.LinkedView.Parent.Name
} | Select-Object VMName,NetworkName,VMHost,Cluster
} ## end foreach-object
} ## end foreach-object
} ## end fn</pre>
And, some sample usage:<br />
<pre class="PowershellSession">PS vN:\> Get-VMOnNetworkPortGroup -NetworkName "223|237"
VMName NetworkName VMHost Cluster
------ ----------- ------ -------
dubuntu0 223.Prod esxi01.dom.com Cluster0
vma5 223.Prod esxi02.dom.com Cluster0
vcsa02 223.Prod esxi02.dom.com Cluster0
tmpl_test1 237.Dev esxi12.dom.com Cluster1
...
</pre>
This illustrates the use of a regular expression pattern to match virtual networks whose names contain "223" or "237".<br />
<br />
And, on the topic of speed increases:<br />
<pre class="PowershellSession">## using standard cmdlets:
PS vN:\> Measure-Command {Get-VirtualPortGroup -Name SomeNetworkName | Get-VM | select name,@{n="VMHostName"; e={$_.VMHost.name}},@{n="ClusterName"; e={$_.VMHost.Parent.Name}}}
...
TotalSeconds : 25.4870345
## using vNugglets function:
PS vN:\> Measure-Command {Get-VMOnNetworkPortGroup -NetworkName SomeNetworkName}
...
TotalSeconds : 0.9676149 ## big winner!
</pre>
So, while similar results can be had with native PowerCLI cmdlets, leveraging this function definitely comes in handy, especially when you are as impatient as we can be here at vNugglets. Enjoy!<br />
<br />MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com0tag:blogger.com,1999:blog-2269516327950490847.post-42294588035172712142013-10-13T21:52:00.000-04:002020-06-12T09:49:10.373-04:00Get VM by IP or MAC address via PowerCLII had need to get VMs based on IP, but, not particular IPs, just IPs in a certain subnet. Previously here on vNugglets we had a post about how to Find VM by NIC MAC Address. I have since added this logic to a function, and added the ability to get a VM by its IP address. With my recent need, I added another piece that allows for the IP address "wildcarding". The function, <span class="VN_codeFace">Get-VMByAddress</span>, with its three ways to find a VM by IP- or MAC address:
<br />
<pre class="brush: powershell" title="'Get-VMByAddress':">function Get-VMByAddress {
<# .Description
Find all VMs w/ a NIC w/ the given MAC address or IP address (by IP address relies on info returned from VMware Tools in the guest, so those must be installed). Includes FindByIPWildcard, so that one can find VMs that approximate IP, like "10.0.0.*"
.Example
Get-VMByAddress -MAC 00:50:56:00:00:02
VMName MacAddress
------ ----------
dev0-server 00:50:56:00:00:02,00:50:56:00:00:04
Get VMs with given MAC address, return VM name and its MAC addresses
.Example
Get-VMByAddress -IP 10.37.31.120
VMName IPAddr
------ ------
dev0-server2 192.168.133.1,192.168.253.1,10.37.31.120,fe80::...
Get VMs with given IP as reported by Tools, return VM name and its IP addresses
.Example
Get-VMByAddress -AddressWildcard 10.0.0.*
VMName IPAddr
------ ------
someVM0 10.0.0.119,fe80::...
someVM2 10.0.0.138,fe80::...
...
Get VMs matching the given wildcarded IP address
#>
[CmdletBinding(DefaultParametersetName="FindByMac")]
param (
## MAC address in question, if finding VM by MAC; expects address in format "00:50:56:83:00:69"
[parameter(Mandatory=$true,ParameterSetName="FindByMac")][string]$MacToFind_str,
## IP address in question, if finding VM by IP
[parameter(Mandatory=$true,ParameterSetName="FindByIP")][ValidateScript({[bool][System.Net.IPAddress]::Parse($_)})][string]$IpToFind_str,
## wildcard string IP address (standard wildcards like "10.0.0.*"), if finding VM by approximate IP
[parameter(Mandatory=$true,ParameterSetName="FindByIPWildcard")][string]$AddressWildcard_str
) ## end param
Process {
Switch ($PsCmdlet.ParameterSetName) {
"FindByMac" {
## return the some info for the VM(s) with the NIC w/ the given MAC
Get-View -Viewtype VirtualMachine -Property Name, Config.Hardware.Device | Where-Object {$_.Config.Hardware.Device | Where-Object {($_ -is [VMware.Vim.VirtualEthernetCard]) -and ($_.MacAddress -eq $MacToFind_str)}} | select @{n="VMName"; e={$_.Name}},@{n="MacAddress"; e={($_.Config.Hardware.Device | Where-Object {$_ -is [VMware.Vim.VirtualEthernetCard]} | %{$_.MacAddress} | sort) -join ","}}
break;
} ## end case
{"FindByIp","FindByIPWildcard" -contains $_} {
## scriptblock to use for the Where clause in finding VMs
$sblkFindByIP_WhereStatement = if ($PsCmdlet.ParameterSetName -eq "FindByIPWildcard") {{$_.IpAddress | Where-Object {$_ -like $AddressWildcard_str}}} else {{$_.IpAddress -contains $IpToFind_str}}
## return the .Net View object(s) for the VM(s) with the NIC(s) w/ the given IP
Get-View -Viewtype VirtualMachine -Property Name, Guest.Net | Where-Object {$_.Guest.Net | Where-Object $sblkFindByIP_WhereStatement} | Select @{n="VMName"; e={$_.Name}}, @{n="IPAddr"; e={($_.Guest.Net | %{$_.IpAddress} | sort) -join ","}}
} ## end case
} ## end switch
} ## end process
} ## end function</pre>
<br />
A few examples of using the function to find VMs by various addresses (as shown in the comment-based help, too):<br />
<pre class="PowershellSession">PS vN:\> Get-VMByAddress -MAC 00:50:56:00:00:02
VMName MacAddress
------ ----------
dev0-server 00:50:56:00:00:02,00:50:56:00:00:04
PS vN:\> Get-VMByAddress -IP 10.37.31.120
VMName IPAddr
------ ------
dev0-server2 192.168.133.1,192.168.253.1,10.37.31.120,fe80::...
PS vN:\> Get-VMByAddress -AddressWildcard 10.0.0.*
VMName IPAddr
------ ------
someVM0 10.0.0.119,fe80::...
someVM2 10.0.0.138,fe80::...
...
</pre>
<br />
There are several places on the web that talk about getting VMs' IPs, getting their MAC addresses, exporting them, and so on, but this is for getting VMs based on the given address. <B>Note:</B> Since IP address info in vCenter is gotten from guest OSes via VMware Tools, this function is going to rely on that info.
And, since the function uses everyone's favorite cmdlet, <span class="VN_codeFace">Get-View</SPAN>, and the calls with this cmdlet are properly tuned, you know that it is going to be FaF!MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com8tag:blogger.com,1999:blog-2269516327950490847.post-49673759027900377942013-08-20T19:44:00.001-04:002013-09-05T19:25:44.731-04:00Copy VIRole via PowerCLII had the occasion of needing to copy some VIRoles from one vCenter to another. There are export/import scripts out there for exporting VIRoles to txt files, and then importing them elsewhere. But, so as to help simplify the copying of VIRoles, I decided to make a <span class="VN_codeFace">Copy-VIRole</span> function that does the copy straight-away.<br />
<br />
It is pretty straight forward: it creates a VIRole of the given name in a destination vCenter, based on the name of a VIRole and source vCenter. This does involve the additional step of getting the VIPrivileges (handled in the function via <span class="VN_codeFace">Get-VIPrivilege</span>) from the destination vCenter -- the PrivilegeList itself did not suffice. The function definition:<br />
<pre class="brush: powershell" title="'Copy-VIRole':">function Copy-VIRole {
<# .Description
Copy a role to another role, either in same vCenter or to a different vCenter
This assumes that connections to source/destination vCenter(s) are already established. If role of given name already exists in destination vCenter, will stop.
Author: vNugglets.com -- Jul 2013
.Example
Copy-VIRole -SrcRoleName SysAdm -DestRoleName SysAdm_copyTest -SrcVCName vcenter.com -DestVCName labvcenter.com
.Outputs
VMware.VimAutomation.ViCore.Impl.V1.PermissionManagement.RoleImpl if role is created/updated, String in Warning stream and nothing in standard out otherwise
#>
param(
## source role name
[parameter(Mandatory=$true)][string]$SrcRoleName_str,
## destination role name
[parameter(Mandatory=$true)]$DestRoleName_str,
## source vCenter connection name
[parameter(Mandatory=$true)]$SrcVCName_str,
## destination vCenter connection name
[parameter(Mandatory=$true)]$DestVCName_str,
## WhatIf switch
[switch]$WhatIf_sw
) ## end param
## get the VIRole from the source vCenter
$oSrcVIRole = Get-VIRole -Server $SrcVCName_str -Name $SrcRoleName_str -ErrorAction:SilentlyContinue
## if the role does not exist in the source vCenter
if ($null -eq $oSrcVIRole) {Write-Warning "VIRole '$DestRoleName_str' does not exist in source vCenter '$SrcVCName_str'. No source VIRole from which to copy. Exiting"; exit}
## see if there is VIRole by the given name in the destination vCenter
$oDestVIRole = Get-VIRole -Server $DestVCName_str -Name $DestRoleName_str -ErrorAction:SilentlyContinue
## if the role already exists in the destination vCenter
if ($null -ne $oDestVIRole) {Write-Warning "VIRole '$DestRoleName_str' already exists in destination vCenter '$DestVCName_str'. Exiting"; exit}
## else, create the role
else {
$strNewVIRoleExpr = 'New-VIRole -Server $DestVCName_str -Name $DestRoleName_str -Privilege (Get-VIPrivilege -Server $DestVCName_str -Id $oSrcVIRole.PrivilegeList){0}' -f $(if ($WhatIf_sw) {" -WhatIf"})
Invoke-Expression $strNewVIRoleExpr
} ## end else
} ## end function</pre>
<br />
An example of using the function to copy a role from one vCenter to another, with a new role name:<br />
<pre class="PowershellSession">PS vN:\> Copy-VIRole -SrcRoleName MyRole0 -SrcVCName myvcenter.dom.com -DestRoleName MyNewRole -DestVCName vcenter2.dom.com
Name IsSystem
---- --------
MyNewRole False
PS vN:\> Get-VIRole MyNewRole -server vcenter2*
Name IsSystem
---- --------
MyNewRole False
</pre>
One can also use this function to clone a VIRole in the same vCenter -- just use the same vCenter for the Source and Destination vCenter parameters.<br />
<br />
<b>Note:</b> this function expects/requires that the PowerCLI session already has a connection to each of the vCenter(s) (one or two) involved in the operation.<br />
<br />
For another way of copying a VIRole (between separate vCenters, particularly), see <a href="http://communities.vmware.com/people/Grzesiekk/" target="_blank">Grzegorz</a>'s post at <a href="http://psvmware.wordpress.com/2012/07/19/clone-roles-between-two-virtual-center-servers/">http://psvmware.wordpress.com/2012/07/19/clone-roles-between-two-virtual-center-servers/</a>.<br />
<br />
Enjoy.MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com2tag:blogger.com,1999:blog-2269516327950490847.post-81183472753403757842013-01-06T21:56:00.000-05:002013-01-06T21:58:05.064-05:00Determine VMs' Uplink vmnic on vSwitch with PowerCLIEver have the need to determine which uplink vmnic on which vSwitch a VM is using? We have, too. And, we have relied on traditional hardware level info in the past to get such info: get with the network team and have them tell us on what physical switch port they see the MAC address of the given VM, and then correlate that with the VMHost's vmnic. Straight forward, fast, easy, and self-service. Not.<br />
<br />
The standard ways described elsewhere on the web are to use esxtop on a VMHost or resxtop from somewhere with the vCLI installed (press "n" once in [r]esxtop). But, wouldn't it be nice if there was a way without having to enable SSH on a host, or SSH'ing to a vMA appliance (if you do not already have the vCLI installed). Maybe, say, with PowerCLI, which everybody has installed (right?). Oh, wait -- there is: <a href="http://www.vmware.com/support/developer/PowerCLI/PowerCLI51/html/Get-EsxTop.html" target="_blank">Get-EsxTop</a>.<br />
<br />
Here is a function that uses <span class="VN_codeFace">Get-EsxTop</span> to get, for VMs on a VMHost, their vSwitch and vmnic uplink information: <br />
<pre class="brush: powershell"><# .Description
Function to retrieve Netports' (portgroup ports') client, uplink info, vSwitch, etc. info. Includes things like VMKernel ports and Management uplinks.
Author: vNugglets.com -- Nov 2012
.Outputs
PSObject
#>
function Get-VNUplinkNic {
param(
## the VMHost DNS name whose VMs' uplink info to get (not VMHost object name -- so, do not use wildcards)
[parameter(Mandatory=$true)][string]$VMHostToCheck_str,
## PSCredential to use for connecting to VMHost; will prompt for credentials if not passed in here
[System.Management.Automation.PSCredential]$CredentialForVMHost_cred
) ## end param
$strThisVMHostName = $VMHostToCheck_str
## check if VMHost name given is responsive on the network; if not, exit
if (-not (Test-Connection -Quiet -Count 3 -ComputerName $strThisVMHostName)) {
Write-Warning "VMHost '$strThisVMHostName' not responding on network -- not proceeding"; exit}
## set/get the credential to use for connecting to the VMHost (get if not already passed as param)
$credToUseForVMHost = if ($CredentialForVMHost_cred) {$CredentialForVMHost_cred} else
{$host.ui.PromptForCredential("Need credentials to connect to VMHost", "Please enter credentials for '$strThisVMHostName'", $null, $null)}
## connect to the given VIServer (VMHost, here)
$oVIServer = Connect-VIServer $strThisVMHostName -Credential $credToUseForVMHost
## if connecting to VMHost failed, write warning and exit
if (-not $oVIServer) {Write-Warning "Did not connect to VMHost '$strThisVMHostName' -- not proceeding"; exit}
## array with PortID to vSwitch info, for determining vSwitch name from PortID
## get vSwitch ("PortsetName") and PortID info, not grouped
$arrNetPortEntries = (Get-EsxTop -Server $strThisVMHostName -TopologyInfo NetPort).Entries
## calculated property for vSwitch name
$hshVSwitchInfo = @{n="vSwitch"; e={$oNetportCounterValue = $_; ($arrNetPortEntries | ?{$_.PortId -eq $oNetportCounterValue.PortId}).PortsetName}}
## get the VM, uplink NIC, vSwitch, and VMHost info
Get-EsxTop -Server $strThisVMHostName -CounterName NetPort | select @{n="VMName"; e={$_.ClientName}},TeamUplink,$hshVSwitchInfo,@{n="VMHostName"; e={$_.Server.Name}}
Disconnect-VIServer $strThisVMHostName -Confirm:$false
} ## end function</pre>
<br />
The comments should pretty much explain what is happening, if it is not already clear. Once you have defined the function, you can use it like:<br />
<br />
<pre class="PowershellSession">PS vNuggs:\> Get-VNUplinkNic -VMHostToCheck somehost
Need credentials to connect to VMHost
Please enter credentials for 'somehost'
User: root
Password for user root: *************
VMName TeamUplink vSwitch VMHostName
---------- ---------- ------- ----------
Management n/a vSwitch0 somehost
vmk1 vmnic0 vSwitch0 somehost
vmk0 vmnic0 vSwitch0 somehost
dev0-vm0 vmnic0 vSwitch0 somehost
dev0-vm12323 vmnic5 vSwitch0 somehost
dev0-vm2 vmnic5 vSwitch0 somehost
dev0-vm32237 vmnic4 vSwitch1 somehost
dev0-vm9 vmnic8 vSwitch1 somehost
...
</pre>
<br />
Pretty handy. And, it does not meet up with the same limitation that you might face with [r]esxtop -- that you can only get uplink info for the top X number of VMs on a host, where X is the number of rows available for display in your console session. So, you can get the uplink info for <i>all</i> VMs on the host. Then, you can sort/filter as needed -- VMs on a given uplink is a nice to know, for example.<br />
<br />
There you go: another tasty vNugglet.<br />
<br />
Postscript: After writing this function, and in the process of composing this post, I found a VMware Communities thread (<a href="http://communities.vmware.com/thread/341604">http://communities.vmware.com/thread/341604</a>) that does also provide a portion of this goodness, but that thread did not include the cool sauce for getting the vSwitch info -- so, at least that part is new -- yeah-hooey.<br />
<br />MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com2tag:blogger.com,1999:blog-2269516327950490847.post-76855080835820253192012-12-16T16:40:00.000-05:002012-12-16T16:40:41.206-05:00Evacuating VMs and Templates From DatastoresIn many environments, ours included, it is not always possible or desired to store all of a VM's virtual disks on the same datastore. For example, the storage performance may not be ideal if the VM has high I/O requirements, you may have a policy to keep database logs on separate datastores from the actual data files, or you might just have different tiers of storage for your OS disks vs. your data disks. Whatever the rationale, it is somewhat troublesome if you need to evacuate the datastore for some reason, such as moving to a new storage array. Why is this? Consider the following scenario:<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://1.bp.blogspot.com/-x0kr_mKkwQk/UMq8Uf0Y9JI/AAAAAAAAAmI/SQYZPc0OgdY/s1600/evacuate_datastore.png" imageanchor="1" style="margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-x0kr_mKkwQk/UMq8Uf0Y9JI/AAAAAAAAAmI/SQYZPc0OgdY/s1600/evacuate_datastore.png" /></a></div>
<br />
<br />
Let's assume DATASTORE1 is the datastore that needs to be evacuated in this example. Initially, you may consider a simple <span class="VN_codeFace">Move-VM</span> command such as this:<br />
<br />
<pre class="brush: powershell">Get-Datastore DATASTORE1 | Get-VM | Move-VM -Datastore DATASTORE4</pre>
<br />
The problem with this command is that it will attempt to move all four VMs to DATASTORE4 but will fail because there isn't enough free space. At first glance, you may be thinking "What are you talking about? The VMs on DATASTORE1 only add up to 400GB and there is 500GB free on DATASTORE4!" Well, the problem with the <span class="VN_codeFace">Move-VM</span> cmdlet is that it will consolidate all the config files and virtual disks that make up a VM at the destination datastore. If you take a closer look at the diagram, the total capacity needed to host all four VMs is actually 1.4TB. So <span class="VN_codeFace">Move-VM</span> is not an option here unless we get a larger datastore, but remember, there was a valid reason for splitting the virtual disks across multiple datastores, so we really don't want to lose the VMs' layout on this migration.<br />
<br />
To the <a href="http://communities.vmware.com/community/vmtn/" target="_blank">VMware (VMTN) Communities</a> I went to begin researching this and big surprise, <a href="http://www.lucd.info/" target="_blank">LucD</a> had <a href="http://communities.vmware.com/message/2035154#2035154" target="_blank">the answer</a> for someone. However, this solution had a few issues for us:<br />
<br />
1) It does not move any templates that may be located on the datastore you are evacuating. Surely you use templates, right?<br />
<br />
2) It moves the VM's config files even if they are not on the datastore you are evacuating. Not a huge deal, but some people like to keep the config files on the same datastore as the "OS disk" and this could break that. For example, if we wanted to evacuate DATASTORE2 instead, VM2 would have not only its 500GB disk moved to the new datastore, but it would also grab the config files from DATASTORE1 as well, which might lead to some confusion since they now reside with the second virtual disk instead of the first (OS disk).<br />
<br />
3) If the VM <i>only</i> has its config files stored on the datastore you are evacuating, then we've got a larger problem. Let's go back to our original example. We want to migrate the VMs on DATASTORE1 to DATASTORE4, but keep their existing layout so it all fits. With the script from the Community, it'll work great except on VM3 (and sort of VM4, see above). With VM3, only the config files are stored there, but because the script sets the "datastore" property of the <a href="http://pubs.vmware.com/vsphere-51/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvim.vm.RelocateSpec.html" target="_blank">VirtualMachineRelocateSpec</a> object regardless of where the config files reside, it'll not only move those files, but also <i><b>all</b></i> virtual disks associated with that VM because the "disk" property is optional. Think of it kind of like a "default datastore" to use for migrating the VM and its virtual disks so you don't need to bother specifying the destination datastore on each disk if you desire. If you do the math on that, it'll move 400GB of virtual disks just for VM3. That brings the total for all VMs on DATASTORE1 to 800GB, which again, will not fit on DATASTORE4.<br />
<br />
So the fix for #3, of course, is to specify the destination datastore for each and every disk--either the new destination datastore if they need moved or the current datastore if they need to stay put. This is done through the <span class="VN_codeFace">VirtualMachineRelocateSpec</span> object's "disk" property, which is itself an array of <a href="http://pubs.vmware.com/vsphere-51/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvim.vm.RelocateSpec.DiskLocator.html" target="_blank">VirtualMachineRelocateSpecDiskLocator</a> objects. Without further adieu, the final code looks like this:<br />
<br />
<pre class="brush: powershell"><#
.Description
Script to evacuate virtual disks and/or VM config files from a given datastore; does not move the entire VM and all its disks if they reside elsewhere. Created 12-Dec-2012 by vNugglets.com.
.Example
EvacuateDatastore.ps1 -SourceDatastore datastoreToEvac -DestDatastore destinationDatastore
Move virtual disks and/or VM config files (if any) from source datastore to the destination datastore
#>
## Params for source and destination datastore
param(
## The name of the source datastore (the one to evacuate). Required.
[parameter(Mandatory=$true)][string]$SourceDatastore_str,
## The name of the destination datastore. Required.
[parameter(Mandatory=$true)][string]$DestDatastore_str
) ## end parameter
## Set proper variable names from the supplied parameters
$strSrcDatastore = $SourceDatastore_str
$strDestDatastore = $DestDatastore_str
## Get the .NET view of the source datastore
$viewSrcDatastore = Get-View -ViewType Datastore -Property Name -Filter @{"Name" = "^${strSrcDatastore}$"}
## Get the linked view that contains the list of VMs on the source datastore
$viewSrcDatastore.UpdateViewData("Vm.Config.Files.VmPathName", "Vm.Config.Hardware.Device", "Vm.Config.Template", "Vm.Runtime.Host", "Vm.Name")
## Get the .NET view of the destination datastore
$viewDestDatastore = Get-View -ViewType Datastore -Property Name -Filter @{"Name" = "^${strDestDatastore}$"}
## Create a VirtualMachineMovePriority object for the RelocateVM task; 0 = defaultPriority, 1 = highPriority, 2 = lowPriority (per http://pubs.vmware.com/vsphere-51/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvim.VirtualMachine.MovePriority.html)
$specVMMovePriority = New-Object VMware.Vim.VirtualMachineMovePriority -Property @{"value__" = 1}
## Create empty arrays to track templates and VMs
$arrVMList = $arrTemplateList = @()
## For each VM managed object, sort into separate arrays based on whether it is a VM or a template
$viewSrcDatastore.LinkedView.Vm | % {
## If object is a template, add to template array
if ($_.Config.Template -eq "True") {$arrTemplateList += $_}
## Else, add it to the VM array
else {$arrVMList += $_}
}
## For each VM object, initiate the RelocateVM_Task() method; for each template object, initiate the RelocateVM() method
$arrVMList, $arrTemplateList | %{$_} | %{
$viewVMToMove = $_
## Create a VirtualMachineRelocateSpec object for the RelocateVM task
$specVMRelocate = New-Object Vmware.Vim.VirtualMachineRelocateSpec
## Create an array containing all the virtual disks for the current VM/template
$arrVirtualDisks = $viewVMToMove.Config.Hardware.Device | ?{$_ -is [VMware.Vim.VirtualDisk]}
## If the VM/template's config files reside on the source datastore, set this to the destination datastore (if not specified, the config files are not moved)
if ($viewVMToMove.Config.Files.VmPathName.Split("]")[0].Trim("[") -eq $strSrcDatastore) {
$specVMRelocate.Datastore = $viewDestDatastore.MoRef
} ## end if
## For each VirtualDisk for this VM/template, make a VirtualMachineRelocateSpecDiskLocator object (to move disks that are on the source datastore, and leave other disks on their current datastore)
## But first, make sure the VM/template actually has any disks
if ($arrVirtualDisks) {
foreach($oVirtualDisk in $arrVirtualDisks) {
$oVMReloSpecDiskLocator = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator -Property @{
## If this virtual disk's filename matches the source datastore name, set the VMReloSpecDiskLocator Datastore property to the destination datastore's MoRef, else, set this property to the virtual disk's current datastore MoRef
DataStore = if ($oVirtualDisk.Backing.Filename -match $strSrcDatastore) {$viewDestDatastore.MoRef} else {$oVirtualDisk.Backing.Datastore}
DiskID = $oVirtualDisk.Key
} ## end new-object
$specVMRelocate.disk += $oVMReloSpecDiskLocator
} ## end foreach
} ## end if
## Determine if template or VM, then perform necessary relocation steps
if ($viewVMToMove.Config.Template -eq "True") {
## Gather necessary objects to mark template as a VM (VMHost where template currently resides and default, root resource pool of the cluster)
$viewTemplateVMHost = Get-View -Id $_.Runtime.Host -Property Parent
$viewTemplateResPool = Get-View -ViewType ResourcePool -Property Name -SearchRoot $viewTemplateVMHost.Parent -Filter @{"Name" = "^Resources$"}
## Mark the template as a VM
$_.MarkAsVirtualMachine($viewTemplateResPool.MoRef, $viewTemplateVMHost.MoRef)
## Relocate the template synchronously (i.e. one at a time)
$viewVMToMove.RelocateVM($specVMRelocate, $specVMMovePriority)
## Convert VM back to template
$viewVMToMove.MarkAsTemplate()
}
else {
## Initiate the RelocateVM task (asynchronously)
$viewVMToMove.RelocateVM_Task($specVMRelocate, $specVMMovePriority)
}
} ## end foreach-object</pre>
<br />
To use the script, you'll need to provide the source and destination datastore as parameters as such:<br />
<br />
<pre class="PowershellSession">PS vNuggs:\> .\EvacuateDatastore.ps1 -SourceDatastore DATASTORE1 -DestDatastore DATASTORE4</pre>
<br />
Many of the comments in the code are self-explanatory, but here are some additional details around the more important/complex parts:<br />
<br />
<b>Lines 35-40:</b> In this section, we determine whether the objects from the datastore's linked view are standard VM managed objects or whether they are actually a template and put them into separate arrays.<br />
<br />
<b>Line 43:</b> This is where we pipe the two arrays into a <span class="VN_codeFace">ForEach-Object</span> loop to start the process of gathering the necessary data to relocate the VM/template to the new datastore. We chose to begin with the VMs first because we eventually want to kick them off as vCenter tasks so that we can then focus on the templates.<br />
<br />
<b>Line 50:</b> This is the part that combats problem #2 above. Here, we parse the datastore name out of the fully-qualified path to the VM/template's config file and if it matches the source datastore, then that's the only time we set the "datastore" property of the <span class="VN_codeFace">VirtualMachineRelocateSpec</span> object to the destination datastore as that's the only time we want to move the config files.<br />
<br />
<b>Lines 56-65:</b> Now the <span class="VN_codeFace">VirtualMachineRelocateSpecDiskLocator</span> object is populated accordingly--if the disk is on the source datastore, then its "datastore" property is set to the destination datastore so it gets moved, otherwise it is set to its current datastore so it does not get moved. Line 63 adds it to the "disk" property of the <span class="VN_codeFace">VirtualMachineRelocateSpec</span> object and everything repeats for the next disk if more exist.<br />
<br />
<b>Lines 68-78:</b> On line 68 we have to check if the current VM object is really a VM or a template, even though we already did this earlier. This is better than having to duplicate all the code from lines 43-65, however. Then lines 70-73 are how we deal with problem #1 from above. Since we determined this object was a template, we must convert it to a VM in order to relocate it to a different datastore. It is a shame VMware still doesn't allow us to move templates for some reason. Finally, line 75 calls the <span class="VN_codeFace">RelocateVM()</span> method of the VM managed object and begins the relocation. It is important to note that this occurs in a synchronous manner (i.e. one template at a time). As you'll see in the next section, we don't do this if it is a VM object, but we really have no choice when dealing with templates because we need to wait for the relocation to complete before we can convert the VM back to a template. This occurs on line 77.<br />
<br />
<b>Lines 79-82:</b> In this section, namely line 81, we call the <span class="VN_codeFace">RelocateVM_Task()</span> method this time since this object is a VM, not a template. This way we kick off "RelocateVM" tasks asynchronously and let vCenter decide how many it can handle at once, which as of vSphere 5.0 and 5.1 is eight per datastore and two per host. In addition, we piped the VM objects into the loop first so that we could kick them all off and then focus on the templates one by one. But, if you are concerned that your storage array won't be able to handle the load of multiple storage migrations, simply change line 81 to look like line 75 and it'll behave synchronously like the templates do.<br />
<br />
If you've read this far, you may be wondering what use this sort of script has in the world of SDRS (Storage DRS). Yes, SDRS has features like datastore maintenance mode that would prevent the need for some of this type of work, but not everyone has SDRS available to them; either because they haven't found the time to implement it yet, haven't upgraded to vSphere 5.x yet, or just don't own the Enterprise Plus edition, so this script is likely to be of use to many people still. We hope so.<br />
<br />AC (@allen_crawford)http://www.blogger.com/profile/05360032132878174436noreply@blogger.com4tag:blogger.com,1999:blog-2269516327950490847.post-70336714923741447152012-10-02T20:38:00.001-04:002012-10-02T20:39:59.779-04:00VMHost Logical Drive Info from CIM Provider with PowerCLIJoe at <a href="http://filippello.com/">filippello.com</a> was grabbing some Logical Volume info for local disks on VMware hosts he was building in his post "<a href="http://www.filippello.com/?p=85" target="_blank">Frustrated with fast booting hardware?</a>". He realized that, rather than going to the RAID controller setup and viewing the logical volume info, the CIM provider is nice enough to provide that info, and vCenter displays it on the Hardware Status tab for the host.<br />
<br />
We wanted to get that info for lots of hosts instead of one at a time in the vSphere client, so I checked into the properties of the <span style="font-family: "Courier New",Courier,monospace;">HostSystem</span>. The CIM provider tells about the logical volumes. vSphere presents this in the <span style="font-family: "Courier New",Courier,monospace;">Runtime.HealthSystemRuntime.HardwareStatusInfo.StorageStatusInfo</span> property. For the HP hosts I used, this property also holds info about each individual local disk, the array controller(s), and their battery. So, if you are looking for such info, this is a good property to explore. But, back to the topic at hand.<br />
<br />
The function:
<br />
<pre class="brush: powershell"><# .Description
Get logical volume info for HP VMHosts from StorageStatusInfo of their managed objects. Depends on CIM provider being installed and in good health (responsive and whatnot), presumably
Author: vNugglets.com -- Aug 2012
#>
function Get-VNVMHostLogicalVolumeInfo {
param(
## name of VMHost to check; if none, queries all hosts
[string]$VMHostName_str
) ## end param
## make the Get-View expression to invoke
$strGetViewExpr = 'Get-View -ViewType HostSystem -Property Name,Runtime.HealthSystemRuntime.HardwareStatusInfo.StorageStatusInfo'
if ($VMHostName_str) {$strGetViewExpr += " -Filter @{'Name' = '$VMHostName_str'}"}
Invoke-Expression $strGetViewExpr | Select name,
@{n="logicalVol";
e={($_.Runtime.HealthSystemRuntime.HardwareStatusInfo.StorageStatusInfo | `
?{$_.Name -like "Logical*"} | %{$_.Name}) -join ", "}}
} ## end function</pre>
<br />
Some example usage:<br />
<pre class="PowershellSession">## for one host
PS vNuggs:> Get-VNVMHostLogicalVolumeInfo.ps1 -VMHostName devhost0323.mydomain.com
Name logicalVol
---- ----------
devhost0323.mydomain.com Logical Volume 1 on HPSA1 : RAID 1 : 136GB : Disk 1,2,3
## for all hosts, call with no parameter
PS vNuggs:> Get-VNVMHostLogicalVolumeInfo.ps1
Name logicalVol
---- ----------
devhost0323.mydomain.com Logical Volume 1 on HPSA1 : RAID 1 : 136GB : Disk 1,2,3
devhost4323.mydomain.com Logical Volume 1 on HPSA1 : RAID 1 : 136GB : Disk 1,2,3
devhost1.mydomain.com Logical Volume 1 on HPSA1 : RAID 1 : 136GB : Disk 1,2,3
devhost27.our.domain.com Logical Volume 1 on HPSA1 : RAID 1 : 68GB : Disk 1,2
devhost2.our.domain.com Logical Volume 1 on HPSA1 : RAID 1 : 68GB : Disk 1,2
devhost743.our.domain.com Logical Volume 1 on HPSA1 : RAID 1 : 68GB : Disk 1,2
devhost31111.our.domain.com Logical Volume 1 on HPSA1 : RAID 1 : 68GB : Disk 1,2
devhost21.our.domain.com Logical Volume 1 on HPSA1 : RAID 1 : 68GB : Disk 1,2
devhost431.our.domain.com Logical Volume 1 on HPSA1 : RAID 1 : 68GB : Disk 1,2
devhost3.mydomain.com Logical Volume 1 on HPSA1 : RAID 1 : 68GB : Disk 1,2
devhost30.mydomain.com Logical Volume 1 on HPSA1 : RAID 1 : 68GB : Disk 1,2
devhost.mydomain.com Logical Volume 1 on HPSA1 : RAID 1 : 68GB : Disk 1,2, Logical Volume 2 on HPSA1 : RAID 1 : 68GB : Disk 3,4
devhost122.mydomain.com Logical Volume 1 on HPSA1 : RAID 1 : 136GB : Disk 1,2
...</pre>
<br />
And, an example of using some of the other info returned by the CIM provider: if you were to change the <span style="font-family: "Courier New",Courier,monospace;">?{$_.Name -like "Logical*"}</span> in the above function (<b>line 17</b>) to <span style="font-family: "Courier New",Courier,monospace;">?{$_.Name -like "Disk*"}</span>, you could get just the local disks' info (instead of info on the logical volumes):
<br />
<pre class="PowershellSession">...
Disk 1 on HPSA1 : Port 1I Box 1 Bay 1 : 136GB : Data Disk, Disk 2 on HPSA1 : Port 1I Box 1 Bay 2 : 136GB : Data Disk, Disk 3 on HPSA1 : Port 1I Box 1 Bay 3 : 136GB : Spare Disk
...</pre>
Enjoy.
MattBoren (@mtboren)http://www.blogger.com/profile/08371304528581535245noreply@blogger.com0