0

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?

  • 1
    PowerShell does not expect the parameter arguments as a comma-separated list. Change the call from `$result = createVssSnapshot("C:\", "C:\vssSnapshot", $false)` to `$result = createVssSnapshot "C:\" "C:\vssSnapshot" -openSnapshotAfter:$false` – Mathias R. Jessen Dec 28 '21 at 09:41
  • In short: PowerShell functions, cmdlets, scripts, and external programs must be invoked _like shell commands_ - `foo arg1 arg2` - _not_ like C# methods - `foo('arg1', 'arg2')`. If you use `,` to separate arguments, you'll construct an _array_ that a command sees as a _single argument_. See [this answer](https://stackoverflow.com/a/65208621/45375) for more information. – mklement0 Dec 28 '21 at 14:07

1 Answers1

2

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
  )

  # ...
}
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206