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);
Related
I am working on a simple SharePoint page that gets data from a dropdown and passes them to a PowerShell script as a parameter. But I get an error when debugging, and I found out that there are no parameters being passed to the script.
The script file is placed inside my layouts folder, with a structure like this:
Param($param1, $param2, $param3)
What I am doing from my C# code is I read the file using a StreamReader and then run the script using this code:
using (PowerShell powerShell = PowerShell.Create()) {
powerShell.Runspace.RunspaceConfiguration.AddPSSnapIn(_powershell,out snapInException);
powerShell.Commands.AddScript(the read script form streamreader);
powerShell.AddParameter("param1", SPContext.Current.Site.Url + "/");
powerShell.AddParameter("param2", selectedText1);
powerShell.AddParameter("param3", selectedText2);
try {
var results = powerShell.Invoke();
} catch (Exception exp) { }
}
I am getting an error that my parameters are null and I don't know why my parameters are not passing. Am I doing something wrong?
Also, I tried running the ps1 script using this one:
RunspaceConfiguration runspaceCOnfig = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceCOnfig);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
Command myCommand = new Command(script path);
CommandParameter param1 = new CommandParameter("param1", SPContext.Current.Site.Url + "/");
CommandParameter param2 = new CommandParameter("param2", selectedText1);
CommandParameter param3 = new CommandParameter("param3", selectedText2);
myCommand.Parameters.Add(param1);
myCommand.Parameters.Add(param2);
myCommand.Parameters.Add(param3);
pipeline.Commands.Add(myCommand);
and I get this error:
'path_to_script.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.
I want to execute some PowerShell script through C# but it requires admin privilege. This is my code (I got it here):
using (new Impersonator("user", "domain", "password"))
{
// 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 parameters if any
foreach (var parameter in parameters)
{
pipeline.Commands[0].Parameters.Add(parameter.Key, parameter.Value);
}
// 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
Collection<PSObject> results = pipeline.Invoke();
// close the runspace
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();
}
Anyway, this doesn't work on my machine. For example, if the script text is "Set-ExecutionPolicy Unrestricted" then I get "Access to the registry key 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell' is denied."
And in my case, it cannot get list of virtual machines through Get-VM command. (I found that Get-VM only return results if it runs under Admin privilege.)
Do I do something wrong? Is there another solution for this problem?
This will launch PowerShell as an Administrator:
var newProcessInfo = new System.Diagnostics.ProcessStartInfo();
newProcessInfo.FileName = #"C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe";
newProcessInfo.Verb = "runas";
System.Diagnostics.Process.Start(newProcessInfo);
If you need to pass in a script to run, then use:
newProcessInfo.Arguments = #"C:\path\to\script.ps1";
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())
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
)
Here is the code:
static String checkBackUp()
{
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.Add("Get-WBSummary");
pipeline.Commands.Add("Out-String");
Collection<PSObject> results = new Collection<PSObject>();
try
{
results = pipeline.Invoke();
}
catch (Exception ex)
{
results.Add(new PSObject((object)ex.Message));
}
runspace.Close();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
return stringBuilder.ToString();
}
The problem is that this runs every cmdlet (like Get-Process for example) but when I try to verify if a backup has been made (Get-WBSummary), it spits out the following error:
The term 'Get-WBSummary' 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.
However when I put the command straight into PowerShell, it executes the command. I have already tried to add a SnapIn but this did not work.
What am I doing wrong here?
Get-WBSummary isn't a regular built-in Powershell cmdlet. You'll need to do
Add-PSSnapin Windows.ServerBackup
at some point in your code after the runspace is initialised.
You'll have to create an initial session state and add the snapin. Here is how to do it
initialSession = InitialSessionState.CreateDefault();
initialSession.ImportPSModule(new[] {"Path\to\module\here"});