Using cmdlet dynamically

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.

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.

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}

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

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. :slight_smile:

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!

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.

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”.