I want to run my virtual machine from C# script, if i try to do this from PowerShell(5.1.18362.752 version) it works,
i put first command
Import-AzureRmContext -Path "C:\Program Files(x86)\WindowsPowerShell\azureprofile.json"
and then second command
$PowerState = ((Get-AzureRmVM -Name Janusz -ResourceGroupName Inzynierska -Status).Statuses[1]).code
If ( $PowerState -contains "PowerState/running")
{
Write-Host "PowerState1: running"
}
ElseIf ( $PowerState -contains "PowerState/deallocated")
{
Start-AzureRmVM -Name Janusz -ResourceGroupName Inzynierska
$PowerState = ((Get-AzureRmVM -Name Janusz -ResourceGroupName Inzynierska -Status).Statuses[1]).code
}
Write-Host "PowerState2: $PowerState"
but if i try to do this in C# .Net Core ,Visual Studio it's doesn't work
static void Main(string[] args)
{
using (PowerShell PowerShellInstance = PowerShell.Create())
{
string text = System.IO.File.ReadAllText(#"C:\Users\Krute\Desktop\Inżynierka\PowerShellScriptRunning\FirstScript.txt");
PowerShellInstance.AddScript(text);
IAsyncResult result = PowerShellInstance.BeginInvoke();
while (result.IsCompleted == false)
{
Console.WriteLine("Pierwsze Zapytanie");
Thread.Sleep(1000);
}
}
using (PowerShell PowerShellInstance1 = PowerShell.Create())
{
string text1 = System.IO.File.ReadAllText(#"C:\Users\Krute\Desktop\Inżynierka\PowerShellScriptRunning\SecondScript.txt");
PowerShellInstance1.AddScript(text1);
IAsyncResult result = PowerShellInstance1.BeginInvoke();
while (result.IsCompleted == false)
{
Console.WriteLine("Drugie Zapytanie");
Thread.Sleep(1000);
}
Console.WriteLine("Finished!");
}
Console.Read();
I check what is inside text and text1 and script is read correct.
Can somebody explain me what is wrong with my code or why it doesn't work? and what i can do to run this PowerShell script from C# ?
Thanks
You can run PowerShell script from C# like this
PowerShell ps = PowerShell.Create();
ps.AddScript(#"D:\PSScripts\MyScript.ps1", true).Invoke();
Reference:
Adding and invoking commands
Related
I have a net-core 3.1 project which runs powershell scripts. It works fine on win10, but not on win7. I get the errorr message "Cannot find drive. A drive with the name 'c' doesn't exist". If I run the same powershell command directly in powershell, it works fine on win7 also, it is just from the c# code it doesn't work. I have referenced both Microsoft.PowerShell.SDK and System.Management.Automation version 7.0.0-rc.1. This simple console app shows the problem. Works on win10, but not on win7. Any suggestions?
static void Main(string[] args)
{
using (var runspace = RunspaceFactory.CreateRunspace())
{
runspace.Open();
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddScript("Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser");
ps.AddScript(#"$PSVersionTable.PSVersion | write-output; get-childitem -path c:\temp");
var commandResults = ps.Invoke();
Console.WriteLine($"PS command result {commandResults.Count} lines");
foreach (var commandResult in commandResults)
{
Console.WriteLine(commandResult);
}
if (ps.Streams.Error.Count != 0)
{
Console.WriteLine("Errors:");
foreach (var error in ps.Streams.Error)
{
Console.WriteLine(error.ToString());
}
}
Console.WriteLine("Finished");
Console.ReadLine();
}
}
}
using (Runspace runspace = System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace())
{
runspace.Open();
using (PowerShell powershell = PowerShell.Create())
{
Command lic1 = new Command("Out-String");
var script1 = "$s = Get-LocalUser -Name test2";
var script2 = "Remove-LocalUser -InputObject $s";
string accessScriptPath = $"{script1} ;\n {script2}";
powershell.Commands.AddCommand(lic1);
powershell.Commands.AddCommand(new Command(accessScriptPath));
var results = powershell.Invoke();
PowerShellErrorCheck(powershell, results);
powershell.Commands.Clear();
}
}
I wants to execute the command and it was assigned to a variable and trying to access in next line but system throw exception. '$s = Get-LocalUser -Name test2 ;
Remove-LocalUser -InputObject $s' 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.
Mainly I was trying the above code was to simulate the below powershell code to c#
$x = Get-CsRgsAgentGroup -Identity service:ApplicationServer:atl-cs-001.litwareinc.com -Name "Help Desk"
$x.AgentsByUri.Add("sip:kenmyer#litwareinc.com")
Set-CsRgsAgentGroup -Instance $x
I have an application, that allows the user to configure basic WMI settings on a Win 10 IoT machine.
I am currently struggling with reading all WEKF_PredefinedKey settings, that are enabled.
I am simply running a skript, that I added as string to the project settings named ReadEnabledKeys:
$CommonParams = #{"namespace"="root\standardcimv2\embedded"}
$CommonParams += $PSBoundParameters
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned;
$keys = Get-WMIObject -class WEKF_PredefinedKey #CommonParams
foreach($k in $keys)
{
if($k.Enabled -eq $false)
{
"$k";
}
}
My call in C# code looks like this (Note: using System.Management.Automation):
using (PowerShell PowerShellInstance = PowerShell.Create())
{
PowerShellInstance.AddScript(Properties.Settings.Default.ReadEnabledKeys);
var result = PowerShellInstance.Invoke();
}
My variable result will always stay empty.
If I run the skript in Powershell directly, the output is just fine (all shortcuts, that are currently not disabled).
I have something similar programmed with the unified write filter, where I enable and disable it:
$COMPUTER = "localhost"
$NAMESPACE = "root\standardcimv2\embedded"
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned;
$objUWFInstance = Get-WMIObject -namespace $NAMESPACE -class UWF_Filter;
$retval = $objUWFInstance.Enable();
if ($retval.ReturnValue -eq 0) {"Unified Write Filter will be enabled after the next system restart."}
else {"Unknown Error: " + "{0:x0}" -f $retval.ReturnValue}
And the C# call:
using (PowerShell PowerShellInstance = PowerShell.Create())
{
PowerShellInstance.AddScript(Properties.Settings.Default.EnableUWF);
// [0] = result or error
var result = PowerShellInstance.Invoke();
if (result[0].ToString().ToLower().Contains("enabled"))
MessageBox.Show(result[0].ToString(), "", MessageBoxButton.OK, MessageBoxImage.Information);
else
MessageBox.Show("Error when enabling the filter! " + Environment.NewLine + result[0].ToString(), "",
MessageBoxButton.OK, MessageBoxImage.Error);
}
Here my result variable will be filled with the expected strings.
I have tried Write-Host $k, as I suspected something wrong with the stream, but this was without any success.
The output in Powershell looks like this:
PS C:\Users\Administrator> C:\Users\Administrator\Desktop\Newfolder\Untitled1.ps1
\\DESKTOP-RMGOBMG\root\standardcimv2\embedded:WEKF_PredefinedKey.Id="Alt"\\DESKTOP-RMGOBMG\root\standardcimv2\embedded:WEKF_PredefinedKey.Id="Application"
\\DESKTOP-RMGOBMG\root\standardcimv2\embedded:WEKF_PredefinedKey.Id="Ctrl+Esc"
\\DESKTOP-RMGOBMG\root\standardcimv2\embedded:WEKF_PredefinedKey.Id="Ctrl+F4"
\\DESKTOP-RMGOBMG\root\standardcimv2\embedded:WEKF_PredefinedKey.Id="Ctrl+Tab"
.
.
.
Can anyone tell me, what the problem is?
The problem appears to be with your script. Setting the ExecutionPolicy midstream doesn't do anything and you aren't writing a function so adding $PSBoundParameters also doesn't do anything. Here's an example that should work (I'd specify PS version in the future. I know you're on v5.1/win10 due to keyboard filtering)
$collection = [System.Collections.Generic.List[string]]::new()
foreach ($key in (Get-CimInstance -Namespace 'root\standardcimv2\embedded' -ClassName WEKF_PredefinedKey)) {
if (-not $key.Enabled) {
$collection.Add($key.ToString())
}
}
return $collection
(simplified)
#(Get-CimInstance -Namespace root\standardcimv2\embedded -ClassName WEKF_PredefinedKey).
Where{-not $_.Enabled}.
ForEach('ToString')
Example:
using (PowerShell ps = PowerShell.Create())
{
string script = #"Import-Module -Name C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Management\Microsoft.PowerShell.Management.psd1 -ErrorAction Stop; #(Get-WmiObject -Namespace root\standardcimv2\embedded -Class WEKF_PredefinedKey -ErrorAction Stop).Where{-not $_.Enabled}.ForEach('ToString')";
ps.AddScript(script);
var result = ps.Invoke();
}
I am working on a c# program using System.Speech.Recognition to recognize speech and run PowerShell commands according to what is said.
I have the following powershell script that represents a macro for creating a speech command:
Add-Type -Path ".\GAVPI.Lib.dll"
Add-Type -Path ".\GAVPI.Lib.Logging.dll"
[Action[GAVPI.Lib.Logging.Parameter]]$speechRecognized = {
param($i)
[System.Windows.MessageBox]::Show("test")
}
$parameter = New-Object -TypeName GAVPI.Lib.Logging.Parameter -ArgumentList
("parameter", "value")
$phrase = New-Object -TypeName GAVPI.Lib.Core.Triggers.Phrase -ArgumentList
("default","test", $speechRecognized, $parameter)
return $phrase
This phrase object is used to tell what commands can be said and recognized. It successfully is passed to c# like this:
var list = new List<Phrase>();
var ps = PowerShell.Create();
var run = RunspaceFactory.CreateRunspace();
ps.Runspace = run;
run.Open();
var script = ps.AddScript(".\\PowershellTemplate.ps1", true);
var result = ps.Invoke();
foreach (var psObject in result)
{
if (psObject.BaseObject is Phrase)
{
list.Add((Phrase)psObject.BaseObject);
}
}
return list;
When a command is recognized,the Phrase class invokes the Action:
public override void Run(Parameter selectedparameter)
{
if (parAction != null)
{
parAction.Invoke(selectedparameter);
}
}
private Action<Parameter> parAction;
When the program is run, if you say "test parameter" it invokes the action<parameter> in the phrase class, which invokes the script block in powershell.
I get the following exception at the parAction.Invoke(selectedparameter); line:
There is no Runspace available to run scripts in this thread. You can
provide one in the DefaultRunspace property of the
System.Management.Automation.Runspaces.Runspace type. The script block
you attempted to invoke was:
param($i)...w("test")
How do I pass the runspace to the Sysem.Action<Parameter> so that it can run the PowerShell script block?
I Have a powershell script to connect on Skype for Business Online and it is working on powershell also on Console application but when I call from ASP.NET not working
The exception when I run through ASP.NET:
"The term 'Get-CsPowerShellEndpoint' 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"
string command = #"$PlainPassword ='****';
$UserName = '****';
$SecurePassword = $PlainPassword | ConvertTo-SecureString-AsPlainText -Force;
$SkypeOnlineCred = New - Object - TypeName System.Management.Automation.PSCredential -ArgumentList $UserName, $SecurePassword;
Remove-Variable -Name PlainPassword;
Remove-Variable -Name SecurePassword;
Remove-Variable -Name UserName;
$SkypeOnlineSession = New-CsOnlineSession Credential $SkypeOnlineCred;
Import-PSSession -Session $SkypeOnlineSession | Out-Null;";
var initial = InitialSessionState.CreateDefault();
initial.ImportPSModule(new string[] {
"C:\\Program Files\\Common Files\\Skype for Business Online\\Modules\\SkypeOnlineConnector\\SkypeOnlineConnectorStartup.psm1"
});
using (Runspace runspace = RunspaceFactory.CreateRunspace(initial))
{
// Open runspace
runspace.Open();
// Initialize PowerShell engine
using (PowerShell shell = PowerShell.Create())
{
shell.Runspace = runspace;
// Add the script to the PowerShell object
shell.Commands.AddScript(command);
try
{
// Execute the script
var results = shell.Invoke();
if (shell.Streams.Error.Count > 0)
{
throw new Exception(shell.Streams.Error[0].Exception.Message);
}
// display results, with BaseObject converted to string
// Note : use |out-string for console-like output
return results;
}
catch (Exception e)
{
throw new Exception("On Invoke" + e.Message);
}
}
}