Quantcast
Channel: Windows PowerShell - SAPIEN Blog
Viewing all 308 articles
Browse latest View live

Finding PowerShell 5.0

$
0
0

There are some amazing new features of Windows PowerShell 5.0. Some of them, including PowerShellGet, are available in Windows PowerShell 3.0 and 4.0. But, many very useful features, including the new advanced features of DSC, PowerShell classes, the information stream, remote debugging, copying between sessions, and advanced logging are supported only in 5.0.

All SAPIEN software products fully support Windows PowerShell 5.0 and the new modules, like Pester and PSScriptAnalyzer.

Unlike previous releases, Windows PowerShell 5.0 will have supported releases, but will not be final. It will be updated with Windows.

So, how do you find and install PowerShell 5.0?

On Windows 10

Windows PowerShell 5.0 is installed with Windows 10. And, it’s updated automatically when Windows Update updates Windows 10.

Notice that Windows PowerShell now has non-negative values for the Build and Revision properties in its version number.

clip_image002

The full version is useful for comparing versions, although not all versions are different from each other. On the downside, the #Requires -Version statement looks only at the Major and Minor property values, so you need to use an IF statement, or something similar, require a particular version.

In this example, #Requires -Version does not stop the script from running.

clip_image004

On older Windows

If you’re running an older version of Windows, you can install Windows PowerShell 5.0. It’s available in the Windows Management Framework (WMF) 5.0 Production Preview.

It is a preview, not a final version, but it is fully supported. That means that all features have been fully tested; none are considered to be experimental. Also, if you hit a blocking issue, Microsoft will help you, including investigating the issue and providing a workaround or an update.

WMF 5.0 supports the following systems:

  • Windows Server 2012 R2
  • Windows 8.1 Pro
  • Windows 8.1 Enterprise
  • Windows Server 2012
  • Windows 7 SP1
  • Windows Server 2008 R2 SP1

To install it:

  1. 1. Uninstall any Windows PowerShell 5.0 preview on the machine.
  2. 2. Install Microsoft .NET Framework 4.5.
  3. 3. Install WMF 5.0 Production Preview.

Where is WMF 5.0 Release?

The final release version of Windows Management Framework 5.0, which includes Windows PowerShell 5.0 for systems older than Windows 10, is expected soon.

A version was actually released in December 2015, but it was recalled and removed from the Download Center when users reported a serious bug that replaced the PSModulePath environment variable value, instead of appending to it. As a result, modules didn’t load and auto-load properly.

The PowerShell team is busy fixing the $env:PSModulePath error and testing thoroughly to make sure that it didn’t miss any other bugs. They expect to release a final version very soon. When they do, they’ll post on the PowerShell Team blog and we’ll post on the SAPIEN blog, too.

If you installed the WMF 5.0 release version while it was posted on the Download Center and you were affected by the PSModulePath bug, there’s hope for you, too. The PowerShell Team is expected to release a fix to restore your PSModulePath value along with the WMF 5.0 release.

If you have questions about installing Windows PowerShell 5 or running any SAPIEN product with Windows PowerShell, be sure to post on our Windows PowerShell forum or the forum for your product.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  


Is there a PSEdit for PowerShell Studio?

$
0
0

My friend, Thom Schumacher, who has been leading the Arizona PowerShell User Group for the past few months, is getting to know PowerShell Studio. Like many of us, he came to PowerShell Studio from PowerShell ISE, so he looks for the “ISE way” to do things in PowerShell Studio.

“How do I use PSEdit in PowerShell Studio?,” Thom asked on Twitter. Here’s my answer.

Um, you don’t need it

Being very literal, you don’t need the PSEdit function in PowerShell Studio.

The PSEdit function, which is defined in and works only in PowerShell ISE (not in the ISE module), opens a script that you specify in a new PowerShell Tab, that is, a new runspace.

Screenshot 2016-02-16 09.51.29

In ISE, you need to create a new runspace because, by default, everything that you run in ISE runs in the same runspace in its console. That’s obviously not the best test environment. A new runspace is an improvement, even though the new runspace still includes your personal PowerShell profiles and anything that they import or auto-load.

As a best practice test environment, by default, PowerShell Studio runs every script in a new runspace every time. It not only creates a new runspace for every script. It creates a new runspace each time you use Run, Run Selection, or Debug, even if you run them repeatedly on the same script. You always get a new runspace. And, that runspace never includes PowerShell profiles, so you don’t need to hide, move, or disable them.

If you need a persistent runspace to share content, like variables, use the PowerShell Studio Console Pane. Run the script from the console or use the Run in Console or Run Selection in Console commands. Commands that run in the same Debug session also share a persistent runspace.

 

A PSEdit to Open a Script in PowerShell Studio

But, that’s probably too literal. Many people who use the PSEdit function aren’t even worried about a runspace. They just want a console command that opens a new script in their favorite editor.

To open any script (.ps1), module (,psm1) in PowerShell Studio, use the Invoke-Item cmdlet or its alias, ii.

For example, this command opens the Get-CmdletAttributes.ps1 script in PowerShell Studio.

ii C:\Scripts\Get-CmdletAttributes.ps1

You can use Invoke-Item in any PowerShell console, including, but not limited to, the PowerShell console in PowerShell Studio.

The Invoke-Item cmdlet works because it opens the file in the program that is associated with that file type. When you install PowerShell Studio, the installer sets the file association for you.

A PSEdit to Open PowerShell Studio

When people ask for a “PSEdit” equivalent, sometimes they just want a console command to open PowerShell Studio.

My CurrentUserAllHosts PowerShell profile includes this function. I named it “SPS” for “SAPIEN PowerShell Studio.” It works anywhere in PowerShell. It’s not limited to PowerShell Studio.

When I want to open PowerShell Studio from any console (except the one in PowerShell Studio, of course), I type sps.

function sps
{
    $keyPath = 'HKLM:\Software\Sapien Technologies, Inc.\PowerShell Studio*'
 
    if ($key = (dir $keyPath | Sort-Object -Descending | Select-Object -First 1) -replace 'HKEY_LOCAL_MACHINE', 'HKLM:' )
    {
       if ($path = Get-ItemProperty -Path $key -Name Path)
       {
           Start-Process $path.Path
       }
       else
       {
           Write-Error "Found PowerShell Studio. Cannot find path in $key."
       }
    }
    else
    {
        Write-Error "Cannot find PowerShell Studio on this computer."
    }
}

So, there you have it. If you’ve just started using PowerShell Studio, and you need an equivalent for your favorite command in your previous tool, post your request on our PowerShell Studio forum.

June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at juneb@sapien.com or follow her on Twitter at @juneb_get_help.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

New PowerShell Reference Tool

$
0
0

SAPIEN Technologies, Inc. is pleased to introduce our new online Windows PowerShell Reference tool, which is based on the reference section of iPowerShell Pro.

Windows PowerShell Reference Tool

To find it, on the SAPIEN web page, click Support and then click PowerShell Reference. Or, go directly to http://sapien.com/powershell.

SAPIEN Support Menu - Powershell Reference

PowerShell Reference contains help for Windows PowerShell and PowerShell modules. This tool allows you to search through Cmdlet Help, About Help and Provider Help with just a click of your mouse.

SAPIEN Technologies, Inc. Windows PowerShell Reference

After you’ve chosen a help categgory, start typing in the search box. The menu will filters as you type.

PowerShell Reference - Cmdlet search

When you choose an item from the list, the document displays with the standard Microsoft formatting.

PowerShell Reference - Cmdlet Search: Get-

The SEE ALSO links in About Help topics are actually clickable, making it easier to jump to related topics.

PowerShell Reference - About Help

If you are surfing PowerShell Reference on your iPhone or iPad, you can jump straight from your browser to the corresponding place in iPowerShell Pro.

Windows Powershell reference - browser viewiPowerShell Pro Windows PowerShell Reference
Our library includes the data from Microsoft’s PowerShell documentation as well as many of the modules found in the PowerShell Gallery. If you’ve written a module for the gallery, and your module includes valid XML help files, it might appear in PowerShell Reference, too. (If you need help writing help, be sure to check out PowerShell HelpWriter!)

We run an updater once a quarter unless more frequency is needed, so check back often for added modules.

And, be sure to let us know if you like PowerShell Reference, including requests for help for particular modules.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

Finding PowerShell 5.0

$
0
0

Update: Windows Management Framework 5.0 RTM, which includes Windows PowerShell 5.0 for systems earlier than Windows 10, is now released. We have updated this blog post to reflect the change.


There are some amazing new features of Windows PowerShell 5.0. Some of them, including PowerShellGet, are available in Windows PowerShell 3.0 and 4.0. But, many very useful features, including the new advanced features of DSC, PowerShell classes, the information stream, remote debugging, copying between sessions, and advanced logging are supported only in 5.0.

Unlike previous releases, Windows PowerShell 5.0 will have supported releases, but will not be final. It will be updated with Windows.

All SAPIEN software products fully support Windows PowerShell 5.0 and the new modules, like Pester and PSScriptAnalyzer.

So, how do you find and install PowerShell 5.0?

On Windows 10

Windows PowerShell 5.0 is installed with Windows 10. And, it’s updated automatically when Windows Update updates Windows 10.

Notice that Windows PowerShell now has non-negative values for the Build and Revision properties in its version number.

clip_image002

The full version is useful for comparing versions, although not all versions are different from each other. On the downside, the #Requires -Version statement looks only at the Major and Minor property values, so you need to use an IF statement, or something similar, require a particular version.

In this example, #Requires -Version does not stop the script from running.

clip_image004

On older Windows

If you’re running an older version of Windows, you can install Windows PowerShell 5.0. It’s available in Windows Management Framework (WMF) 5.0. After being recalled, this RTM version was re-released on February 24, 2016.

WMF 5.0 supports the following systems:

  • Windows Server 2012 R2
  • Windows Server 2012
  • Windows Server 2008 R2 SP1
  • Windows 8.1
  • Windows 8.1
  • Windows 7 SP1

To install it:

  1. Uninstall any Windows PowerShell 5.0 previews on the machine (KB3094174, KB3094175, KB3094176). To detect them, use Get-HotFix.
  2. Install Microsoft .NET Framework 4.5. To get the installed versions, use a script that checks the registry, such as Get-DotNetVersion.ps1.
  3. Install Windows Management Framework 5.0. (Be sure to read the cautions on this page, too, including incompatible versions of commonly used programs.)

If you installed the WMF 5.0 release version while it was posted on the Download Center and you were affected by the PSModulePath bug, there’s hope for you, too. The PowerShell Team is expected to release a fix to restore your PSModulePath.

 

If you have questions about installing Windows PowerShell 5.0 or running any SAPIEN product with Windows PowerShell, be sure to post on our Windows PowerShell forum or the forum for your product.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

PowerShell Studio 2016 Released! – What’s New? (Part 1)

$
0
0

PowerShell Studio 2016 is released as part of the regular update cycle for our subscribers. We will cover all the new features in a series of “What’s New” articles.

Now let’s take a look at visual changes made to the application.

image

Updated UI

We made some major UI changes by modernizing the controls, improving the theme support throughout the application and updating all the ribbon icons:

image

 

 

 

Join the Dark Side or the Light Side?

For those of you who enjoy dark backgrounds, we improved support for the dark theme throughout the application. In fact, the dark theme is the new default for the application.

When switching to and from the “Visual Studio 2013 Dark” theme, PowerShell Studio will automatically update the editor’s syntax coloring to match the theme.

Editor Dark Theme:

image

 

Editor Light Theme:

image

You can choose your preferred theme by using the ribbon’s theme menu:

image

Note: When updating from PowerShell Studio 2015, 2016 will retain your current theme and coloring preferences.

 

New Source Control Ribbon Tab

We moved all our source control features into a dedicated tab for your convenience.

image

You can now access Restore point, Version Recall and Source Control commands in this unified tab.

 

Theme Triggered Editor Coloring

For those of you who wish to use your own editor coloring scheme when switching between themes, we have you covered. All you have to do is create an editor preset and name it the same name as the theme you wish to be the trigger.

For example, you can override the “Visual Studio 2013 Dark” coloring by creating an editor preset with the name “Visual Studio 2013 Dark”:

image_thumb4[2]

  1. Go to Options->Editor->Font and Color
  2. Configure your color settings
  3. Press the “Save As Preset” button.
  4. Save the preset using the desired theme name.

 

image_thumb5[1][2]

Now PowerShell Studio 2016 will automatically load your editor preset when the matching theme is selected.

Updated Panels

We updated the PowerShell Studio panels and in most cases added search / filtering functionality. For example, the Functions Panel now has a search field in addition to modernized look:

image
Now you can filter the functions in the Functions Panel by simply typing in the search field:

image

 

Tools Panel:

We made several changes to the Tools Panel. As mentioned above, we added filtering capabilities to each tab:

image

We moved the list of used controls to its own tab:

image

You can use the selection list to select controls in the designer. Use the search field to quickly location the desired control in your GUI.

 

Help Panel:

The Help panel now supports the Dark theme:

image

 

Additional Search Capabilities

We also add search / filtering capabilities to various dialogs throughout the application.

Form Templates Dialog

SNAGHTML228a06

Add Events Dialog

SNAGHTML22f805

 

 

 

 

 

 

Select Property Sets Dialog

SNAGHTML236316

 

Stay tuned for Part 2 of “PowerShell Studio 2016: What’s New?” blog series.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

PowerShell Studio 2016: What’s New? (Part 2)

$
0
0

PowerShell Studio 2016 is released! We’ve written a series of blog posts to introduce you to the newest features. In Part 1, we reviewed new UI features, including our new dark themes.

In Part 2, we will look at the new debugging features of PowerShell Studio 2016.

 

The first debugging feature we are looking at is the new interface for dynamic breakpoints.

image

 

Variable Breakpoints

You can trigger a break when a variable is read or modified, by setting a Variable Breakpoint:

SNAGHTML1149a41

Variable: Enter the name of the variable. Dollar sign is not necessary.

File: Bind the breakpoint to a particular file. Leave blank to apply to the current session instead.

Action: Specifies commands that run at each breakpoint instead of breaking.

Mode: Determines the mode of access that triggers variable breakpoints (Read, ReadWrite, Write).

 

Function Breakpoints

You can also trigger a breakpoint when a particular command is called, by setting a Function Breakpoint:

SNAGHTML11a21e7

Function: Enter the name of the command.

File: Bind the breakpoint to a particular file. Leave blank to apply to the current session instead.

Action: Specifies commands that run at each breakpoint instead of breaking.

 

Edit Breakpoints Dialog

The Edit Breakpoint dialog allows you to view all the breakpoints and tracepoints in one location.

SNAGHTML11bb993

Enable / Disable / Remove Breakpoints

You can enable or disable the specific breakpoint by unchecking the check box:

image

Add Breakpoints

Using the buttons at the top, you can add new variable and function breakpoints.

image

Remove Breakpoints

To remove the highlighted breakpoints, press the X button.

Edit Breakpoints

You can also edit existing variable or function breakpoints directly:

image

Filter Breakpoints

When dealing with a large number of breakpoints, you can filter specific types of breakpoints using the filter drop-down menu:

image

When you are done editing the breakpoints, to commit the changes, click OK. To undo the changes, click Cancel.

 

Variable Panel Updates

We revamped the Variable Panel to make it easier to find the variables you are looking for.

image

Filtering

You can now choose to selectively display variables, such as: user variables, PowerShell variables, or all variables.

image

Search

To filter variables by name, type the variable into the Search box.

image

We hope these new features will improve your overall debugging experience.

 

Stay tuned for Part 3 of “PowerShell Studio 2016: What’s New?” blog series.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

PowerShell Studio 2016: What’s New? (Part 3)

$
0
0

PowerShell Studio 2016 is released! We’ve written a series of blog posts to introduce you to the newest features. In Part 1, we reviewed new UI features, including our new dark themes. In Part 2, we covered new debugging features, including variable and function breakpoints and improvements to the Variables pane.

In Part 3, we will look at some of the new editor features of PowerShell Studio 2016.

 

Import Functions

PowerShell Studio already allowed you to convert functions into a new module (File->New->New Module from Functions). Now, with PowerShell Studio 2016, you can import functions into your existing scripts or modules.

You can find the Import Functions feature in the Edit group in the Home tab of the ribbon:

image

Or in the Functions panel:

image

You’ll be prompted to select the files that contain the functions. You can select and remove files at any time. All functions in the files will be listed in the Import Functions dialog box.

image

To insert the checked functions in the script, press the Import button.

image

 

Code Folding Options

PowerShell Studio supported collapsible code in the form of regions, multiline comments, and script blocks. PowerShell Studio 2016 lets you control which regions collapse and expand when you use the collapse / expand commands.

To select collapsible regions, in the Edit group on the ribbon, click Regions, and then click Include.

image

 

New Code Formatting Options

We added two new formatting options.

Automatically expand aliases

When enabled, this option expands command and parameter aliases when formatting your script.

Before:
image

After:
image

Convert curly quotes to straight quotes

When enabled, this option automatically replaces curly quotes (blog quotes) with straight quotes when formatting your script.

Before:
image

After:
image

 

TODO / DONE Tasks comments

When creating event handlers for PowerShell GUI applications, you might have noticed that a TODO: comment is included:

image

These comments are meant to be reminders that you have to place your custom script in the event script block.

To help you find these uncompleted tasks, PowerShell Studio will display the TODO: comments in the Navigation menu that is located in the upper right corner of the Script tab:

image

Tip

DONE: comments will appear in the Navigation menu as you complete the tasks.

To quickly jump directly to these task comments in your script, select them from the Navigation menu.

 

New Document Tab Commands

PowerShell Studio 2016 adds a few new commands to the context menu that appears when you right click the tab for a file:

SNAGHTML19dce1f

Copy File Name

Copies the file name to the clipboard.

Copy Folder Path

Copies the file folder path to the clipboard.

Reload Document

Reloads the document, undoing any unsaved changes.

 

Edit Options

For your convenience, we moved all PrimalSense-related options to their own Options page:

image

Separating these options declutters the Editor page and makes it easier for you to find the settings you are looking for.

image

Now, all the auto-insert options are grouped in one convenient location.

 

PowerShell V2 Compatibility 

In build v5.2.116, we introduced a new option (Options->Designer): Enable PowerShell V2 assembly compatibility.

image

When this option is enabled, PowerShell Studio will use .NET 2.0 assembly references when generating GUI scripts and will warn you if any assembly does not support the .NET 2.0 Runtime.

Tip
You can access the file’s assemblies using the Ribbon->Home->Edit->Assemblies:

image

If the option is unchecked, it will use the 4.0 .NET or later assemblies and place a #requires –Version comment at the top of the generated script.

 

 

Next we will look at PowerShell Studio 2016’s new Custom PrimalSense feature.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

My First Form: New Videos for PowerShell GUI Beginners

$
0
0

Like most things, once you know the basics, it’s really easy to build GUI applications with Windows PowerShell and PowerShell Studio. And, like most things, it’s hard to learn the basics. We’re here to help.

We just posted a two-part series of videos. You can watch them in any order.

  • My First Form: Build a Simple PowerShell GUI App is a step-by-step guide to building a little PowerShell GUI app that displays the versions of Windows and Windows PowerShell on your system.
  • My First Form: Controls and Properties is like a prequel. It introduces you to the concepts of the Windows Forms controls that we use in the GUI applications. It shows you how to add them to your app and how to find and change their property values. It also introduces you to the SAPIEN Spotlight articles that provide clear, simple help for each control, along with examples written in Windows PowerShell.

If you want more information designed especially for GUI development, see PowerShell GUIs; Where do I start?

To see all of the videos from SAPIEN Technologies, subscribe to our YouTube channel: SAPIENTech. If you have comments, questions, ideas for more videos, be sure to let us know.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  


PowerShell Studio 2016: Custom PrimalSense

$
0
0

We’ve written a series of blog posts to introduce you to the newest features of PowerShell Studio 2016. In this blog, Part 4, we cover new customizable PrimalSense in PowerShell Studio 2016.

But, there’s more:

  • In Part 1, we review the new UI features, including our new dark themes.
  • In Part 2, we introduce our new debugging features, including variable and function breakpoints and improvements to the Variables pane.
  • In Part 3, we look at some of the new editor features of PowerShell Studio 2016.

 

Custom PrimalSense Lists

The new customizable PrimalSense feature allows users to tailor their PrimalSense experience. The contents of the custom PrimalSense can be derived from a static list or from a dynamically created list using a PowerShell script.

These custom PrimalSense lists can be triggered via a shortcut name, similar to snippet shortcuts. For example, if you type the following shortcut:

image

To display the custom PrimalSense list, press [Ctrl + Alt + P] or [TAB].

image

The shortcut will be replaced with the selected item in the PrimalSense list.

image

 

In addition, custom PrimalSense lists can be triggered by typing a particular cmdlet / parameter combination or a specific parameter regardless of command.

image

The custom list in this case is triggered when the user presses [SPACE] after typing the Name parameter of Get-Process.

Let’s look at the types of lists in more detail.

 

Static Lists

Static lists are the simplest method for creating a custom PrimalSense list. These lists are simply read from a static data file source, such as a CSV file, when the list is triggered. Let’s look at the supported data file formats.

 

Data File Formats

There are two supported data file formats: CSV and XML files.

CSV Format

The CSV is the simplest format. It can consist of simple list where there can only be one list item per line.

For example, GetProcess_Name.csv data file contains the following:

image

Note: Since this is a CSV file format, you must escape double quotes using another double quote “”.

You have the option to associate each item with a pre-defined picture (via index) and a value using the following format:

Name, Index, Value

  • Name – This is the text displayed in the PrimalSense list.
  • Index – (Optional) The numeric index of the image you that will be displayed next to the name in the PrimalSense list. Use –1 if you do not wish to associate an image. See below for a list of image indexes.
  • Value – (Optional) The value that is inserted into the editor when the item is selected from the PrimalSense list.

 

Here is an example csv that uses images and values:

image

The resulting PrimalSense list:

image

The inserted value:

image

The following table contains the list of supported image indexes:

Index Image
0 Keyword
1 Folder
2 Code Snippet
3 Namespace
4 Assembly
5 Assembly Checked
6 Public Class
7 Private Class
8 Public Property
9 Public Field
10 Public Interface
11 Public Delegate
12 Public Structure
13 Public Method
14 Public Enumeration
15 Enumeration Item
16 Cmdlet
17 Alias
18 Variable
19 Function
20 Document Function
21 Global Function
22 Static Method
23 Static Property
24 Static Field
25 Snapin
26 Module
27 Operator
28 Help
29 Object Browser
30 Parameter
31 Parameter Alias
32 Job
33 File
34 External Tool
35 Workflow
36 Configuration
37 Event
38 Breakpoint
39 Tracepoint
40 Caret
41 Last Edit Position
42 Syntax Error
43 Debug Position
44 Region
45 Bookmark
46 Parameter Set
47 Task
48 Task Completed
49 Computer
50 Gear

 

 

XML Format

The second supported data format is XML. Use the XML file format to insert more complex values, such as a multiple line script.

image

The XML file consists of a root element named List, which contains a child element for each item named Item.

The item element contains the following attributes:

  • name – contains the display name of the item in the PrimalSense list.
  • image – contains the image index of the item.

A CDATA block contains the multi-line text that is inserted when the item is selected in the PrimalSense list.

For example, the functions shortcut triggers the following list of functions:

image

When an item is selected, a complete function is inserted:

image

Dynamic Lists

For the cases where a static list isn’t enough, PowerShell Studio gives you the option to dynamically create the data file before displaying it in the PrimalSense list. This is accomplished, by running a custom PowerShell script that generates the necessary data file. Next, we will look at how to configure triggers and create scripts that generate dynamic lists.

 

Configuring Triggers

The custom PrimalSense list triggers are stored in the following XML file:

C:\ProgramData\SAPIEN\PowerShell Studio 2016\CustomSense\Triggers.xml

The XML file is made up of a Triggers root element and each individual list trigger is defined by a child element named Trigger.

image

Each Trigger element has the following attributes:

  • shortcut – (Optional) The shortcut name that triggers the custom PrimalSense list when the user presses [Ctrl + Alt + P]. The shortcut must not contain spaces.
  • command – (Optional) The command/cmdlet that the trigger is bound to. Use an asterisk * to denote all commands. This field requires the parameter attribute.
  • parameter – (Optional) The parameter that triggers the custom PrimalSense list. This field requires the command attribute.
  • type – [cached|dynamic] (Default: cached) Determines if the list is cached in memory or is read every time the list is triggered.
  • datafile – (Required) Specifies the data file that is to be loaded (CSV or XML).
  • elevated – (Optional) (Default: False) Determines if the script needs to be elevated.
  • timeout – How long PowerShell Studio should wait for the process to complete before quitting.
  • autoquote – [True|False] (Default: True) If set to True, PowerShell Studio will automatically wrap quotes around the values contained in a CSV file when necessary.
  • scriptfile – Specifies the script to run in order to create the data file.

Note: If you modify the Triggers.xml file, you will need to reload PowerShell Studio in order for the changes to take effect.

 

Script Files

When you specify a script file in the triggers XML file, PowerShell Studio will execute said script when the list is triggered.

Let us look at the contents of the sample GetProcess_Names.ps1 script:

 Get-Process | Select-Object -ExpandProperty Name -Unique > "$CustomSensePath\GetProcess_Name.csv"

The script simply pipes out the results of Get-Process to a basic csv file. Notice the $CustomSensePath variable, this is a special variable that contains path information. You can utilize the following variables in your script:

 

$CustomSensePath

This variable contains the path to the CustomSense folder. For example:

C:\ProgramData\SAPIEN\PowerShell Studio 2016\CustomSense\

Note: The data file must be located in the same folder as the triggers.xml.

$CurrentFile

This variable contains the file path to the active script in PowerShell Studio. This value will be empty for new unsaved files.

 

 

You should now have a better understanding of how to use PowerShell Studio’s Custom PrimalSense feature. This feature is another tool you can use to tailor PowerShell Studio to fit your specific needs.

If you have any comments or feedback, please feel free to post in our PowerShell Studio product forum.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

Inheritance in PowerShell Classes

$
0
0

If you’re learning about classes in Windows PowerShell 5.0, one of the first new concepts that you’ll encounter is inheritance. When you create a class that is based on another class, your new subclass or child class automatically gets the inheritable members (e.g. properties and methods) of the parent class or base class.

Inheritance is a really powerful and useful concept, so it’s important that you understand it. Fortunately, it’s pretty easy. Also, the inheritance principles that you learn in PowerShell are also used in other programming languages, so learning them in PowerShell gives you a head start on new languages.

Subclasses of System.Object

All PowerShell classes are subclasses of the System.Object class. So, they inherit the inheritable methods of the System.Object class.

Create an empty class.

PS C:\> class AnyClass {}

Look at its type. The BaseType property shows the immediate parent class.

PS C:\ > [AnyClass]

IsPublic IsSerial Name     BaseType
-------- -------- ----     --------
True     False    AnyClass System.Object

And, when you create an instance of the AnyClass class and pass it to Get-Member, you can see that there are four methods of the AnyClass class that you didn’t define. These methods are inherited from the System.Object base class.

PS C:\> $anything = New-Object -TypeName AnyClass

PS C:\> $anything | Get-Member

TypeName: AnyClass

Name        MemberType    Definition
----        ----------    ----------
Equals      Method        bool Equals(System.Object obj)
GetHashCode Method        int GetHashCode()
GetType     Method        type GetType()
ToString    Method        string ToString()

You can call these methods on the instance of the AnyClass class. They work as though you wrote them in the AnyClass class.

PS C:\> $anything.GetType()

IsPublic IsSerial Name     BaseType
-------- -------- ----     --------
True     False    Anyclass System.Object

PS C:\> $anything.ToString()
Anyclass

NOTE: All PowerShell classes are automatically subclasses of System.Object. You do not need to specify System.Object as the base class.

Create a subclass

Creating a subclass is easy.

Let’s create a base class and a subclass. Here’s the Glass class. The full code is in Glass.ps1 on GitHub. If you’re testing this code, be sure to dot-source the file so that the class is added to the session.

class Glass
{
    # Properties
    [int]$Size
    [int]$CurrentAmount
 
    # Constructors
    Glass ([int]$Size, [int]$Amount)
    {
        $this.Size = $Size
        $this.CurrentAmount = $Amount
    }
 
    # Methods
  + [Boolean] Fill ([int]$volume)
    {}
 
  + [Boolean] Drink ([int]$amount)
    {}
}

The syntax for a subclass is:

class subclass : base class { ... }

PowerShell classes can inherit from only one base class, so you can’t specify more than one class name. (The class can implement multiple interfaces, but we’ll save that for another blog post.)

To start with the simplest case, let’s create an empty subclass based on the Glass class. We’ll call it AnyGlass.

PS C:\> class AnyGlass : Glass {}

First, make sure that the class was created and that the base type is Glass.

PS C:\> [AnyGlass]

IsPublic IsSerial Name     BaseType
-------- -------- ----     --------
True     False    AnyGlass Glass

Now, let’s create an AnyGlass object. There are several different ways to create an object (“instantiate”) based on a class, but we’ll use New-Object here, because it’s so PowerShell.

PS C:\> $anyGlass = New-Object -TypeName AnyGlass

PS C:\> $anyGlass | Get-Member

TypeName: AnyGlass

Name          MemberType     Definition
----          ----------     ----------
Drink         Method         bool Drink(int amount)
Equals        Method         bool Equals(System.Object obj)
Fill          Method         bool Fill(int volume)
GetHashCode   Method         int GetHashCode()
GetType       Method         type GetType()
ToString      Method         string ToString()
CurrentAmount Property       int CurrentAmount {get;set;}
Size          Property       int Size {get;set;}

Notice that the AnyGlass object has the properties defined in the Glass class (Size, CurrentAmount), the methods defined in the Glass class (Drink, Fill), and the methods that the Glass class inherited from its base class, System.Object (Equals, GetHashCode, GetType, ToString).

So, the AnyGlass class inherits from its parent and grandparent classes — its entire ancestry — just like people do.

Add Members to a Subclass

A subclass can have properties and methods (and all types of members) that are not in the base class. For example, the Glass class has properties that are not in System.Object.

I’ll add a Name property to the AnyGlass class.

PS C:\> class AnyGlass : Glass
{
    [String]$Name
}

PS C:\> $anyGlass = New-Object AnyGlass
PS C:\> $anyGlass

Name Size CurrentAmount
---- ---- -------------
     0    0

You use inherited members in exactly the same way as you use members that are defined in the current class. In fact, unless you do some quick discovery, you really don’t know if a property or method is inherited or defined.

PS C:\> $anyGlass.Name = 'AnyGlass'
PS C:\> $anyGlass.Size = 6
PS C:\> $anyGlass

Name      Size   CurrentAmount
----      ----   -------------
AnyGlass  6      0

Also, inside the class, when you use $this to refer to the current object, you treat defined properties and inherited properties in the same way.

class AnyGlass : Glass
{
    [String]$Name
 
    AnyGlass () {
        $this.Size = 6
        $this.CurrentAmount = 0
        $this.Name = "My glass"
    }
}

Overloading Methods in the Base Class

You can have members that have the same name as a member in the base class, but take different parameters. This is called an overloaded method. In a subclass, it works the same way that it would if you had a method defined twice in the same class.

For example, the Fill method in the Glass class takes one integer argument that represents the volume added to the Glass.

  + [Boolean] Fill ([int]$volume)

The Fill method in the AnyGlass takes the same volume integer argument and a string argument that represents a warning that it returns when you’ve overfilled the glass. (The Fill method in the base class has a predetermined warning.)

class AnyGlass : Glass {
 
	# Methods
	[void] Fill ([int]$volume, [string]$Warning)
	{
		if ($this.currentAmount + $volume -le $this.Size)
		{
			$this.CurrentAmount += $volume
		}
		else
		{
			Write-Warning $Warning
		}
	}
}

When I pipe $AnyGlass to Get-Member and specify the Fill method, it tells me it has two overloads. It doesn’t mention (and doesn’t really care) which one is defined locally and which one is inherited.

PS C:\> $anyGlass | Get-Member -MemberType Method -Name Fill

TypeName: AnyGlass

Name     MemberType     Definition
----     ----------     ----------
Fill     Method         void Fill(int volume, string Warning), bool Fill(int volume)

When I call the Fill methods, they works exactly as they would if both Fill methods were defined in the same class. That is, the argument number and types determine which Fill method is called. I don’t need to do anything to call the Fill method of the Glass class, other than to provide only an integer.

As a reminder, here’s the signature of each of the Fill methods:

# In Glass
+ [Boolean] Fill ([int]$volume)
 
# In AnyGlass
+ [void] Fill ([int]$volume, [string]$Warning)

If I call the Fill method with 2 arguments, an integer and a string, it calls the Fill method of the AnyGlass class, which when full, returns the warning string I specify.

PS C:\> $anyGlass.Fill(3, "Oops! Too much")
WARNING: Oops! Too much

If I call the Fill method with 1 argument, an integer, it calls the Fill method of the Glass class, which has a predefined warning message that includes the room left in the glass. It also returns a Boolean value, $False, which indicates that the AnyGlass was not filled. Notice that I didn’t need to specify anything to get the inherited Glass method, because the AnyGlass class has both methods.

PS C:\> $anyGlass.Fill(3)
WARNING: Sorry. The glass isn't big enough. You have room for 2.
False

Overriding Methods of the Base Class

To hide a method in the base class, write a method that has the same arguments as the method in the parent class. That’s called overriding a method. When methods have the same name and take arguments of the same type, the method in the subclass takes precedence, hides, or overrides the method in the parent class.

You can do the same thing with Properties.

Here’s the AnyGlass class with a Fill method that takes just one argument, an integer, just like the Fill method in the Glass class.

class AnyGlass : Glass {
    # Methods
    [void] Fill ([int]$volume)
    {
        if ($this.currentAmount + $volume -le $this.Size)
        {
            $this.CurrentAmount += $volume
        }
        else
        {
            Write-Warning "Oops! Not enough room"
        }
    }
}

Notice that the signatures of the Fill methods are not identical. The Fill method of the Glass class returns a Boolean. The Fill method of the AnyGlass class returns nothing ([void]).

# In Glass
+ [Boolean] Fill ([int]$volume)
 
# In AnyGlass
+ [void] Fill ([int]$volume)

But, when I create an AnyGlass object and pipe it to Get-Method, it returns only one Fill method signature, instead of two. And, because the return type is Void, we know that it’s returning the Fill method of the AnyGlass class, which overrides the Fill method of the Glass class.

PS C:\> $anyGlass | Get-Member -MemberType Method -Name Fill

TypeName: AnyGlass

Name     MemberType    Definition
----     ----------    ----------
Fill     Method        void Fill(int volume)

When I call the Fill method with a volume, it calls the local Fill method.

PS C:\> $anyGlass.Fill(1)
PS C:\> $anyGlass.Fill(1)
PS C:\> $anyGlass.Fill(1)
WARNING: Oops! Not enough room.
PS C:\>

When a subclass overrides a base class, does it completely hide the parent class? Happily, no!

Calling a member of a base class

Even when a base class member is hidden by a subclass member, you can still call the base class member on an instance of the subclass.

Here’s the syntax:

([baseClass]$instance).member

Essentially, you cast the object to the base class, enclose the casted object in parentheses to make sure it’s evaluated first, and then call the member in the usual way. For example, to call the Fill method of the Glass class on an AnyGlass object:

PS C:\> ([Glass]$anyGlass).Fill(4)
WARNING: Sorry. The glass isn't big enough. You have room for 2.
False

In the script for a class, you can use the same syntax to modify the $this variable that refers to the current object.

For example, in my WineGlass class, the Fill method of the WineGlass class calls the Fill method of the Glass class, which updates the CurrentAmount property. Then, the Fill method of the WineGlass class updates a local property, TotalPoured.

[void] Fill ([int]$volume)
{
    if (([Glass]$this).Fill($volume))
    {
        $this.TotalPoured += $volume
    }
}

You can also call all the way back to our common ancestor, System.Object. For example, if I add a ToString method to the AnyGlass or Glass class, I can call it. Or, I can call the ToString method on System.Object.

PS C:\> $anyGlass = [AnyGlass]::New()
PS C:\> $anyGlass.Size = 6
PS C:\> $anyGlass.CurrentAmount = 4

PS C:\> $anyGlass.ToString()
A 6-ounce glass with 4 ounces.

PS C:\> ([System.Object]$anyGlass).ToString()
AnyGlass

Constructors are not inherited

When I talked about inheritance, I was careful not to say that “all” members, or all properties and methods, are inherited. Constructors, which are really just special methods, are not inherited. Instead, like all PowerShell classes, the new class is created with a default (parameter-less) constructor.

(Need help with constructors? See: Why do we need constructors?)

To find the constructors of a class, use the New static property that PowerShell adds to all classes. (Be sure to use the property, with no parentheses, not the method, with parentheses, which creates a new object).

This command shows that the Glass class has two constructors; a default constructor and a constructor that takes two integers; the first for the size and the second for the amount.

PS C:\> [Glass]::New

OverloadDefinitions
-------------------
Glass new()
Glass new(int Size, int Amount)

But the AnyGlass class just has the default constructor that is added automatically to all PowerShell classes.

PS C:\> [AnyGlass]::New

OverloadDefinitions
-------------------
AnyGlass new()

You can add constructors to the subclass as you would to any class. Remember, that when you add a constructor to the class, it replaces the automatic default constructor. So, if you want a default constructor on your class, you need to add it explicitly.

Calling a base class constructor

The last piece of the inheritance puzzle is calling the constructor of the base class.

(Need help with constructors? See: Why do we need constructors?)

Here’s the scenario. The base class defines a constructor that takes property values as arguments and assigns each value to the correct property. The Glass class is intentionally simple, but it can get complex when the class defines many properties, or the arguments are used to calculate property values.

Glass ([int]$Size, [int]$Amount)
{
    $this.Size = $Size
    $this.CurrentAmount = $Amount
}

In the subclass, you could easily define a corresponding constructor, such as:

AnyGlass ([int]$Size, [int]$Amount)
{
    $this.Size = $Size
    $this.CurrentAmount = $Amount
}

But, you’re maintaining virtually the same code twice. Instead, you can call the base class constructor from the subclass.

The syntax, which uses the base keyword, is:

 Subclass (arguments) : base (argumentsToBaseClassConstructor) { ... }

For example, this AnyGlass constructor calls the Glass class constructor. In this case, there’s no logic in the constructor (inside the script block), but it’s permitted if you need it.

AnyGlass ([int]$Size, [int]$Amount) : base($Size, $Amount) { }

The arguments and their types can be different, just so the call to the base class constructor provides the arguments it requires. For example, this AnyGlass constructor creates a full AnyGlass (Size -eq CurrentAmount) every time.

AnyGlass ([int]$Amount) : base($Amount, $Amount) { }

However, when creating an instance of a subclass, you cannot call the constructor of a base class. It’s explicitly prohibited, because it’s error prone.

You can’t inherit from that (it’s sealed)

Now, a few limits to all of this power.

You can’t create a subclass based on any class; only classes that are not sealed. The sealed keyword in C# creates a class that you cannot use as a base class.

Screenshot 2016-03-10 12.11.32

Programmers use sealed when they want to protect the interface from development that they cannot control. They don’t want to be responsible for someone’s bad implementation or any side effects it might have. They’d rather weather a bit of anger from a stymied programmer than a pile of bugs in code they don’t own. (Many thanks to Doug Finke, Kevin Ilsen, Adam Driscoll, Lee Holmes, Rodney Stewart, Eric Slesar, and David J. Brown for their insights on this topic.)

clip_image004

As an aside, the opposite of sealed, well sort of, is abstract, which indicates that a class is designed only to be a base class for other subclasses. You can’t create an instance of an abstract class (e.g. New-Object or [<Class>}::New() ), but you can create subclasses.

Most .NET classes are sealed, but the PowerShell classes that you create are not sealed (and the sealed keyword is not valid), so you can use any PowerShell class as a base class. And, you can use .NET classes that are not sealed, such as KeyedCollection, which is an abstract base class.

You can’t inherit from that either (no default constructor)

In Windows PowerShell 5.0.10586.122 classes, you cannot inherit from a class that does not have a default constructor (a constructor with no parameters), unless you explicitly define a default constructor in the subclass.

 Screenshot 2016-03-10 12.01.47

According to Jason Shirk on the PowerShell Team, it’s a bug, but it’s not yet fixed.

When it’s fixed, you’ll be able to base a class on a class that has no default constructor, but the derived class constructor must call a constructor in the base class, just like in C#.

That just about wraps it up. Thanks to Jason Shirk, Sergei Vorobev, and many others on Twitter and the PowerShell Facebook group for their help with this post.

June Blender is a technology evangelist at SAPIEN Technologies, Inc. You can reach her at juneb@sapien.com or follow her on Twitter at @juneb_get_help.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

Exporting from Modules: A Reminder

$
0
0

There are so many new things in Windows PowerShell that I often assume that I know the basics. But, while working on a project about modules, I ran into some new guidance from PowerShell developer Jason Shirk and a great blog post that demonstrates that information about variables in a TechNet topic about module manifests is wrong.

Here are some important reminders about modules and their manifests:

  • By default, all functions and aliases are exported, but variables are not exported.

    “By default, all variables are exported” in How to Write a Module Manifest (MSDN) is wrong. This topic is outdated anyway. It lingers from the time of the original New-ModuleManifest cmdlet, which prompted you for about 20 of the 49 parameters, even when only Path is mandatory

  • The Export-ModuleMember cmdlet overrides the default export behavior. When you use it, only the commands that you specify are exported.

    Therefore, by itself, this command prevents all functions and aliases, and all other variables in the module, from being exported.

    Export-ModuleMember -Variable myVar
  • You can have multiple Export-ModuleMember commands in a module. All of the statements are processed; none takes precedence. So, the result is the union of the statements.

    Therefore, these statements, in any order…

    Export-ModuleMember -Variable myProfiles
    Export-ModuleMember -Function Get-Profile, Set-Profile
    Export-ModuleMember -Function Get-Profile

    …are equivalent to:

    Export-ModuleMember -Variable myProfiles -Function Get-Profile, Set-Profile

    As a best practice, mostly for visibility, I prefer one Export-ModuleMember command as the last statement in a module file, but that’s just a recommendation.

  • The value of the Variable parameter of Export-ModuleMember must be a name, not a variable that begins with $.

    This is correct:

    Export-ModuleMember -variable myProfiles   # Omits $

    This has no effect, but it does not generate any errors.

    Export-ModuleMember -variable $myProfiles # Includes $
  • The *ToExport keys in a module manifest can only further restrict exports. They cannot add to exports.

    Therefore, if the module includes:

    Export-ModuleMember -Function Get-Widget

    And, the manifest includes:

    FunctionsToExport = 'Get-Widget', 'Set-Widget'

    Only Get-Widget is exported.

    Be very careful with this one. When the value of any *ToExport key is an empty array, no objects of that type are exported, regardless of the value the Export-ModuleMember.

    FunctionsToExport = @()
  • Redundant Export-ModuleMember and module manifest values do no harm and have no special effect.
    # In module 
    Export-ModuleMember -Function Get-Profile    
     
    # In module manifest
    FunctionsToExport = 'Get-Profile'

 

Important stuff

  • Use explicit names in the value of the *ToExport keys in the module manifest, instead of wildcard characters (*).Jason Shirk (@lzybkr), the PowerShell team developer who maintains the module discovery code, says:

    “PowerShell does expensive work during command discovery if you use wildcards, skips that if you are explicit….[O]n a fresh Win10 system, if all modules do it correctly, can save 15 [seconds].”

    For example:

    FunctionsToExport = 'Get-Profile', 'Set-Profile'

    Instead of:

    FunctionsToExport = '*'

 

I needed the reminders and Jason’s performance report will change how I write my module manifests.

June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at juneb@sapien.com and follow her on Twitter at @juneb_get_help.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

PowerShell Studio 2016: Service Release v5.2.118 and PSScriptAnalyzer

$
0
0

We released a new service build for PowerShell Studio 2016 (v4.2.118).

Here’s what’s new:

 

Support for PSScriptAnalyzer module

PSScriptAnalyzer module is a community driven module that evaluates your PowerShell scripts and ensures they follow community approved best practices.

http://www.powershellgallery.com/packages/PSScriptAnalyzer/

 

PowerShell Studio 2016 now allows you to run PSScriptAnalyzer directly from the ribbon (Tools->Analysis->Analyze Script):

image

Note: This option will be disabled if the PSScriptAnalyzer is not installed.

 

When you use the Analyze Script command, the module results are displayed in the Debug Panel:

image

Tip
Jump to the respective line in the script by double-clicking on result.

 

Triggered Analysis

PowerShell Studio 2016 also includes an option to trigger PSScriptAnalyzer every time you run / debug a PowerShell script or a project (Options->Editor):

image

Now when you test your scripts, the analysis is automatically displayed in the Debug panel.

 

Displaying Whitespaces

We added the option to display whitespaces in the editor.

image

This feature should help you spot those unintentional (and annoying) white spaces that trail behind a back tick at the end of a line.

image

Preventive Measures in Packager Executables

We added some preventive measures to help deter unwanted debugging of your package executables. You can further help improve the security of your executables by enabling restrictions in the packager settings to ensure they do not run on unauthorized machines.

 

 

Please continue providing your feedback. Many of the new features included in the service builds are suggestions from users like you. Therefore if you have any suggestions or feature requests, please share them with us on our Wish List and Feature Requests forum.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

Giving a talk? PowerShell Studio Presentation Features

$
0
0

One of the best parts of the PowerShell community culture is the willingness of people at all levels of expertise to help others to learn. It acknowledges that we learn from each other all the time and pays backward and forward for help that others have given to us.

So, there are many people giving talks and presentations about PowerShell. And, PowerShell Studio has several features that make presentations easier.

  • Filegroups: Open all scripts and modules for your presentation in a single click, even if the code files are on different machines in different locations. The files open in PowerShell studio in the order that you specify. No more fumbling at presentation time; no more delays during practice.The process does not change the script files, so it doesn’t invalidate testing or jeopardize demos. For information about filegroups, see a demo video: FileGroups in PowerShell Studio.

    Screenshot 2016-03-21 15.39.07

  • Pin to Recent Documents: Beginning in PowerShell Studio 5.2.117, you can pin files to the Recent Documents list in PowerShell Studio. You can pin your filegroup file and any other files you need so they’re available quickly during your presentation.
  • Quick-switch themes: It’s easy to change the theme of your PowerShell Studio display. If you prefer one theme, but it’s not optimal for presentation mode, switch it. And when the presentation ends, switch it right back. To change the theme, use the drop-down menu in the top right corner of the PowerShell Studio window.

    Screenshot 2016-03-13 10.01.03

  • Font slider: The font slider lets you adjust the font size in the Editor pane dynamically to optimize it for the audience. The font slider is in the lower left corner of the PowerShell Studio window.

    Screenshot 2016-03-13 10.01.03 - Copy

  • Layouts: A layout is an arrangement of panes in a PowerShell Studio window. You can use the preset layouts or use the Save Layout feature to create custom layouts.I often use a custom layout to simplify my window during presentations.

    If it suits your presentation, you can turn Auto-Layout off. (The switch is in the bottom left corner of the PowerShell Studio window, just to the right of the font slider.)

    Screenshot 2016-03-21 13.51.17

    But, more often, I just change the Auto-Layout settings (Home\Windows\Options\Panels\AutoLayout) to those that are best for my presentation. For example, I change the Editor Layout to Editor Only Layout.

    Screenshot 2016-03-21 13.51.16

  • Copy HTML: After my talk, when I’m working on a follow-up blog, it’s easy to copy my code from PowerShell Studio — with the formatting and syntax coloring — and paste it into my blogger. Select the code, right-click, and then click Copy HTML.

These few tricks make my presentations much smoother and allow me to focus on the content.

Do you have tricks I haven’t listed? Use the comments to let me know and I’ll add them to this post.

June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at juneb@sapien.com or follow her on Twitter at @juneb_get_help.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

Setting Conditional Breakpoints

$
0
0

Applies to PowerShell Studio 2016, PrimalScript 2016, and later.


I write lots of scripts — for production, for research, for testing, and for demonstrations. And, inevitably, I hit a bug. I’m actually relieved when I do, because no code is perfect and I’d rather find the bugs before my users do. In fact, I make sure the content in my test database is full of oddities so it’s as close to the real world as possible.

When you are debugging with a large test sample, like a database or directory, the default line breakpoints are not sufficient. I can hit a line numerous times before I get to the condition that breaks it. And, I don’t want to spend my time repeatedly banging on the F10 (step over) and F11 (step into) keys until I hit the offending condition.

In PowerShell Studio 2016 and PrimalScript 2016, you can create and edit line, function, and variable breakpoints, and beyond that, you can set conditions for breaking. For example, I don’t want to break on line 32 every time it runs. I want to break when the $ID variable has a value of 9999 or only when the Set-Widget function runs and $ID is 0.

Good old line breakpoints

Line breakpoints break just before the line of code with the breakpoint runs. Because most debuggers support line breakpoints, we’re very accustomed to using them. But, they might not be most efficient, so before you use a line breakpoint, consider whether a function or variable breakpoint might be a better choice.

One of the nice things about line breakpoints is that they’re easy to see. You can see the big red dot beside the breakpoint on line 24 in this image. But if you want to break when the Set-Maximum function runs — not just when it’s called on line 24, consider a function breakpoint.

function breakpoint

Use Function Breakpoints

A function breakpoint breaks right before the first line of code in the function runs. It actually breaks on the first curly brace in the function script block.

If the function has BEGIN, PROCESS, and END blocks, a function breakpoint breaks on the first curly brace of the BEGIN block, then on the first curly brace of the PROCESS block, and again on the first curly brace of the END block.

a function breakpoint breaks on the first curly brace of the BEGIN block, then on the first curly brace of the PROCESS block, and again on the first curly brace of the END block.

The breakpoint does not break on the function declaration — when PowerShell reads the function into memory. It breaks only on the function call — where the function actually runs. So, if you have defined a function in a script, but the function doesn’t run, the function breakpoint is not triggered.

Also, by default, a function breakpoint breaks every time the function runs, which might be handy, depending on your use case.
 
To set a function breakpoint in PowerShell Studio:

  1. Click Home and, in the Run group, click Breakpoints / Set Function Breakpoint or Edit Breakpoints.
    Click Home and, in the Run group, click Breakpoints / Set Function Breakpoint or Edit Breakpoints.
  2. Select a function from the Function drop-down menu. You can also specify a file if you’re debugging with multiple files in a module or project.
    specify a file if you're debugging with multiple files in a module or project.

    You can’t see the function breakpoint — there’s no big red dot in your script — but it’s effective.
    You can't see the function breakpoint -- there's no big red dot in your script -- but it's effective.

    And, the Edit Breakpoints dialog box display shows that it’s created and enabled.
    the Edit Breakpoints dialog box display shows that it's created and enabled.

    TIP : I always use the Edit Breakpoints dialog to create, enable, disable, and delete my breakpoints. It displays all of the breakpoints in the session and reminds when that I create a breakpoint twice, instead of changing a breakpoint. To create a function breakpoint in Edit Breakpoints, click the “cube+” icon in the upper left corner.

Use Variable Breakpoints

Variable breakpoints are my favorites. They break when the variable value is used (“read”), is changed (“write”), or either (“ReadWrite”).
 
To set a variable breakpoint:

  1. Click Home and, in the Run group, click Breakpoints / Set Variable Breakpoint.
     
    -or-
     
    In the Edit Breakpoints dialog, in the upper left corner, click the “square+” icon.
  2.  

  3. Select a variable from the Variable drop-down menu.

    You can also type the variable name. Technically, you’re supposed to enter only the variable name without the ‘$’, but PowerShell Studio is wonderful, so if you forget and type the ‘$’, PowerShell Studio ignores it.

    Create a variable breakpoint

  4. From the Mode box, select Read (break whenever the variable value is read), Write (break when the variable value changes), or ReadWrite (both).
  5. Like a function breakpoint, you won’t see a big red dot in your script to indicate a variable breakpoint, but you can see it in the Edit Breakpoints dialog box. (See why I like that dialog so much?)

    For example, in this script, a write-mode variable breakpoint on ‘n’ is triggered on line 26, when the value of $n changes to the next value in the $numbers array. But, it is not triggered on line 28, when $n is read, but not changed. If I need a different behavior, I can change the mode of the breakpoint to Read or ReadWrite.

    a write-mode variable breakpoint on 'n' is triggered on line 26, when the value of $n changes to the next value in the $numbers array.

Create conditional breakpoints

Variable and function breakpoints are very valuable, but conditional breakpoints are the extreme time-saver — an uber-breakpoint.

To set a conditional breakpoint:

  • When creating or editing a breakpoint, in the Action box, enter a script block.
  • The Action value replaces the break in the breakpoint. That is, when the breakpoint event occurs and an Action is defined, Windows PowerShell runs the Action script block instead of breaking (not in addition to breaking). If you want it to break, use the Break keyword (see about_Break).

The value in the Action box is a script block that runs when the breakpoint is triggered.

The Action script block should be enclosed in curly braces, but PowerShell Studio is wonderful, so if you forget the curly braces, it adds them automatically. I like to type the curly braces, but it’s not necessary.

For example, this variable breakpoint breaks when the value of $n is changed to 4.

{ if ($n -eq 4) { break } }

In the Action script block, the ‘n’ variable is referred to as $n, just like it is in my script. I use the Break keyword in my script block to tell Windows PowerShell to break into the debugger when the condition is met.

use the Break keyword in my script block to tell Windows PowerShell to break into the debugger when the condition is met.

When an Action is set, the variable breakpoint is still triggered every time the value of $n changes. But, the script does not break into the debugger. Instead, it runs the Action script block. If $n is not 4, the ‘{break}’ in the Action doesn’t occur and the script continues.

But when the variable breakpoint is triggered on a change in $n, and the value of $n is 4, the script breaks into the debugger.

when the variable breakpoint is triggered on a change in $n, and the value of $n is 4, the script breaks into the debugger.

You can set conditional function breakpoints, too. For example, this function breakpoint breaks into the debuggers only when the Get-DeviceID function is called with a parameter value of ‘localhost’. Otherwise, it records the value of the ComputerName in a text file.

if ($ComputerName -eq 'localhost') { break } else { $ComputerName | Out-File .\Test.txt }

this function breakpoint breaks into the debuggers only when the Get-DeviceID function is called with a parameter value of 'localhost'.

Conditional breakpoints are so powerful that, after a bit of experience, you’ll use them all the time. Just remember to include the Break keyword if you want to break into the debugger.

June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at juneb@sapien.com or follow her on Twitter at @juneb_get_help.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

How to Write About Help for your Module

$
0
0

Since installing PowerShell 5.0, I’ve been using the PowerShellGet cmdlets to install and examine many of the new modules on PowerShell Gallery.

Unfortunately, this is often quite a chore. While many have some help for cmdlets, few have an About topic that tells me how to use the cmdlets together to solve real-world problems. And, in those that do, the About topic feels like the authors wrote whatever popped into their minds at the time.

In this post, I’ll share my ideas for best practices for writing the primary About_Help topic for your module.

Best Practices for a Module About_Help Topics

If you don’t have time to read the whole post, here’s a summary of the most important points. (#TL;DR)

  • Explain how the commands in the module work together to solve problems or perform tasks.
  • Use clear, simple language. Avoid jargon. Don’t be clever.
  • Define all terms that the audience is unlikely to know.
  • Short Description is a summary of the Long Description. Write it last.
    • Identify the technology.
    • List system requirements.
  • Long Description:
    • Start with an outline
    • Arrange paragraphs in an order meaningful to the reader. Do not use “stream of consciousness” writing.
    • Use subtitles to label paragraphs
    • Reorder after writing.
    • Include lots of examples.
  • Have a GitHub wiki? List it in the See Also section.

Why Write About Help for a Module?

About Help explains how the cmdlets in the module work together to perform tasks or solve problems.

We write cmdlet help for the same reason that we script: efficiency. When you invest an hour or two writing help, everyone who uses your commands, including busy IT pros on deadline, is saved the time it takes to delve in to figure out the intent and operation of your cmdlets. If it sounds familiar, it’s the same rationale that we use for automation.

But, after writing cmdlet help, why do we write an About help topic for the module?

About Help: Without it, your module is a confusing collection of unrelated commands

As the module author, you become so familiar with the commands in the module that their use appears self-evident. But it is likely to be far less evident to your users.

When a user runs “Get-Command -Module <ModuleName>,” they get a list of exported commands in alphabetical order. But, it doesn’t tell them which commands they are supposed to use, in which order, to solve the problem or perform the task that your module is designed to enable.

Which commands do you use first? Which commands are prerequisites for others? Which commands set up the environment? Which commands create objects for parameter values of other commands? Which commands pipe to each other?

Where do I start?

That’s the role of the About topic. In the words of Windows PowerShell MVP Chrissy LeMaire (@cl), “The About topic tells the story of your module.

The About topic includes information that would be inappropriate in any individual cmdlet help topic. It explains the bigger picture and provides essential guidance in using your module.

Without it, the module is a confusing collection of unrelated commands.

Mechanics of an About Help Topic

About Help topics are text files that have the following name format:

about_<TopicName>.help.txt

The “a” in “about” is lower case. The topic name is camel-cased, that is, the first letter of each word in a compound word is capitalized, like about_PSScheduledJob.help.txt or about_BitsCmdlets.help.txt.

In the primary About topic for a module, the topic name is the module name. Users learn to look for these About topics and they’re delighted (and relieved!) when they find them. It’s a big time-saver.

about_<ModuleName>.help.txt

The content of the text file is technically arbitrary. Get-Help will spill out to the console whatever content is in the file.

However, there is a best-practice format, shown in this image, and in about_Topic_Template.help.txt. This format is expected by cmdlets and other tools that use and display and process the help files for other uses.

about_topic template; best-practice format

If your About topic does not conform to the expected format, it will not display properly. For example, if the short description in the About topic is not on line 5, beginning at column five, “Get-Help About*” does not display it correctly.

Get-Help About* displaying incorrectly

Also, if, in the future, PowerShell supports a serialized format for About topics (this has been “on the list” since PowerShell 2.0), the conversion tools will expect this format. If yours is not correctly formatted, it won’t work.

What do I write in the Short Description?

The short description is a summary of the long description, so I usually write it after the long description is complete. Otherwise, there’s nothing to summarize.

Guidelines for the Short Description:

  • 1-2 paragraphs that answer: “Will this module solve my problem?”
  • What tasks can you perform
  • In which domain or technology does it work?
  • System requirements
  • If the topic is long, list the subtitles in this section, like a table of contents.

For example, I rewrote the short description for the About_Pester help topic. The original description is incomplete (Pester does far more than just run tests) and it includes ‘BDD’, which is an unfamiliar term to many of us, without a description.

Original:

Pester is a BDD based test runner for Pester

To:

Pester is a test framework for Windows PowerShell. Use the Pester language
and its commands to write and run tests that verify that your scripts and
modules work as designed.

Pester 3.4.0 supports Windows PowerShell 2.0 and greater.

What do I write in the Long Description?

The Long Description in an About topic for a module explains the tasks that the cmdlets in the module are designed to perform and the problems that their designed to solve. It explains how you use the cmdlets together in a logical sequence.

Because the About topic describes using cmdlets together, the content of an About topic is like meta-cmdlet-help; it wouldn’t fit in any one cmdlet help topic.

Among the issues you might cover are:

  • Where do I start? Which commands do I use first (or even read about first)?
  • In what order do I use the other commands?
  • Are there implicit groups of commands (beyond nouns)?
  • Is one a prerequisite for another?
  • Is one designed to pipe to another?
  • Examples: Lots of them (Need help? See: How to Write Great Help Examples)

Here are the steps I use to write an About topic:

  1. Brain-storm topics.
  2. Arrange the topics in an order that makes sense to the reader (not to you)
    • Logical order (based on prerequisites)
    • Simple – complex
    • Common – rare techniques
  3. Write a paragraph or two for every topic.
  4. Reorder the topics.

HINT: If topic content repeatedly refers to topics below it, the topic might be out of order.

Here’s a general Long Description topic outline that I use frequently:

  • Purpose / Solution / Task
  • Basic example
  • Cmdlet/Function list
  • How-to sections (New/Get/Set/Save)
  • Examples (try it)
  • Background info

Use examples liberally throughout the topic. Include lots of examples. They’re required for inductive learners and helpful to everyone.

For example, here’s the outline I used for the long description in the about_Pester topic:

  • Problem statement: Unit/integration testing
  • Language basics, DSL (describe, it, should be)
  • How-to: Create, Write, Run
  • How to save; default output is Write-Host
  • Example. Try it.
  • Real-world examples (from original file)

You can read the current About_Pester topic here: about_Pester on GitHub

Other Sections of an About topic

There are several optional sections of an About help topic.

  • EXAMPLES : This is a section dedicated to examples, or one or two extended examples. The examples here are an addition to the examples that you use throughout your topic. I like examples that walk me through a process step by step.Need help? See: How to Write Great Help Examples
  • NOTE : A section for information that isn’t appropriate elsewhere, including technical information, warnings, corner cases, and, rarely, implementation details.
  • TROUBLESHOOTING NOTE : List workarounds for known bugs that aren’t yet fixed, but might be fixed in the future. Let the user know that they shouldn’t rely on this behavior because it’s likely to change.
  • SEE ALSO : List related topics with a URL, when appropriate. This is a great place for a link to the GitHub project or wiki.
  • KEYWORDS : Use this section to list synonyms or search terms that are relevant to the topic. We added this section to support the full-text search feature of Get-Help. While Get-Help will find all words used in the topic, you can put them here rather than trying to force them into your text.

If you have questions or need help with an About topic, ask on our Windows PowerShell forum or ping me on Twitter at @juneb_get_help or @SapienTech.

June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at juneb@sapien.com or follow her on Twitter at @juneb_get_help.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  


Use PSScriptAnalyzer in PowerShell Studio

$
0
0

Applies to:

  • Windows PowerShell 3.0 and later
  • PSScriptAnalyzer 1.1.0 and later
  • PowerShell Studio 5.2.118 and later

PowerShell Studio has long supported best practices in Windows PowerShell, including running and debugging without profiles, avoiding cmdlet and parameter aliases (right-click\Expand to cmdlet, Expand all aliases: Ctrl+Shift+A), using consistent formatting to make maintenance and debugging easier, and using module-qualified command names (Ctrl+Shift+H).

Beginning in PowerShell Studio 5.2.118, we’ve added deep support for PSScriptAnalyzer, the static analysis tool designed especially for Windows PowerShell.

To use the Script Analyzer features in PowerShell Studio, you must be running in Windows PowerShell 3.0 and later and have the PSScriptAnalyzer module installed on the computer.

What is PSScriptAnalyzer?

PSScriptAnalyzer is a Microsoft-sponsored open-source Windows PowerShell module that evaluates scripts, modules, DSC resources (.ps1, .psm1, .psd1), commands, functions, and expressions (in strings) for compliance with a set of rules established by the PowerShell team and the community.

The rules vary in their severity (Error, Warning, Information), which is a measure of the importance of the rule violation. Many platforms that use PSScriptAnalyzer will not install or host modules that have PSScriptAnalyzer errors, although they might allow Warnings and Information messages.

You can specify the rules in each test, write custom rules, and suppress rules in your code.

The PSScriptAnalyzer module has only two cmdlets:

  • Get-ScriptAnalyzerRule: Gets all or selected rules. You can use this cmdlet to learn about the rules and to select a set of rules use as the value of the IncludeRule or ExcludeRule parameters of Invoke-ScriptAnalyzer.
  • Invoke-ScriptAnalyzer: Runs a PSScriptAnalyzer test on specified files or command strings.

Although PSScriptAnalyzer is not part of Windows PowerShell core, it’s so widely accepted that many people think of it as a core module.

Script Analyzer in PowerShell Studio

PowerShell Studio can run Script Analyzer automatically and on demand.

To run Script Analyzer on a file at any time:

  • Click Tools and, in the Analysis group, click Analyze Script.clip_image001

To run automatically:

  • Whenever you run or debug a script, PowerShell Studio runs a Script Analyzer test on your script.

In either case, PowerShell Studio writes the results of the script analysis to the Debug tab of the Output Pane.

clip_image003

To avoid annoying you, the Debug tab doesn’t pop up. Instead, PowerShell Studio adds a reminder to the Output Pane. This reminder is not part of the output stream (stdout) and it does not affect the script results.

clip_image005
To use Script Analyzer results:

  • In the Debug tab, click any rule violation. PowerShell Studio scrolls the Script tab to the line where the violation occurred so you can fix it.clip_image007

Of course, you can turn the autorun feature on and off.

To enable and disable automatic script analysis:

  • On the Home tab, in the Windows group, click Options.
  • Click Editor and, in the Analysis section, click Automatically analyze scripts on run.clip_image008

How to Get PSScriptAnalyzer

To use the script analyzer features of PowerShell Studio, install any valid version of the PSScriptAnalyzer module in a path listed in the value of your PSModulePath environment variable, $env:PSModulePath.

PSScriptAnalyzer is supported on Windows PowerShell 3.0 and later.

To install PSScriptAnalyzer:

Install the released version of PSScriptAnalyzer from PowerShell Gallery. To install scripts and modules from PowerShell Gallery, you need the PackageManagement and PowerShellGet modules. (PowerShellGet requires PackageManagement.)

  • Windows PowerShell 5.0: The PackageManagement and PowerShellGet modules are included in Windows PowerShell 5.0 in Windows 10 and in Windows Management Framework 5.0.To install PSScriptAnalyzer (in $home\Documents\WindowsPowerShell\Modules):
    Install-Module PSScriptAnalzyer -Scope CurrentUser
  • Windows PowerShell 3.0 and 4.0:
    1. Download the latest version of the PackageManagement and PowerShellGet modules from the Microsoft Download Center.https://www.microsoft.com/en-us/download/details.aspx?id=51451 is the latest version at the time this blog post was published. Officially, it’s still a preview. Always search for later versions. They don’t always remember to remove the earlier ones.
    2. Use PowerShellGet to install PSScriptAnalyzer (in $home\Documents\WindowsPowerShell\Modules):
      Install-Module PSScriptAnalzyer -Scope CurrentUser

You can also install an experimental version of PSScriptAnalyzer from GitHub: https://github.com/powershell/PSScriptAnalyzer. The PSScriptAnalyzer repository is a working site, so use this option only if you are an advanced user who is tolerant of in-progress versions.
If you have questions about PSScriptAnalyzer, ask them on our Windows PowerShell forum or use the Issues section of the PSScriptAnalyzer repository on GitHub. You don’t need to have any GitHub tools to read, search, open, or participate in an Issues discussion.

June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at juneb@sapien.com or follow her on Twitter at @juneb_get_help.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

How to Run a Pester Test

$
0
0

Applies to: Pester 3.4.0

When you crack open the Pester module, you find the New-Fixture function, which creates a script and test file pair, and the Invoke-Pester function, which runs Pester tests.

But New-Fixture is not the only way to create a Pester test and Invoke-Pester is not the only way to run a test.

In this blog post, we’ll discuss the different ways to run a Pester test, including, but not limited to, the Invoke-Pester function. In the next post, I’ll rave about the cool parameters of Invoke-Pester.

Where can I put Pester tests?

To decide where to put your Pester tests, consider how you plan to run them and when you want them to be available.

The best place to put a Pester test is in a *.Tests.ps1 file. A .Tests.ps1 script is immediately recognizable as a file of Pester tests. This is critical in a shared project, like an open source module, where collaborators might need to search for or identify tests, or verify that tests exist.

Also, by default, Invoke-Pester runs all *.Tests.ps1 files. When you make it easy for people to run your tests, they’re more likely to run them.

However, syntactically, a Pester test is a Describe block and its valid contents, including at least one It block that encloses a test. A .Tests.ps1 script is the best place to put Pester tests, but it’s not the only valid place.

You can put the Pester test in any one of these places (and probably in a few others):

  • Tests script: The best place to put Pester tests is in a Tests script, that is, a *.Tests.ps1 file.
  • Script: You can place Pester tests in a standard Windows PowerShell script (.ps1), including the script that contains the code that is being tested.
  • Command: You can place Pester tests in a cmdlet, function, or workflow. Be sure that the code that is being tested is in a scope that the test can access.
  • Module: You can place Pester tests in a *.Tests.ps1, a different .ps1, or .psm1 file in a module directory. Again, be sure that the command that is being tested is available to the test, including being in an accessible scope. To mock or test commands in a function that are not exported, enclose the tests in an InModuleScope script block. To export a test into a session, place it in an exported cmdlet, function, or workflow.

How can I run Pester tests?

The standard way to run Pester tests is by using the Invoke-Pester function. Invoke-Pester is a fantastic tool — a little dynamo in your toolbox. When you use Invoke-Pester, you get it’s terrific output and parameters.

But it’s not the only way to run a Pester test.

A Pester test consists of valid Windows PowerShell commands. We don’t think of it as such, but Describe is a Windows PowerShell function that the Pester module exports. Its contents, including Context and It blocks and Should assertions are all valid Windows PowerShell commands.

Therefore, you can run Pester tests…

  • At the command line
    You can run a Pester test at the command line in the console. Notice that you don’t get the little test summary that Invoke-Pester adds, but it’s otherwise the same.clip_image002

    clip_image004

  • By running a scriptWhen you run a script that contains a Pester test, the Pester test runs. So, any way that you can run a script runs a Pester test, including typing the path at the command line or running in your favorite script editor.

    In PowerShell Studio, you can run and debug Pester tests. I like to use the Run in Console command so I can see the familiar purple, green, and red colors of the test results.

    clip_image006

  • By using Invoke-Pester
    Invoke-Pester is a terrific function. You don’t need to use it to run scripts, but once you understand it fully, you’ll use it more often and enjoy its features.By default, Invoke-Pester runs all Pester tests in all .Tests.ps1 files in the local directory and all subdirectories recursively.

    It’s a brilliant default because it works well for continuous integration and it doesn’t duplicate other commands that require more complex command syntax to run recursively.

    But, the power of Invoke-Pester is in it’s knockout parameters. I’ll save those for a separate post.

 

Learning Pester? Check out Real-World Test-Driven Development with Pester. The code and slides are in Github at https://github.com/juneb/PesterTDD.

June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at juneb@sapien.com or follow her on Twitter at @juneb_get_help.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

Invoke-Pester: Running Selected Tests

$
0
0

Applies to: Pester 3.4.0

In How to Run Pester Tests, I talked about the different places that you can put your Pester days and the different ways to run them, including, but not limited to, the Invoke-Pester function.

Today, I’ll talk about the parameters of Invoke-Pester function that let you determine which tests run. Next, I’ll show you how to pass parameters to a Pester test file.

clip_image002

By default, Invoke-Pester runs all *.Tests.ps1 files in the local directory and its subdirectories. That’s a useful default, but the parameters of Invoke-Pester let you control the alternatives.

Run all Tests.ps1 files in a path

To run all *.Tests.ps1 files in a particular directory or collection of directories, use the Script parameter. The Script parameter of Invoke-Pester was originally named Path, but it does so many things that they had to come up with a more generic name for it.

When you use the Script parameter of Invoke-Pester and give it paths to one or more directories, Invoke-Pester runs all .Tests.ps1 files in all subdirectories of the directories recursively. This is terrific for testing modules and other projects in progress. It supports wildcard characters, too.

For example, this command runs all *.Tests.ps1 files in the two specified directories and their subdirectories.

Invoke-Pester -Script C:\GitHub\MyProject, D:\Working\*\1.0

But, you can tell it to run other types of files.

Run tests in other files

To direct Invoke-Pester to run any file, enter the path and file name in the value of the Script parameter. For example, this command tells Invoke-Pester to run the elusively named Test-ScriptWithPesterTest.ps1 file.

Invoke-Pester -Script C:\GitHub\MyProject\Test-ScriptWithPesterTest.ps1

Invoke-Pester runs the files that you specify as the value of the Script parameter, just as though you ran them at the command line, including code that is not part of the Pester test.

You can even use Invoke-Pester to run PowerShell scripts that contain no tests, like my PowerShell profile. It dutifully reports that no tests passed or failed.

PS C:\> Invoke-Pester C:\Users\JuneB\Documents\WindowsPowerShell\profile.ps1

Tests completed in 0ms
Passed: 0 Failed: 0 Skipped: 0 Pending: 0 Inconclusive: 0

Be sure to include the file name of non-.Tests.ps1 files. If you use a wildcard, Invoke-Pester reverts to its default, which runs only the .Tests.ps1 files (recursively).

Invoke-Pester -Script C:\GitHub\MyProject\*.ps1   # Runs only .Tests.ps1 files

You can specify both directories and files. Again, if you specify a directory, Invoke-Pester runs only the .Tests.ps1 files in the directory (recursively).

Invoke-Pester -Script C:\GitHub\MyProject\Project.ps1, D:\Working\*\1.0

And, you can specify a particular .Tests.ps1 file, too.

Invoke-Pester -Script C:\GitHub\MyProject\Project.ps1, C:\Scripts\Module.Help.Tests.ps1

But, you can also select tests within files

Run Selected Pester Tests

To run only certain tests within the files specified by the Script parameter, use the TestName, Tag, and ExcludeTag parameters of Invoke-Pester. These parameters filter within the files specified by the paths in the Script parameter; they never expand its range.

The TestName parameter runs only Describe blocks with the specified test names or name patterns. It is case-insensitive. Remember that TestName looks only at names of Describe blocks, even though the InModuleScope, Context, and It blocks have required names.

For example, this command runs only the Describe blocks with names that include “parameter.”

Invoke-Pester C:\Scripts\Module.Help.Tests.ps1 -TestName '*parameter*'
 
#In file
Describe "gets parameter descriptions" {...}  # runs this one
Describe "gets correct types of parameters" {...} # runs this one, too
Describe "gets mandatory" { It "parameter is mandatory" {...}...} # doesn't run this one

If you specify multiple TestName values, Invoke-Pester runs tests that have any of the values in the Describe name (it ORs the values).

Invoke-Pester C:\Scripts\Module.Help.Tests.ps1 -TestName '*correct*', "*mandatory*"
 
#In file
Describe "gets parameter descriptions" {...}  # doesn't run this one
Describe "gets correct parameter types" {...} # runs this one
Describe "gets mandatory" { It "parameter is mandatory" {...}...} # runs this one

The Tag and ExcludeTag parameters run Describe blocks that have the specified tags, that is, the values of the Tag parameter of the Describe function. They are case-insensitive, but they don’t support wildcard characters. And, at least in Pester 3.4.0, they cannot find tags that include spaces. So they find “UnitTest,” but cannot find “Unit Test,” even if its an exact match for a tag.

Invoke-Pester C:\Scripts\Module.Help.Tests.ps1 -Tag UnitTest, 'Unit test'
 
#In file
Describe "finds the synopsis" -Tag UnitTest {...}         #Runs this test
Describe "finds the return value" -Tag 'Unit Test' {...}  #Doesn't run this test

When you specify multiple tags, Invoke-Pester runs tests that have any of the listed tags (it ORs the tags).

Invoke-Pester C:\Scripts\Module.Help.Tests.ps1 -Tag Unit, Regression
 
#In file
Describe "gets parameter descriptions" -Tag Unit       {...}     # Runs this test
Describe "gets mandatory value" -Tag regression {...}            # Runs this test
Describe "gets correct parameter types" {...}                    # Doesn't run this test

But, when you use the TestName and Tag parameters in the same command (at least in version 3.4.0), Invoke-Pester combines the requirements and runs only the tests that have the specified TestName and Tag (it ANDs the requirements).

Invoke-Pester C:\Scripts\Module.Help.Tests.ps1 -TestName '*parameter*' -Tag UnitTest
 
#In file
Describe "gets parameter descriptions" -Tag UnitTest {...} # Runs this test
Describe "gets correct parameter types" {...}              # Doesn't run this test
Describe "gets mandatory value" -Tag UnitTest {...}        # Doesn't run this test

Predictably, the ExcludeTag parameter runs all Describe blocks except for those that match any of the Tag values. If a test is included by the Tag parameter and excluded by the ExcludeTag parameter, ExcludeTag takes precedence over Tag, and the test does not run.

Interestingly, tests that are filtered out by TestName, Tag, and ExcludeTag are not counted as skipped. Only tests that have the Skip parameter of the It function are listed in the Skip count value.

For example, there are multiple tests in the file, but only one has the NullTest tag. Notice that the Skipped value is 0.

PS C:\ > C:\Scripts\Module.Help.Tests.ps1 -TestName '*parameter*' -Tag NullTest

Describing gets parameter descriptions

[+] parameter description is not null 42ms
Tests completed in 0ms

Passed: 1 Failed: 0 Skipped: 0 Pending: 0 Inconclusive: 0

That’s pretty high-resolution control. Next, we’ll talk about passing parameters to a Pester test script.

 

Learning Pester? Check out Real-World Test-Driven Development with Pester. The code and slides are in Github at https://github.com/juneb/PesterTDD.

June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at juneb@sapien.com or follow her on Twitter at @juneb_get_help.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

How to Pass Parameters to a Pester Test Script

$
0
0

Applies to Pester 3.4.0

Like any Windows PowerShell script, a script that contains Pester tests can include parameters. It’s easy enough to run the script and pass parameters and values in the usual way.

But, when you use Invoke-Pester to run the script, you need to pass the parameters in a hash table. This blog explains how to do it.

This post is the third in a series about how to run Pester tests. See also, How to Run Pester Tests and Invoke-Pester: Run Selected Tests.

————————–

To use Invoke-Pester to pass parameters to a script, use a command like this one:

Invoke-Pester -Script @{Path='C:\Tests\MyTests.Tests.ps1';Parameters=@{Name='Pester';Version='3.4.0'}}

Or, this one:

Invoke-Pester -Script @{Path = 'C:\Tests\MyTests.Tests.ps1'; Arguments = 'Pester', '3.4.0'}

 

The Script parameter of Invoke-Pester typically takes a array of paths, either paths to a directory or to scripts that typically contain Pester tests, or both.

But, it can also take a hash table. One hint is that Script parameter type is [System.Object[]], not [System.String[]].

Here are hash table keys:

  • Path (required) <string>: The value of the Path key must be a single string, presumably (but not required) the path to directories or files. Wildcards are supported. A hash table with only the Path key is equivalent to submitting a string value to the Script parameter, except that this key is limited to one string.
    Invoke-Pester -Script @{Path='C:\Tests\MyTests.Tests.ps1'}
  • Parameters <hashtable>:  Each key-value pair in the (nested) hash table consists of a parameter name and its value, such as @{ComputerName = ‘localhost’}. Use this key to pass named parameter names and values to a script.
    Invoke-Pester -Script @{Path = 'C:\Tests\MyTests.Tests.ps1'; Parameters = @{Name = 'Pester'; Version = '3.4.0'}}
  • Arguments <array>: Use this key to pass positional parameter values to a script, such as ‘localhost’, $true or @(‘localhost’, $true).
    Invoke-Pester -Script @{Path = 'C:\Tests\MyTests.Tests.ps1'; Arguments = 'Pester', '3.4.0'}

 

Invoke-Pester splats the parameters and arguments to the scripts as it calls them.

Typically, the Path value in the hash table resolves to a particular script that takes the specified named and/or positional parameters. But, when you pass parameters to a script that has no parameters, the extraneous parameters are ignored, so you can use a directory value effectively.

For example, this command passes the ComputerName to one .Tests.ps1 file, but the command runs all .Tests.ps1 files in the directory and its subdirectories.

Invoke-Pester -Script @{Path = 'C:\Tests\MyTests'; Parameters = @{ComputerName = 'localhost'}}

Of course, this strategy is error-prone and will not work when more than one of the scripts being run takes different parameters, so it’s probably not advisable.

But, it’s easy enough to pass parameters to a Pester test. Pester really is amazing!

 

Learning Pester? Check out Real-World Test-Driven Development with Pester. The code and slides are in Github at https://github.com/juneb/PesterTDD.

June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at juneb@sapien.com or follow her on Twitter at @juneb_get_help.

 

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

Which PowerShell Versions are Users Running?

$
0
0

In March 2016, SAPIEN Technologies, Inc. posted a survey asking users and administrators which versions of Windows PowerShell they’re running. We got 148 responses by the April 8 when we closed the survey. This blog post reports the findings. While reading them, please keep in mind that this is not a statistically valid survey. We didn’t select users or control for anything. Still, I did not expect these results.

I might be a bit naïve about enterprise computing, but I’m surprised by the widespread adoption of Windows PowerShell 4.0 and 5.0. My sense is that the community moved much more slowly from 2.0 to 3.0 and then still quite cautiously to 4.0.

But, things have changed!

Half of users run 5.0 most often

In general, almost half of the respondents (49%) run PowerShell 5.0 most often, even though it’s fairly new.

I don’t have the data, but I suspect that this is very quick adoption for a new version of PowerShell and it’s likely to have been driven by the assertive push of Windows 10. Remember that WMF 5.0 was released in February, retracted, and then re-released in April after this survey was closed. The release didn’t seem to affect the survey results; the data trends did not change over time.

This was one-choice only (radio button) question, so that might have pushed people who use several versions into a false choice.

85% of users run 4.0 or 5.0 most often

Right behind 5.0 is Windows PowerShell 4.0 at 36%. Combining the two means that 85% of users are using a version greater than 3.0, which is the unofficial standard version. Only 11% use 3.0 and only 4% use 2.0 most often.

clip_image002

Official work version: PowerShell 4.0

When we asked about the “official version used at work,” the numbers shifted a bit, but not as much as I would have guessed. As expected, 16% of respondents skipped this question, which I interpret to mean that their workplace doesn’t have an official version of Windows PowerShell.

Again, this was one-choice only (radio-button) question.

51% of users report that their official work version is Windows PowerShell 4.0. In fact, more users reported that PowerShell 4.0 was their “official version” than PowerShell 2.0, 3.0, and 4.0 combined.

PowerShell 2.0 and 3.0 were almost tied at about 18% and PowerShell 5.0 came in last, as expected, at 12%.

clip_image003

We also asked which version each participant used most often at work, in case they didn’t need to use the official version.

I don’t have an official explanation for the popularity of 4.0, but I suspect we’re seeing some coattails from Windows Server 2012, Exchange 2010 and 2013, and Configuration Manager. Several participants mentioned that installations and upgrades of PowerShell 5.0 failed, but they’re likely to try again now that 5.0 has stabilized.

This comment is pretty typical:

“At work we tend to stick with whatever PS version the OS came with, while I tend to develop on the latest version whether at home or at work.”

It actually might summarize all of these results.

PowerShell Versions Used at Work

In addition to asking about the official version used at work (choose one), we also asked about versions used at work. This was a checkbox question in which respondents could select more than one choice.

PowerShell 4.0 “won” this round with 71% of participants selecting it. PowerShell 5.0 was not far behind at 49%, even though WMF 5.0 was not officially released for down-level systems until after the survey closed.

clip_image004

In this choose-many question, PowerShell 2.0 rose to 41% using it at some time with PowerShell 3.0 at 43%, which is about the same, given the lax data.

I would have expected to see PowerShell 3.0 at nearly 100%. I use it sometimes, even though I don’t have to, if only to test scripts in a 3.0 environment.

As expected, 2/5 of users, 41%, still use PowerShell 2.0 at work. That’s important data for planners.

At home, it’s 5.0

In our own homes, where we can presumably use what we please, 86% are using PowerShell 5.0. With the release of WMF 5.0 after the survey closed, we can expect this number to increase.

clip_image005

This was a choose-many question, where the numbers don’t sum to 100%, but this is still a huge result.

Windows PowerShell 4.0 lagged significantly at 28%, with 2.0 and 3.0 at 4-5% — far lower than I would have guessed.

Again, the survey wasn’t scientific and I might have teased out more data by asking if they “ever” used a version, or if they “needed” a certain version.

Conclusion: People are upgrading

When we released the 2.0 version of Windows PowerShell, it was a struggle to get people to try the new version, even though it had the much-requested remoting features. PowerShell 3.0, which exploded with new cmdlets and modules, simpler syntax, more powerful language, and cool features like session config files, took a while for many users to switch.

PowerShell 4.0 brought us Desired State Configuration, but again, it wasn’t a very quick switch.

That seems to have changed with PowerShell 5.0. Users upgraded quickly. Although 4.0 remains the most commonly used version in all categories, few people are stuck at 3.0 refusing to upgrade. I wonder if the new fast-release cadence of Windows is prompting enterprises to upgrade more quickly.

The comments revealed that many of the respondents who use PowerShell 2.0 at work are “stuck” there for a variety of reasons, including the time and cost of reviewing, approving, and migrating to a new system. We might see some of these switch to 5.0 with the upcoming release of Windows Server 2016.

If you have any insight, please post it in the comments. And, thanks to everyone who participated in the survey.

June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at juneb@sapien.com or follow her on Twitter at @juneb_get_help.

 

 
[Google+]   [Facebook]   [LinkedIn]   [StumbleUpon]   [Digg]   [Reddit]   [Google Bookmark]  

Viewing all 308 articles
Browse latest View live