Summary: Microsoft Scripting Guy, Ed Wilson, talks about combining functions into a single function file, and using them in scripts.
Microsoft Scripting Guy, Ed Wilson, is here. This morning is sort of mellow. It seems as if the clouds are touching the ground, and all sound is suppressed by a thick cloth batten. After seemingly weeks of rain, it is nice to have a not so wet day. I am on the lanai sitting in our porch swing reading my email via Outlook Web Access on my Surface RT. I love the long battery life and the portability of this device, and the fact that it has Windows PowerShell makes it even better.
Note This is the third part of a multipart series about using Windows PowerShell functions and modules. Prior to reading this blog, you should read the previous posts:
- I Found this PowerShell Function—Now What Do I Do? Part 1
- I Found this PowerShell Function—Now What Do I Do? Part 2
If one function is cool, then two are even better
Yesterday in Part 2, I talked about dot sourcing a script that contains a function into the Windows PowerShell console so I could use the function just like it was a cmdlet. Today I want to expand on that idea just a bit by including two functions in a script file. The two functions use WMI to create a similar output to standard CIM functions in Windows 8. The equilivant functions in Windows 8 are Get-Volume and Get-NetAdapter. Here is the content of the two WMI functions:
TwoWmiFunctions.ps1
Function Get-Volume
{
Param($cn = $env:computername)
Get-WmiObject -class win32_volume -ComputerName $cn|
Select-Object driveletter, @{LABEL='FileSystemLabel';EXPRESSION={$_.label}},
filesystem,
@{LABEL="Size";EXPRESSION={"{0:N2} Gigabytes" -f ($_.capacity/1GB) }},
@{LABEL="SizeRemaining";EXPRESSION={"{0:N2} Gigabytes" -f ($_.freespace/1GB) }}
} #end function Get-Volume
Function Get-NetAdapter
{
Param($cn = $env:computername)
Get-WmiObject win32_networkadapter |
Where-Object {$_.netconnectionstatus} |
Select-Object name,
@{LABEL='InterfaceDescription';EXPRESSION={$_.Description}},
@{LABEL='ifIndex';EXPRESSION={$_.Index}},
@{LABEL='Status';EXPRESSION={
If($_.netconnectionstatus -eq 2){"not present"}
If($_.netconnectionstatus -eq 4){"up"}}}
} # end function get-NetAdapter
For ease of use, I have uploaded these functions to the Scripting Guys Script Repository: Two WMI Functions.
Using the function script by dot sourcing it
To dot source the script that contains the two functions, all I need to do is to place a period (dot) at the beginning of the console line, and then use the path to the script that contains the functions. I can then use the functions directly. This is shown here.
. C:\fso\TwoWmiFunctions.ps1
The following image shows dot sourcing the script that contains the two functions and then using the two functions.
Dot source to interop between Windows versions
Lots of people are migrating to Windows 8 on their desktops; but unfortunately for many network administrators, they are forced to interop between Windows 8 and other versions of Windows. One of the things that is great about Windows 8 (and Windows Server 2012 for that matter) are the many CIM functions that wrap WMI classes. These are convenient and easy to use. However, for down-level systems, I still need to use the WMI classes. To avoid really cluttering up a script with a bunch of WMI code, I can use dot sourcing to handle the transition period. Here is an example of how that might work:
if(gcm get-volume){Get-Volume} ELSE {. C:\fso\TwoWmiFunctions.ps1; Get-Volume}
So all I need to do is to use Get-Command to see if the Get-Volume function (available in Windows 8) exists. If it does, I call the Get-Volume command. If the Get-Volume function is not available (because the version of Windows is older than Windows 8), I dot source my TwoWMIFunctions.ps1 script that contains my two functions, and then I call Get-Volume from the dot-sourced script. This makes for a nice transitional bit of code.
Note When you create this sort of transitionalfunction, ensure that the property names are the same. In this way, using one function or the other will also be the same. In my example TwoWmiFunctions.ps1 script, I had to rename several WMI class property names for compatibility.
In the following image, I use the dot-source technique to bring in the script that contains the compatibility functions.
Now What Do I Do? Week will continue tomorrow when I will talk about using a Windows PowerShell module. It is really cool, and you do not want to miss it.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy