Advanced Functions and Test-LeapYear.ps1

PowerShell Team

Welcome to CTP3!  There are just an amazing amount of really important features in V2 but the one I want everyone to start using ASAP is Advanced Functions.  In CTP2 we called this cmdlets.  We dropped that term in favor of taking the idea of a FUNCTION and just making it more and more capable.  It is a bit of a misnomer in that you can have an “Advanced function” by just adding a single line to your script.  You’ll be amazed what that single line gives you; but we’ll explore that later.  This entry recaps where we are with functions and then begins to give you a feel for some of the great benefits you have with advanced functions.  There is a LOT more to advanced functions than I’ll show you here.  You get an incredible amount for just a tiny amount of additional code.

Going forward, I think that the community should/will establish the norm that the functions you share with other people and blog about should be Advanced Functions.

This post is a bit of mouthful but I encourage you to follow it and get on the Advanced Function bandwagon.  This is a gamechanger.  Alternatively, you can just start messing with them.  I’ve attached a ZIP file containing both Test-LeapYear.ps1 and a demo-test-leapyear.txt file that you can run using my Start-Demo script.   Either way – invest and you will be rewarded!

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

 

[0]PS> #Functions can be simple
[1]PS> function Test-LeapYear {[DateTime]::IsLeapYear($args[0])}

[2]PS> Test-LeapYear 2008
True

 

[3]PS> # But there are issues with simplicity
[4]PS> # The obvious one is that you have readability issues.
[5]PS> # What is $args[0] anyway?
[6]PS> # Also you have no type checking on the parameter.

[7]PS> Test-LeapYear ThisYear
Start-Demo : Cannot convert argument “0”, with value: “ThisYear”, for “IsLe
apYear” to type “System.Int32”: “Cannot convert value “ThisYear” to type “S
ystem.Int32″. Error: “Input string was not in a correct format.””
At line:1 char:11
+ start-demo <<<<  .\demo-Test-LeapYear.ps1
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorE
   xception
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExce
   ption,Start-Demo

[8]PS> # There is no checking on the # of arguments
[9]PS> Test-LeapYear 2008 2009 2010 2011
True

 

[10]PS> ##############################################
[11]PS> # In V1 you could remedy these issues with Named parameters:

[12]PS> function Test-LeapYear {param([Int]$Year=[DateTime]::Now.Year)  [Dat
eTime]::IsLeapYear($Year)}

 

[13]PS> # Now you use variables whose names are self-documenting
[14]PS> # You get the same functions you got before

[15]PS> Test-LeapYear 2008
True

 

[16]PS> # But now you also get NAMED parameters which makes it
[17]PS> # even more self-documenting

[18]PS> Test-LeapYear -Year 2008
True

 

[19]PS> # You now have type checking on the parameter.
[20]PS> Test-LeapYear ThisYear
Start-Demo : Cannot process argument transformation on parameter ‘Year’. Ca
nnot convert value “ThisYear” to type “System.Int32”. Error: “Input string
was not in a correct format.”
At line:1 char:11
+ start-demo <<<<  .\demo-Test-LeapYear.ps1
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorE
   xception
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExce
   ption,Start-Demo

 

[21]PS> # But there is still no checking on the # of arguments
[22]PS> Test-LeapYear 2008 2009 2010 2011
True

[23]PS> # Of course you were on your own for help as well.

 

 

 

[24]PS> ##########################################
[25]PS> #
[26]PS> # But now you have Advanced Functions:
[27]PS> Get-Content .\Test-LeapYear.ps1
<#
.Synopsis
    Determines whether a year is a leapyear or not.
.Description
    This is a simple function to demonstrate the capabilities of PowerShell
    V2 Advanced Functions by telling whether a year is a leap year or not.
.Parameter Year
    Which year would you like tested?
.Example
    PS> Test-LeapYear 2008

.ReturnValue
    [Boolean]

.Link
    about_functions
    about_functions_advanced
    about_functions_advanced_methods
    about_functions_advanced_parameters

.Notes
NAME:      Verb-Noun
AUTHOR:    NTDEV\jsnover
LASTEDIT:  12/22/2008 20:39:07
#Requires -Version 2.0
#>

param(
[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
[Int]$Year
)

Process
{
    [DateTime]::IsLeapYear($Year)
}#Process

 

 

[28]PS> # You have all the stuff you had before but now look what you get:
[29]PS> # It ensures that you send it the right number of parameters:
[30]PS> .\Test-LeapYear 2008 2009 2010 2011
Start-Demo : A positional parameter cannot be found that accepts argument ‘
2009′.
At line:1 char:11
+ start-demo <<<<  .\demo-Test-LeapYear.ps1
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorE
   xception
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExce
   ption,Start-Demo

 

[31]PS> # It supports pipelining
[32]PS> 2008,2009,2010,2011 | .\Test-LeapYear
True
False
False
False

 

[33]PS> # I can’t demo it year but it also supports Tab-Completion of paramete
rnames
[34]PS> # Best of all, it supports HELP
[35]PS> Get-Help .\Test-LeapYear -full

NAME
    C:\temp\Test-LeapYear.ps1

SYNOPSIS
    Determines whether a year is a leapyear or not.

SYNTAX
    C:\temp\Test-LeapYear.ps1 [-Year] [<Int32>] [-Verbose] [-Debug] [-Error
    Action [<ActionPreference>]] [-WarningAction [<ActionPreference>]] [-Er
    rorVariable [<String>]] [-WarningVariable [<String>]] [-OutVariable [<S
    tring>]] [-OutBuffer [<Int32>]] [<CommonParameters>]

DETAILED DESCRIPTION
    This is a simple function to demonstrate the capabilities of PowerShell
    V2 Advanced Functions by telling whether a year is a leap year or not.

PARAMETERS
    -Year
        Which year would you like tested?

        Required?                    true
        Position?                    0
        Default value
        Accept pipeline input?       true (ByValue)
        Accept wildcard characters?

    <CommonParameters>
        This cmdlet supports the common parameters: -Verbose, -Debug,
        -ErrorAction, -ErrorVariable, -WarningAction, -WarningVariable,
        -OutBuffer and -OutVariable. For more information, type,
        “get-help about_commonparameters”.

INPUT TYPE

RETURN TYPE
    [Boolean]

NOTES

        NAME:      Verb-Noun
        AUTHOR:    NTDEV\jsnover
        LASTEDIT:  12/22/2008 20:39:07
        #Requires -Version 2.0

    ————————– EXAMPLE 1 ————————–

    PS> Test-LeapYear 2008

RELATED LINKS
    about_functions
    about_functions_advanced
    about_functions_advanced_methods
    about_functions_advanced_parameters

 

[36]PS> # Notice that while we only declared one parameter,
[37]PS> # it actually has 9!
[38]PS> # These are provided by the PowerShell engine.
[39]PS> (Get-Command .\Test-LeapYear.ps1).Parameters

Key                                   Value
—                                   —–
Year                                  System.Management.Automation.Param…
Verbose                               System.Management.Automation.Param…
Debug                                 System.Management.Automation.Param…
ErrorAction                           System.Management.Automation.Param…
WarningAction                         System.Management.Automation.Param…
ErrorVariable                         System.Management.Automation.Param…
WarningVariable                       System.Management.Automation.Param…
OutVariable                           System.Management.Automation.Param…
OutBuffer                             System.Management.Automation.Param…

 

[40]PS> # Let’s see them in action
[41]PS> 2008,2009,2010 |.\Test-LeapYear.ps1 -OutVariable Results
True
False
False

[42]PS> $results
True
False
False

 

 

[43]PS> 2008,”Burp”,2010 |.\Test-LeapYear.ps1 -ErrorAction Stop
True
Start-Demo : Command execution stopped because the preference variable “Err
orActionPreference” or common parameter is set to Stop: The input object ca
nnot be bound to any parameters for the command either because the command
does not take pipeline input or the input and its properties do not match a
ny of the parameters that take pipeline input.
At line:1 char:11
+ start-demo <<<<  .\demo-Test-LeapYear.ps1
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorE
   xception
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExce
   ption,Start-Demo

[44]PS> 2008,”Burp”,2010 |.\Test-LeapYear.ps1 -ErrorAction SilentlyContinue

True 
 False

Test-LeapYear.zip

0 comments

Discussion is closed.

Feedback usabilla icon