Powershell hashtables as argument to custom cmdlet in C#

自古美人都是妖i 提交于 2019-12-11 12:12:20

问题


Ive been using a custom class for some time like this in PS (2.0):

import-module .\MyClassLib.dll

$task = New-Object MyClassLib.OracleScript -Property @{
                                                            Files="MyScript.sql" 
                                                            Database="TEST"
                                                            User="USER" 
                                                            Password="PASSWORD"  
                                                        }
$result = $task.Execute()

And this works just fine.

However i wanted to create a CmdLet in C# to do the work instead. So after creating the cmdlet i thought I could do one of the following:

Invoke-OracleScript @{
                            Files="Script.sql" 
                            Database="db"
                            User="user" 
                            Password="password"  
                           }

Invoke-OracleScript @{
                            Files="Script.sql"; 
                            Database="db";
                            User="user"; 
                            Password="password";  
                           }

Invoke-OracleScript -Property @{
                            Files="Script.sql"
                            Database="db"
                            User="user"
                            Password="password"  
                           }

But no luck. :(.

I keep getting errors like:

  • Cannot find the file System.Collections.Hashtable ( it thinks the entire hashtable is the Files parameter)
  • A parameter cannot be found that matches parameter name 'Property'
  • And a couple more.

My Class:

[Cmdlet(VerbsLifecycle.Invoke, "OracleScript", ConfirmImpact = ConfirmImpact.High, SupportsShouldProcess = true, SupportsTransactions = false)]
public class Invoke_OracleScript : Cmdlet, IOracleScript
{
    [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
    public string Files { get; set; }

    [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
    public string Database { get; set; }
    ....

If I instead use parameters like this: -Files "" -Database "", it works just fine, but everything has to be on 1 line which is very bad for reading. So the hashtable is really my biggest wish :).

Can anyone explain to me what im missing here? (ParameterSets?, a secret attribute i've been unable to find in the docs, other)

Kind regards


回答1:


If all you care is to make the cmdlet call to be in multiple lines, you can use backtick (`) to extend the command to the next line:

get-process -Name notepad `
            -Computername localhost `
            -Verbose

Or, you can create custom object:

$process = new-object psobject
$process | add-member -name name -value notepad -type noteproperty
$process | add-member -name computername -value localhost -type noteproperty
$process | get-process

Or, what you were doing:

$process = new-object psobject -property @{ name="notepad";
                                            computername = "localhost";}

$process | get-process

I think hashtable as objects was a feature that was added in v3.0 ( currently in CTP)




回答2:


You might want to take a look at a feature of PowerShell called Splatting. By default, a Cmdlet can take all its parameters and their values as a hashtable and you can pass that hash in as a param.

Function Add-ThreeNumbers {
param ($a,$b,$c)
$a + $b + $c
}

$params = @{a=10; b=15; c = 20}

Add-ThreeNumbers @params


来源:https://stackoverflow.com/questions/8144477/powershell-hashtables-as-argument-to-custom-cmdlet-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!