As I work a lot with PowerShell to support data migrations for a variety of scenarios, I need to be flexible in providing parameters for certain cmdlets. Parameter sets and splatting provides this flexibility by adding parameters and values conditionally.

Data migrations to Microsoft 365 usually follow typical patterns like importing a folder or folder contents from a file share to Microsoft Teams. To support this, you don’t want to have redundant functions in PowerShell. Instead, you can define the basic and conditional parameters and values in a splat.
Depending on the scenario, the splat may contain the parameter to import a folder or the folder contents.

The basic setup

Let’s explain the setup by the (simplified) parameter part of an example function that is based on the use of ShareGate for importing files to SharePoint Online or OneDrive for Business (Import-Document):

function Start-SGFilesImport {
    [CmdletBinding(DefaultParameterSetName = 'All')]
    param (
        [Parameter(Mandatory = $true)]
        $list,
        [Parameter(Mandatory = $true, ParameterSetName = 'sourceItems')]
        [array]$sourceItems,
        [Parameter(Mandatory = $true, ParameterSetName = 'sourceFolder')]
        [string]$sourceFolder,
        [Parameter(Mandatory = $false)]
        $userMapping,
        [Parameter(Mandatory = $false)]
        $copySettings,
        [Parameter(Mandatory = $false)]
        $propertyTemplate,
        [Parameter(Mandatory = $false)]
        [switch]$whatIf)

}

Parameter sets

The parameter section used a default parameter set called ‘All’. By default, all parameters are part of this set. Except for the $sourceItems and $sourceFolder parameters. These are part of different parameter sets. So if the parameter $sourceItems in provided, the $sourceFolder is not used to avoid double input of sources which is not intended.

The parameters include support for two distinct scenarios:

  • $sourceItems – Importing the contents of a folder;
  • $sourceFolder – Importing a folder and the underlying contents.

So, depending on how the PowerShell script calls this function, it may contain either one of these parameters.

Creating the splat

To provide the ShareGate Import-Document cmdlet with the set of parameters based on the parameter input of the Start-SGFilesImport function, a basic parameter splat is created. In short, this is a basic key-value pair table that is fed into the cmdlet.

There are always mandatory and common parameters that can be defined in the table:

 #Set the request parameters
 $requestParams = @{
        ErrorAction             = 'Stop'
        DestinationList         = $list
        InsaneMode              = $true
        WaitForImportCompletion = $true
}

For example, when calling the cmdlet and an unhandled error occurs, the ‘ErrorAction’ would be ‘Stop’. Furthermore, a migration is always performed into a list-object ($list). This object is generated by the ShareGate Get-List cmdlet which uses the output of the ShareGate Connect-Site cmdlet as input.

Apart from these mandatory or basic parameters, there are the ones that are conditional depending on the parameter set and if the parameters are used when calling the function.

So as there are conditional, they can be added to the splat conditionally.

    #Add additional parameters based on input
    if ($sourceItems) {
        $requestParams.Add('SourceFilePath', $sourceItems)
    }
    if ($sourceFolder) {
        $requestParams.Add('SourceFolder', $sourceFolder)
    }
    if ($destinationFolder) {
        $requestParams.Add('DestinationFolder', $destinationFolder)
    }
    if ($userMapping) {
        $requestParams.Add('MappingSettings', $userMapping)
    }
    if ($copySetings) {
        $requestParams.Add('CopySettings', $copySettings)
    }
    if ($whatif) {
        $requestParams.Add('WhatIf', $true)
    }

In the example above, the $sourceItems are added to the splat, if the parameter is used when calling the function. and that depends on the used parameter set.

The ‘CopySettings’ key is added with a value, only if the $copySettings value is available in the function. As this is not a mandatory parameter, it could also be not be used when calling the function. The same applies to the ‘MappingSettings’.

The ‘WhatIf’ is different as it is a switch type parameter. So if the switch is used when calling the function, the key is added and the value is set to $true. In the context of using the ‘Import-Document’ cmdlet. the switch will tell it to not actually migrate the data, but perform a pre-check instead. Always handy to have this available to test a migration end-to-end in an early stage.

Calling the cmdlet

So having defined the $requestParams table dynamically, it can now be used to call the ‘Import-Document’ cmdlet for which the function was designed to work with.

Import-Document @requestParams

When outputting $requestParams after it has been defined with keys and populated with values, the result is something like the following:

Name                           Value
----                           -----
WaitForImportCompletion        True
InsaneMode                     True
SourceFilePath                 {file:///U://HomeDrive/AdeleVance/January, ...}
ErrorAction                    Stop
MappingSettings                Sharegate.Automation.Entities.Mappings.MappingSettings

The SourceFilePath key is an array type with, in this case, multiple source locations.

So by using the parameter splat, the actual execution of the cmdlet is super simple and dynamic. Notice the @- instead of the $-sign when executing the cmdlet.

Obviously the concept of parameter sets and splatting is generic. So it can be used in whatever you want to achieve in a consistent way.

Enjoy scripting to automate data migrations and other stuff!!