© Adam Bertram 2020
A. BertramBuilding Better PowerShell Codehttps://doi.org/10.1007/978-1-4842-6388-4_5

5. Create Building Blocks with Functions

Adam Bertram1  
(1)
Evansville, IN, USA
 

Once you create a few PowerShell scripts, you’re bound to start feeling like you’re re-creating the wheel. You will inevitably begin seeing patterns in what solutions you build with PowerShell.

One of the most important concepts when building great PowerShell code is treating code like building blocks. Don’t build unique solutions for all problems. Instead, build blocks in the form of functions and modules and then use those modules.

Over time, you’ll find that you’re saving tons of time by not rewriting the same code you wrote months ago and you only have one piece of code to maintain rather than ten copies.

Write Functions with One, Single Goal

Functions are supposed to be small, bite-sized code snippets that perform a single action. Build functions to not boil the ocean but to increase the temperate one degree at a time.

Functions should serve one primary purpose and should be easily describable with a quick glance of the code. If you find it hard to describe a function without saying the word “and,” it probably needs to be split into multiple functions.

Make functions small and easily callable from other functions. Functions are your building blocks. Build solutions with blocks not by pouring a solid building of concrete at once.

For example, perhaps you’re writing a script that places a file on multiple, remote. Perhaps it’s some configuration file meant for another application. You want to copy this file to a variable number of servers in the same location. Since you need to perform the same task multiple times (on multiple servers), this would be a great case for a function with a single goal, getting a file reliably on a server.

When you build a function with a single goal, managing many functions becomes a lot easier over time. In this example, check out the function in the code snippet in the following called Copy-ConfigurationFile. This function does one “thing,” copies a file to a server. However, notice the ServerName parameter is using string[]] as the type. This allows you to pass in multiple server names at once. Then, using the foreach loop, you can copy that configuration file to many servers with one function call. Overall though, the function still has one purpose and one purpose only.
function Copy-ConfigurationFile {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$FilePath,
        [Parameter(Mandatory)]
        [string[]]$ServerName
    )
    foreach ($server in $ServerName) {
        if (Test-Connection -ComputerName $server -Quiet -Count 1) {
            Copy-Item -Path $FilePath -Destination "\$serverc$"
        } else {
            Write-Warning "The server [$server] is offline. Unable to copy file."
        }
    }
}

Tip Source: https://twitter.com/pgroene

Further Learning

Build Functions with Pipeline Support

PowerShell wouldn’t be PowerShell without the pipeline. Be a good PowerShell citizen and include pipeline support in your functions. Passing command output to other commands via the pipeline is an intuitive way to run functions. It’s also easier for newcomers to understand.

When you build functions with pipeline support, your function can begin “linking” your functions to other PowerShell commands. You can run functions simply by piping output from one command to another.

For example, let’s say you’re building a tool to help you back up and restore a set of important files that some third-party line-of-business application uses. When this software is installed on a user’s computer, it creates a directory called *C:Files. This folder contains crucial files that must get backed up on a regular basis. You decide to create a module with a couple of functions called Start-AppBackup to kick off the backup, Get-AppBackup to pull the set of files from a backup server somewhere, and Restore-AppBackup to put the files back on a machine. Your little module looks like this:
function Start-AppBackup {
    param(
        [Parameter()]
        [string]$ComputerName,
        [Parameter()]
        [string]$BackupLocation = '\MYBACKUPSERVERBackups'
    )
    Copy-Item -Path "\$ComputerNamec$Program FilesSomeAppDatabase*" -Destination "$BackupLocation$ComputerName"
}
function Restore-AppBackup {
    param(
        [Parameter(Mandatory)]
        [string]$ComputerName,
        [Parameter()]
        [string]$BackupLocation = '\MYBACKUPSERVERBackups'
    )
    Copy-Item -Path "$BackupLocation$ComputerName*" -Destination "\$ComputerNamec$Program FilesSomeAppDatabase"
}
Now, let’s say you’re using this tool as is without pipeline support. You would run each function above like this:
Start-AppBackup -ComputerName FOO
Restore-AppBackup -ComputerName FOO
This appears to be fine but does require two lines. Add in pipeline support and you may get:
function Start-AppBackup {
    param(
        [Parameter()]
        [string]$ComputerName,
        [Parameter()]
        [string]$BackupLocation = '\MYBACKUPSERVERBackups'
    )
    Copy-Item -Path "\$ComputerNamec$Program FilesSomeAppDatabase*" -Destination "$BackupLocation$ComputerName"
}
function Get-AppBackup {
    param(
        [Parameter(Mandatory)]
        [string]$ComputerName,
        [Parameter()]
        [string]$BackupLocation = '\MYBACKUPSERVERBackups'
    )
    [pscustomobject]@{
        'ComputerName' = $ComputerName
        'Backup'       = (Get-ChildItem -Path "\$BackupLocation$ComputerName")
    }
}
function Restore-AppBackup {
    param(
        [Parameter(Mandatory,ValueFromPipelineByPropertyName)]
        [string]$ComputerName ,
        [Parameter()]
        [string]$BackupLocation = '\MYBACKUPSERVERBackups'
    )
    Copy-Item -Path "$BackupLocation$ComputerName*" -Destination "\$ComputerNamec$Program FilesSomeAppDatabase"
}
You can then easily find existing backups and restore them by using the pipeline using a single line. This method is also a little easier to understand.
Get-AppBackup -ComputerName FOO | Restore-AppBackup

Further Learning

Save Commonly Used, Interactive Functions to Your User Profile

If you’re working at the PowerShell console interactively, it’s always handy to have a function created and available as a shortcut to performing a certain task. Think about all of the common tasks you perform while working in the PowerShell console.

To ensure these “console” functions are available to you across all sessions, add them to your PowerShell profile. This will allow you to always have them available.

For example, maybe you have a handy function that changes what your PowerShell prompt looks like. The default is PS [working directory]> but you have your own prompt function that makes it look like PS>. You’re tired of seeing the working directory. Your function looks like this:
function prompt { 'PS>' }
When you close out of the current PowerShell console though, the default prompt is back. You need to add it to your profile. To do that, first figure out where PowerShell stores your user profile.
$Profile

Once you find the path to your profile script, create or edit that file and then place your function inside. Restart your console and you’ll see the prompt gets changed every time. PowerShell reads this profile every time it starts up allowing you to keep persistent settings.

Tip Source: https://www.reddit.com/user/TheDinosaurSmuggler/

Further Learning

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.21.12.100