Mastering PowerCLI
上QQ阅读APP看书,第一时间看更新

Chapter 2. Reusable Advanced Functions and Scripts

In the first chapter, we revisited PowerShell and PowerCLI basics. Then, we discussed how we could use the GitHub version to control our work and collaborate with others to work on the same project. We also learned how to use Pester to do unit testing on our work. In this chapter, we are going to cover advanced functions and their implementations in PowerShell. Specifically, we are going to talk about the following topics:

  • Specifying function attributes
  • Specifying parameter attributes
  • Using parameter validation attributes
  • Using dynamic parameters
  • PowerShell help files
  • Creating comment-based help
  • Error handling in PowerShell

Before we start discussing advanced functions, let's take a look at normal functions. If you type Get-Help About_Functions in PowerShell, you can get the details of functions. The description says a function is a list of Windows PowerShell statements that has a name that you can assign. When you run a function, you type the function name. The statements in the list run as if you had typed them at the Command Prompt. Typically, we will use a function to write a portion of code that we will reuse multiple times in a script or external to the script. A sample of a typical function is as follows:

Function Get-VC( $vcname,$username){
    Write-Host "vCenter Server is $vcname"
    Write-Host "User name is $username"
}

When the preceding function is called, we get the required result:

PS C:\> Get-VC vcenter.lab.com vcadmin@lab.com
vCenter Server is vcenter.lab.com
User name is vcadmin@lab.com

Since this is a mastering book, I will assume that you already know about functions and will not go into details of a simple function.

Tip

For more details, I suggest that you go through the following two links, which will provide you a very good explanation of the same:

http://blogs.technet.com/b/heyscriptingguy/archive/2015/07/08/fun-with-powershell-functions.aspx

http://blogs.technet.com/b/heyscriptingguy/archive/2013/04/09/using-powershell-functions-best-practices.aspx

Before we go ahead and start talking about the details of an advanced function, let's find out what exactly is an advanced function, how are they different from the normal functions, and where we can or should use them.

Cmdlet in PowerShell is like a function written in C# and provides a lot more functionalities than a standard function. An advanced function in PowerShell is a function that lets you define and write a function but with all the added benefits of cmdlets. So, an advanced function is more like a cmdlet, but it is written in a normal PowerShell way rather than in C#.

The main difference between normal functions and advanced ones is the capabilities that advanced functions provide. With advanced functions, you can have native support for pipeline input, use common parameters that you use with cmdlets, such as –Verbose and -WhatIf, parameter validation, and you can use dynamic parameters to name a few.

So, where should we use normal functions and advanced functions? Well, by all means advanced functions are much better than normal functions, but they are complex as well. So, it depends on the purpose and the personal choice. But in general, if you are writing a function that is very small (consisting of few lines at most) or if you are going to use it as a helper function for another function, probably a normal function would be more appropriate for this. But if you want to write a function that is a major one or if you want to share the function with others, probably you are better off with an advanced function. By all means, if you are sharing it with others and treating it like a module, then you should use an advanced function instead of a simple normal function.

Since we have spoken about advanced functions, what they are, and their main uses, let's take a look at the structure of one advanced function.

In general, an advanced function will look like the following code:

<#
     Comment Based Help
#>
Function <function_name> {
[CmdletBinding()]
[OutputType()]
Param(
<Parameters>
)
BEGIN{<# some script> }
PROCESS{<#some script>}
END{<#some script>}
}

Note

It is not mandatory to place Help before the function. We can place it inside the function as well. We will talk more about help in the upcoming sections.

Before we go ahead and talk about the other topics, let's discuss the general structure of an advanced function. In the structure provided earlier, I started with the comment-based help. Then comes the function declaration with the function name.

In the preceding format, the [CmdletBinding()] line is very important and denotes that the function is an advanced function. A function must have the CmdletBinding attribute, the Parameters attribute, or both in order to mark the function as an advanced function. The other lines and formats are optional and can be used with normal functions as well. Advanced functions are more or less used to make the functions more structured and compact and to provide advanced capabilities.

The [OutputType()] line denotes the type of the output variable of the function.

Next comes the Param() definition. Here, we need to define all the parameters and their attributes that we are going to use in the function.

Next come the three very interesting declarations:

BEGIN{<# some script> }
PROCESS{<#some script>}
END{<#some script>}

The script block defined in the BEGIN portion will be executed only once and can be used as a preprocessing section. So, if you want to execute/do some tasks, such as initializing certain parameters or checking some prerequisites, then write this portion here.

The PROCESS section is the portion that will be processed every time for each of the objects. So, your actual script should go here.

The END portion will be executed only once, at the end of the script execution. So, you should put your house keeping/clearing portion of the script here. Also, if you want to do something that needs to be executed only once and at the end of the script, then it should go into this section.