How to module and function with Powershell
For first timer, like me, in Powershell this could be a starting point for quite serious developing. Just to know: Powershell previously was made for Windows automation tasks and was used with VMware modules to automate vSphere, vRA, NSX (and many other) environments. Now this shell is available for Mac and Linux; check this for further info and installation (https://github.com/PowerShell/PowerShell).
It’s easy to automate using a single main flow:the execution starts from the first line and ends to end of the file. In this way all module should be invoked at the top of the file and a kind of result must be showed in the end or in the middle depending on conditional flows and/or what you’re reaching during execution.
But what happens when your are executing the same set of actions with a change of some variables? In every beginner programming guide there’s written: << you should use a function >>
The function construct
This is a standard template that could be used to build a function in many implementations:
1 2 3 4 5 6 7 8 9 10 11 |
function Myfunction{ param( [string]$sOne, [string]$sTwo ) process{ return "$sOne and $sTwo" } } |
There are 3 main parts:
- params: 0…more variables that could be used in the code execution. All of these are not available for other function or in the main stream
- process: the main code
- the return-s
You could call this function in 2 ways:
- Using param position: Myfunction “one” “two”
- Specifying every param, in this case the order in declaration doesn’t matter: Myfunction -sTwo “two” -sOne “one”
In some cases it could happens to pass a type of variable that is different from the type required in the function… don’t worry! variable casting is performing at param level.
The function callback… nightmare
Ok now let’s see what happens in this function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
function MyReturnFunction{ param( [string]$sOne, [string]$sTwo ) process{ echo "process sOne w $sOne" echo "process sTwo w $sTwo" return "$sOne and $sTwo" } } $s = MyReturnFunction -sOne "First" -sTwo "Second" Write-Host $s |
Output:
Oh my gosh! all of echoed string in the output? Ok let’s go further:
1 |
$s.GetType() |
Ok all of the echoed will join the return in array form:
1 |
Write-Host $s[2] |
If you wish to write a debug string during function execution you should use Write-Host:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
function MyReturnFunction{ param( [string]$sOne, [string]$sTwo ) process{ Write-Host "process sOne w $sOne" Write-Host "process sTwo w $sTwo" return "$sOne and $sTwo" } } $s = MyReturnFunction -sOne "First" -sTwo "Second" $s.GetType() Write-Host "the result:" Write-Host $s |
Writing a module
A module is the good way to distribute your code across systems, user, … The abstraction and the documentation must be at the highest possible level because, the nature of the module is to distribute an implementation for general purpose. Well! let’s se a simple module construct:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<# Module name Author Description #> function FirstModuleFunction{ <# .SYNOPSIS The function do something .PARAMETER sOne First param .PARAMETER sTwo Second param .LINK See git-hib link… and contribute with… .EXAMPLE FirstModuleFunction –sOne “Fisrt” –sTwo “Second” #> param( [string]$sOne, [string]$sTwo ) process{ return "$sOne and $sTwo" } } |
The file extension of a Powershell module must be “.psm1” and could be invoked in a ps1 file or in the shell with the command ImportModule:
1 2 3 |
Import-Module .\Module-Sample.psm1 FirstModuleFunction -sOne "one" -sTwo "two" |
NOTE: if your developing and testing in the module, be sure you unload and re-import the module. Otherwise, new changes are not available until you correctly remove module from memory (the Import-Module skip additional import with the same module to avoid the duplication in memory).