Search code examples
functionpowershellargumentsvisual-sourcesafe

Passing arguments to a function


I found this link for creating vss Shadow copies under Windows. But the code uses fixed strings for the parameters:

function createVssSnapshot{
[cmdletbinding()]
param(
    [string]$targetVolume="C:\",
    [string]$accessPath='C:\vssSnapshot',
    [bool]$openSnapshotAfter=$true
)
[..]

I'd like to modify it in order to be more flexible:

function [String]createVssSnapshot{
[cmdletbinding()]
param(
    [String]$targetVolume,
    [String]$accessPath,
    [Bool]$openSnapshotAfter
)
[..]

and call it using

$result = createVssSnapshot("C:\", "C:\vssSnapshot", $false)

But I get the following error:

createVssSnapshot : Die Argumenttransformation für den Parameter "targetVolume" kann nicht verarbeitet werden. Der Wert kann nicht in den Typ "System.String" konvertiert werden.
In F:\Powershell_4_Pure\Object_based.ps1:143 Zeichen:28
+ $result = createVssSnapshot("C:\", "C:\vssSnapshot", $false)
+                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidData: (:) [createVssSnapshot], ParameterBindingArgumentTransformationException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,createVssSnapshot

Sorry for German error message, but it seems targetVolume isn't of type System.String.

What am I missing here?

For future questions: How can I modify PowerShell ISE to have english error messages?


Solution

  • In PowerShell, parameter arguments are passed to command by name or position, but arguments for separate parameters are NOT separated by comma (unlike many C-like languages).

    The correct way to pass the arguments shown would be:

    $result = createVssSnapshot "C:\" "C:\vssSnapshot" -openSnapshotAfter:$false
    

    I'd strongly suggest changing the type constraint on the $openSnapshotAfter parameter to a [switch] instead of a [bool] - it will always default to $false and you can then specify it by just doing -openSnapshotAfter instead of -openSnapshotAfter:$true.

    Since you'll no longer be providing default values for the first 2 parameters, I'd also recommend marking those Mandatory - this way PowerShell will refuse to een attempt executing your function if the caller doesn't pass arguments for those:

    function New-VssSnapshot {
      [CmdletBinding()]
      param(
        [Parameter(Mandatory)]
        [string]$TargetVolume,
    
        [Parameter(Mandatory)]
        [string]$AccessPath,
    
        [switch]$OpenSnapshotAfter
      )
    
      # ...
    }