Invoking PSScriptAnalyzer in Pester Tests for each Rule

This is a quick walkthrough on how you can get output from PSScriptAnalyzer rules in your Pester tests.

So you’ll need

  • Pester ( Version 3.4.0 or above )
  • PSScriptAnalyzer ( Version 1.4.0 or above )

Please note this is shown running on PowerShell  v5 as part of Windows 10 Build 14295 – results may vary on other PowerShell Versions

In the nature of the way we want to work we may have new ScriptAnalyzer rules in the near future (new version / additional community additions / your own custom ScriptAnalyzer rules etc) and we would want ensure that we test for them all without having to change much of the below code

to dynamically do this within our Context Block.

 

So our example code in our Pester Test would look like this

#Script#PesterScriptAnalzyerExample#

$Here = Split-Path -Parent $MyInvocation.MyCommand.Path

$Scripts = Get-ChildItem $here\” -Filter ‘*.ps1’ -Recurse | Where-Object {$_.name -NotMatch ‘Tests.ps1’}

$Modules = Get-ChildItem $here\” -Filter ‘*.psm1’ -Recurse

$Rules = Get-ScriptAnalyzerRule

Describe ‘Testing all Modules in this Repo to be be correctly formatted’ {

    foreach ($module in $modules) {

        Context “Testing Module  – $($module.BaseName) for Standard Processing” {

            foreach ($rule in $rules) {

                It “passes the PSScriptAnalyzer Rule $rule {

                    (Invoke-ScriptAnalyzer -Path $module.FullName -IncludeRule $rule.RuleName ).Count | Should Be 0

                }

            }

        }

    }

}

Describe ‘Testing all Scripts in this Repo to be be correctly formatted’ {

    foreach ($Script in $scripts) {

        Context “Testing Module  – $($script.BaseName) for Standard Processing” {

            foreach ($rule in $rules) {

                It “passes the PSScriptAnalyzer Rule $rule {

                    (Invoke-ScriptAnalyzer -Path $script.FullName -IncludeRule $rule.RuleName ).Count | Should Be 0

                }

            }

        }

    }

}

And the result that we would get would be the below

 

PS C:\Users\Ryan\OneDrive\GitHub\kilasuit\Scripts-WIP\PesterScriptAnalzyerExample> .\PesterScriptAnalzyerExample.ps1

Describing Testing all Modules in this Repo to be be correctly formatted

Describing Testing all Scripts in this Repo to be be correctly formatted

   Context Testing Module  – PesterScriptAnalzyerExample for Standard Processing

    [+] passes the PSScriptAnalyzer Rule PSAvoidUsingCmdletAliases 233ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidDefaultValueSwitchParameter 124ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidUsingEmptyCatchBlock 134ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidGlobalVars 87ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidInvokingEmptyMembers 104ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidNullOrEmptyHelpMessageAttribute 70ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidUsingPositionalParameters 879ms

    [+] passes the PSScriptAnalyzer Rule PSReservedCmdletChar 75ms

    [+] passes the PSScriptAnalyzer Rule PSReservedParams 81ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidShouldContinueWithoutForce 85ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidUsingDeprecatedManifestFields 117ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidDefaultValueForMandatoryParameter 123ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidUsingUserNameAndPassWordParams 95ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidUsingComputerNameHardcoded 113ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidUsingConvertToSecureStringWithPlainText 98ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidUsingInvokeExpression 75ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidUsingPlainTextForPassword 103ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidUsingWMICmdlet 138ms

    [+] passes the PSScriptAnalyzer Rule PSAvoidUsingWriteHost 91ms

    [+] passes the PSScriptAnalyzer Rule PSMisleadingBacktick 100ms

    [+] passes the PSScriptAnalyzer Rule PSUseBOMForUnicodeEncodedFile 100ms

    [+] passes the PSScriptAnalyzer Rule PSUseToExportFieldsInManifest 87ms

    [+] passes the PSScriptAnalyzer Rule PSUseOutputTypeCorrectly 128ms

    [+] passes the PSScriptAnalyzer Rule PSMissingModuleManifestField 84ms

    [+] passes the PSScriptAnalyzer Rule PSPossibleIncorrectComparisonWithNull 99ms

    [+] passes the PSScriptAnalyzer Rule PSProvideCommentHelp 98ms

    [+] passes the PSScriptAnalyzer Rule PSUseApprovedVerbs 75ms

    [+] passes the PSScriptAnalyzer Rule PSUseCmdletCorrectly 867ms

    [+] passes the PSScriptAnalyzer Rule PSUseDeclaredVarsMoreThanAssigments 82ms

    [+] passes the PSScriptAnalyzer Rule PSUsePSCredentialType 91ms

    [+] passes the PSScriptAnalyzer Rule PSShouldProcess 160ms

    [+] passes the PSScriptAnalyzer Rule PSUseShouldProcessForStateChangingFunctions 86ms

    [+] passes the PSScriptAnalyzer Rule PSUseSingularNouns 177ms

    [+] passes the PSScriptAnalyzer Rule PSUseUTF8EncodingForHelpFile 176ms

    [+] passes the PSScriptAnalyzer Rule PSDSCDscTestsPresent 98ms

    [+] passes the PSScriptAnalyzer Rule PSDSCDscExamplesPresent 102ms

    [+] passes the PSScriptAnalyzer Rule PSDSCUseVerboseMessageInDSCResource 81ms

    [+] passes the PSScriptAnalyzer Rule PSDSCUseIdenticalMandatoryParametersForDSC 110ms

    [+] passes the PSScriptAnalyzer Rule PSDSCUseIdenticalParametersForDSC 74ms

    [+] passes the PSScriptAnalyzer Rule PSDSCStandardDSCFunctionsInResource 122ms

    [+] passes the PSScriptAnalyzer Rule PSDSCReturnCorrectTypesForDSCFunctions 101ms

 

This allows you to see from your test if it fails or not and as shown is able to be used for scripts and modules.

The example is a good example as well of getting Pester to test your Pester tests Winking smile

This example is being added into ISE_Cew (see post) in the next feature release (next week some point) though you can just copy and paste it from this blog post as well thanks to a PowerShell ISE addon called CopytoHtml by Gary Lapointe in which you can find more about it and download it at http://blog.falchionconsulting.com/index.php/2012/10/Windows-PowerShell-V3-ISE-Copy-As-HTML-Add-On/

 

Please note that although the above works fine – I dont see the point in running the Describe block if the tests below wont run so I’m adding what I think to be the better version below – this will only run the Describe blocks if there is any scripts or modules

#Script#PesterScriptAnalzyerExample#

$Here = Split-Path -Parent $MyInvocation.MyCommand.Path

$Scripts = Get-ChildItem $here\” -Filter ‘*.ps1’ -Recurse | Where-Object {$_.name -NotMatch ‘Tests.ps1’}

$Modules = Get-ChildItem $here\” -Filter ‘*.psm1’ -Recurse

$Rules = Get-ScriptAnalyzerRule

if ($Modules.count -gt 0) {

    Describe ‘Testing all Modules in this Repo to be be correctly formatted’ {

        foreach ($module in $modules) {

            Context “Testing Module  – $($module.BaseName) for Standard Processing” {

                foreach ($rule in $rules) {

                    It “passes the PSScriptAnalyzer Rule $rule {

                        (Invoke-ScriptAnalyzer -Path $module.FullName -IncludeRule $rule.RuleName ).Count | Should Be 0

                    }

                }

            }

        }

    }

}

if ($Scripts.count -gt 0) {

    Describe ‘Testing all Scripts in this Repo to be be correctly formatted’ {

        foreach ($Script in $scripts) {

            Context “Testing Module  – $($script.BaseName) for Standard Processing” {

                foreach ($rule in $rules) {

                    It “passes the PSScriptAnalyzer Rule $rule {

                        (Invoke-ScriptAnalyzer -Path $script.FullName -IncludeRule $rule.RuleName ).Count | Should Be 0

                    }

                }

            }

        }

    }

}

C’Ya Manchester – Hello Derby!!

After yet more changes in my housing see my previous post for a bit of background link – I have decided to settle in Derby and this has been for a few very good reasons.

  • I’ve got a good group of friends here.
  • Manchester, London, Nottingham, Birmingham & Wolverhampton are all short train journeys away and I’m expecting to spend more time between them in the coming months ahead.
  • I almost moved here back in January – but I decided to try and give Manchester another go from the work perspective and this seemingly wasn’t to be the case

However I made a good group of friends in Manchester at the various events I’ve been to there over the last 2 years (more so the last year – see this page for more details) and I’ll still be trying to attend some of the amazing events there when it is feasible.

This is yet another new chapter in the book of my life and it is one that really should allow me to lay the foundations for the future a bit easier.

3 & half Months into 2016 and it feels like its the beginning of yet another new year.

Pulling the Community Together to Improve the Quality of PowerShell Modules

In a discussion that started on Twitter a while back with June Blender about the quality of the Modules being posted to the PowerShell Gallery I had an Idea on a way that we could help improve this from the community – using the tools that we have available to us and more importantly the expertise of the rest of the community to help shape and guide the direction for modules.

The Idea starts off with a simple GitHub Organisation, in this case this one – PowerShellModules – in which we set up a number of teams in that organisation. Some of the teams that I have had in mind include but are not limited to, Documentation, Unit testing, Practise guidance and then module maintainers.

This means that there will be a much more open way of directing the development of Modules for the community but still having the ability to allow modules to be developed in a way that allows others to add to them instead of branching out and creating a second module. This also will mean that there is a stronger focus on modules being updated as the overhead isn’t on a single maintainer but can be given to a number of multiple maintainers at any given time.

 

My thoughts around this would start with me porting my current ‘in progress’ modules to the organisation and building out the teams as mentioned above with a suggestions/RFC like repository that would allow us to drive this for the better of the community.

The end goal from my perspective would be to have 1 community recommended Module for a technology (examples being GitHub, Trello, VSTS, Slack etc) that has been widely community developed that covers as much of the functionality as it can without the need for a separate module.

We have a great community of people and I think that this is the right point in time to start the drive to improve the quality of what we all output to the community in a targeted and effort efficient method.

If your interested in getting involved please comment on this post with your GitHub User Name and I’ll get you added to the Organisation in due time but please keep an eye out for the Email from GitHub requesting you to join the Organisation especially in the Junk Folder Winking smile

The Power of the Humble Pint and the Community when things are difficult!

Disclaimer This isn’t a fun post (to read or to write) and nor is it a technical post – this is a reflection on the last few years and is in its very nature quite a personal post. I expect that there will be some kick backs about this post in future and I would humbly ask that you try and imagine yourself having been in my shoes at the time of these events happening and also at the time of writing this post.

If this isn’t the sort of thing that you wish to read then I would advise that you don’t carry on from this point and find something else more fitting to your taste.

 

Sometimes I have those moments where my thoughts can be expressed along the lines of “Fuck this I’m getting out of IT” or in other cases it can be put forward even simpler “Fuck it – I’m Done with all of this”

Now I know that likely read in a way that is different from the actual truth behind it but this is something that we in IT (and generally in Adult life) tend to be expected to sweep this sort of emotion under the carpet as if it doesn’t actually exist. For me this is no longer acceptable and I will not hide my emotions away like this especially when I am struggling to deal with it all and I, like many others in similar situations have to find our own ways of coping with the daily struggles and the tipping points that we each have.

My tipping points have always been centred around home-life stability – something that most people take for granted, however for me this has been something that has been in almost constant flux since I was 16. I’ve had some good spells where things have been stable for almost 2 full years but I’ve also had the other extreme where things have been extremely volatile for a time which could typically be anywhere up to 6 months or so.

This being an area that I;m frequently reminded of I decided in the spirit of writing this post that I would do some data digging and work out a few things around my home life that could be determined as statistically interesting – or at least it was to me at the time and it has been something that I have been thinking of doing for quite some time now, so when better to do it than when I want to write about it.

So I’ve only worked out places I’ve lived since (just before) I turned 16 (I’m 26 in 2 weeks and think that 10 years is a good measure point) and I haven’t split all hotels out into separate rows in my Spreadsheet – if I did that then I feel that it would skew the data but for my own amusement I will likely do this at some point in future.

However the crunch really comes down to the numbers and I have found the following facts – some of which shock me now by looking at them

  • I’ve lived in roughly 24 different places in 10 years – this includes adding spells of stays in hotels, hostels and even a spell of time spent in my car/s
    • I’ve rented 11 places – these I had actual tenancy agreements in place
    • I’ve lived in 8 different forms of shared housing – this doesn’t include any spells of living with family or those that would be classified as family
    • I’ve lived in 4 places that were the direct result of being made homeless – although this is technically skewed as the only time this happened was when my ex partner, son and I were all made homeless – Other than this I have received NO HELP from any UK Council Housing department as I am seen as “Not in Priority Need” according to their data charts
    • I’ve spent 4 different spells where I’ve basically lived in hotels prior to this weekend (as it will be spell number 5 now)

The duration of the average spell is roughly as follows

    • Days per place = 152
    • Weeks per place = 21
    • Months per place = 5
    • Years per place = 0.42

 

The Longest spell is as follows

    • Days = 663
    • Weeks = 94
    • Months  = 21
    • Years  = 1.82

 

So where does this fit in with the Title of this blog post?

Well I suppose it really all started for me in September 2013 when it became the right time to make the decision to move away from everyone that I knew and try and start afresh closer to work and part of that was to work out how to end up meeting new people. Thankfully I learned of the SharePoint User Group, of which I’ve become a regular attendee at, as well as a few other groups thanks to them having Meetup groups, these included LeanAgile and DigiCurry to name a few.

This was the type of surrounding where I realised I felt that I was comfortable with meeting new people and I strongly feel that though these groups (& the resulting conferences I’ve attended too) I’ve made some amazing friends along the way and at some point I came to the conclusion that I would most likely still feel comfortable on the presenting side of the groups and not just as an attendee and that started me off on the journey as stated in this post and followed up in this post , this post and this post.

However its not all been fantastic throughout the years but having found various communities that I enjoy attending, I have somehow managed to scrape through all the difficult moments and made it this far however it is now getting to the point where the number of “Fuck this I’m getting out of IT” or “Fuck it – I’m Done with all of this” days are getting somewhat out of balance with what I’m able to maintain. A key part of this is again due to my current housing situation, aka a downright mess.

With this in mind I suppose what I’m getting at is that without the communities that I’ve become a part of I’m not sure I would be able to write this post.

Also over the last few weeks I’ve been asked around the why’s & how’s I manage to juggle it all. The short and simple answer is that all these communities are essentially a part of the extended family to me and with this I feel that at times I want to see and help direct the communities growth for the benefit of the community members much akin to how a parent would do the same for their children, something that I currently cannot do for my own children.

As I see the communities as extended family I plan things around “the next event” which has been a major driving force keeping me going over the last year.

So with all that in mind there may be times ahead where I’m struggling and especially more so with the Core items in life but that wont ever stop me from continuing the work I put into the community where it is still feasibly possible. There may be times ahead where I may need to unfortunately let conferences/user groups down that I’ve promised my time to speak at but this as things stands is an unfortunate bi-product of the situation I currently find myself in and if I can in anyway mitigate having to do so then I will, but currently it is looking like I may have to cancel everything that I have planned ahead, which is frustrating and infuriating especially when I’ve been looking so forward to the events I’ve got planned over the coming weeks/months.

 

2016 was supposed to be the beginning of an amazing year where things fell into place, however 3 (almost 4) months in and its feeling like 2013, 2014 & 2015 all over again.

 

It’s 4:12 and I really shouldn’t hit publish on this article but I feel that it needs done – Yes I’m 25 and Yes I Suffer from depression, but that hasn’t stopped me achieving a hell of a lot in the last few years and I don’t expect that to change. I can and will get though it no matter how difficult the roads ahead are for me.

Updated! Quick Win – Install PowerShell Package Management on systems running PowerShell v3 / v4

**Update 9th March 2016 PowerShell Team released an updated version of the PackageManagement modules today and I’ve updated the Script accordingly and will install the latest PackageManagement modules for you with a little verbose output

Updated Microsoft blog is at https://blogs.msdn.microsoft.com/powershell/2016/03/08/package-management-preview-march-2016-for-powershell-4-3-is-now-available/ **

 

This is a very very quick post about the latest feature being made available downlevel from Powershell v5.

As Microsoft have released PackageManagement (formally OneGet) that is now avaliable for PowerShell v3 & v4 as detailed in this link http://blogs.msdn.com/b/powershell/archive/2015/10/09/package-management-preview-for-powershell-4-amp-3-is-now-available.aspx

That’s right the ability to pull directly from the PowerShell Gallery but you need to install the Package Management release which I’ve Scripted for you here.

And what better way than a simple 1 liner to grab and run the script

Invoke-Expression (New-Object Net.WebClient).DownloadString(‘http://bit.ly/PSPackManInstaller’)

And if you want to look at the Script then direct link is http://bit.ly/PSPackManInstaller – this takes you to the RAW version of the file on Github so will not download or execute – but will allow you to read it

Hope this is useful for you

PS credit goes to @lee_holmes for the idea from following tweet https://twitter.com/lee_holmes/status/318799702869041153

Beware where you place Comment based Help

In working on the PSWordPress Module that Stephen Owen (@foxdeploy) has started I came across an interesting issue after running my Pester tests which calls – $ModuleFunction.Definition.Contains(‘.Synopsis’) | Should be True to check for comment based help – and it was failing even though I had Comment Based help in there. The problem was that the Help was Above the Function Keyword – so this means that it wasn’t carried through to the $ModuleFunction.Definition property. So this is a good example of why CommentBased Help for a module should be held within the initial Curly Bracket for the function.