Idiomatic parameter parameters for functions working with files and directories

If I wrote "idiomatic" PowerShell, what types of parameters would I use for functions that work with files or directories?

For example, I created a module containing this function:

$bookmarks = @{}
$bookmarkKeys = @{}

function Set-Bookmark {
    param(
        [Parameter(Mandatory = $true)]
        [string] $Id,
        [System.Management.Automation.DirectoryInfo] $Path = (Get-Location))
    $script:bookmarks[$Id] = $Path
    $script:bookmarkKeys[$Path.Path] = $Id
}

The problem is that the following does not work:

PS>Set-Bookmark -Id Code -Path C:\Code
Set-Bookmark : Cannot process argument transformation on parameter 'Path'.
Cannot convert the "C:\Code" value of type "System.String" to type
"System.Management.Automation.PathInfo".
At line:1 char:29
+ Set-Bookmark -Id Code -Path C:\Code
+                             ~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Set-Bookmark], ParameterBindingArgumentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Set-Bookmark

Oddly enough, this is not the case (but for a slightly different reason):

PS>Set-Bookmark -Id Code -Path (gi C:\Code)
Set-Bookmark : Cannot process argument transformation on parameter 'Path'.
Cannot convert the "C:\Code" value of type "System.IO.DirectoryInfo" to type
"System.Management.Automation.PathInfo".
At line:1 char:29
+ Set-Bookmark -Id Code -Path (gi C:\Code)
+                             ~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Set-Bookmark], ParameterBindingArgumentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Set-Bookmark

So, should I define my parameters as strings (i.e. the lowest common denominator) and then try to use / parse them in more meaningful types? It doesn’t sound like that, because it’s a shame if I work with the results of things like Get-Item, and they are transferred to stringfor transmission, only for this function, the type of level is again.

+4
3

, [IO.DirectoryInfo]. :

function t {
  param(
    [IO.DirectoryInfo] $d
  )
  "You passed $d"
}

t (Get-Item "C:\Windows")

[IO.FileInfo], .

+3

System.Management.Automation.PathInfo , System.Management.Automation.DirectoryInfo, TypeNotFound . System.Management.Automation DirectoryInfo. , @Bill_Stewart, System.IO.DirectoryInfo . PathInfo PowerShell, (, , cert registry ).

, (System.IO.FileInfo) (System.IO.DirectoryInfo), (, System.IO.FileSystemInfo):

function Set-Bookmark {
    Param(
        [Parameter(Mandatory=$true)]
        [string] $Id,
        [Parameter(Mandatory=$false)]
        [IO.FileSystemInfo]$Path = (Get-Location)
    )
    ...
}

System.String ( ):

function Set-Bookmark {
    Param(
        [Parameter(Mandatory=$true)]
        [string] $Id,
        [Parameter(Mandatory=$false)]
        [ValidateScript({Test-Path -LiteralPath $_})]
        [string]$Path = (Get-Location)
    )
    ...
}

, String -Path , . , IO.FileSystemInfo, (.. Set-Bookmark -Id 42 -Path "C:\some\path" ).

:

, . System.IO.FileSystemInfo. , System.String, () / .

+1

type string. PowerShell , . , , , Set-Bookmark . , :

$id = 0
Get-Content 'bookmarks.txt' | For-EachObject { Set-Bookmark -id $i++ -Path $_ } 

There is also the fact that you cannot always use a file provider, so assuming your Path always represents a file path will limit the usefulness of this function. If, say, you used a Microsoft SQL provider, you might need your function to provide bookmarks for paths in the SQL provider. (Your second solution using Test-Pathwill work.) Again, I don't know your target audience, but it's worth considering.

+1
source

All Articles