<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Powershell Template Archives - the Sysadmin Channel</title>
	<atom:link href="https://thesysadminchannel.com/tag/powershell-template/feed/" rel="self" type="application/rss+xml" />
	<link>https://thesysadminchannel.com/tag/powershell-template/</link>
	<description>Documenting My Life as a System Administrator</description>
	<lastBuildDate>Mon, 15 Nov 2021 18:49:49 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.2</generator>
<site xmlns="com-wordpress:feed-additions:1">144174110</site>	<item>
		<title>A Powershell Template For Creating The Perfect Function</title>
		<link>https://thesysadminchannel.com/powershell-template/</link>
					<comments>https://thesysadminchannel.com/powershell-template/#comments</comments>
		
		<dc:creator><![CDATA[Paul Contreras]]></dc:creator>
		<pubDate>Sun, 17 Jan 2021 05:12:18 +0000</pubDate>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[create Powershell function parameters]]></category>
		<category><![CDATA[Powershell Advanced Function in Depth]]></category>
		<category><![CDATA[Powershell Template]]></category>
		<guid isPermaLink="false">https://thesysadminchannel.com/?p=1902</guid>

					<description><![CDATA[<p>Anytime I&#8217;m writing a new Powershell script I always find my self scratching my head trying to recall the exact syntax inside the parameter block. Even though I&#8217;ve created hundreds of scripts in my day, I always use a template&#8230; <a href="https://thesysadminchannel.com/powershell-template/" class="more-link">Continue Reading <span class="meta-nav">&#8594;</span></a></p>
<p>The post <a href="https://thesysadminchannel.com/powershell-template/">A Powershell Template For Creating The Perfect Function</a> appeared first on <a href="https://thesysadminchannel.com">the Sysadmin Channel</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Anytime I&#8217;m writing a new Powershell script I always find my self scratching my head trying to recall the exact syntax inside the parameter block.  Even though I&#8217;ve created hundreds of scripts in my day, I always use a template because its much easier. Today I&#8217;m going to share with the exact <strong>Powershell template</strong> I use when creating my Powershell Scripts.</p>
<p>The format I use is pretty straight forward.  More often then not, I use a parameter that allows a string array for input.  This can be achieved by using the type <code>[string[]]</code> with double square brackets.  The double brackets means that the input accepts multiple string values.  A parameter that only allows a single value would look like this: <code>[string]</code></p>
<p><a href="https://thesysadminchannel.com/wp-content/uploads/2021/01/Powershell-Template-Function-Feat.jpg" target="_blank" rel="noopener"><img fetchpriority="high" decoding="async" src="https://thesysadminchannel.com/wp-content/uploads/2021/01/Powershell-Template-Function-Feat.jpg" alt="Powershell Template Function" width="1024" height="571" class="aligncenter size-full wp-image-3698" srcset="https://thesysadminchannel.com/wp-content/uploads/2021/01/Powershell-Template-Function-Feat.jpg 1024w, https://thesysadminchannel.com/wp-content/uploads/2021/01/Powershell-Template-Function-Feat-768x428.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><br />
&nbsp;</p>
<div id="tableofcontents">
<h2>Table Of Contents</h2>
<ul>
<li><a href="#PowershellTemplate">Powershell Template</a></li>
<li><a href="#CommentBasedHelp">Comment Based Help</a></li>
<li><a href="#CmdletBinding">CmdletBinding and the Param Block</a></li>
<ul>
<li><a href="#SupportsShouldProcess">SupportsShouldProcess</a></li>
</ul>
<li><a href="#FunctionParameters">Create Powershell Function Parameters</a></li>
<ul>
<li><a href="#Alias">How To Use Alias</a></li>
<li><a href="#ValidateSet">How To Use ValidateSet and ValidateRange</a></li>
<li><a href="#ValidateScript">How To Use ValidateScript</a></li>
<li><a href="#ParameterSetName">How To Use ParameterSetName</a></li>
</ul>
<li><a href="#BeginProcessEnd">Begin, Process And End Blocks</a></li>
<ul>
<li><a href="#BeginEndBlock">Begin and End Blocks</a></li>
<li><a href="#ProcessBlock">Process Block</a></li>
</ul>
</ul>
</div>
<p>&nbsp;</p>
<div id="PowershellTemplate" style="scroll-margin-top: 15px;"></div>
<h2>Powershell Template</h2>
<p>I&#8217;m going to post the basic Powershell template here and we&#8217;ll go over other options in detail so you can use it to your hearts content.</p>
<pre class="brush: powershell; title: ; notranslate">

Function Get-Something {
&lt;#
.SYNOPSIS
    This is a basic overview of what the script is used for..


.NOTES
    Name: Get-Something
    Author: theSysadminChannel
    Version: 1.0
    DateCreated: 2020-Dec-10


.EXAMPLE
    Get-Something -UserPrincipalName &quot;username@thesysadminchannel.com&quot;


.LINK
    https://thesysadminchannel.com/powershell-template -
#&gt;

    [CmdletBinding()]
    param(
        [Parameter(
            Mandatory = $false,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
            )]
        [string[]]  $UserPrincipalName
    )

    BEGIN {}

    PROCESS {}

    END {}
}

</pre>
<p>&nbsp;</p>
<h2>Powershell Advanced Function Explained in Depth</h2>
<p>Here I&#8217;m going to explain how to write a Powershell advanced function and essentially how to parameter-ize your scripts.  This way you can share the script without people having to open and edit the file (and possibly breaking it).  </p>
<p>Below is the start of our basic function.  After the word &#8220;Function&#8221; is the name of our function that we&#8217;ll call to run the script. </p>
<pre class="brush: powershell; title: ; notranslate">
    Function Get-Something {

    }
</pre>
<p>One thing to mention here is that we should always strive to have one function per purpose.  Also, best practice is to use a verb-noun naming convention. Powershell has an approved verb list which can be found by using the <code>Get-Verb</code> cmdlet.   </p>
<div id="attachment_2739" style="width: 810px" class="wp-caption aligncenter"><a href="https://thesysadminchannel.com/wp-content/uploads/2021/01/Powershell-Approved-Verbs.png" target="_blank" rel="noopener noreferrer"><img decoding="async" aria-describedby="caption-attachment-2739" src="https://thesysadminchannel.com/wp-content/uploads/2021/01/Powershell-Approved-Verbs.png" alt="Powershell Approved Verbs" width="800" height="436" class="size-full wp-image-2739" srcset="https://thesysadminchannel.com/wp-content/uploads/2021/01/Powershell-Approved-Verbs.png?v=1610096561 800w, https://thesysadminchannel.com/wp-content/uploads/2021/01/Powershell-Approved-Verbs-768x419.png?v=1610096561 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><p id="caption-attachment-2739" class="wp-caption-text">The most commonly used verbs are Get and Set.</p></div>
<p>&nbsp;</p>
<div id="CommentBasedHelp" style="scroll-margin-top: 15px;"></div>
<h2>Comment Based Help</h2>
<p>When I write my function I always have the SYNOPSIS, NOTES, LINK and sometimes even an example of how its supposed to be ran. This block of code is used for <strong>comment based help</strong> and can be called by using the <code>Get-Help</code> cmdlet. </p>
<p>You&#8217;ll need to take note of the opening and closing tags.  The &lt;# and the #&gt; is used as a multi-line comment and is perfect for this use case. Below is a snippet of my usual comment based help.</p>
<pre class="brush: powershell; title: ; notranslate">
&lt;#
.SYNOPSIS
    This is a basic overview of what the script is used for..


.NOTES
    Name: Get-Something
    Author: theSysadminChannel
    Version: 1.0
    DateCreated: 2020-Dec-10


.EXAMPLE
    Get-Something -UserPrincipalName &quot;username@thesysadminchannel.com&quot;


.LINK
    https://thesysadminchannel.com/powershell-template -
#&gt;
</pre>
<p><a href="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Help-Get-Something.png" target="_blank" rel="noopener noreferrer"><img decoding="async" src="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Help-Get-Something.png" alt="Get-Help Get-Something" width="920" height="483" class="aligncenter size-full wp-image-2750" srcset="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Help-Get-Something.png?v=1610100145 920w, https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Help-Get-Something-768x403.png?v=1610100145 768w" sizes="(max-width: 920px) 100vw, 920px" /></a></p>
<p>&nbsp;<br />
If the function has examples in the comment based help section, which most published functions should be doing, we could view those using the <code>-Examples</code> parameter.<br />
<a href="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Help-Get-Something-Example.png" target="_blank" rel="noopener noreferrer"><img decoding="async" src="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Help-Get-Something-Example.png" alt="Get-Help Get-Something -Example" width="920" height="auto" class="aligncenter size-full wp-image-2798" srcset="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Help-Get-Something-Example.png?v=1610342095 790w, https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Help-Get-Something-Example-768x280.png?v=1610342095 768w" sizes="(max-width: 790px) 100vw, 790px" /></a></p>
<p>&nbsp;</p>
<div id="CmdletBinding" style="scroll-margin-top: 15px;"></div>
<h2>CmdletBinding and the Param Block</h2>
<pre class="brush: powershell; title: ; notranslate">

    [CmdletBinding()]
    param(
        #Parameters go here
    )

</pre>
<p>Anytime you use the <code>[CmdletBinding]</code> attribute you&#8217;re actually creating an advanced function in Powershell.  Pretty cool huh.  By adding this little snippet of code, you&#8217;re giving your function access to use Powershell <a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-7.1" rel="noopener noreferrer" target="_blank">common parameters</a>. I&#8217;m going to list out the ones per the documentation.</p>
<ul>
<li>Debug</li>
<li>ErrorAction</li>
<li>ErrorVariable</li>
<li>InformationAction</li>
<li>InformationVariable</li>
<li>OutVariable</li>
<li>OutBuffer</li>
<li>PipelineVariable</li>
<li>Verbose</li>
<li>WarningAction</li>
<li>WarningVariable</li>
</ul>
<p>&nbsp;</p>
<div id="SupportsShouldProcess" style="scroll-margin-top: 15px;"></div>
<h3>SupportsShouldProcess</h3>
<p>Within the cmdletbinding attribute we have the ability to add a <strong>SupportsShouldProcess</strong> attribute to allow us to call the <code>-Whatif</code> and <code>-Confirm</code> parameters.  This is mostly used if you want to change the state of the command (Set, Remove etc..) so it shouldn&#8217;t always be used by default.  I wrote another detailed article about the difference between <a href="https://thesysadminchannel.com/shouldcontinue-vs-shouldprocess-whats-the-difference/" rel="noopener noreferrer" target="_blank">ShouldContinue and ShouldProcess</a>.  I would suggest you take a look when you get a chance.</p>
<p>If not, a basic TL;DR is:</p>
<ul>
<li><strong>ShouldContinue</strong>: Used to prompt the user by default</li>
</ul>
<ul>
<li><strong>ShouldProcess</strong>: Does NOT prompt by default</li>
</ul>
<p>&nbsp;</p>
<div id="FunctionParameters" style="scroll-margin-top: 15px;"></div>
<h2>Create Powershell Function Parameters</h2>
<p>Arguably one of the most important items to take away from all of this is the ability to <strong>create Powershell function parameters</strong> as you see fit. As mentioned earlier, I usually setup my scripts to allow for multiple inputs and always try to replicate what the Powershell community is used to using. This is why I have it as a default in my Powershell Template.  </p>
<p>An excellent example of this is the ComputerName parameter.  Microsoft uses this whenever it wants to identify a machine so if you&#8217;re writing a script, you should be using this too.  This is the unofficial official parameter that&#8217;s widely used so don&#8217;t use System or Ip etc..  Try to keep it relevant to what the community is already used to using.  If you&#8217;re stuck on using other parameter names, we&#8217;ll talk about using Alias&#8217; further down the article.</p>
<p>There&#8217;s so much information to convey here so let&#8217;s start off with a basic snippet of what this looks like in its basic form.</p>
<pre class="brush: powershell; title: ; notranslate">

    [Parameter(
        Mandatory = $false,
        ValueFromPipeline = $true,
        ValueFromPipelineByPropertyName = $true,
        Position = 0
        )]
    [string[]]  $UserPrincipalName = &quot;username@thesysadminchannel.com&quot;

</pre>
<p>The position and mandatory attributes are pretty self explanatory. Mandatory tells Powershell that we must have a value added using the function.  If you have a default value like my example above, Powershell will still ask you for a value so its best to set it to false if you plan on using a default value. Position is used so you don&#8217;t have to use the parameter when calling the function.  An example would be:</p>
<pre class="brush: powershell; gutter: false; title: ; notranslate">
Get-Something 'username@thesysadminchannel.com'
</pre>
<p>&nbsp;<br />
ValueFromPipeline and ValueFromPipelineByParameterName are attributes that are used to determine if you want to allow values to be used as input in the pipeline.  An example of this would be:</p>
<pre class="brush: powershell; gutter: false; title: ; notranslate">
Get-ADUser username | Get-Something
</pre>
<p>Since the <code>Get-ADUser</code> and <code>Get-Something</code> cmdlets both use UserPrincipalName, we can pass the output from Get-ADUser into the input of Get-Something. This scenario is specifically referring to <strong>ValueFromPipelineByPropertyName</strong>. Alternatively, if they don&#8217;t match exactly, we can use the <strong>ValueFromPipeline</strong> to still use the pipeline.  I use this technique for most of my scripts because I want to try to make things as adaptable as I can.  It should mention that I use caution and try to make it happen where it makes sense.<br />
&nbsp;</p>
<div id="Alias" style="scroll-margin-top: 15px;"></div>
<h3>How To Use Alias</h3>
<p>I mentioned above that we should always strive to use community standards.  In an example earlier I referenced using ComputerName.  However, what if we wanted to have something else show up as a parameter and tie it into the function.  In that case, we would use an Alias.  Let&#8217;s see what this looks like in our sample function Get-Something. </p>
<pre class="brush: powershell; highlight: [4]; title: ; notranslate">
    [Parameter(
        Mandatory = $false
    )]
    [Alias(&quot;UserName&quot;, &quot;SamAccountName&quot;)]
    [string[]]  $UserPrincipalName

</pre>
<p><a href="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-Alias-Powershell.png" target="_blank" rel="noopener noreferrer"><img decoding="async" src="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-Alias-Powershell.png" alt="Get-Something Use Alias Powershell" width="850" height="218" class="aligncenter size-full wp-image-2826" srcset="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-Alias-Powershell.png?v=1610603498 850w, https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-Alias-Powershell-768x197.png?v=1610603498 768w" sizes="(max-width: 850px) 100vw, 850px" /></a><br />
&nbsp;</p>
<div id="ValidateSet" style="scroll-margin-top: 15px;"></div>
<h3>How To Use ValidateSet and ValidateRange</h3>
<p>An attribute that comes in the clutch when you want a specific range or want a predetermined set is the <strong>ValidateRange</strong> or <strong>ValidateSet</strong>.  </p>
<p>Let&#8217;s say you have a script that uses numbers and you only want to allow numbers between 1 through 100.  Instead of writing an if statement to say if $num -gt 100..  do fail blah blah, you can use ValidateRange to automatically tie that in there and have Powershell work the logic for you.  Let&#8217;s see what that looks like in our Get-Something script.</p>
<pre class="brush: powershell; highlight: [4]; title: ; notranslate">

    [Parameter(
        Mandatory = $false
    )]
    [ValidateRange(1,100)]
    [int]  $MaxResults

</pre>
<p><a href="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-ValidateRange-Powershell.png" target="_blank" rel="noopener noreferrer"><img decoding="async" src="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-ValidateRange-Powershell.png" alt="Get-Something Use ValidateRange Powershell" width="979" height="257" class="aligncenter size-full wp-image-2827" srcset="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-ValidateRange-Powershell.png?v=1610603680 979w, https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-ValidateRange-Powershell-768x202.png?v=1610603680 768w" sizes="(max-width: 979px) 100vw, 979px" /></a></p>
<p>Here we can take note of the ValidateRange attribute and the MaxResults data type. Since we&#8217;re dealing with numbers, or an integer data type, we set our MaxResults variable data type to <code>[int]</code>.  Furthermore, in our screenshot we entered a number greater then the allowed top range and it errored automatically.</p>
<p>&nbsp;</p>
<p>Almost the same can be said for the ValidateSet attribute. However instead of integers, we use preset values for our strings.  This way the person running the script only has a limited amount of strings they can pass into the function. Another great take away from using ValidateSet is that the user can tab complete the options that are available to them so it makes for a better user experience.  Let&#8217;s see what it looks like in the code block.</p>
<pre class="brush: powershell; highlight: [4]; title: ; notranslate">

    [Parameter(
        Mandatory = $false
    )]
    [ValidateSet('paul@thesysadminchannel.com', 'don@thesysadminchannel.com')]
    [string[]]  $UserPrincipalName

</pre>
<p><a href="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-ValidateSet-Powershell.png" target="_blank" rel="noopener noreferrer"><img decoding="async" src="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-ValidateSet-Powershell.png" alt="Get-Something Use ValidateSet Powershell" width="979" height="299" class="aligncenter size-full wp-image-2828" srcset="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-ValidateSet-Powershell.png?v=1610603977 979w, https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-ValidateSet-Powershell-768x235.png?v=1610603977 768w" sizes="(max-width: 979px) 100vw, 979px" /></a></p>
<p>In our script here we can only use the values &#8216;<em>paul@thesysadminchannel.com</em>&#8216; and &#8216;<em>don@thesysadminchannel.com</em>.&#8217;  Had I put some logic in there, the script would have went through its flow and continued on.</p>
<p>However, when I use a non permitted value such as &#8216;<em>jane@thesysadminchannel.com</em>&#8216; we can see that there is an error saying <strong>Cannot validate argument on parameter &#8216;UserPrincipalName&#8217;</strong>. </p>
<p>&nbsp;</p>
<div id="ValidateScript" style="scroll-margin-top: 15px;"></div>
<h3>How To Use ValidateScript</h3>
<p>Definitely one of the trickiest, yet most flexible attributes of the bunch is the use of <strong>ValidateScript</strong>. This will allow you to script out a validation to see if it works with your logic.  A real world example of this would be checking if a user exists in AD before continuing on with the function.  Let&#8217;s see what the code looks like.</p>
<pre class="brush: powershell; highlight: [4]; title: ; notranslate">

[Parameter(
    Mandatory = $false
)]
[ValidateScript( {Get-ADUser -Filter &quot;UserPrincipalName -eq '$_'&quot; | select -ExpandProperty UserPrincipalName} )]
[string[]]  $UserPrincipalName

</pre>
<p><a href="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-ValidateScript-Powershell.png" target="_blank" rel="noopener noreferrer"><img decoding="async" src="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-ValidateScript-Powershell.png" alt="Get-Something Use ValidateScript Powershell" width="979" height="266" class="aligncenter size-full wp-image-2829" srcset="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-ValidateScript-Powershell.png?v=1610605137 979w, https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-Use-ValidateScript-Powershell-768x209.png?v=1610605137 768w" sizes="(max-width: 979px) 100vw, 979px" /></a></p>
<p>The key take away here is that your parameter input must match the validation script&#8217;s output.  In my ValidateScript example above, I don&#8217;t have a user with the UPN paul@thesysadminchannel.com so it threw an error.  However, when I used pcontreras@thesysadminchannel.com which is a user in my lab, it worked.</p>
<p>Another item to mention is the <code>$_</code> in your validation script is going to be pulled from the parameter input.  It&#8217;s similar to how you would use a <code>Foreach-Object</code> or <code>Where-Object</code> in the pipeline.<br />
&nbsp;</p>
<div id="ParameterSetName" style="scroll-margin-top: 15px;"></div>
<h3>How To Use ParameterSetName</h3>
<p>The <strong>ParameterSetName</strong> attribute is useful when you want to have 2 or more parameters, but don&#8217;t want them to run simultaneously.  Think of it as a &#8220;this or that&#8221; parameter. An example of this would be if you wanted to add a parameter to include an object, but also wanted to add a parameter to exclude similar objects.  This is an arbitrary example but hopefully you get the idea.  Let&#8217;s look at what the sample code snippet would look like.</p>
<pre class="brush: powershell; highlight: [1,10,16]; title: ; notranslate">

[CmdletBinding(DefaultParameterSetName=&quot;Default&quot;)]
param(
    [Parameter(
        Mandatory = $true
    )]
    [string[]]  $UserPrincipalName,

    [Parameter(
        Mandatory = $false,
        ParameterSetName = 'AnyName_A'
    )]
    [switch]    $Include,

    [Parameter(
        Mandatory = $false,
        ParameterSetName = 'AnyName_B'
    )]
    [switch]    $Exclude
)

</pre>
<p>The focus here is that we can choose which parameters we don&#8217;t want to run together and which ones we do. Alternatively, if a parameter doesn&#8217;t belong to a  parameter set  (like UserPrincipalName in our example above), it&#8217;s able to be used with all parameters in the param block.</p>
<div id="attachment_2851" style="width: 896px" class="wp-caption aligncenter"><a href="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-ParameterSetName-Example.png" target="_blank" rel="noopener noreferrer"><img decoding="async" aria-describedby="caption-attachment-2851" src="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-ParameterSetName-Example.png" alt="Get-Something ParameterSetName Example" width="886" height="297" class="size-full wp-image-2851" srcset="https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-ParameterSetName-Example.png?v=1610687576 886w, https://thesysadminchannel.com/wp-content/uploads/2021/01/Get-Something-ParameterSetName-Example-768x257.png?v=1610687576 768w" sizes="(max-width: 886px) 100vw, 886px" /></a><p id="caption-attachment-2851" class="wp-caption-text">-Include and -Exclude work independently of each other, but not simultaneously.</p></div>
<p>Another take away here is that the CmdletBinding attribute also has a default parameter set name.  This allows the function to run when A or B is not specified.  So in our case, we want to run the UserPrincipalName parameter but don&#8217;t need to run the Include or Exclude parameter if we don&#8217;t want to.</p>
<p>&nbsp;</p>
<div id="BeginProcessEnd" style="scroll-margin-top: 15px;"></div>
<h2>Powershell Begin, Process and End Blocks</h2>
<p>While this is not technically required to have in your functions, I always like to explicitly put it in there because it gives it a cleaner look.  In my opinion it gives it a better structure. </p>
<p>Omitting the <code>begin</code> and <code>end</code> block will automatically have the code run under the <code>process</code> block.  However, I like to give my code some structure so I&#8217;ve drilled it into my head to have it in every script.  Furthermore, this is why I have it set in my Powershell Template.</p>
<p>&nbsp;</p>
<div id="BeginEndBlock" style="scroll-margin-top: 15px;"></div>
<h3>Begin and End Blocks</h3>
<p>If you take a step back, the begin and end block don&#8217;t need to be complicated at all.  After all, everything you run in here can be ran inside the process block, but the question is&#8230; When, why and what for that matter should you use this for.</p>
<p>An important thing to keep in mind is that <strong>the code inside the begin and end block will only run once</strong>.  With that being said, I like to use the begin block whenever I am making or validating a connection to an endpoint.  Whether it be a SQL database or Azure AD, there are ways to tell if you&#8217;re already connected or if you need to connect.  If it&#8217;s not connected, I usually throw in an <code>-ErrorAction Stop</code> so the code doesn&#8217;t run past that point.</p>
<p>The end block is pretty much the opposite.  I&#8217;ll usually close whatever connection I need or run some kind of output.  In all honesty though, 9 times out of 10 I leave the end block empty.</p>
<p>&nbsp;</p>
<div id="ProcessBlock" style="scroll-margin-top: 15px;"></div>
<h3>Process Block</h3>
<p>The meat and potatoes of the Powershell function is the Process block.  This is where the majority of your code will run so it&#8217;s important to mention that <strong>the code inside the process block will iterate over the objects</strong>.  If you have objects coming in the pipeline or if you run a foreach loop, the code gets ran here.  In the case of our Powershell template, I went ahead left it empty since we&#8217;ll be writing this from scratch.</p>
<p>&nbsp;</p>
<p>Hopefully this complete guide to create a function using our Powershell template was able to help you understand how this works.  If you want some more real world examples, be sure to check out our <a href="https://thesysadminchannel.com/powershell/" rel="noopener noreferrer" target="_blank">Powershell Gallery</a>.  It&#8217;s full of actual scripts that you can use in your organization.</p>
<p>Finally, don&#8217;t forget to check out our <a href="https://www.youtube.com/c/theSysadminChannel" rel="noopener noreferrer" target="_blank">Youtube Page</a> for sysadmin video content.</p>
<p>The post <a href="https://thesysadminchannel.com/powershell-template/">A Powershell Template For Creating The Perfect Function</a> appeared first on <a href="https://thesysadminchannel.com">the Sysadmin Channel</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://thesysadminchannel.com/powershell-template/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1902</post-id>	</item>
	</channel>
</rss>
