Select file on Import-Csv

后端 未结 3 1677
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-07 13:31

The code below is part of a switch and it\'s working fine, but the problem is: I need to change my file name to 15... Is it possible to to change it so that when I start it,

3条回答
  •  走了就别回头了
    2021-01-07 13:48

    The simplest solution is to make your script accept the target file as an argument, by declaring a parameter:

    param(
      # Declare a mandatory parameter to which the file path of the CSV
      # file to import must be passed as an argument on invocation.
      [Parameter(Mandatory)]
      [string] $FilePath
    )
    
    $names = Import-Csv $FilePath -Header Givenname,Surname -Delimiter ";"
    foreach ($Name in $Names) {
        $FirstFilter = $Name.Givenname
        $SecondFilter = $Name.Surname
        Get-ADUser -Filter {GivenName -like $FirstFilter -and Surname -like $SecondFilter} |
            select Enabled, SamAccountName, DistinguishedName,
                @{n="ou";e={($_.DistinguishedName -split ",*..=")[2]}} |
            Export-Csv .\sam.csv -NoTypeInformation -Append
    }
    

    If you invoke your script without a file path, you will be prompted for it; let's assume your script is located in the current dir. and its name is someScript.ps1:

    ./someScript    # invocation with no argument prompts for a value for $FilePath
    

    Unfortunately, such an automatic prompt is not user-friendly and offers no tab completion.

    However, on the command line PowerShell's tab completion defaults to completing file and directory names in the current location, so that:

    ./someScript 
    

    cycles through all files and directories in the current folder.

    You can even type a wildcard expression and tab-complete that, if you don't know the full filename or don't want to type it in full:

    ./someScript *.csv
    

    This will cycle through all *.csv files in the current dir. only.

    If you want to go even further and customize tab completion to only cycle through *.csv files, you can use an [ArgumentCompleter({ ... })] attribute (PSv5+):

    param(
      [Parameter(Mandatory)]
      # Implement custom tab-completion based on only the *.csv files in the current dir.  
      [ArgumentCompleter({
        param($cmd, $param, $wordToComplete)
        Get-ChildItem -Name "$wordToComplete*.csv"
      })]
      [string] $FilePath
    )
    
    # ...
    

    Now,

    ./someScript 
    

    will cycle only through the *.csv files in the current directory, if any.

    Caveat: As of PowerShell 7.0, tab-completing an argument for which the ArgumentCompleter script block returns no matches (in this case, with no *.csv files present) unexpectedly falls back to the default file- and directory-name completion - see this GitHub issue.

    Similarly,

    ./someScript 1
    

    will cycle only through the *.csv files in the current directory whose name starts with 1, if any.


    As an alternative to using an attribute as part of a script's / function's definition, you can use the PSv5+ Register-ArgumentCompleter cmdlet to attach tab completions to the parameters of any command, i.e., including preexisting ones.


    In PSv4- you have two (cumbersome) options for custom tab completion:

    • Use a dynamic parameter with a dynamically constructed [ValidateSet()] attribute - see the link in Rohin Sidharth's answer.

    • Customize the tabexpansion2 (PSv3, PSv4) / tabexpansion (PSv1, PSv2) function, but be sure not to accidentally replace existing functionality.

提交回复
热议问题