Execute PowerShell script without 'PowerShell.SDK' - c#

I want to execute the PowerShell script without SDK. In my project, I have to execute the PowerShell script and also want to create an EXE file for the same. But the problem is:
When I remove Microsoft.PowerShell.SDK then the script is not executed and gives an error but creates an exe file. Error is "Cannot load PowerShell snap-in Microsoft.PowerShell.Diagnostics because of the following error: Could not load file or assembly".
When the above package is not removed from the project then the script is working fine but it gives an error while creating an exe file.
Please share your suggestion.
Here is my code:
string readLocationFile = File.ReadAllText(#"gravity_location.ps1");
using (PowerShell powerShell = PowerShell.Create())
{
powerShell.AddScript(readLocationFile);
powerShell.AddParameter("name", _locationName.Text);
powerShell.AddParameter("targetPath", filePath);
powerShell.Invoke();
}

You can use System.Management.Automation which is the core of the PowerShell SDK like this
using System.Management.Automation;
using System.Management.Automation.Runspaces;
//...
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
//Here's how you add a new script with arguments
Command myCommand = new Command("your/script/file/path.ps1");
CommandParameter testParam = new CommandParameter("key","value"); //e.g. "-Path" "value"
myCommand.Parameters.Add(testParam);
pipeline.Commands.Add(myCommand);
// Execute PowerShell script
results = pipeline.Invoke();
Detailed information about the packages.
https://learn.microsoft.com/en-us/powershell/scripting/dev-cross-plat/choosing-the-right-nuget-package?view=powershell-7.2
Another post about the topic:
Execute PowerShell Script from C# with Commandline Arguments

Related

Remote PowerShell Script not working with c#

My Powershell Script that invoke some commands to remote machine (on same domain) works very well.
Invoke-Command -script { get-host } -ComputerName 'AD' -Credential (New-Object System.Management.Automation.PSCredential ('admin', (ConvertTo-SecureString 'passwd' -AsPlainText -Force)))
but My C# Rest API program that uses above code is not working.
using (PowerShell ps = PowerShell.Create())
{
ps.AddScript(ps_script_above);
Collection<PSObject> psOutput = ps.Invoke();
logger.Debug("Result Count is : " + psOutput.Count);
}
Result Count is always zero.
But when except 'invoke-command' phrase, it works well.
My Powershell version is 7.x and dotnet version is 5.
Anyone with experience creating C# programs using remote powershell commands,
plz help me.

Invoking Powershell file blocks referenced Libraries

I am executing a Powershell script file from C# with the following code:
Runspace _rs = RunspaceFactory.CreateRunspace();
_rs.ApartmentState = ApartmentState.STA;
_rs.Open();
PipeLine _pipeLine = _rs.CreatePipeline();
Command scriptCommand = new Command(filePath);
_pipeLine.Invoke();
In the powershell script file I am referencing libraries:
Add-Type -Path Filepath.dll
In C# i am disposing the runspace and pipeline afterwords trying to unlock the associated libraries.
finally
{
_rs.Dispose();
_pipeLine.Dispose();
}
Unfortunately in a later step when trying to delete the dll files associated in the script, i get a UnauthorizedException. Please note that i dont get the exception if i never run the script from C#. I def should have accss to it.

PowerShell script run from C# is lacking several modules

var runspace = RunspaceFactory.CreateRunspace()
runspace.Open();
var ps = PowerShell.Create()
ps.Runspace = runspace;
ps.AddCommand(...);
ps.Invoke()
Some cmdlets that exist in a regular shell are missing from the runtime started by C#, e.g. all the commands from the Microsoft.PowerShell.LocalAccounts module :
Error: System.Management.Automation.CommandNotFoundException: The term 'New-LocalUser' 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.
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
By comparing the Get-Module -ListAvailable output from a regular shell and a C# started one I noticed multiple modules are missing :
AppBackgroundTask
AssignedAccess
BitLocker
ConfigCI
Defender
Microsoft.PowerShell.LocalAccounts
MMAgent
NetworkSwitchManager
PcsvDevice
PSWorkflow, PSWorkflowUtility
SmbShare, SmbWitness
StartLayout
WindowsSearch
The version ($PSVersionTable) is reported as the same in both shells : 5.1.14393.693
Edit
Seems to be the same issue & solution : Why do powershell modules not import when running powershell via start process in c#?
You can import modules directly on your script instead of trying to do that from C#.
Import-module bitlocker
For example.

How to get PowerShell script execution error - System.Management.Automation.dll

I execute a PowerShell script from C# code. I use System.Management.Automation.dll Nuget package. Although my script has an obvious error, powerShell.Invoke() returns no results, nor error messages.
using (var powerShell = PowerShell.Create())
{
powerShell.AddScript("an erroneous script");
powerShell.Invoke(); // yields an empty PSObject list
}
How can I get a list of errors?

The term 'connect-QADService' is not recognized as the name of a cmdlet... inside C# function

Can someone, please, help to understand why the following code inside a Csharp function
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipe = runspace.CreatePipeline();
Command connectToActDir = new Command("connect-QADService");
connectToActDir.Parameters.Add("Service", "'ip:port'");
connectToActDir.Parameters.Add("ConnectionAccount", "'user.local\administrator'");
connectToActDir.Parameters.Add("ConnectionPassword", "'password'");
pipe.Commands.Add(connectToActDir);
pipe.Invoke();
causes the following error
The term 'connect-QADService' 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.
while ActiveRoles cmdlets are installed and running the equivalent command in power shell succeeds. Do I miss some dll in project references?
Thanks
The Quest ActiveRoles cmdlets are not loaded into a PowerShell session by default, because they're not part of PowerShell.
PowerShell 3 will automatically load modules when needed. I don't know if this holds true when using a RunSpace as I've never used PowerShell this way.
Do you load the Quest snap-in or module in your PowerShell profile? You'll need to do the equivalent in your C# code.

Categories