03Apr/17

Quick Tip: Using Variables In ActiveDirectory Filters

If you work with the ActiveDirectory PowerShell module, you’ve probably used the -filter parameter to search for accounts or objects in Active Directory. You’ve probably wanted to use variables in those filters, too.

Say you have a command from something like an remote Exchange management shell, that returned an object that includes a username (called Alias in this example).

And let’s use that in an ActiveDirectory command. Ignoring the fact that you could find the account that has this username without using a filter, let’s see how you would use it in a filter.

You might try this.

But you’d get errors.

That’s because the filter can’t handle your variable that way. To use a variable in an ActiveDirectory cmdlet filter, you need to wrap the filter in curly braces.

And you get your results!

Pretty easy fix for a pretty silly issue.

01Mar/17

How To Tell If The Verbose Parameter Of A Function Is From [CmdletBinding()] Or Manually Added

Pardon the long title. I had a task recently to go through a big folder full of scripts written by random people with equally random skill levels. Lots of the scripts had a -Verbose parameter, but they weren’t all done correctly.

Some scripts correctly included the [CmdletBinding()] line above the param() block. Some just had a [Switch]$Verbose parameter (wrong). Others had both (double wrong, script won’t even run).

Consider the following three functions, which illustrate the three categories I was dealing with.

Continue reading

08Feb/17

Honorary Scripting Guy Award

Yesterday, Microsoft’s Ed Wilson announced the Honorary Scripting Guys for 2016. I am honored and very proud to be the newest Honorary Scripting Guy, joining this year’s repeat winners: Sean Kearney, Teresa Wilson, and Will Anderson.

The Hey, Scripting Guy! blog is a resource that was an enormous part of my self-learning journey when I first got started with PowerShell, just as I am sure it was for you. Just having the opportunity to write posts and share information on HSG is a huge privilege. I still find to be a surreal experience every time I see my content go up. My HSG posts are tagged with my name, in case you want to check them out.

Earlier this month, Ed and his wife, Teresa, announced their upcoming retirement in March. I’d like to thank them both so much for their immeasurable, phenomenal contributions to PowerShell and the community. Ed and Teresa, we are going to miss you both tremendously. I hope retirement treats you both excellently, as you more than well deserve.

18Jan/17

Invoking Pester and PSScriptAnalyzer Tests in Hosted VSTS

Overview

Pester and PSScriptAnalyzer are both fundamental tools for testing the effectiveness and correctness of PowerShell scripts, modules, and other PowerShell artifacts. While it is relatively convenient and straightforward to run these tools on a local development workstation, and even on owned/on-prem testing servers, it is somewhat more complicated to execute these tests in your own Microsoft-hosted Visual Studio Team Services environment.

Pester is an open source domain specific language developed originally by Dave Wyatt, which enjoys contributions from a variety of prominent members of the PowerShell community, as well as Microsoft employees on the PowerShell product team. Microsoft is a big enough fan of Pester that it comes with Windows 10, and reference it frequently in talks and written material. Pester is used for PowerShell unit testing.

PSScriptAnalyzer is a static code checker for PowerShell modules and scripts that checks the quality of code by comparing it against a set of rules. The rules are based on PowerShell best practices identified by the PowerShell team at Microsoft and the community. It is shipped with a collection of built-in rules but supports the ability to include or exclude specific rules, and also supports custom rule definitions. PSScriptAnalyzer is an open source project developed originally by the PowerShell team at Microsoft.

Lots of DevOps teams use the above tools together, along with their internally generated standards and style guide, to ensure that PowerShell code that is released into any environment meets their standards. By using Pester to ensure that a piece of code performs the tasks required, using PSScriptAnalyzer to inspect code for general best practice violations, and using a peer review process to validate that code conforms to our standards and style guidelines, you can rigorously test and ensure the quality and functionality of all PowerShell code that you produce.

As part of a PowerShell Release Pipeline, you may store your code in the source control portion of VSTS, hosted by Microsoft. I’d suggest you use the automated build and release components of VSTS to execute a series of tasks before deploying, and to deploy PowerShell code. Two of these tasks are running Pester tests and PSScriptAnalyzer. As a standard, don’t release builds if any part of either of these two tests fail.

In previous versions of VSTS, the hosted build service ran PowerShell 4.x. Because installing modules from the PowerShell Gallery (to get Pester and PSScriptAnalyzer module files so they may be run) requires PowerShell 5.0 or higher, it was necessary to use a third-party configured build step or perform some other hijinks that possibly compromised the integrity of a build. Now that VSTS runs PowerShell 5.0, we can run Pester, PSScriptAnalyzer, and many other helpful modules without exporting them with our other code, or using third-party build steps.

Continue reading

28Dec/16

Does A String Start Or End In A Certain Character?

Can you tell in PowerShell if a string ends in a specific character, or if it starts in one? Of course you can. Regex to the rescue!

It’s a pretty simple task, actually. Consider the following examples

In the first two examples, I’m checking to see if the string ends in a backslash. In the last two examples, I’m seeing if the string starts with one. The regex pattern being matched for the first two is .+?\$ . What’s that mean? Well, the first part .+? means “any character, and as many of them as it takes to get to the next part of the regex. The second part \\ means “a backslash” (because \ is the escape character, we’re basically escaping the escape character. The last part $ is the signal for the end of the line. Effectively what we have is “anything at all, where the last thing on the line is a backslash” which is exactly what we’re looking for. In the second two examples, I’ve just moved the \\ to the start of the line and started with ^ instead of ending with $ because ^ is the signal for the start of the line.

Now you can do things like this.

Here, I’m checking to see if the string ‘bears’ ends in a backslash, and if it doesn’t, I’m appending one.

Cool, right?

07Dec/16

Quick Tip: Validate The Length Of An Integer

A little while ago, I fielded a question in the PowerShell Slack channel which was “How do I make sure a variable, which is an int, is of a certain length?”

Turns out it’s not too hard. You just need to use a little regex. Consider the following example.

$v6 is an int that is six digits long. $v2 is an int that is only two inches long. On lines three and four, we’re testing to see if each variables match the pattern ‘^\d{6}$’ which is regex speak for “start of the line, any digit, and six of them, end of the line”. The first one will be true, because it’s six digits, and the second one will be false. You could also use something like ‘^\d{4,6}$’ to validate that the int is between four and six digits long.

21Nov/16

PowerShell 10 Year Anniversary Code Golf Winners

For the PowerShell 10 Year Anniversary, Will Anderson (@GamerLivingWill on Twitter) and I (@MrThomasRayner on Twitter) ran a three-hole code golf competition on code-golf.com, a site developed by fellow MVP Adam Driscoll.

Here is the link to all the background info on the competition: https://github.com/ThmsRynr/PS10YearCodeGolf . Check this page out for links to the individual holes, too.

So, without further delay, let’s announce the winners!

Hole 1

The challenge was to get all the security updates installed on the local computer in the last 30 days and return the results in the form of a [Microsoft.Management.Infrastructure.CimInstance] object (or an array of them).

The winner of this hole is Simon Wåhlin. Here is their 46 character submission.

gcls *ix* gets the CimClass win32_quickfixengineering and % *mC*e gets the CimClassName property. gcim is an alias for Get-CimInstance which, as per the previous section, is getting the win32_quickfixengineering class. The results are piped into the where-object cmdlet where the property matching the pattern I*n (which happens to be InstalledOn) is greater than the current date, minus 30 days.

Hole 2

The challenge was to get the top ten file extensions in c:\windows\system32, only return 10 items and group results by extension.

The winner of this hole is Simon Wåhlin again. Here is their 42 character submission.

ls c:\*\s*2\*.* means Get-ChildItem where the path is c:\<any directory>\<a directory matching s*2>\<files, not directories> and this pattern only matches the path c:\windows\system32\<files>. This is piped into the foreach-object cmdlet to retrieve the property that matches the pattern E*n, which is the Extension property. The extensions are piped into the sort-object cmdlet, sorted by the property that matches the pattern c*, which is count, and returned in descending order. This is an array, and the items in positions 0-9 are returned.

There were shorter submissions for this hole that didn’t explicitly target c:\windows\system32 and therefore missed the challenge. You could not assume we were already on c: or running as admin, etc. Some solutions included folders in the results which also missed the challenge.

Hole 3

The challenge was to get all the active aliases that are fewer than three characters long and do not resolve to a Get- command. For this hole, even though it wasn’t in the Pester test, you had to assume that non-standard aliases might be on the system. That’s why we specifically mentioned that we didn’t want you to return aliases that resolve to Get-*, and the Pester test checked the ResolvedCommand.Name property of the aliases you returned.

To break some submissions that didn’t check what the aliases resolved to, you could just run New-Alias x Get-ChildItem to create a new alias of ‘x’ that resolves to Get-ChildItem.

The winner of this hole is EdijsPerkums. Here is their 24 character submission.

Get-Alias is passed an array of regex patterns, ?,?? which corresponds to one and two characters. The results are piped into the where-object cmdlet to isolate aliases whose property that matches the pattern Di* (DisplayName) doesn’t match Get.

Congratulations to all the winners! We will be in touch to get you your prizes. We hope you all had fun with this mini-competition. Don’t forget to check out all the terrific material from the PowerShell 10 Year Anniversary on Channel 9!