Building a function | Powershell
Tags: powershell, getservice, restartingservices, function
Published: 2022-01-13 17:19:33

---
title: Building a function | Powershell
published: true
date: 2022-01-06 17:33:24 UTC
tags: Powershell,GetService,RestartingServices,Function
canonical_url: 
---

 **Version:**  5.1.x

During this post, I’ll share some concepts that I’ve used to build a function from a piece of code already shared on my blog in an earlier post. If you want to give it a look, please use the following **[link](https://dev.to/toolgbrmaker/get-service-cmdlet-continuation-powershell-59p)**.

The piece of code that I’ll reuse and change to fit my function needs is:

```powershell
#starting the stopped services or restarting the running ones
Get-Service -ComputerName 'PTPOPF247203' -Name '*Pharma*' |
Where-Object { 
    if ($_.Status -eq 'Running') {
        Write-Host 'Attempting to restart' $_.DisplayName 'with status' $_.Status -BackgroundColor DarkRed
        Restart-Service $_
    }
    elseif ($_.Status -eq 'Stopped') {
        Write-Host 'Attempting to start' $_.DisplayName 'with status' $_.Status -BackgroundColor DarkGreen
        Start-Service $_
    }      
}
```

The above code has the goal to restart executing services and start stopped ones.

**Our new function…**

Our function will have the name of **Set-ServiceRunningStatus** and will need as Parameters the **ComputerName** , **Name** , and **Force**. Regarding **Name** I’ll set this one as mandatory, to avoid a restart of all running services or the start of all stopped services, by mistake. Furthermore, the types used for these parameters are, by order, a string array, string, and a switch type, if the user wants a service restart no matter what’s.

```powershell
function Set-ServiceRunningStatus{
    [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipeline=$true)]
        [string[]]$ComputerName,
        [Parameter(Mandatory=$true,
            HelpMessage = "Enter a service name (or filter for multiple) to set Running Status")]
        [string]$Name,
        [switch]$Force
    )
    BEGIN { } #BEGIN
    PROCESS { } #PROCESS
    END { } #END  
}
```

So far so good, we have already our function structure. If you give a close look at our preliminary function structure you’ll be able to see that we have the **BEGIN** , **PROCESS** and **END** blocks. Let’s explain these **[input processing methods](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions_advanced_methods?view=powershell-7.2#input-processing-methods)** one by one:

- **BEGIN** – Contains all the code that is needed to execute at the beginning of the function;
- **PROCESS** – Contains the main functionality of the function;
- **END** – Contains all the code that is needed to execute at the end of the function. 

These methods can be read as follows – Begin to Process to end.

In our example won’t be strictly necessary to use all these blocks, but why not start to get used to them!?

**Begin:**

Let’s start with our **BEGIN** block, firstly I’ll enforce our coding rules in expressions, scripts, and script blocks (**[Set-StrictMode](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/set-strictmode?view=powershell-7.2)**), afterward I’ll **[write a verbose](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/write-verbose?view=powershell-7.2)** to indicate in which step is our function and start to handle some of the service parameters to use on my cmdlets. These parameters will be dynamically set, because of the non-mandatory ones.

```powershell
BEGIN {
  Set-StrictMode -Version 2.0

  Write-Verbose "[BEGIN] Starting: $($MyInvocation.Mycommand)"

  $serviceParam = @{ Name = $Name }
} #BEGIN
```

**PROCESS:**

Now, time to get into our PROCESS block, where the action will happens… By first, I’ll need to ensure that Parameter $ComputerName has been used and if so, I’ll add the **$ComputerName** to my **$serviceParam**. To accomplish that I’m using the automatic variable **[$PSBoundParameters](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables?view=powershell-7.2#psboundparameters)**. Also, take note that I’m switching the **$ComputerName** parameter in case of being called more than once when our function is being invoked.

```powershell
if ($PSBoundParameters.ContainsKey('ComputerName')) {
  if($serviceParam.ContainsKey('ComputerName')){
    $serviceParam.ComputerName = $ComputerName
  } else {
    $serviceParam.add('Computername',$ComputerName)
  } #if already have
  Write-Verbose "[PROCESS] Getting Services for $($ComputerName)"
} else {
  Write-Verbose "[PROCESS] Getting Services"    
}#if param ComputerName
```

After, I’ve built my list of parameters to be used on my Services cmdlets, I’ll start by getting the services result list, using **[Get-Service](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-service?view=powershell-7.2)** cmdlet, and pipe it to my **[Where-Object](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-7.2)**, where I’ll check if it’s a service to restart or to start.

```powershell
    PROCESS {
        if ($PSBoundParameters.ContainsKey('ComputerName')) {
            if($serviceParam.ContainsKey('ComputerName')){
                $serviceParam.ComputerName = $ComputerName
            } else {
                $serviceParam.add('Computername',$ComputerName)
            } #if already have
            Write-Verbose "[PROCESS] Getting Services for $($ComputerName)"
        } else {
            Write-Verbose "[PROCESS] Getting Services"    
        }#if param ComputerName

        Get-Service @serviceParam |
        Where-Object {

            Try {
                If ($_.status -eq 'Running') {
                    if ($Force) {
                        Write-Verbose "[PROCESS] Restarting Service $($_.Name) with -Force"
                        Restart-Service $_ -Force    
                    } else {
                        Write-Verbose "[PROCESS] Restarting Service $($_.Name)"
                        Restart-Service $_       
                    }#if force
                } elseif ($_.status -eq 'Stopped') {
                    Write-Verbose "[PROCESS] Starting Service $($_.Name)"
                    Start-Service $_    
                } #if status 
            } Catch {
                Write-Warning "[PROCESS] Attemp Failed for Service $($_.Name). Reason: $($_.Exception.message)"
            } #try

        } #Where-Object
    } #PROCESS
```

_All PROCESS block_

You should notice, by reading the code above, that besides normal Service cmdlet invocation, I’m also writing some verbose to keep the user aware of what is being done during PROCESS execution. Parallelly to that, I’m also checking if our function was been invoked with Force option, and if so, combined if it’s a restart, I’m forcing the cmdlet execution with force option.

**END:**

By last, on my end block, I’m only writing as a verbose mentioning the ending of my function execution.

```powershell
    END {
        Write-Verbose "[END] Ending: $($MyInvocation.Mycommand)"
    } #END 
```

And that’s it. Now I have a function, that will be available to reuse in multiple scenarios, like importing a new license (that demands a restart for the impacted services). Another example could be a start/restart service, at the end of the day, to ensure that the services get the last released code.

**Examples of Execution:**

This function will, by definition, execute the **[Get-Service](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-service?view=powershell-7.2)** cmdlet on your local machine and it’s optional the use of parameter **$ComputerName** , so only if you want to play it on a list of Computer Names, you’ll need to use it. A possible call would be…

```powershell
'localhost' | Set-ServiceRunningStatus -Name '*Pharma*' -Verbose
```

I’ll use this function in future references to show you how we can use it in different tasks and also introduce the Automated testing on PowerShell. Keep aware of future posts.

**Note:** Besides internet references, I’ve also used the learning concepts acquired in the following **[book](https://www.amazon.com/gp/product/1617295094/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1617295094&linkCode=as2&tag=toolgbrmaker2-20&linkId=afa15f19fc0419a6851496e32f39b370)**. I advise it as a good lecture.

**Hint:** On any doubts about cmdlets, always look for help on official internet pages, about those cmdlets, and from PowerShell helper.

**Ps:** I didn’t handle all possible function calls, so by now, this function is not bulletproof. If you detected the missing approach on it, please comment on this post. Good hunt!

Stay safe!