User Rating: 5 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Active
 

I just returned from the second annual PowerShell Conference Asia 2016 (@PSConfAsia) in Singapore and it was a blast. Like all of the best conferences, it was small and designed for learning and interaction, not focused on huge auditoriums and collecting swag. It had a top-notch panel of speakers including four PowerShell Team members and representatives from AWS, Chef, and Puppet.

But, for me, the best part was the attendees. This was an audience that we don't often meet in person, because it's tough and expensive for folks from South Asia, Southeast Asia, Australia, and NZ to travel to the U.S. or Europe. It was really a pleasure. The attendees were smart and knowledgeable, participated in every activity, asked great questions, and engaged in fascinating discussions. SAPIEN Technologies, Inc, a founding sponsor of PSConfAsia, was so honored to sponsor this conference again.

PSConfAsia

June Blender and friends at PowerShell Conference Asia 2016.
Photo by @seanwongcf, Campus Lead for NYP Microsoft Student Partners (Singapore)

 

This blog post is taken from my Avoiding Version Chaos in a Multi-Version World talk, which I first delivered for the Mississippi PowerShell User Group in January 2016, but revised substantially to include PowerShell 6.0.0-alpha. I'll start with the basics of #Requires -Version and continue in a follow-up post about the new SemanticVersion object that PowerShell uses in PowerShell 6.0.0-alpha.


What does #Require -Version Require?

The standard and official way to require a particular version of Windows PowerShell is the #Requires -Version directive. Help says that a #Requires directive works only in a script (not interactively) and must be the first line of code in the script (after comments). In reality, you can put other lines of code before #Requires, but PowerShell runs the #Requires first, and then runs any commands that precede it.

 

#Requires is a minimum version

Let's see how it works. In this script, I'll require PowerShell version 4.0. If the version of PowerShell on my system fulfills the requirement, the script runs and print the required and actual versions of PowerShell

#Requires -Version 4.0
'Requires version 4.0'
"Running PowerShell $($PSVersionTable.PSVersion)."
PS C:\> .\Test-PSVersionRequirement.ps1
Requires version 4.0
Running PowerShell 5.1.14393.206

The script ran without error, even though it required PowerShell 4.0 and I'm running 5.1. This demonstrates that #Requires establishes a minimum version, not a specific version.

Because PowerShell is backward-compatible, this is probably the way you want it to work.

 

#Requires inspects only Major and Minor properties

Next, we'll test for a version greater than the one that we're running.

#Requires -Version 5.1.99999.999
'Requires version 5.1.99999.999'
"Running PowerShell $($PSVersionTable.PSVersion)."
PS C:\> .\Test-PSVersionRequirement.ps1
Requires version 5.1.99999.999
Running PowerShell 5.1.14393.206

But, this one works, too. No errors! That's because #Requires -Version inspects only the Major and Minor properties of the version object. It does not compare the Build or Revision numbers.

PS C:\ps-test> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      14393  206

#Requires -Version was developed for PowerShell 1.0 in an era where only the Major and Minor properties were used (1.0, 2.0, 3.0, 4.0). It was only in PowerShell 5.0 that we saw the PowerShell team populating and incrementing the Build and Revision properties.

To require a specific version, use comparison operators

If you need to require a particular version of PowerShell, skip #Requires and use the comparison operators.


$versionMinimum = [Version]'5.1.99999.999'

if ($versionMinimum -gt $PSVersionTable.PSVersion)
{ throw "This script requires PowerShell $versionMinimum" }

"Requires version $versionMinimum"
"Running PowerShell $($PSVersionTable.PSVersion)."

Here's the result:

PS C:\> ."C:\Scripts\Test-PSVersionRequirement-Works.ps1"            
This script requires PowerShell 5.1.99999.999                                                                                                        
At C:\Scripts\Test-PSVersionRequirement-Works.ps1:7 char:3                  
+ { throw "This script requires PowerShell $versionMinimum" }                                                                                        
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                                                          
    + CategoryInfo          : OperationStopped: (This script req...l 5.1.99999.999:String) [], RuntimeException                                      
    + FullyQualifiedErrorId : This script requires PowerShell 5.1.99999.999                                                                          

Testing #Requires -Version on PowerShell 6 (alpha)

 Now, let's test #Requires on the new open-source version. (Get it on GitHub!)

#Requires -Version works just the way it does on released versions of PowerShell. It requires a minimum version...

#Requires -Version 4.0
'Requires version 4.0'
"Running PowerShell $($PSVersionTable.PSVersion)."
PS C:\> .\Test-PSVersionRequirement.ps1
Requires version 4.0
Running PowerShell 6.0.0-alpha

And, its evaluation inspects only the Major and Minor properties of the version object. In this example, which requires version 6.0.1, the 6.0.0-alpha version, which is less than the minumum, appears to meet the requirement.

#Requires -Version 6.0.1
'Requires version 6.0.1'
"Running PowerShell $($PSVersionTable.PSVersion)."
PS C:\> .\Test-PSVersionRequirement.ps1
Requires version 6.0.1
Running PowerShell 6.0.0-alpha

But, what is that 'alpha' and how do I test that version?

Beginning in PowerShell 6.0 (alpha), $PSVersionTable.PSVersion uses a new object. Instead of System.Version, it's a SemanticVersion object (System.Management.Automation.SemanticVersion). We'll look at it in the next article: Working with SemanticVersion.

PS C:\Program Files\PowerShell\6.0.0.11> $PSVersionTable.PSVersion

Major Minor Patch Label
----- ----- ----- -----
    6     0     0 alpha


PS C:\Program Files\PowerShell\6.0.0.11> $PSVersionTable.PSVersion | Get-Member

   TypeName: System.Management.Automation.SemanticVersion

Name        MemberType Definition
----        ---------- ----------
CompareTo   Method     int CompareTo(System.Object version), int CompareTo(System.Management.Automation.SemanticVersion value)...
Equals      Method     bool Equals(System.Object obj), bool Equals(System.Management.Automation.SemanticVersion other), bool I...
GetHashCode Method     int GetHashCode()
GetType     Method     type GetType()
ToString    Method     string ToString()
Label       Property   string Label {get;}
Major       Property   int Major {get;}
Minor       Property   int Minor {get;}
Patch       Property   int Patch {get;}

 June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Microsoft Cloud and Datacenter MVP. You can reach her at This email address is being protected from spambots. You need JavaScript enabled to view it. or follow her on Twitter at @juneb_get_help.

If you have questions about our products, please post in our support forum.
For licensed customers, use the forum associated with your product in our Product Support Forums for Registered Customers.
For users of trial versions, please post in our Trial Software Questions forum.
Copyright © 2017 SAPIEN Technologies, Inc.