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
0 comments