问题
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