VMware library

2017-06-25_203353The entire vSphere community (myself included) seems to be in a flutter over the release of the long awaited Host Resources Deep Dive by Frank Denneman and Niels Hagoort. For me this recently resulted in a tweet-thread to see who had bought the most copies (I lost). The upside to this whole thing is I came across Mr. Ariel Sanchez Mora’s (you should follow him ) VMware book list. I love book reviews, so with Ariel’s permission I’m stealing his idea! In fairness you should really go check out his page first, but make sure to come back! Without further ado, here’s the best of my VMware library.

 

Certification

Like many people, this is where I started. I’d heard horror stories about about the VCP, so after taking Install, Configure, Manage I bought my first book, coincidentally (or not) written by the instructor of my class. I immediately followed it up by adding the second piece to my library.

The Official VCP5 Certification Guide (VMware press) by Bill Ferguson

VCP5 VMware Certified Professional on vSphere 5 Study Guide: Exam VCP-510

(Sybex) by Brian Atkinson

I think that in terms of the earlier books, I’d give the edge to the Sybex version. It covers the same fundamentals as the official guide, but goes much deeper.

Just last year while at 2016 I was wandering around the expo floor at VMworld 2016, bumming from failing my VCP6 (it was expected, but disappointing nonetheless), and I walked straight into a book signing for the new VCP6-DCV cert guide. It was destiny or something like that

VCP6-DCV Official Cert Guide (Exam #2V0-621) (VMware Press) by John Davis, Steve Baca, Owen Thomas

Here’s the thing with certification guides; the majority of the material doesn’t change from version to version. DRS is DRS is DRS (not really, but the fundamentals are all there). If you’re just getting started, or able to get a hand-me-down version of an earlier version you’ll still be leaps and bounds ahead of folks who haven’t read the books. They can be a good way to get a grasp on the fundamentals if all you’re looking to do is learn. To that end, if you’re goal is to pass the test, you can’t go wrong with picking up an official certification guide. I know the VCP6-DCV guide provided an invaluable refresher for me.

For more on the VCP-DCV, please check out my study resources.

Hands On

Learning PowerCLI (Packt publishing) by Robert van den Nieuwendijk

I didn’t realize until just right now that there was a second edition of this book released in February of this year! Regardless, this book is a great way to get started with PowerCLI, however it’s more of a recipe cookbook than a tutorial. If you need a getting started with PowerShell book, look no further than:

Learn Windows PowerShell in a Month of Lunches by Donald Jones and Jeffrey Hicks.

This is the guide to get started with PowerShell. Honestly I think the authors should give me commission for how many people I’ve told to go buy this book. It’s not a vSphere book, but if you want to be effective with PowerCLI, this book will help you on your way. It breaks the concept up into small manageable chunks that you can swallow on your daily lunch break.

DevOps for VMware Administrators (VMware press) Trevor Roberts, Josh Atwell, Egle Sigler, Yvovan Doorn

“DevOps” to me is like “the cloud”. It means different things to different people. In this case the book focuses solely on the tools that can be used to help implement the framework that is DevOps. Nonetheless, it’s a great primer into a number of the most popular tools that are implemented to support a DevOps philosophy. If you’re struggling with automation and/or tool selection for your DevOps framework, there are far worse places to start.

Mastery

Mastering VMware vSphere series

The gold standard for learning the basics of vSphere. This title could just as easily appear under the certification section, as it appears on almost every study list. A word of warning, this is not the book to learn about the latest features in a release. That’s what the official documents are for. You may notice that I linked an old version above, and that’s because the latest version was conspicuously missing nearly all of the new features in vSphere 6. That being said, it’s another standard that should be on all bookshelves.

VMware vSphere Design (Sybex) Forbes Gurthrie and Scott Lowe

Age really doesn’t matter with some things, and while that rarely pertains to IT technologies, good design practices never go out of style. This thought provoking book will help you learn how to design your datacenter to be the most effective it can be. I’d recommend this book to anyone who’s in an infrastructure design role, regardless of whether they were working on vSphere or not.

It Architect: Foundation in the Art of Infrastructure Design: A Practical Guide for It Architects John Yani Arrasjid, Mark Gabryjelski, Chris Mccain

And then on the other hand you have a design book that’s built for a specific purpose and that’s to pass the VCDX. Much of the content is built and delivered specifically for those who are looking to attain this elite certification. This is a good book, but as someone who has no intention of ever going after a VCDX, I expected something a bit less focused on a cert, and a bit more focused on design principles. If unlike me you have VCDX aspirations, you definitely need to go grab a copy.

VMware vSphere 5.1 Clustering Deepdive (Volume 1) Duncan Epping & Frank Denneman

I really don’t care if this was written for a five year old OS or not. If you want to learn about how vSphere makes decisions and how to work with HA/DRS/Storage DRS/Stretched Clusters, this is an essential read. Put on your swimmies because you’re going off the diving board and into the deep end!

I’m just going to go ahead and leave a placeholder here for the aforementioned VMware vSphere 6.5 Host Resources Deep Dive. Having heard them speak before and read their other works, I expect this book to be nothing less than mind blowing.

If you liked this, please check out my other book reviews.

Thanks for visiting!

It’s a bird, it’s a plane, it’s… Invoke-VMScript

I was at work today and a need came across my desk for a solution that requires SNMP. For some reason which I can’t fathom, SNMP is not installed as a service on the majority of the servers. Who do we turn to in tumultuous times like these? PowerShell and his mighty sidekick PowerCLI!

michael-corleone-pull-me-back-in-just-when-i-thought-i-was-out-they-pull-me-back-inFirst things first I wanted to know the scope of what I was dealing with. When I dove into this problem I had every intention of trying to broaden my horizons and move away from PowerCLI, but it’s so easy to get sucked back into what you know. Besides, I knew I was only targeting a couple of clusters, so it only made sense to go back to PowerCLI, right? Right???

If you ignore the ugly formatting, what I did below was load all of the VM’s I needed to target into an object and then iterate through each of them to make sure they were windows machines and that they were powered on. In hindsight I knew that I was probably going to use invoke-vmscript to get the job done, so I probably should have checked for vmTools status (ExtensionData.Guest.ToolsRunningStatus) while I was at it.  snmp1

So now we’ve got a nice neat little hashtable full of servers that need a little TLC. You’d think that we could immediately get rocking, but without going into details things unexpectedly got a little dodgy at this point. I mentioned earlier that I originally intended to try and break away from PowerCLI just to broaden my horizons. Unfortunately as an Infrastructure person you don’t always have the opportunity to do things the way you’d like, and you have to sacrifice elegance for just getting things done. Luckily as VMware admins when we need to get $hit done, we have a very handy and very powerful tool available to us and that is invoke-vmscript.

b436ea981cd43a8a244370d95fa3f343_super-troopers-better-fix-meow-super-troopers-meme_250-131If you’ve heard me talk, reviewed my scripts or spent any time around me you’d know that I think invoke-vmscript is the cat’s meow. It is without a doubt my favorite cmdlet as it lets you get away with some pretty awesome stuff. At it’s root, invoke-vmscript allows you to run a script via VMtools within the context of the local VM. Now this is different from PSexec or PowerShell remoting; you are actually running the a script within the local OS where VMtools and PowerCLI are just the mechanisms to enable this super hero activity.

Quick sidebar: With great power comes great responsibility. I said above that invoke-vmscript “lets you get away with some pretty awesome stuff.” Many people in this world just deploy VMtools and vCenter with default permissions and credentials. If you are a security person, you need to ensure that your roles and privileges are setup appropriately, of you could have exposure due to what you can accomplish with VMtools.

But I digress. We are here to get things done and at the center of it this whole exercise boils down to a one liner:

<strong>Invoke-VMScript -VM $client.Name -ScriptText "DISM /online /enable-feature /norestart /featurename:SNMP" -ScriptType Powershell

 

If you refer back to the original snip, we stored all of the servers into an array, which is being iterated through. We invoke the script targeting $client.name. The parameter for ScriptText is where we pass in the script that we would like to run on the remote system. In this case we are using the Microsoft DISM tool to add the SNMP feature to our Windows installation. Lastly is the parameter for ScriptType. You have three ScriptType options available to you as of today: Bat for you old school Windows Cats, Bash for the nix kittens and PowerShell for the up and coming cubs.

When you put it all together, here’s the code to get it done:

$serverset=$(get-cluster cluster1|Get-VM) + $(get-cluster cluster2|Get-VM)

$ArrRemediate=@()

foreach ($client in $serverset){

if($client.powerstate -eq "PoweredOn" -and $client.guestid.contains("windows")){

if(!$(get-service -ComputerName $client -Name SNMP -ea silentlycontinue)){
$ArrRemediate+=$client
Invoke-VMScript -VM $client.Name -ScriptText "DISM /online /enable-feature /norestart /featurename:SNMP" -ScriptType Powershell
get-service -ComputerName $client.Name -Name SNMP|Select-Object -Property name, status, starttype |ft

}

}

}

&nbsp;

$ArrRemediate.Count

I hope for today you’ll excuse the formatting and less than efficient code, as the mission was to get things done. We achieved our mission and escaped certain doom due to our friendly neigboorhood hero Invoke-VMScript. I hope to have a deeper expose into our masked super hero soon, but until then if you have any thoughts or would like to contribute to the conversation, please reach out.

Why you need more PowerShell

or: How I stopped worrying and learned to love the CLI

I recently gave a Tech Talk at our spring Champlain Valley VMUG on PowerShell and PowerCLI. The talk definitely was more of an introductory instructional, but one of our attendees expressed that they wanted to hear more about the value that can be delivered back to the organization by scripting with PowerShell. Hopefully I can give you a solid overview of the immense value of PowerShell here today.

Why?

The only constant is change and that holds true for IT infrastructure folks as well. Terms like DevOps, distruptor, and Shadow IT have become firmly established in our lexicon. And with good reason! We are in a world that is moving faster and faster everyday and you often see where it’s not the best product that corners a market, but rather it’s the first/fastest to market that gets a stranglehold. If you come from a classical IT role with silos and legacy processes/policies that slow your Organization down… well is it any wonder that you have disruptors changing the model?!? But what if there was a way that you could help accelerate your business, work collaboratively with the Developers, combat against Shadow IT and be the disruptor yourself? Powershell can be the tool that enables this transformation by delivering Time and Consistency to your organization.

Time

This one is simple. Time is money and by investing a little bit of effort up front  scripting a solution, you will save time moving forward. Here is the no-brainer part of the value prop: Do you want to take on the timely task of building environments by hand? Of course you don’t! You want something that’s fast and easy. There’s a take on the old adage that I’ll paraphrase here “Do it once, ok. Do it twice, shame on me. Do it three times, why haven’t you scripted it yet?”

Let’s suppose for a second that you have to install a widget dozens, hundreds or thousands of times. This activity takes hours. Once you script & automate that install, you turn it into a hands off activity freeing up your engineers to do more of the activities that will drive value instead of just watching the progress bar. Simply by the act of writing that script, you’ve saved your business time/money, and honestly you’ve probably gained a bit of expertise and employee engagement as well. Extrapolate this out to all of the infrastructure elements you need to manage: people, policy, applications, servers, storage, network, security and the list goes on and on. Even if you can only automate part of a process, you’re still going to see dividends.

51oYzgTCiyL._SX427_BO1,204,203,200_[1]A less intuitive reason for starting with PowerShell is that it has a pretty quick learning curve, especially if you come from a windows environment. If you have any programming/scripting background you can likely dive right in. This means that your team can be scripting sooner, and can start ensuring that they are driving the non-value added operations out of your day to day. Many infrastructure folks don’t have a background in development activities and as such scripting can be a bit of a hard sell. PowerShell was meant to build upon and extend the foundation of items like Batch and VBscript, but in a way that is intuitive to learn and become efficient with quickly. One of my go to guides for learning PowerShell is the Learn Windows PowerShell in a Month of Lunches guide. This book is so successful in large part because it demonstrates just how easily accessible PowerShell really is.

2017-03-28 11_47_02-Windows PowerShell ISEI mentioned earlier that you can create collaborative opportunities and combat against Shadow IT. PowerShell is built on top of the .NET framework and has support for RestAPI’s baked in. This means that you can share code, speak the same language and have smoother hand-offs. By using PowerShell you have an opportunity to increase the amount of collaboration between your groups. If you can harness this opportunity you’re likely going suffer from less finger pointing, and be able to cut out some unnecessary meetings.

Consistency

Time and consistency (and money) go hand in hand in IT. Having inconsistent environments results in more frequent issues and longer times to resolution. When you start scripting out your activities you will have a much more predictable environment, outages will decrease in frequency and your time to resolution will also drop. This all yields in greater up-time. More up-time means happier customers and happier engineers. Your business is winning!

tom-brady-goat[1]
One is a goat. The other is the GOAT.
Speaking of winning, do you know why Tom Brady is one of the Greatest Of All Time? It’s not because of his ugg’s or his supermodel wife. It’s because he has put in the work up front to ensure that no matter who he is working with, he will have a predictable and consistent outcome. This is what you should be aiming for with your environment: consistent and predictable.

Having a consistent repeatable infrastructure makes that environment easier to rebuild. If you can kick off a PowerShell script that results in a fresh server in a matter of minutes, why would you spend hours troubleshooting a problem? The saying “treat your servers like cattle, not like pets” became popularized for a reason. Wikipedia states that “The term commodity is specifically used for an economic good or service when the demand for it has no qualitative differentiation across a market.” Your servers SHOULD have no qualitative differences, and are therefore inherently commodities, and replaceable. Diving into PowerShell and PowerCLI can help get you there.

PowerCLI

I’ve mentioned it a number of times but some of you may be going, what is this PowerCLI thing? PowerCLI is VMware’s implementation of PowerCLI modules which allow you to “automate all aspects of vSphere management, including network, storage, VM, guest OS and more.” To put it short, it’s a super efficient and reliable (not to mention fun) way to manage your vSphere environments. It’s also incredibly powerful.  There are over 500 separate commandlets in the modules which make up PowerCLI. By some accounts VMware has approximately 80% of the hypervisor market, which means the majority of the worlds infrastructure run’s on vSphere and can be managed with PowerCLI.

Using PowerCLI just allows you to further expand on the amount of Time and Consistency that you can deliver back into your business. With PowerCLI you can automate/manage the network, hypervisors, storage and all of the elements that encompass your “infrastructure”. You can also take it one step further and thanks to the security models built into vSphere you can let your users do it too! With a little bit of thought and design, you can give your developers the ability to spin up and spin down their own VM’s. No more test/dev headaches for you and your developers are happier! The winning doesn’t stop!

As I said to start my VMUG presentation, I’m not an expert in PowerShell or PowerCLI, but I have used it very effectively in my day to day. It’s also a topic that I’m passionate about, otherwise you’d never catch me voluntarily speaking in front of 100 people! I’ve also managed to write some fairly complex scripts that have helped my Organizations reach goals. I hope this post helps you understand some of the value PowerShell & PowerCLI scripting. If you’d like to keep the conversation going or if you have any questions I’d love to hear from you.

Another day, another PowerCLI report

Another day another reason to love PowerShell.

 I have to come up with a list of all of my Windows machines, their OS versions and editions. My first thought being nearly 100% virtualized is “WooHoo, thank you PowerCLI”…

Except that they don’t include the edition for each VM… Sad face.

image001

However, one of my favorite elements of the PowerCLI tool is the Invoke-VMScript cmdlet contained within the VMware.VimAutomation.Core module. For more about modules, see my post Getting Started with PowerCLI. This script does exactly what it sounds like; it allows you to run a script in the guest OS. Now there’s obviously a number of pre-requisites to leveraging this tool. The big ones are as such.

  • VMtools must be running within the VM
  • You must have access to vCenter or the host where the machine resides
  • You must have Virtual Machine.Interaction.Console Interaction privilege
  • And of course you must have the necessary privileges within the VM.

There could also be some security concerns, allowing your VMware administrators the ability to run scripts within the virtual Operating System Environment, but this opens a whole other bag of worms that we’ll put aside for another conversation.

Once you’ve comfortable with the pre-req’s and any potential security elements, you can get started.

get-vm vm-vm | `
Invoke-VMScript -ScriptType Powershell -ScriptText "gwmi win32_Operatingsystem" 

So what are we doing here? We get the VM object and pipe it to the Invoke-VMScript commandlet where we are running the Powershell script “gwmi win32_Operatingsystem” within the context of the virtual OSE! What you get back is another PowerShell object containing the ExitCode of the script and the output within the ScriptOutput property.

Now just a quick sidenote. If you write powershell scripts, then inevitably you know about Get-member (aliased to: GM), but that only shows you methods and properties, not the values. If you’re not sure what you’re looking for and you’d like to see all the property elements of the object, you can just use $ObjectName|select -property * to output.

Back to the task at hand, I know I need a count of each OS type. I’d also ideally like that broken down by cluster. It would also be nice to know the machines that weren’t counted, so I can go and investigate them manually. So here we go.

$daCred=$host.ui.PromptForCredential("Please enter DA credentials","Enter credentials in the format of domainname\username","","")
foreach($objCluster in Get-Cluster){
    write-host "~~~Getting Window OS stats for $objCluster~~~"
    $arrOS=@()
    foreach ($objvm in $($objCluster|get-vm)){
        if($objvm.guestid.contains("windows")){
            $status=$objvm.extensiondata.Guest.ToolsStatus
            if ($status -eq "toolsOk" -or $status -eq "toolsOld"){
                $arrOS+=$(Invoke-VMScript -VM $objvm -ScriptType Powershell -ScriptText '$(gwmi win32_operatingsystem).caption' -GuestCredential $daCred -WarningAction SilentlyContinue).ScriptOutput
            }else{
                Write-Host "Investigate VMtools status on $($objvm)   Status = $status" -BackgroundColor Red
            }
        }
    }
    $arrOS|group |select count, name |ft -AutoSize -Wrap
    Write-Host
}

You may say, what’s happening here? Let me tell you

After we enter in credentials that we know will work, we are going to iterate through each cluster and as we do such we are going to create an array of each OS that we find in our journey. As we iterate through each VM in the cluster we’ll check on VMtools status as we go, and if necessary flag the VM’s for check later. Then we are going to run Invoke-VMScript within a variable so that we can only capture the ScriptOutput property that’s returned within our array. Finally we can do a little sorting and counting on the array, output to the screen, and go investigate why we have so many darn red marks dirtying up our screen!

image002

Until next time, be well!

Sweep up that mess!

I have a perhaps daunting task in front of me, and that’s to clean up a network block, and I don’t know what’s on it. So what’s a person to do? Well, I took a couple of minutes to write my own simple ping sweep.

Thankfully Microsoft made this nice and easy with the Test-Connection cmdlet. In the past you’d have to parse the output from our good old ping, and honestly nobody wants to spend their time doing that.

Throw in a loop and a test condition, and you’re almost all the way there. I decided that I wasn’t happy not knowing whether an IP was reachable or not, but not knowing who was at the receiving end, so I decided to use the .NET DNS class to do a lookup.  Now when this class doesn’t find a result it throws an ugly and unfriendly error message. For this reason you may have noticed that I set preferences for ErrorAction and WarnAction at the top of the script.

As written it won’t scan more than a class C, but you could pretty easily alter it to fit your needs.

And there you go! Simple ping sweeps.

</pre>
$ErrorActionPreference ="SilentlyContinue"
 $WarningPreference = "SilentlyContinue"

$range = "192.168.42."
 $firstip=1
 $lastip=15
 $numpings =3

write-host "Please be patient.
 Based on the IP range entered, the script will take at least $(($lastip - $firstip) * ($numpings+1)) seconds to complete.
 Information that appears hereafter are hosts that are able to be reached"

$count=0
 For ($ip=$firstip; $ip -lt $lastip; $ip++){
 $testip=$range
 $testip+=$ip
 if(Test-Connection $testip -Quiet -count $numpings ){
 write-host $testip -NoNewline
 $nsresult = [System.Net.Dns]::gethostentry($testip)
 if ($nsresult){
 write-host ", "$nsresult.HostName
 }else{
 write-host ""
 }
 $count++
 }
 #ping $testip -n 1
 if ($nsresult){$nsresult = $null}
 Clear-Variable testip
 }

Write-Host "You found $count reachable addresses in this range"
 write-host "Fin!" -BackgroundColor Cyan -ForegroundColor Black
<pre>

2016-12-20-14_04_38-administrator_-windows-powershell-ise

Let’s Hash it out

In the past I always found it to be a giant PITA computing HASH values for files on Windows.

Why do you need to compute HASH values? Once you have the fun experience of trying to deploy a solution from an iso or ova image that got corrupted during download, you’ll never ask that question again.

What does the hash (or checksum) do? It simply is a computation of the bits in a file and is commonly used as an integrity check.

Why is an article about hash values on a VMware blog? Because the kind folks at VMware provide you with the MD5/SHA1/SHA256 calculations for all of their downloads. And if you have at least PowerShell 4.o, Microsoft gave you a little cmdlet for calculating file hashes. And since I’m about to install an eval of vRO as a proof of concept/value, here’s the handy dandy code you’d use to calculate a simple checksum:

 Get-FileHash .\vRO6_4.ova -Algorithm SHA256  

get_filehash

As with any other cmdlet there’s way more that you can do, but for 90% of my needs this simple commandlet is all you need.

Getting started with PowerCLI

I’m setting up a new computer and thought to myself “hey self, this might be a good time to write your first PowerCLI post”

The first post was going to be about how to customize your profile, but why recreate the wheel. Check out awesome post on how to customize your PowerShell profile.

With that being said if you’re actually reading this, chances are you’re really bored or you’re newish to PowerCLI/PowerShell, so we are going to start back at basics. If it’s the later the first thing you’re going to want to do is update PowerShell to the latest version. PowerShell 2 was interesting, and PowerShell 3 was a huge improvement but at this point you really shouldn’t be running anything less than PowerShell 4.0.  To see what version you’re running, you could simply enter $PSVersionTable and hit enter. However what you’re really interested in is the major version that can be accessed by entering the following and hitting enter.

$PSVersionTable.PSVersion.Major

The output from this variable is the primary version of PowerShell that you’re running

sidenote: If you’re paying close attention, you probably noticed that PowerShell has tab complete functionality that will be one of your best friends as you move along with your PowerShell adventures.

2016_11_29_13_14_39_administrator_windows_powershell_ise

We just established that you’re paying attention, so you’ve also noticed that the above screenshot is not just the PowerShell command interpreter. What you’re looking at it is PowerShell ISE (Integrated Scripting Environment). It’s a scripting pane (the top part where you write the script), along with the command interpreter and a command window, but if you know how to use the help commandlet (we’ll get there) the command window is largely useless IMHO.

Now since you are an astute reader you’d probably first ask yourself “how do I get this ISE thing?”. Why it’s not installed by default, I’ll never know, but if you want to use it (you do) then you’ll need to add from the Windows feature menu.

Secondly you’re probably saying, isn’t this supposed to be about PowerCLI? We’re getting there, be patient! These are a couple of the items that have helped me be successful when I was first starting to write PowerShell/PowerCLI scripts.

OK, PowerCLI. You’ll need to logon to your my.vmware.com account to get the latest release, 6.5 as of this writing. You should check out the VMware PowerCLI blog as well. Lots of great information about the releases, and you can pick up some good tips along the way. IF you already have scripts written for earlier versions of PowerCLI, be cautious about the version you install. Why? Let me tell you.

The kind folks at VMware have been working to convert from snap-ins to modules and as of a few days ago that conversion appears to be complete. This is great for you because the scripts that you’re going to write, just became a whole lot more portable and therefore useful. BUT if you’re using scripts that are already built,  that leverage snap-ins AND you upgrade to a PowerCLI version that has converted that functionality to modules… uh oh…

Now that you’ve finally installed PowerCLI you fire it up and …. wait, where’s my ISE window? VMware does not give you a PowerCLI_ISE window, so you fire up good old PowerShell_ISE and … what? you don’t have the PowerCLI commandlets available to you??? Who’s idea of a cruel prank is this? So you enter the command

Get-Module -ListAvailable | Where-Object {$_.name.Contains(“VMware”)}

and when you hit enter, phew, you’ve finally got some stuff to work with.

posercli_modules

To load any of the modules, you simply enter the command import-module . For example to leverage many of the common vCenter tasks, you’d load the core module via the command:

import-module VMware.VimAutomation.Core

I don’t know about you, but I don’t like repeating myself. The way we avoid having to run the commands to load modules every time we want to write a script is via our PowerShell profile. (see what I did there, connected it all together I did)**   I’m going to presume that you at least skimmed the article referenced at the top of this post, so you already have a PowerShell profile that can be accessed by running notepad $profile in a PowerShell window. Simply enter the commands that you want run when you launch PowerShell hit ctrl-s and BLAMMO you get your PowerCLI modules loaded automagically every time that you launch PowerShell!

If you find this useful, please let me know. I’m planning on writing a series of PowerShell/PowerCLI posts for beginners, so your feedback is really appreciated.

Have a great one!

**read in your best yoda voice