Using cmdlet dynamically

This topic contains 7 replies, has 5 voices, and was last updated by Profile photo of Peter Jurgens Peter Jurgens 2 years, 5 months ago.

  • Author
    Posts
  • #16667
    Profile photo of Corey Thomas
    Corey Thomas
    Participant

    Question:
    I'm writing some code that will take in options from the user and execute a cmdlet. I'm then taking that output and binding to a datagrid. How do I take all the parameters options and build a single cmdlet statement dynamically?

    I was hoping I could bind an object to a cmdlet, set it's parameters using dot notation, then execute it.

  • #16668
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Is the code that's doing all of this work PowerShell, or C#? If you're doing this in .NET code, then what you've described could work (creating an instance of a cmdlet, etc.)

    If it's PowerShell, then just build a hashtable and splat it to the cmdlet.

  • #16670
    Profile photo of Corey Thomas
    Corey Thomas
    Participant

    It's all powershell. For example, Get-Eventlog

    I can pass -EntryType Error,Warning and only get Errors and Warnings. Error,Warning cannot be a string so I'm finding it difficult to account for that using variables.

    There are other parameters as well like the event ID or event message. Those work fine with strings, but I'm still wondering how I can build my cmdlet line using logic.

    For example: If an event ID is supplied, include something like this when I execute the cmdlet:

    | where {$_.EventId -eq 1309}

  • #16675
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Well, Where-Object is a different cmdlet, and if you're talking about building a whole pipeline dynamically, things might get more complicated.

    If you have a string that is "Error, Warning" and want to pass that to the cmdlet, you'd just split the string to form an array that the cmdlet can handle:

    $userEntryType = 'Error, Warning'
    $userMessage = 'Some Message'
    
    $params = @{}
    
    if ($userEntryType) {
        $params['EntryType'] = $userEntryType -split '\s*,\s*'
    }
    
    if ($userMessage) {
        $params['Message'] = $userMessage
    }
    
    # and so on for other parameters you might pass to Get-EventLog
    
    Get-EventLog @params
    
  • #16678
    Profile photo of Corey Thomas
    Corey Thomas
    Participant

    AH! $params may be the key! Thanks Dave!

    BTW, I solved that Error,Warning issue. Apparently strings are fine, but I was doing "Error,Warning", not "Error","Warning". Doh! And the coolest part is that I can build that into an array and pass that. 🙂

  • #16685

    Hi!

    Just to clarify, the name of the variable holding the hashtable is irrelevant. It could be

    
    $x = @{}
    # code to load up paramets in $x
    
    Some-Command @x
    

    $params just makes the intended use more clear.

    Cheers!

  • #16714
    Profile photo of Martin Nielsen
    Martin Nielsen
    Participant
    function Get-Drink {
        [CmdletBinding()]
        param(
            [ValidateSet("Lemonade","Water","Tea","Coffee")]
            $Drink
        )
    
        Write-Verbose @($Drink).Count
        $Drink
    }
    
    PS C:\Users\mni> Get-Drink -Drink Coffee,Water,Lemonade -Verbose
    VERBOSE: 3
    Coffee
    Water
    Lemonade
    

    This is how Get-EventLog does its fancy parameters that aren't strings.

    But if you're looking to extend the functionality of existing Cmdlets, perhaps you should look into proxy functions instead of recreating them from scratch.

    I found a post by some guy called Don Jones explaining how to do it: http://windowsitpro.com/blog/powershell-proxy-functions

    Though I have to admit I don't know if there have been any improvements to the process since 2011.

  • #16751
    Profile photo of Peter Jurgens
    Peter Jurgens
    Participant

    Well, the cmdlet does that for you already though... If you don't need to use a parameter on some cmdlet, then don't use it. I don't see much reason for a PowerShell "wrapper".

You must be logged in to reply to this topic.