Select file on Import-Csv

后端 未结 3 1678
佛祖请我去吃肉
佛祖请我去吃肉 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 <press tab here>
    

    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<press tab here>
    

    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 <tab>
    

    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<tab>
    

    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.

    0 讨论(0)
  • 2021-01-07 13:55

    Below is my example.ps1 file that I use to write 1-off scripts. In your case I think you can get what you want with it. For example (no pun intended) you could call this script by typing

    C:\PathToYourScripts\example.ps1 [tab]
    

    where [tab] represents pressing the tab key. Powershell intellisense will kick in and offer autocompletion for file names. If your .csv file is not in the current director you can easily use Powershell intellisense to help you find it

    C:\PathToYourScripts\example.ps1  C:\PathToCSvFiles[tab]
    

    and powershell will autocomplete. Would-be-downvoters might notice that powershell autocomplete is definitely NOT a complete file-picker but this seems to fulfill the intent of the asked question. Here's the sample.

    <#
    .NOTES
        this is an example script
    .SYNOPSIS
        this is an example script
    .DESCRIPTION
        this is an example script
    
    .Example
        this is an example script
    .LINK
        https://my/_git/GitDrive
    #>
    [CmdletBinding(SupportsShouldProcess=$True, ConfirmImpact="Low")]
    param (
          [string] $fileName
    )
    Begin {
    }
    
    Process {
        if ($PSCmdlet.ShouldProcess("Simulated execution to process $($fileName):  Omit -Whatif to process ")) {
           Write-Information -Message "Processing $fileName" -InformationAction Continue
        }
    }
    
    End {
    }
    

    If you want to get autocomplete help for multiple parameters just type in the parameter name(s) and press [tab] after each one. Note that leaving the parameters blank will not break the script but you can either extend this to mark the parameters required or just fail with a helpful message. That seems a bit beyond the original question so I'll stop here.

    0 讨论(0)
  • 2021-01-07 14:04

    So you want Intellisense in your script. Ambitious move. Most people would settle for the file browser dialog box. Anyway, I am going to have to refer you to smarter men than me. I was thinking ValidateSet attribute would serve your purpose but I realized that the traditional param block is not enough. So I looked up DynamicParams and this is what I found. This should work for you.

    https://blogs.technet.microsoft.com/pstips/2014/06/09/dynamic-validateset-in-a-dynamic-parameter/

    0 讨论(0)
提交回复
热议问题