I've written a bunch of classes that reach out to an API and get JSON. When compiled, I get nice commands like get-host, get-version, get-app, etc.
each cmdlet takes an argument like -host or -app.
I've got about 160 of these that I can write but I'm now looking to write a more generic cmdlet that can accept arbitrary parameters and values.
From what I can see, I can't declare parameters as such where i can issue
get-info -app "appname"
or
get-info -host "hostname"
or
get-info -version "5.5"
unless i declare all the parameters of which there could be hundreds. Also, if the parameter is not declared, it throws a nice error
Get-Info : A parameter cannot be found that matches parameter name 'host'.
Is there a way I can not declare any parameters and then parse the arguments manually or is there a something in c# to automatically parse the list of arguments and then assign them to variables named appropriately?
for example
get-info -host "hostname" -backup "backupid"
and the variables host and backup would be set automatically?
Accept your arbitrary parameters as a HashTable:
get-mydata #{ Host = "hostname"; version = "1.0" }
That is how most of the built-in cmdlets handle arbitrary KVPs.
Related
I'm referencing c# resource strings from my template (which uses $ as delimiters). I'm doing so by passing in as one of the arguments to the template the object "strings", which is a c# ResourceManager. The formatString is expected to be the name of the resource desired. This allows me to put in my template for example:
<Name>$strings;format="ItemName"$</Name>
The only issue with this solution is, there are times I want something from my object tree to help build the name of the resource string to look up. For example, a generic lookup for a localized value for an enum could be provided with:
<Type>$strings;format="ItemType$myItem.Type$"$</Type>
However - when I attempt to call the renderer this way, if I use the above syntax, the myItem.Type is not resolved into its value, and instead passed directly as part of the string, so I get the value "ItemType$myItem.Type$" rather than say, "ItemTypeBicycle".
If I don't place quotes around it however, such as:
<Type>$strings;format=ItemType$myItem.Type$$</Type>
I get a compile-time error that this "doesn't look like an expresson"
Is there another syntax I'm missing, or are you not able to resolve something that is then passed as a string like this?
I received a WSDL from a customer and created a proxy class that I can use in .NET. The WSDL contains one call with a large number of parameters.
In my code, I collect data from entities in Microsoft CRM. Some of the fields in the entities are mandatory and others are not. The result is that I can retrieve an entity with missing (non-mandatory) fields that I have to send through the SOAP interface.
The generated proxy class contains the signature of the method with the large number of parameters. When I call the method with a reference type parameter that is "null", it works just fine. Sometimes a value type parameter is "null" (not returned in the entity). I can't call the generated method in the proxy class because the (value type) parameters of the method in the proxy are not nullable.
Is it possible to use nullable types (bool?, long?) on the .NET side that will result in '< s:element minOccurs="0"' attributes on the SOAP side?
My problem is not solved with the answer from this question: Can I have an optional parameter for an ASP.NET SOAP web service
That question relates to one optional parameter. That can be solved with overloads. In my case, the signature has more than 30 parameters and 7 of them are value types that sometimes have no value. If I implement that with overloads, I need 128 overloaded methods to match all combinations.
I tried to make the parameters optional in the proxy class:
long accountCountry,
[System.Xml.Serialization.XmlElementAttribute(IsNullable = true)]long? accountLegalForm,
string accountName,
This resulted in an System.InvalidOperationException "Method xxx can not be reflected." with an inner exception "There was an error reflecting 'accountLegalForm'."
I have written a C# Tool where i can enter script parameters with an GUI which is generated based on the parmeter definitions of the script.
Now i want to have a dropdown list which offers me a dynamically generated set of values. The informations for this dropdown list should come from the parameter definition of the script.
(In my case i want to select an existing AD OU by Listing all Child-Objects of the Base OU.)
One way to get a list of valid parameters is to use "ValidateSet" for Parameter definition. There is abway to get te ValidateSet from the Script an build the dropdown list. But ValidateSet is a static deffinition and i have to update the script each time the list should be changed.
A good way for dynamic validation is "ValidateScript". The script command would be something like Test-Path. This would work for validation, but for my GUI i would not be able to generate a list of valid values.
Maby i can dynamically generate a custom enum type and use it as parameter type. A dropdown list for enum types is already implemented for GUI.
But i think i's not a good idea and may not work to generate a enum type dynamically.
So, any other ideas for a list of valid values which is dynamically built?
I tried doing that with an enum once, and it got problematic due to differences in the valid character sets between enum values and AD names.
If you've wanting to keep the GUI separate from the script, you might investigate using AST to extract the parameter validation code from the script, and then run it outside the script to build your list.
You can use a dynamic parameter in you Powershell script.
A good example a of a ValidateSet parameter attribute dynamically generated from a scriptblock and added to a dynamic parameter can be found here :
http://blogs.technet.com/b/pstips/archive/2014/06/10/dynamic-validateset-in-a-dynamic-parameter.aspx
DynamicParam works well for PowerShell.exe.
But i have Problems to read the ValidateSet with C# Program.
Here is the Code i use:
InitialSessionState initial = InitialSessionState.CreateDefault();
initial.ImportPSModule(new string[] { #"C:\Users\kritzinger\OneDrive\Test-DynamicValidateSet.psm1" });
Runspace runspace = RunspaceFactory.CreateRunspace(initial);
runspace.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;
ps.Commands.AddCommand("Get-Command").AddArgument("Test-DynamicValidateSet").AddParameter("ArgumentList", "Path");
Collection<PSObject> get_Command = ps.Invoke();
PSObject command = get_Command[0];
Dictionary<String, ParameterMetadata> parameters = command.Properties["parameters"].Value as Dictionary<String, ParameterMetadata>;
At the last line i get the following Exception when i try to access the Value:
An unhandled exception of type
'System.Management.Automation.GetValueInvocationException' occurred in
System.Management.Automation.dll
Additional information: Exception getting "Parameters": "Cannot
retrieve the dynamic parameters for the cmdlet. The pipeline has been
stopped."
I get the same Exeption when i try to access the Value in VisualStudio Watch window.
With a static ValidateSet deffinition the c# code works well.
Apologies if I've framed the question incorrectly but I'm not sure where it fits in exactly.
I am executing a powershell script from C# which returns a collection of type PSObject. The data I want is contained in the field BaseObject and when debugging it tells me its type is (PowerShellInside.NetCmdlets.Commands.MessageInfoObject) and I can see all the information there. So my question is assuming that a 3rd party vendor assembly is not available to be referenced, what is the correct approach to retrieving data from this object say
(PowerShellInside.NetCmdlets.Commands.MessageInfoObject).Subject
Do you create your own version of this class omitting what you dont need or is there some neat dynamic typing that can be done.
I'm not a POSH developer so I'll take this from the C# angle.
I'll assume PSObject is the equivalent of System.Object and MessageInfoObject is the type returned from the script... I'd say using something like the following should work:
dynamic msgInfo = ExecutePOSHScript(...);
i was wondering, can a parameter be used more then once in the same query, like this :
MySqlParameter oPar0 = new MySqlParameter("e164", MySqlDbType.String);
oPar0.Value = user.E164;
string sSQL0 = "Delete from callmone.call where (caller=?e164 or called=?e164);";
clsDatabase.ExecuteSQL(sSQL0, oPar0);
Is this possible or should i write 2 parameters?
If the database driver handles named parameters, then you can reuse the parameter.
If the database driver doesn't handle named parameters, the parameter names are ignored and you have to add one parameter values for each use, in the exact order that they are used.
From the code that you presented it looks like the driver supports named parameters. If the code runs without an error, it works. If the driver would not support names parameters, the code would cause an error as there is only one parameter value.
I don't know of any reason why you can't do that.