Category Archives: Twitter Reply

Twitter Reply – More AWS PowerShell Changes Due to Twitter (and Me)

It happened again. My Tweet, that was linked to a post here, became the catalyst for a change in the AWS PowerShell module. I’m 2 for 2. This time, AWS didn’t simply correct the spelling of a parameter name; they wrote a new cmdlet. Remove-EC2Instance works as advertised. It’ll prompt for confirmation before terminating an EC2 instance, unless the -Force parameter is also included with the command. It is flawless. You can always get the newest AWSPowerShell module at http://aws.amazon.com/powershell.

What this didn’t do, however, is fix Stop-EC2Instance. Steve, the individual that spotted this and my last AWS Tweet, and likely made these corrections and additions, said they couldn’t remove the malfunctioning -Terminate parameter from Stop-EC2Intance. For those that didn’t read my last AWS post, the -Terminate parameter never prompted for confirmation before terminating an instance (unless a change has been made since Remove-EC2Instance was released).

I read an interesting article recently that indicated to use termination protection:

Use termination protection for non-auto-scaling instances. Thank me later.
If you have any instances which are one-off things that aren’t under auto-scaling, then you should probably enable termination protection, to stop anyone from accidentally deleting the instance. I’ve had it happen, it sucks, learn from my mistake!”

While it was still quite amazing to get a second change made to the AWSPowerShell module, I’d recommend that everyone continue to be careful with Stop-EC2Instance. Perhaps you can write your own wrapper function, with the same name as the cmdlet (and therefore, it’ll be the default when Stop-EC2Instance is called), that forces confirmation. Then again, you can just use Remove-EC2Instance now. We’ll hope that when people look to terminate an EC2 instance, that they find Remove-EC2Instance before they find the -Terminate parameter in Stop-EC2Instance, such as I would have, had it previously existed. 🙂

Twitter Reply – AWS Stop-EC2Instance Needs Complimentary Cmdlet

Well, it’s time to try this again: Can a Tweet get another change to the AWSPowerShell module? Maybe you’ve read a recent post about an inconsistent parameter name between the same parameter, in two corresponding cmdlets. One tweet later and that was on its way to being fixed. You can read about that here: http://tommymaynard.com/twitter-reply-hashtag-aws-tweet-prompts-fix-to-awspowershell-module-2016.

I get that a tweet probably isn’t the preferred method of reporting problems, but it worked before, so why shouldn’t it again? That said, if there is a preferred method, then I’d be happy to use that, although it doesn’t make for as good a story.

So, here’s where we need a fix. The Stop-EC2Instance cmdlet includes a -Terminate switch parameter that indicates it will terminate the instance (think, remove) in addition to stopping it. It works; it really does terminate the instance. The problem here is that the help file indicates it will prompt the user for confirmation unless the -Force parameter is also included. Nope; it doesn’t prompt. Not for me at least. It does terminate the instance, however, and it does so with no questions asked. It didn’t get me, but it might ruin someone’s day someday.

I didn’t try it, but it seems that there’s some built-in protection, although it’s not the default.

aws-stop-ec2instance-needs-complimentary-cmdlet01

So you can see it yourself, here’s two PowerShell commands I ran against two different EC2 instances. In the first command I simply stop an EC2 instance. In the second, I added the -Terminate switch. As I mentioned, it works, but there wasn’t a confirmation prompt. This was tested on AWS Tools for Windows PowerShell 3.1.66.0 and the newest version as of this writing, 3.1.71.0.

aws-stop-ec2instance-needs-complimentary-cmdlet02

aws-stop-ec2instance-needs-complimentary-cmdlet03

My suggestion to resolve this problem is to remove the -Terminate switch from the Stop-EC2Instance cmdlet, and make a Remove-EC2Instance cmdlet. Maybe alias it with Terminate-EC2Instance, as Terminate isn’t an approved verb. In fact, when I first wanted to remove an EC2 instance, I started by hunting for a Remove-EC2Instance cmdlet. Tracking down the -Terminate switch of Stop-EC2Instance was the last place I would’ve looked. It seems to go against all PowerShell conventions. Does Stop-Transcript have an option to remove a transcript as part of its usage? Does Stop-VM in Hyper-V delete the VM? Does Stop-Cluster include a way to delete the cluster. No. Terminating an instance shouldn’t be a part of stopping an instance unless Stop-EC2Instance can be piped to Remove-EC2Instance. Think about the safety that a separate cmdlet would provide (and it’s not like the AWS Tools team is shy about adding new cmdlets).

There’s a couple cmdlets out there that can be used to get the metadata from a compiled PowerShell cmdlet. We use it as a part of writing proxy functions. By using this, I was able to determine the reason why it doesn’t prompt. The problem, as best I can tell, is that Stop-EC2Instance’s ConfirmImpact CmdletBinding argument is set to Medium and the default value of the $ConfirmPreference variable is set to High.

aws-stop-ec2instance-needs-complimentary-cmdlet04

This means that no matter how the Stop-EC2Instance cmdlet is run, it’s never going to prompt for confirmation to terminate, unless someone has modified their $ConfirmPreference value to Medium, and that’s not likely at all. Since a cmdlet, or advanced function, can’t have more than one ConfirmImpact argument, we need the terminate functionality removed from Stop-EC2Instance and the development of a Remove-EC2Instance cmdlet. For comparison, here’s the CmdletBinding attribute for the Remove-ADGroupMembership Active Directory cmdlet. This one always prompts unless we include -Confirm:$false.

aws-stop-ec2instance-needs-complimentary-cmdlet05

I get this fix is much more involved than the last one I brought up (changing the name of a parameter), and would require more work. Additionally, it’s probably one of those things that have to be discussed among the AWS Tools team members and management. Before I close, I should make sure everyone knows that AWS is still new to me, and as such, there may be things that weren’t considered, or known, when this post was written.

Thanks for reading, and enjoy the upcoming weekend.

Twitter Reply – Hashtag AWS Tweet Prompts Fix to AWSPowerShell Module

I started the Twitter Reply category so I would be able to reply to things I saw on Twitter that needed to be done outside of the 140 character limit. I’ve used it this way a few times, however, today usage is a little different. Although it incorporates Twitter and it’s going to take longer than 140 characters, I’m not actually replying to someone so much. Instead, I am bringing up an event that transpired on Twitter.

First, let me begin by saying how impressed I am with at least one of the developers — I’m guessing he’s a developer — working on the AWSPowerShell module. Last Wednesday, I tweeted that I had started and then stopped an EC2 instance using the Start-EC2Instance and Stop-EC2Instance cmdlets. I noticed a naming difference between identical parameters used by these two, complimentary cmdlets, as I mentioned in my Tweet.

Steve Roberts — a complete stranger to me — replies to my tweet as he must follow the #AWS hashtag. The part the sticks out is that he wrote, “…Fixing…,” as if he was going to correct this difference. Hilarious, right?

Cut to just over 24 hours later and it’s fixed. I downloaded the newest version of the module, installed it, and tested it. It was fixed. The complimentary cmdlets now use the same, -InstanceId parameter.

Did that really just happen? For all I knew, this Steve guy was messing with me, but no, my Tweet really did initiate a (very minor) fix included in the newest version of the AWSPowerShell module. That’s a first. Well, I’ve found a new problem. Maybe I can get that one fixed, too. I’ll be writing about that in an upcoming post and will link it from here, as soon as it’s complete.

Twitter Reply – A Desired State Configuration Print Book

First things first: This post has been written for quite some time. It’s that I’ve been somewhat apprehensive about publishing it. Well, I’m tired of waiting, I’ve read it too many times now, and I just need to get it over with already. These are my opinions, and I’m smart enough, and big enough, to admit when my opinions are wrong.

It’s one thing to leave an opinion on Twitter, and another to have to explain why you “said” what you did. On Tuesday, August 25th, I tweeted about wanting a print DSC (Desired State Configuration) book, and mentioned Don Jones, Steve Murawski, and Jeffery Hicks — a well-qualified team to make something like that happen.

Both Don and Steve expressed the same sentiment: “DSC is likely to change faster than the print cycle can keep up,” and “agree with Steve. Print can’t keep up.” Okay, I could have left it there (because I trust those guys are probably right), and probably would have, until Don asked a follow up question: “curious why print is important for you.” Oh… well, now I needed an organized approach as to why I wanted a print DSC book, more than just to say, “Uh…, because.”

Besides “because,” I’ve organized my reply into a few different points. I certainly don’t think this will change the minds of people like Don and Steve, or get the Manning folks running around the office doing high tens, while chanting my name (it’s Tommy Maynard, just in case). An awesome visual, but not likely.

The de facto standard in Windows PowerShell publishing was written by Don Jones and Jeffery Hicks, and printed by Manning Publications. Learn Windows PowerShell in a Month of Lunches has become the book to use, to learn PowerShell. Mentions of it are everywhere. It comes up on Reddit every couple weeks, I see it on Microsoft TechNet, PowerShell.org (of course), and (also, of course) hear it mentioned on the PowerScripting Podcast. People that use those forums are always asking: how do I learn?, where do I learn?, and more often than not, this print book title comes up. It comes up even when people aren’t even asking for a PowerShell resource. I’ve said it myself: “You’d being doing yourself a favor by reading this book…,” after seeing that they’ve asked a question the book directly answered: “Why can’t I use Get-Process right after Get-Service?” — I just read this one again, somewhere.

Every religion needs a bible, and so DSC needs start to finish guide — a single, bound resource using PowerShell 4.0 and 5.0, that highlights those differences, as it walks people though DSC, that already have an understanding of PowerShell. If “DSC is the ultimate outcome of PowerShell,” (http://powershell.org/wp/2014/03/03/dsc-must-have-or-just-nice-to-have) then how can we skip the progression that is Learn Windows PowerShell in a Month of Lunches and Learn PowerShell Toolmaking in a Month of Lunches?

After reading the Learn Windows PowerShell in a Month of Lunches and Toolmaking book, I came to realize that I could have easily decreased the time it took to learn PowerShell, had I not done it on my own. These books explained things I ended up learning all over the place. I learned with help files and about topics, by reading questions and answers in various forums, and by finding random blogs on Twitter to consume. This bounce around, sporadic method of learning left holes, and it wasn’t something I realized until after I read those two titles. See, my specific reason to read those two books was to help fill in any cracks I may have missed — and there were plenty. To not have a trustworthy source to do the same thing with DSC concerns me.

I’m aware that Microsoft has online resources, but equally so, that books are written in a way that educates the user, not written for an existing expert that needs a reminder or refresher, or to clarify something that they almost already know. I recently read Jason Helmick‘s IIS book and I am a few chapters into Richard Siddaway‘s Active Directory book. I expect the same thing to happen: I’m going to read things, that I already know — lots of it. But still, in the end, I’ll feel confident I gave myself a thorough run down of the topic. It’s impossible to know that I’m not missing something when bouncing from blog to whitepaper to forum.

I know nothing about the time and involvement in getting a published book to market, but I can appreciate that it’s a long and involved process. You don’t have to read too many acknowledgement pages to understand that it takes a good number of people, a good amount of work, over a good amount of time. The timing just seems right here. We’re getting into PowerShell 5.0 heavily now. It comes with new cmdlets, and new declarations for DSC. There’s new DSC resources all time. I can’t think of a better time to ensure the community members — those coming from PowerShell, and even those joining fresh — have a beginning to end DSC walk though and print reference. Just as the MoL (Month of Lunches) PowerShell books are a good starting place, even when they reference PowerShell 3.0 (two versions back), DSC needs a print beginning.

In closing, I think it should be reiterated that even in 2015, where I never have to be away from cat pictures, idiotic Facebook political posts that indicate the education level of old high school “friends,” and instant news updates, we should have a print book on Desired State Configuration. Give me something to recommend, let me make sure I don’t miss anything in my continued effort to learn, and help me take advantage of the relative newness of this topic. Feed us the fundamentals of DSC — how much are those going to change? If we can end up where we are now with the MoL PowerShell books, then why don’t we start the progression with DSC? Jeffery Hicks, when asked why there aren’t updates to MoL, says, “the fundamentals haven’t really changed since PowerShell 3.0. In fact some fundamentals are unchanged since v2” http://jdhitsolutions.com/blog/powershell/4478/updating-month-of-lunches. How much of the current fundamentals of DSC are going to change in PowerShell 6.0 (DSC 3) and 7.0 (DSC 4)? It’s moving faster than print, I can appreciate that, but is it going to veer so severely that a print book won’t work?

It was a special day when I was able to enforce a registry setting via DSC, even though it’s so small and simple. Give me more; walk me though more defining moments. Help make me the expert. Prepare me for a career in DevOps. Help me ensure I have a complete understand of Desired State Configuration, and if it moves too fast, then align yourself with Microsoft. Ask them to partner in the effort to include everything up to the point of publication. Snover loves this community; his favorite conference is the PowerShell Summit (unless he says that about all the conferences he attends).

In closing (really this time, I promise), I want to mention the DSC eBook provided by PowerShell.org. It’s bound to come up. I’m certainly aware of its existence and that print copies were distributed at the last TechEd, or first Ignite — I don’t remember which one, and I wasn’t there for either. I’ve downloaded it and used it. I was a great first step, but when I first downloaded it, it seemed written out of order, only helped with minimal deployment scenarios (Windows backup), and seemed to lack a full walk though of the product. I went to grab it now, and the PDF version on Penflip wasn’t a complete version. It stopped after the “Where to find Resources” chapter. I think this was part of my frustration, although it seems isolated to the pdf version. The text and Word versions included the other chapters.

Thanks to anyone that read these opinions. Again, that’s all they are, and really, I’m not sure how influential they really are, or if I even really made much of a case for print.

Twitter Reply – Finding Parameters that Include a Default Value

Adam Bertram, an active PowerShell MVP, wrote on Twitter about the need to determine which parameters have default values. I can’t resist a challenge, and so I very quickly wrote out the function below. No guarantees, but maybe it’ll help.

Update: It turns out that the function that Adam was working with, didn’t include help. Shame. Even so, this small script may assist someone to pull back the parameters that have default values.

Get-Help Get-Service |
    Select-Object -ExpandProperty parameters |
    Select-Object -ExpandProperty parameter | 

    Foreach {
        If ($_.DefaultValue -ne '') {
            $Object = [pscustomobject]@{
                Name = $_.Name
                Default =$_.DefaultValue
            }
        Write-Output -InputObject $Object
        }
    }

Twitter Reply – Randomly Selecting a Name from a CSV File

I have to admit, I’m kind of excited to be doing another Twitter Reply post. This one is the result of a post by Michael Bender. I’ve never met him, but I’ve follow his career a bit in the last few years, when I was introduced to his name via TechEd. He made a recent Tweet where he asked for a PowerShell genius to help build him a script. The goal was to randomly select a name from a CSV file, with an option to choose how many names it should randomly select.

Here’s the Tweet: https://twitter.com/MichaelBender/status/593168496571322370

I wouldn’t consider myself a genius, but if you consider what he’s after — a name from a CSV file (not a line from a text file) — then there’s a better option then the one he accepted: “get-content file.csv | get-random.” This will work, but there’s some reasons why this isn’t such a great idea. We can use the Get-Content cmdlet with CSV files, but we generally don’t. CSV files are created and formatted in such a way, that using Get-Content, instead of Import-Csv, isn’t the best way to do things.

Let’s consider that we’re using the CSV file in the image below. It has three headers, or column names: Name, Age, and HairColor.

Randomly Selecting Name from a CSV File01

First of all, if we use Get-Content, it’s going to consider the first line — the header line, or the column headings — a selectable line within the file. Here’s that example:

PS C:\> Get-Content .\file.csv | Get-Random
Name,Age,HairColor

Uh, not helpful. While this isn’t the end of the world, as we can simply rerun the command (and probably get something different), we’d be better off to write this so that this error is not a possibility — something we’ll see in a moment, when we use Import-Csv.

Second of all, unless the only column in the CSV file is Name, then we’re not returning just a name, but instead, everything in a row of the file. This means that if I randomly choose a line in the file, that it will include information that Michael didn’t request — the age and hair color.

PS C:\> Get-Content .\file.csv | Get-Random
Jeff,19,Brown

I suppose we could start parsing our returned value to just return the name ((Get-Content .\file.csv | Get-Random).Split(‘,’)[0]), but seriously, let’s skip that and use one of the cmdlets that was built to work with CSVs directly. We’ll assume we’re still using the same CSV file in the image above.

PS C:\> Import-Csv .\file.csv | Get-Random | Select-Object Name

Name
----
Lance

Um, that was easy. If we wanted to increase the number of names returned from our CSV file, then we would use Get-Random’s -Count parameter and an integer value, such as in this example:

PS C:\> Import-Csv .\file.csv | Get-Random -Count 3 | Select-Object Name

Name
----
Bob
Stephen
Sue

I think we’re best off when we use the *-Csv cmdlets with CSV files, and the Get-Content cmdlet with most other file types we can read in PowerShell. There is at least one exception of doing this in reverse: Using Import-Csv with a text file, that has a delimiter, might help you better parse the information in your file. Consider this text file:

Randomly Selecting Name from a CSV File02

The next few examples will progressively show you how to use Import-Csv with a delimited text file until all of the “columns” are broken apart. When we’re finished, we can even export our data into a properly formatted CSV file, and then import it, piping those results to other cmdlets — take a look.

PS C:\> Import-Csv .\file.txt

001|Sunday|Car7
---------------
002|Monday|Car2
003|Tuesday|Car3
004|Wednesday|Car3
005|Thursday|Car7
006|Friday|Car2
007|Saturday|Car3

PS C:\> Import-Csv .\file.txt -Header Id,Day,Car

Id                                      Day                                     Car
--                                      ---                                     ---
001|Sunday|Car7
002|Monday|Car2
003|Tuesday|Car3
004|Wednesday|Car3
005|Thursday|Car7
006|Friday|Car2
007|Saturday|Car3

PS C:\> Import-Csv .\file.txt -Header Id,Day,Car -Delimiter '|'

Id                                      Day                                     Car
--                                      ---                                     ---
001                                     Sunday                                  Car7
002                                     Monday                                  Car2
003                                     Tuesday                                 Car3
004                                     Wednesday                               Car3
005                                     Thursday                                Car7
006                                     Friday                                  Car2
007                                     Saturday                                Car3

PS C:\> Import-Csv .\file.txt -Header Id,Day,Car -Delimiter '|' | Export-Csv -Path C:\file-cars.csv -NoTypeInformation
PS C:\> Import-Csv .\file-cars.csv

Id                                      Day                                     Car
--                                      ---                                     ---
001                                     Sunday                                  Car7
002                                     Monday                                  Car2
003                                     Tuesday                                 Car3
004                                     Wednesday                               Car3
005                                     Thursday                                Car7
006                                     Friday                                  Car2
007                                     Saturday                                Car3

PS C:\> Import-Csv .\file-cars.csv | Where-Object Car -eq 'Car3'

Id                                      Day                                     Car
--                                      ---                                     ---
003                                     Tuesday                                 Car3
004                                     Wednesday                               Car3
007                                     Saturday                                Car3

PS C:\> Import-Csv .\file-cars.csv | Where-Object Car -eq 'Car3' | Select-Object Day

Day
---
Tuesday
Wednesday
Saturday

So, if I had seen the Tweet first, I would have to recommend Import-Csv, piped to Get-Random, and then piped to Select-Object Name. Thanks for reading the post.

Twitter Reply – Rebel Doesn’t Mean Rebel to Everyone

Twitter Reply to: no link

I saw a recent Twitter #PowerShell post and while I wanted to respond to it on Twitter, I didn’t. I was opposed to what it said, but I didn’t feel it was my place to call anyone out in that fashion. That’s why there isn’t a link above, where they might’ve been otherwise.

The twitter post in which I’m referring indicated that a person was a “rebel” by not using an approved PowerShell verb. I saw the included :P, and that’s fine, but only if the author is joking about the whole thing — I didn’t get that they were.

To use an unapproved verb, especially while knowing you shouldn’t, is everything that PowerShell is trying to stay away from. Part of the success of PowerShell has been the consistency in which it’s been developed by Microsoft, and others. While you might consider yourself a rebel, I consider what you’re doing, a problem.

I will admit, there has been a time or two that I’ve struggled with the best option for my verb, but I’ve always found one. Here’s my recommendation if you are not satisfied with the list of approved verbs: Use an alias; don’t be a “rebel.”

Let’s say I have a function I want to invoke using the name Smack-Yourself, and it looks like this:

Function Smack-Yourself {
    Write-Output -Verbose "I've been smacked!"
}

I can tell you without looking; smack is not an approved verb. We’ll check if it exists anyway.

PS C:\> Get-Verb -Verb Smack
PS C:\>

Nope, this verb hasn’t (yet?) been approved by Microsoft.

Instead of using an unapproved verb, let’s give our function an approved verb and then make an alias we can use instead. There’s no best practice for aliases; name them whatever you want. As far as your function name, please stay consistent and follow the verb dash noun naming convention, using an approved verb.

Set-Alias -Name Smack-Yourself -Value Pop-Yourself

Function Pop-Yourself {
    Write-Output -Verbose "I've been smacked!"
}

In the example above, we’ve used Set-Alias to modify (or create) an alias, called Smack-Yourself. When run, this alias will ultimately execute the Pop-Yourself function, where Pop is an approved verb. Even if the approved verb you choose doesn’t perfectly align with the verb you wanted to use, you can use whatever you want, if you’re using an alias.

Twitter Reply – Out-GridView in a PSRemoting Session

Twitter Reply to:

We can’t use the Out-GridView cmdlet in a remote session. How do we know this? Well for one, the documentation says so (search for ‘You cannot use a remote command’ on that webpage), and two, because if you try, you’ll get a straight forward error message on the topic: “Out-GridView does not work in a remote session.” Okay, but why?

Out-GridView produces a Graphic User Interface (GUI) — something we don’t use in PSRemoting sessions. In fact, everything about a PSRemoting session is text only. This isn’t just about Out-GridView, though. Other graphical elements in Windows PowerShell aren’t going to work either. This includes Get-Help’s -ShowWindow parameter, and the Show-Command cmdlet. It just wasn’t designed to work this way.

Other GUI elements don’t work either. While you won’t get a helpful message, like you do with the PowerShell cmdlets and parameters, launching notepad.exe and calc.exe isn’t going to work like it does on a local computer. Those programs work a little differently though, as they will actually launch on the remote computer. It just won’t be in any useable fashion from your remote session. Bonus: They may lock up your remote session until they are closed.

Note: If you were to try this, one way to rectify the situation would be to open a second PowerShell console and run the following, assuming you launched calc.exe: Invoke-Command -ComputerName computername -ScriptBlock {Get-Process -Name calc.exe | Stop-Process}. This would end the process on the remote computer, and give you back your prompt on the console where you were running your PSRemoting session.

Everything until now, assumed we were talking about an interactive PSRemoting session (using the Enter-PSSession cmdlet). Well, what about Invoke-Command? Invoke-Command is used to run commands on remote systems and return the results to the local computer. As you can see in the examples below, we can run a command on a remote computer and then display the results on our local computer, inside Out-GridView.

Note: Although I didn’t have any problems with the small handful of cmdlets I tried, the same webpage linked above indicates that data returned from a remote computer may not be formatted correctly for use with Out-GridView.

PS C:\> $Services = Invoke-Command -ComputerName dc01 -ScriptBlock {Get-Service}
PS C:\> $Services | Out-GridView
PS C:\> $PSWARules = Invoke-Command -ComputerName PSWAServer01 -ScriptBlock {Get-PSWAAuthorizationRule}
PS C:\> $PSWARules | Out-GridView

Thanks for the inspiration to write a little about this topic, Tim.