Build Your Own PowerShell Cmdlet: Part 7 of 9

Doctor Scripto

Dr Scripto

Summary: Microsoft Windows PowerShell MVP, Sean Kearney, continues a series of guest blogs detailing building your own cmdlet. Microsoft Scripting Guy, Ed Wilson, is here. Guest blogger and Windows PowerShell MVP, Sean Kearney, has written a series about building cmdlets. For more about Sean, see his previous guest blog posts.

Note This is Part 7 of a nine-part series about building your own Windows PowerShell cmdlet. Read the entire series as it unfolds. Here’s Sean…

Begin, Process, and End blocks

So far, we haven’t discussed three sections for your cmdlet. They are Begin, Process, and End.

  • The Begin block runs only once for each instance of the cmdlet. An example of script that you could place here might be the definition of static variables that will never change.

  • The Process block can be more dynamic in nature. It will run for each record in the pipeline. If you ran Import-CSV for some data and piped it to your cmdlet, for every row that existed within the CSV, this block of script would execute.

  • The End block also runs only once for each instance of the cmdlet. It is meant for any clean-up that may need to be performed, for example, closing open files that were created by the cmdlet.

We’ll modify our current advanced function to more correctly reflect processing the cmdlet. Because we are going to be piping in data, and we are no longer dealing with a single element by default, we must adjust the parameters to reflect this. Whenever we pass data through the Process block, it is received as a single-element object array. To your script, this is actually a very minor change—simply alter each passed parameter in the Process block with a [0] to reflect this. In our current cmdlet, we would look for references to the $Folder, $Preface, and $Extension variables. Most of the actual processing of our cmdlet will happen in the Process block, and this is where you need to ensure that you affect those changes on the variables. Our current cmdlet modified to have its structure broken into appropriate script blocks, with variables reflecting input from the pipeline, will look like this.

function global:ADD-LOGFILE{













HelpMessage=’Folder to Store Logfiles in’)]





HelpMessage=’TEXT to prepend all logfiles with’)]






HelpMessage=’File Extension for Logfiles’)]




Begin {}

Process {


WRITE-DEBUG “`$Folder: $Folder[0]”

WRITE-DEBUG “`$Preface: $Preface[0]”

WRITE-DEBUG “`$Extension: $Extension[0]”


# GET the Current Date for our Logfile



WRITE-DEBUG “`$Today: $Today”

# Extract the Date removing the “/”



WRITE-DEBUG “`$Date: $Date”


# Extract the Time removing the “:”



WRITE-DEBUG “`$Time: $Time”


# Build our Filename



WRITE-DEBUG “`$Logfilename: $Logfilename”


# Test and ensure file does not already exist


IF (TEST-PATH -path $Logfilename)


{ WRITE-ERROR –message “Error: $Logfilename exists.” –category ‘WriteError’


# If file exists, return a status of Boolean $False for Unsuccessful


RETURN $Logfilename,$FALSE }






# Create logfile


NEW-ITEM –Type File -path $Logfilename -Force | OUT-NULL

WRITE-DEBUG “$Logfilename successfully created”


# Return the Full path and filename if successful


RETURN $Logfilename,$TRUE


End {}


} ~Sean Thank you, Sean. You are a marathoner, and you are really going the distance on this series. Guest Blogger Week will continue tomorrow when Sean will bring us Part 8. I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace. Ed Wilson, Microsoft Scripting Guy 


Comments are closed. Login to edit/delete your existing comments