I am trying to pass a string from my c# app to my powershell script .
I keep geting an error:"A positional parameter cannot be found that accepts argument '$null'
what should I do?
my c# code:
public void PowerShell()
{
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
String scriptfile = #"c:\test.ps1";
Command myCommand = new Command(scriptfile, false);
CommandParameter testParam = new CommandParameter("username", "serverName");
myCommand.Parameters.Add(testParam);
pipeline.Commands.Add(myCommand);
Collection<PSObject> psObjects;
psObjects = pipeline.Invoke(); <---error- "A positional parameter cannot be found that accepts argument '$null'"
runspace.Close();
}
my powershell code:
Out-Host $username
Your PS script have no parameters, it simply uses variable. So, try this instead:
Param($username)
Write-Output $username
Please, notice that Out-Host is not acceptable in you case, because it tries to output param to calling scope, not simply write something to output stream.
Also, you can set variable in runspace, so it will be available in script without params:
runspace.SessionStateProxy.SetVariable("username", "SomeUser");
(it must be done after runspace.Open() and before pipeline.Invoke())
Related
I've been trying to enable RabbitMQ management plugin using C# code.
I was successfully able to install RabbitMQ server using c# by using following code.
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
Command myCommand = new Command("Start-Process");
CommandParameter testParam = new CommandParameter("FilePath", #"C:\Users\saadp\Desktop\Dependencies\rabbitmq-server-3.8.3.exe");
CommandParameter testParam2 = new CommandParameter("ArgumentList", new string[] { "/S" });
CommandParameter testParam3 = new CommandParameter("Wait");
myCommand.Parameters.Add(testParam);
myCommand.Parameters.Add(testParam2);
myCommand.Parameters.Add(testParam3);
pipeline.Commands.Add(myCommand);
var results = pipeline.Invoke();
But, When I try to enable RabbitMQ management plugin using following CommandParameters, It doesn't affect anything. What actually happens is after executing this code new Command Prompt opens and closes in a matter of fraction.
Here is the code which I've tried.
CommandParameter testParam = new CommandParameter("FilePath", #"""C:\Program Files\RabbitMQ Server\rabbitmq_server-3.8.3\sbin\rabbitmq-plugins.bat""");
CommandParameter testParam2 = new CommandParameter("ArgumentList", new string[] { "'enable rabbitmq_management'" });
CommandParameter testParam3 = new CommandParameter("Wait");
I got this working by following this code.
private static string RunScript(string scriptText)
{
// create Powershell runspace
Runspace runspace = RunspaceFactory.CreateRunspace();
// open it
runspace.Open();
// create a pipeline and feed it the script text
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(scriptText);
// add an extra command to transform the script
// output objects into nicely formatted strings
// remove this line to get the actual objects
// that the script returns. For example, the script
// "Get-Process" returns a collection
// of System.Diagnostics.Process instances.
pipeline.Commands.Add("Out-String");
// execute the script
pipeline.Invoke();
// close the runspace
runspace.Close();
}
Try this:
var startInfo =
new ProcessStartInfo
{
FileName = #"C:\Windows\System32\cmd.exe",
Arguments = "/c rabbitmq-plugins enable rabbitmq_management",
WorkingDirectory = #"C:\Program Files\RabbitMQ Server\rabbitmq_server-3.7.11\sbin",
WindowStyle = ProcessWindowStyle.Maximized
};
Process.Start(startInfo)?.WaitForExit();
Process.Start("net", "stop RabbitMQ")?.WaitForExit();
Process.Start("net", "start RabbitMQ")?.WaitForExit();
How to call power shell script file by passing attributes in c#.
I'm using below code to call ps1 file by passing inputs but getting error near invoke.
error message:
System.Management.Automation.CommandNotFoundException: 'The term
'Get-Childitem C:\samplemm.ps1' is not recognized as the name of
a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path
is correct and try again.'
namespace SCOMWebAPI.Services
{
public class MaintennceModeService
{
private static IEnumerable<PSObject> results;
internal static string post(MaintenanceMode value)
{
// create Powershell runspace
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
//Here's how you add a new script with arguments
Command myCommand = new Command("Get-Childitem C:\\samplemm.ps1");
CommandParameter testParam = new CommandParameter("mgmtserver", "NodeName");
myCommand.Parameters.Add(testParam);
pipeline.Commands.Add(myCommand);
// Execute PowerShell script
results = pipeline.Invoke();
runspace.Close();
// convert the script result into a single string
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
return stringBuilder.ToString();
}
}
}
When you type the command Get-ChildItem C:\\samplemm.ps1 into powershell, you are actually binding the text C:\\samplemm.ps1 to the default parameter Path.
The problem with your code is that you have included the first parameter as part of the command name. Simply separate it out.
Instead of
Command myCommand = new Command("Get-Childitem C:\\samplemm.ps1");
Separate out the parameter:
Command myCommand = new Command("Get-Childitem");
CommandParameter pathParameter = new CommandParameter("Path", "C:\\samplemm.ps1");
myCommand.Parameters.Add(pathParameter);
I have some powershell scripts that I want to call from C#.
From the commandline I would do this:
Import-Module c:\provisioning\newModule.psm1 –Force
Get-MTMailbox -customerID custid0001
This works and gives the correct result.
I want to call my scripts from C#:
InitialSessionState initial = InitialSessionState.CreateDefault();
initial.ImportPSModule(new string[] { "C:\\provisioning\\newModule.psm1" });
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(initial);
runspace.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;
ps.AddCommand("Get-MTMailbox").AddArgument("-customerID custid0001");
// Also tried this. Still ignored.
//ps.AddParameter("-customerID", "custid0001");
ps.Invoke();
Collection<PSObject> results = ps.Invoke();
foreach (PSObject psObject in results)
{
Console.Write("Result: "+psObject.ToString());
if (psObject.BaseObject is System.Collections.Hashtable)
{
Hashtable ht = (Hashtable) psObject.BaseObject;
foreach (DictionaryEntry keypair in ht)
{
Console.WriteLine(keypair.Key+" "+keypair.Value);
}
}
}
The command runs, but my arguments are always ignored.
I'm very new to C# so maybe I don't know what to search for.
What's the correct way to pass arguments to a cmdlet in C#?
try with this:
ps.AddParameter("customerID", "custid0001");
You do not need the - to specify the argument name
I'm invoking a PowerShell script from C#, I'm using a hashtable to pass through parameters however when it comes to invoking the PowerShell script I get
A positional parameter cannot be found that accepts argument
The PowerShell script has two parameters. The hashtable has two keys with one value each. PowerShell script below:
param([string]$username,[string]$path)
#Gets SID
$objUser = New-Object System.Security.Principal.NTAccount($username)
$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
$SID = $strSID.Value
# delets user
net user $username /DELETE
# removes folder
rmdir /q $path
Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$SID"
C# that calls the PowerShell script:
class RunScript
{
public static void FireScript(String script, Hashtable var)
{
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
String scriptfile = "..\\..\\Resources\\" + script + ".ps1";
Command myCommand = new Command(scriptfile, false);
foreach (DictionaryEntry entry in var)
{
CommandParameter testParam = new CommandParameter(entry.Key.ToString(),entry.Value);
//CommandParameter testParam = new CommandParameter(null, entry.Value);
myCommand.Parameters.Add(testParam);
}
pipeline.Commands.Add(myCommand);
Collection<PSObject> psObjects;
psObjects = pipeline.Invoke();
runspace.Close();
}
}
Code that calls firescript:
Hashtable var = new Hashtable();
var.Add("username","testb");
var.Add("path", "C:\\Documents and Settings\\testb");
RunScript.FireScript("remove user",var);
I think that you need to set this parameter attribute: ValueFromPipeline which conform to this link represents an 'Optional named parameter. True indicates that the cmdlet parameter takes its value from a pipeline object. Specify this keyword if the cmdlet accesses the complete object, not just a property of the object. The default is false.'
You can check also check this link for some examples. The code could be like this:
param(
[parameter(Position=0, ValueFromPipeline=$true)][string]$username
[parameter(Position=1, ValueFromPipeline=$true)][string]$path
)
I'am tring to call a powershell script and pass through a parameter. I would all so like to pass through a more than one parameter eventually
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
String scriptfile = "..\\..\\Resources\\new group.ps1";
Command myCommand = new Command(scriptfile, false);
CommandParameter testParam = new CommandParameter("test3");
myCommand.Parameters.Add(testParam);
pipeline.Commands.Add(myCommand);
Collection<PSObject> psObjects;
psObjects = pipeline.Invoke();
runspace.Close();
The problem seems to be ... well nothing happens. Is this how to correctly assign the varibles? Giving test powershell script
# creates group
net localgroup $username /Add
# makes folder
#mkdir $path
This line of code:
CommandParameter testParam = new CommandParameter("test3");
Creates a parameter named test3 that has a value of null. I suspect you want to create a named parameter e.g.:
CommandParameter testParam = new CommandParameter("username", "test3");
And you're script needs to be configured to accept parameters e.g.:
--- Contents of 'new group.ps1 ---
param([string]$Username)
...
The PowerShell script needs to be setup to accept parameters:
Try adding the following to the top of that script and re-testing:
param([string]$username)
Alternatively, you could add the folowing line to the top of your script:
$username = $args[0]
Good luck.