Day 21 - Creating your Own "cmdlets" and modules
I decided to try and get ahead and get through the last couple of chapters over the weekend since monday is the start of "The Scripting Games", and im going to take part this year. I want to test what I have learned so far. Problem is that its now late saturday night and im going through it for the third time.
Todays chapter is over building your functions to act like cmdlets, basically making them into cmdlets. Just writing a function doesn’t allow them to act like cmdlets you see. If you write in parameter functions then they accept them, but there are special things that you must do to allow them to accept pipeline input.
Pipeline function Is the first topic of the day, these are otherwise known as filtering functions. These types of functions allow for the input of either one or multiple objects. They are formated as such:
function get-manmodinfo
{
Begin
{}Process {
$computer = $_
$computerSystem = Get-WmiObject -ComputerName $computer Win32_computerSystem
$processor = Get-WmiObject -ComputerName $computer win32_processor
$obj = New-Object -TypeName PSObject
$obj | Add-Member -MemberType Noteproperty `-name Manufacturer -Value $ComputerSystem.Manufacturer
$obj | Add-Member -MemberType NoteProperty `-name Model -Value $computerSystem.Model
Write-Output $obj
}
END {}
}
get-content computers.txt | get-manmodinfo | Format-Table -AutoSize
The only issue with this is that it will now only accept pipeline inputs. You could add a parameter block and the script will still function with the pipeline input but the parameter command, Get-ManModInfo -computer (get-content computers.txt) will not accept the multiple objects. Don explains that in order to make these functions act as cmdlets do you will need to break them them down into two separate parts with a what he calls a worker function. Ive show this below:
function manmodinfowork
{
param
([string]$computername)$computerSystem = Get-WmiObject -ComputerName $computername win32_computerSystem
$processor = Get-WmiObject -ComputerName $computername win32_processor
$obj
= New-Object
-TypeName PSObject
$obj | Add-Member -MemberType
Noteproperty `-name Manufacturer -Value $computerSystem.Manufacturer
$obj | Add-Member -MemberType NoteProperty `
-name Model -Value $computerSystem.Model
Write-Output $obj
}
Function Get-ManModInfo
{
Param
([string[]]$computername
)
Begin {
$usedparameter = $false
if ($PSBoundParameters.containskey('computername')) {
$usedparameter = $true
}
}
Process {
if ($UsedParameter) {
foreach ($computer in $computername) {
manmodinfowork -computer $computer
}
} else {
ManModInfoWork -computer $_
}
}
End {}
}
get-manmodinfo -computer
(get-content C:\Users\Chris\Documents\Scripts\computers.txt)
get-content C:\Users\Chris\Documents\Scripts\computers.txt
| get-manmodinfo
| Format-Table
-AutoSize
Now as you can see it will accept both the Pipeline and Parametized input acting just as a cmdlet would. You can add or modify this to add further Paramters in the WorkInfo function. The functions can get far more advanced from here and add all kinds of support for many other parts for PowerShell that I just don’t have the time or space to cover. You would be far better served to read the help file or any of the documentation available on advanced functions.
The last thing I will cover here is the packaging of the function as a module for use and distribution. This is a simple process and only required that you save the script file as a .PSM1 file. These are module files. Now you can place these in the module directory under c:\Windows\System32\windowspowershell\v1.0\modules. For use by anyone on the computer or place them in the personal profile modules directory under your profile\documents folder.
And that is it. Just distribute the PSM1 files for other personal to use and set back and wait for the complaints about the way it works to fly in, or the requests for more features. Some people want to be PowerShell Lazy without the work.
No comments:
Post a Comment