An Example ScriptModule and Advanced Function

Finishing up a PowerShell class and the students made me actually comment out an entire script module, so might as well share it with ya.

Don Jones

June 23, 2011

3 Min Read
ITPro Today logo in a gray background | ITPro Today

And here it is...

function Restart-Host {[CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='High')]param ([Parameter(Mandatory=$True,           ValueFromPipeline=$True,   ValueFromPipelineByPropertyName=$True)]    [Alias('host')][ValidateLength(3,30)][string[]]$computername,[string]$logname = 'errors.txt')begin {        write-verbose "Deleting $logname"del $logname -ErrorAction SilentlyContinue}process {write-verbose "Beginning process loop"                # The $computername parameter will contain 1+ names, so        # we want to work with just one at a time. A ForEach loop[        # permits us to do that.        foreach ($computer in $computername) {                    # If a Stop error occurs in a Try block, the following            # catch block will execute.            try {                            # we'll use $continue to track whether or not this fails                $continue = $true                Write-Verbose "Trying $computer"                $os = Get-WmiObject -class Win32_operatingsystem -computer $computer -erroraction stop            } catch {                # set $continue to false, so we know not to try anything else                # with this failed computer. Also log the computer name.                Write-Verbose "$computer failed; logging"                $computer | out-file $logname -append                $continue = $false            }                         # only do this if the WMI call succeeded.            if ($continue) {                Write-Verbose "Connection to $computer successful"                                # this generates the confirm/whatif prompt/output                # and will return False if we're not supposed to                # actually execute                if ($pscmdlet.ShouldProcess($computer)) {                    write-verbose "Executing reboot on $computer"                    $os.reboot()                }            }        }}}function Get-ComputerInfo {<#.SYNOPSISGets OS version information.DESCRIPTIONSee synopsis..EXAMPLEGet-OSVersion -computername server-r2.EXAMPLE'localhost','server-r2' | Get-OSVersion.EXAMPLEImport-Module ActiveDirectoryGet-ADComputer -filter * | Select @{n='computername',e={$_.name}} | Get-OSVersion.EXAMPLEGet-OSVersion -computername (Get-Content names.txt).PARAMETER computernameThe computer name to query. Just one..PARAMETER lognameThe name of a file to write failed computer names to. Defaults to errors.txt.#>[CmdletBinding()]param (        # see about_functions_advanced_parameter for this stuff[Parameter(Mandatory=$True,           ValueFromPipeline=$True,   ValueFromPipelineByPropertyName=$True,                   HelpMessage='What computer name would you like to target?')]    [Alias('host')][ValidateLength(3,30)][string[]]$computername,[string]$logname = 'errors.txt')        # this block executes once when the function is first calledbegin {        write-verbose "Deleting $logname"del $logname -ErrorAction SilentlyContinue}        # this block will execute once if nothing was piped in    # if something was piped in, this will execute once for    # each thing that was piped inprocess {                # we don't need to explicitly code a -verbose parameter.        # PowerShell will handle it automagically.write-verbose "Beginning process loop"                # $computername may contain 1+ items, so we'll use a foreach loop        # that allows us to just work with one computer at a time.        # that way if one computer fails, we can still continue trying        # the other ones        foreach ($computer in $computername) {                    # in a try block, errors that occur with -ErrorAction Stop will be            # captured instead of making the whole script explode. The following            # catch block will allow us to deal with the error.            try {                            # setting $continue to True allows us to track whether                # or not this WMI call succeeds                Write-Verbose "Trying $computer"                $continue = $true                $os = Get-WmiObject -class Win32_operatingsystem -computer $computer -erroraction stop            } catch {                            # the WMI call failed, so we set $continue to false. That                # will let us skip the rest of the script for the current                # computer.                Write-Verbose "$computer failed."                $computer | out-file $logname -append                $continue = $false            }                         # only do this is $continue is still true.            if ($continue) {                write-verbose "$computer succeeded; trying next WMI calls"                write-verbose "BIOS"                $bios = get-wmiobject -class win32_Bios -computer $computer                                # we only need to query one processor                write-verbose "Processor"                $proc = get-wmiobject -class win32_processor -computer $computer |                     select-object -first 1                                # we have WMI information in $os, $bios, and $proc.                 # so let's create a hashtable with all the info we                # want to have in our final output                Write-Verbose "Creating output for $computer"                $info = @{                    'ComputerName'=$computer;                    'OSVersion' = $os.caption;                    'OSBuild' = $os.buildnumber;                    'SPVersion' = $os.servicepackmajorversion;                    'BIOSSerial' = $bios.serialnumber;                    'OSArchitecture' = $os.osarchitecture;                    'ProcArchitecture' = $proc.addresswidth                }                                # create the output object with the above info                $obj = New-Object -TypeName PSObject -Property $info                                # output the object to the pipeline                write-output $obj            }        }}}# create an aliasNew-Alias gif Get-ComputerInfo# make sure our two functions and the alias get# exposed when someone imports this moduleExport-ModuleMember -function Get-ComputerInfoExport-ModuleMember -function Restart-HostExport-ModuleMember -Alias gif


This is intended to be saved in DocumentsWindowsPowerShellModulesToolsTools.psm1 on your computer. Load using Import-Module Tools.

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like