Tips and Tricks

Tips and Tricks
Don Jones
PowerShell for Admins

Installing PowerShell v5? Be a Little Careful, OK?

I’m getting a lot of questions from folks, via Twitter and other venues, regarding Windows Management Framework 5.0 - which is where PowerShell v5 comes from. It’s awesome that people are installing v5 and kicking the tires - however, please help spread the word:

  • v5 is a preview. It isn’t done, and it isn’t guaranteed bug-free. It shouldn’t be installed on production computers until it’s officially released.
  • v5 doesn’t install ‘side by side’ with v3 or v4. You can’t run it with “-version 3” to “downgrade.” Now, v5 shouldn’t break anything - something that runs in v3 or v4 should still work fine - but there are no guarantees as it’s a preview and not released code at this stage.
  • Server software (Exchange, SharePoint, etc) often has a hard dependency on a specific version of PowerShell. You need to look into that before you install v5.
  • After installing v5, you might not be able to cleanly uninstall and revert to a prior version.

Generally speaking, v5 should be installed in a test virtual machine at the very least, not on a production computer. It’s great to play with it, and you should absolutely log bugs and suggestions to http://connect.microsoft.com.
This situation will be true for any pre-release preview of PowerShell or WMF going forward. “Preview” is the new Microsoft-speak for “beta,” and you should treat it as such. Play with it, yes - that’s the whole point, and it’s how we get a stable, clean release in the end. But play with caution, and never on production computers.

Steven Murawski
Tips and Tricks

Going Deeper on DSC Resources

Desired State Configuration is a very new technology and declarative configuration management is a very young space yet.  We (Microsoft and the community) are still figuring out the best structure for resources, composite configurations, and other structures.
That said, there are certain viewpoints that I’ve come to, either from hands on experience or in watching how other communities (like the Puppet community or Chef community) handle similar problems.

How Granular Should I Get?

There is no absolute answer.

Don Jones
PowerShell for Admins

Why Get-Content Ain't Yer Friend

Well, it isn’t your enemy, of course, but it’s definitely a tricky little beast.
Get-Content is quickly becoming my nemesis, because it’s sucking a lot of PowerShell newcomers into its insidious little trap. Actually, the real problem is that most newcomers don’t really understand that PowerShell is an object-oriented, rather than a text-oriented shell; they’re trying to treat Get-Content like the old Type command (and why not? type is an alias to Get-Content in PowerShell, isn’t it?), and failing.
Worse, PowerShell has just enough under-the-hood smarts to make some things work, but not _everything. _
For example, this works to replace all instances of “t” with “x” in the file test.txt, outputting the result to new.txt:

Steven Murawski
Tips and Tricks

Desired State Configuration – General Availability Changes

PowerShell DSC, along with Windows Server 2012 R2 has reached General Availability!  Yay!
However, there is (at least one so far) breaking change** **in Desired State Configuration (DSC).
Fortunately, the change is in an area I haven’t blogged about yet.. creating custom resources.  Unfortunately, it does mean I’ll have to update the GitHub repository and all my internal content (should be done by early next week).
The short version is that DSC resources are now resources inside modules, rather than each resource being independent modules.  The benefit of this is that now DSC resources won’t pollute the module scope, each resource won’t need its own psd1 file (the source module will require one though), and it provides an easier way to group resources, which wasn’t really possible before.
So, with GA, resources should go under the module root in a folder DSCResources.  You can have one or more resources in one PowerShell module.  The PowerShell module version is what will be used for the resource version number, so if you have several resources, a version number bump affects all the resources in the module.
I’ll be picking back up with the DSC series next week with how to configure DSC clients, so stay tuned.

Don Jones
PowerShell for Admins

Regular Expressions are a -replace's best friend

Are you familiar with PowerShell’s -replace operator?

"John Jones" -replace "Jones","Smith" Most folks are aware of it, and rely on it for straightforward string replacements like this one. But not very many people know that -replace also does some amazing stuff using regular expressions.

"192.168.15.12,192.168.22.8" -replace "\.\d{2}\.","10" That’d change the input string to “192.168.10.12,192.168.10.8,” replacing all occurrences of two digits, between periods, to 10. The 12 would be skipped because it isn’t followed by a period, as specified in the pattern. Note that all occurrences are replaced, in keeping with the usual operation of -replace.
The operator can also do capturing expressions, and this is where it gets really neat-o.

Don Jones
PowerShell for Admins

Why Doesn't My ValidateScript() work correctly?

I’ve received a few comments from folks after my observations on the Scripting Games Event 1. In those observations, I noted how much I loved:
[ValidateScript({Test-Path $_})][string]$path
As a way of testing to make sure your -Path parameter got a valid value, I love this. I’d never thought of it, and I plan to use it in classes. I may write a book about it someday, or maybe even an ode. Seriously good logic. But… I also bemoaned some scripts that provided an additional Test-Path, in the script’s main body of code. Why have a redundant check?
So, first, thanks for the e-mails you all sent. Second… please understand that I can’t respond to you all. I’ve got this full-time job thing, and I’ve got to do it or the grocery store will stop taking our checks. You’re welcome to drop comments here, and I really appreciate when you say stuff like, “can you explain ___ in a future post?” because it gives me ideas to write about. I just can’t get into private e-mail based education for a dozen folks. Teaching is kinda what I do for my job, so most of my time has to go to that.
But - there’s a great teaching point here. Let’s take this example:
valid-default-path
This works as you would hopefully expect. When given a valid path, it’s fine. When allowed to use a valid default, it’s fine. When given an invalid path, it barfs in the ValidateScript. Now look at the next example - which more closely approximates what people have been seeing in their Scripting Games scripts:
invalid-default-path
In the Games, you were given a default path that wasn’t valid on your computer. So folks allowed their script to run with that default, and got errors, and were annoyed that ValidateScript() didn’t catch the problem.
It never will.
When you run a command, PowerShell goes through a process called parameter binding, wherein it attaches values to parameters and runs any declarative validation - like ValidateScript(). That validation will always catch invalid incoming data that’s been manually specified or sent in via the pipeline (for parameters that accept pipeline input). Because my -Path parameter wasn’t declared as mandatory, the validation routine will let me run the script and not specify -path.
Then the shell actually runs my code - and that’s when it assigns the default value to $path if one wasn’t specified on -path. Validation is over by this point, so an invalid default value will sneak by. The assumption by the shell is that you’re providing the default value, so you’re smart enough to provide a valid one. If you don’t, it’s your problem.
So do you just add a second, in-code check for the parameter? I’d still say no. I really dislike redundancy. If you know, because of your situation, that you can’t rely on ValidateScript(), then don’t use it at all - one check should suffice, and if it needs to be in-code instead of declarative, that’s fine. What’d be nice is if there was a declarative way of specifying a default, like [Default(‘whatever’)] that ran before the validation checks, but such a thing doesn’t exist. Frankly, you could probably argue that if you can’t guarantee the validity of a default, then you shouldn’t provide one - and I’d probably buy into that argument, and subscribe to your newsletter.
In this case, the problem is entirely artificial. The default path value given to you in the Games scenario is valid in the context of the Games; it’s just when you test it on your system, outside that context, that a problem crops up.
Hopefully this helps explain how the ValidateXXX() attributes work, and how they interact with other features, like a default value.
Now explain why this will never assign C:\ as a default value:
[Parameter(Mandatory=$True)][string]$path = ‘c:'

Don Jones
PowerShell for Admins

What are Your PowerShell Newbie Gotchas?

I’m putting together a list of common “gotchas” for PowerShell, mainly things that affect newcomers. So far, I’ve got:

  • Piping the output of a Format cmdlet to nearly anything else
  • Using -contains instead of -like
  • Selecting a subset of object properties and then trying to sort/fiter on a now-missing property
  • Wrong syntax for -filter parameters on various commands
  • Commands that don’t produce pipeline output (e.g., piping Export-CSV to something)
  • Using ConvertTo-HTML without -Fragment and appending multiple pages in one file
  • Confusion with ( [ { and the other punctuation
  • Concatenating strings (hard) vs. using double quotes (easier)
  • $ not being part of the variable name (esp with -ErrorVariable)
  • Accumulating objects in a variable and returning it, vs. outputting to the pipeline directly

What are your “gotchas?”

Don Jones
Tips and Tricks

PowerShell.org Forums Etiquette

Folks often ask for some advice on what to do, and what not to do, in the forums. Here are some suggestions.

  1. Don’t apologize for being a “noob” or “newbie” or “n00b.” There’s just no need - nobody will think you’re stupid, and the forums are all about asking questions. Just ask.
  2. Try to avoid using obscure or punctuation aliases (like ? and %) - use command names instead. It makes your post easier for everyone, including n00bs, to follow.
  3. Use the CODE or POWERSHELL buttons in the forums editor to format PowerShell and other code.
  4. If your problem is solved, find the little green checkmark button along the top of your message (or one of the replies; it’s near the Twitter and Facebook and other buttons), and click it. That helps indicate to everyone else that you found a solution.
  5. Don’t post massive scripts. We’re all volunteers, and we don’t have time to read all that, nor will we copy, paste, and run it. Post an excerpt, and clearly state what you’re having problems with.
  6. Post error messages, as appropriate. They help.
  7. Don’t ask folks to provide you with a complete script, or to rewrite your script. Again, we’re all volunteers - respect that we’re taking time to help you, and help us minimize that time.
  8. Try to ask just one question at a time. Posts with ten questions are a lot harder to help with.
  9. DO post what you’ve tried, what errors you got, and what didn’t work. It’s a lot easier, sometimes, to correct what you’ve already done than to try and write something from scratch.
  10. If you’ve been given a working solution, SAY THANK YOU! Then make sure you know WHY it works… and ask for an explanation if you don’t!
  11. Take the time to educate yourself. Pick up a book, or a training video, or take a class, or attend a conference. Yes, those take time - but it’s time well-spent. If you’re continually asking other people to spend time answering questions that are already answered in every book, video, course, etc…. well, that’s kinda wasting their time, right? Folks on the forums can help you more effectively if you have a base education first.

Have your own etiquette suggestions? Drop ’em in the comments!