Hello a have a file with 21 lines of code in power shell. I need a way to run this file with a button in c#. I use c# in Visual Studio 2010. Please let me know if there is a way to achieve.
// Powershell
$Proc = Get-Process | Sort-Object CPU -Descending
$cores = Get-WmiObject Win32_processor
$memory = Get-WmiObject Win32_OperatingSystem
$Total = 10
$num = 1
Clear-Content c:\scripts\prueba.txt
foreach ($objItm in $Proc) {
If ($num -gt $Total) {
break #break the loop
}
[string] $strID=[System.Convert]::ToString($objItm.ID)
[string] $strProcessName=[System.Convert]::ToString($objItm.ProcessName)
[string] $strCPU=[System.Convert]::ToString($objItm.CPU)
[string] $strNUM=[System.Convert]::ToString($num)
$info=$strNUM+"-"+$strID+"-"+$strProcessName+"-"+$strCPU
$num += 1
$info|Add-Content c://scripts/prueba.txt
}
//Code c#
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open(); RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.Add(scriptFile)
Execute PowerShell script results = pipeline.Invoke();
I need for example press a button and make the script happens
You can use PS2EXE by Ingo Karstein
This creates a c# executable with it's own powershell host and with your script embedded.
I have a c# project which takes the c# code in PS2EXE, adds ability to read the contents of an encrypted powershell script, decrypt it and run it.
some tips that works for me . My application is already working
Run Visual Studio with permissions of Administrator this to avoid get a error with the Hkey_Local...
In power shell run this get-executionpolicy to view the policy and set unregistered with set-executionpolicy unregistered. This avoid any restriction by the OS.
And with the code write above the app work. Get ready and test !!!
Related
I'm able to run puppet bolt command in powershell. In powershell, I got output as below
Started on winrm://remotemachine
Finished on winrm://remotemachine
STDOUT:
RemoteMachineHostName
Successful on 1 target Run on 1 tartget in 3.2 sec
My C# is as below
PowerShell ps = PowerShell.Create();
ps.AddScript("C:\\User1\\GetRemoteAzureVMHostName.ps1");
Collection<PSObject> results = ps.Invoke(); // in results, I'm getting value as 0.
foreach (PSObject result in results)
{
//Do something
}
I tried changing build platform target to x64 in Visual Studio 2019 but it didn't worked.
How to fix above issue
Update 1:
I have used below command in powershell script.
bolt command run hostname --targets winrm://158.28.0.546 --no-ssl-verify --user testuser123 --password test#84p
It seems you cannot input the path of the PowerShell to the method AddScript(). Here is an example that runs the PowerShell script through C#:
private static string script =File.ReadAllText(#"Path\Sum.ps1");
private static void CallPS1()
{
using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
runspace.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;
ps.AddScript(script);
ps.Invoke();
foreach (PSObject result in ps.Invoke())
{
Console.WriteLine("CallPS1()");
Console.WriteLine(result);
}
}
}
So you can try to read the script out and then input them in the method AddScript().
I figured it out that, Visual Studio is calling 32 bit powershell and unable to run bolt commands as bolt module installed on 64 bit powershell.
I have changed project build platform to x64 and build it.
It worked.
I'm building a C# application that has to run some powershell scripts.
While the application works well on all my colleagues computers, I have issue having it to work properly on a Windows Server 2012 virtual machine.
Whenever I run a script through the application I'm getting the following error message:
Access to the registry key 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell' is denied. To change the execution policy for the default (LocalMachine) scope, start Windows PowerShell with the "Run as administrator" option. To change the execution policy for the current user, run "Set-ExecutionPolicy -Scope CurrentUser".
I precise that I went through a LOT of topics and tried many things that did not solve my problem
I tried:
set-executionpolicy unrestricted
set-executionpolicy unrestricted -Scope -CurrentUser
And of course I ran these commands on both x64 and x86 powershell instances (running the powershell application as administrator)
Now the strange part is that I have no trouble running the script through the powershell window directly, the error only occurs when running the script through the C# application.
Here's the code involved:
public static List<string> RunPowerShellScript(Sequence sq, Script script)
{
try
{
script.Results = new List<Result>();
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
RunspaceInvoke runspaceInvoker = new RunspaceInvoke(runspace);
//runspaceInvoker.Invoke("set-executionpolicy bypass");
runspaceInvoker.Invoke("set-executionpolicy unrestricted");
//Create a pipeline to send variables
Pipeline pipeline = runspace.CreatePipeline();
//Create a command
Command myCommand = new Command(Properties.Settings.Default.Scripts + "\\" + script.ScriptName + ".ps1", false);
foreach (Parameter p in script.Parameters)
{
CommandParameter param = new CommandParameter(p.ParameterName, sq.GetUpdatedParameter(p));
myCommand.Parameters.Add(param);
}
pipeline.Commands.Add(myCommand);
//Return the output from the script
Collection<PSObject> returnObjects = pipeline.Invoke();
runspace.Close();
List<string> output = new List<string>();
foreach (PSObject po in returnObjects)
{
if (po != null)
output.Add(po.ToString());
}
return output;
}
catch(Exception e)
{
return new List<string> { e.Message, "1" };
}
}
To resolve this issue, Open powershell as an administrator and run the command again:
Set-ExecutionPolicy Unrestricted
may be this can solve your problem:
1- open "Visual Studio" az administrator
2- open your project solution with visualstudio
3- run it
Invoke-MyFunction is a commandlet I wrote that takes an input file, changes it, and creates a new output file at a specified location. If I open a PowerShell on my desktop, import MyCommandlet.ps1, and run
Invoke-MyFunction -InputPath path\to\input -OutputPath path\to\output
everything works as expected. But when I try to import and invoke the command from a C# program with the code below, the commandlet doesn't run, doesn't log output, and doesn't produce the output file. It doesn't throw a CommandNotFoundException, so I assume the PowerShell object recognizes my commandlet. But I can't figure out why it doesn't execute it.
//set up the PowerShell object
InitialSessionState initial = InitialSessionState.CreateDefault();
initial.ImportPSModule(new string[] { #"C:\path\to\MyCommandlet.ps1" });
Runspace runspace = RunspaceFactory.CreateRunspace(initial);
runspace.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;
//have MyFunction take input and create output
ps.AddCommand("Invoke-MyFunction");
ps.AddParameter("OutputPath", #"C:\path\to\output");
ps.AddParameter("InputPath", #"C:\path\to\input");
Collection<PSObject> output = ps.Invoke();
Further, after invoking MyFunction, the PowerShell object ps fails to execute any other commands. Even known ones.
This works for me:
//set up the PowerShell object
var initial = InitialSessionState.CreateDefault();
initial.ImportPSModule(new string[] { #"C:\Users\Keith\MyModule.ps1" });
Runspace runspace = RunspaceFactory.CreateRunspace(initial);
runspace.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;
//have MyFunction take input and create output
ps.AddCommand("Invoke-MyFunction");
ps.AddParameter("OutputPath", #"C:\path\to\output");
ps.AddParameter("InputPath", #"C:\path\to\input");
var output = ps.Invoke();
foreach (var item in output)
{
Console.WriteLine(item);
}
With a MyModule.ps1 of:
function Invoke-MyFunction($InputPath, $OutputPath) {
"InputPath is '$InputPath', OutputPath is '$OutputPath'"
}
One thing that did cause me a failure is that on Visual Studio 2013 (maybe 2012 as well) AnyCPU apps will actually run 32-bit on a 64-bit OS. You have to have set the execution policy for PowerShell x86 to allow script execution. Try opening up a PowerShell x86 shell in admin mode and run Get-ExecutionPolicy. If it is set to Restricted, use Set-ExecutionPolicy RemoteSigned to allows scripts to execute.
I want to use specific command that are provided by the "Active Directory Administration with Windows PowerShell". So I installed this module on my server.
Now, I want to use these commands in my code. My project is in c# - ASP.NET.
Here's the code I use to call traditional "cmdlet" command (New-Mailbox, Set-User, ...) :
string runasUsername = #"Mario";
string runasPassword = "MarioKart";
SecureString ssRunasPassword = new SecureString();
foreach (char x in runasPassword)
ssRunasPassword.AppendChar(x);
PSCredential credentials =
new PSCredential(runasUsername, ssRunasPassword);
// Prepare the connection
var connInfo = new WSManConnectionInfo(new Uri("MarioServer"),
"http://schemas.microsoft.com/powershell/Microsoft.Exchange",credentials);
connInfo.AuthenticationMechanism =
AuthenticationMechanism.Basic;
connInfo.SkipCACheck = true;
connInfo.SkipCNCheck = true;
// Create the runspace where the command will be executed
var runspace = RunspaceFactory.CreateRunspace(connInfo);
//Params
....
// create the PowerShell command
var command = new Command("New-Mailbox");
command.Parameters.Add("Name", name);
....
// Add the command to the runspace's pipeline
runspace.Open();
var pipeline = runspace.CreatePipeline();
pipeline.Commands.Add(command);
// Execute the command
var results = pipeline.Invoke();
if (results.Count > 0)
System.Diagnostics.Debug.WriteLine("SUCCESS");
else
System.Diagnostics.Debug.WriteLine("FAIL");
runspace.Dispose();
This code work perfectly ! Great ! But let say I want to use "Set-ADUser", this command is from ActiveDirectory module (RSAT tools).
Given that all is set on the server (the module is installed), I tried to simply change "New-Mailbox" for "Set-ADUser" :
var command = new Command("Set-ADUser");
When I run the code, I have this error :
The term 'Set-ADUser' is not recognized as the name of a cmdlet, function, script file, or operable program.
So, that's my question :
How can we run command from the ActiveDirectory module (RSAT tools) in c# ? (Im using VS 2010).
As #JPBlanc pointed out in the comments section, you will need to ensure that the ActiveDirectory PowerShell module is loaded. PowerShell version 3.0 and later have module auto-loading enabled by default (it can be disabled), but if you're still targeting PowerShell 2.0, then you must first call:
Import-Module -Name ActiveDirectory;
.. before you can use the commands inside the module.
For the purposes of validation, you can use the Get-Module command, to ensure that the ActiveDirectory module has been imported.
Get-Module -Name ActiveDirectory;
If the above command returns $null, then the module is not imported. To verify that PowerShell can "see" the ActiveDirectory module, without actually importing it, run this command:
Get-Module -Name ActiveDirectory -ListAvailable;
I have a PowerShell script stored in a file, MergeDocuments.ps1. When I run the script from the Windows PowerShell command prompt it runs fine
.\MergeDocuments.ps1 1.docx 2.docx merge.docx
Calling the script from a Windows console application also runs fine.
When I tried calling the script from an Asp.Net web service, I faced some issues regarding registry access. I used impersonation and gave permission to Network Service account to the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell to solve this problem
Next I faced issue about PowerShell being unable to create objects of type OpenXmlPowerTools.DocumentSource[], so I added the following to my script
Add-Type -Path "C:\Users\Administrator\Documents\WindowsPowerShell\Modules\OpenXmlPowerTools\OpenXmlPowerTools.dll"
Import-Module OpenXmlPowerTools
Now the current problem is that I am getting the error "The term 'Merge-OpenXmlDocument' is not recognized as the name of a cmdlet, ..."
How can I solve that?
PowerShell Script
Add-Type -Path "C:\Users\Administrator\Documents\WindowsPowerShell\Modules\OpenXmlPowerTools\OpenXmlPowerTools.dll"
Import-Module OpenXmlPowerTools
# The last argument is the path of the merged document
$noOfSourceDocs = ($($args.length) - 1)
# Create an array to hold all the source documents
[OpenXmlPowerTools.DocumentSource[]] $docs = New-Object OpenXmlPowerTools.DocumentSource[] $noOfSourceDocs
for ($i = 0; $i -lt $noOfSourceDocs; $i++)
{
$docs[$i] = New-Object -TypeName OpenXmlPowerTools.DocumentSource -ArgumentList $args[$i]
$docs[$i].KeepSection = 1
}
Merge-OpenXmlDocument -OutputPath $args[-1] -Sources $docs
Webservice .Net Code
using (new Impersonator(username, domain, password))
{
// create Powershell runspace
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
RunspaceInvoke invoker = new RunspaceInvoke(runspace);
invoker.Invoke("Set-ExecutionPolicy Unrestricted");
// create a pipeline and feed it the script file
Pipeline pipeline = runspace.CreatePipeline();
Command command = new Command(ConfigurationManager.AppSettings["PowerShellScript"]);
foreach (var file in filesToMerge)
{
command.Parameters.Add(null, file);
}
command.Parameters.Add(null, outputFilename);
pipeline.Commands.Add(command);
pipeline.Invoke();
runspace.Close();
}
Can you just try to install OpenXmlPowerTools module in the PowerShell System module path :
C:\Windows\system32\WindowsPowerShell\v1.0\Modules