I need to run this command from C#
Get-AppxPackage -AllUsers | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register "$($_.InstallLocation)\AppXManifest.xml"}
and i use this code:
Runspace runspace2 = RunspaceFactory.CreateRunspace();
runspace2.Open();
Pipeline pipeline2 = runspace2.CreatePipeline();
pipeline2.Commands.AddScript("Get-AppxPackage -AllUsers | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register \"$($_.InstallLocation)\\AppXManifest.xml\"}");
pipeline2.Invoke();
runspace2.Close();
The code return error:
C:\AppXManifest.xml not Found
But if i run this command from powershell it work and install all Apps so i think is an error for special characters in this part "$($_.InstallLocation)\AppXManifest.xml", suggestions?
Related
I need to get which network interface is connected to which network. I found that this information is accessible in MSFT_NetConnectionProfile. Unfortunatelly I cannot access it directly from C# (I get ManagementException: Provider load failure on computer where it should run) but when I access it from PowerShell, it works. Then my idea is to run PowerShell command from C# but I cannot get the result.
using System.Management.Automation;
string command = "Get-WmiObject -Namespace root/StandardCimv2 -Class MSFT_NetConnectionProfile | Select-Object -Property InterfaceAlias, Name";
PowerShell psinstance = PowerShell.Create();
psinstance.Commands.AddScript(command);
var results = psinstance.Invoke();
foreach (var psObject in results)
{
/* Get name and interfaceAlias */
}
The code runs without errors but results are empty. I tried even adding Out-File -FilePath <path-to-file> with relative and absolute file path but no file was created. I even tried old >> <path-to-file> but without luck. When I added Out-String then there was one result but it was empty string.
When I tested the commands directly in PowerShell then it worked. Is there a way how to get it in C#?
The PS commands must be constructed in a builder-pattern fashion.
Additionally, in PS Core the Get-WmiObject has been replaced by the Get-CimInstance CmdLet.
The following snippet is working on my env:
var result = PowerShell.Create()
.AddCommand("Get-CimInstance")
.AddParameter("Namespace", "root/StandardCimv2")
.AddParameter("Class", "MSFT_NetConnectionProfile")
.Invoke();
The image shows the same powershell command executed in a C# and Powershell ISE. My question is, Powershell shows complete list of process and process directory, but the result of the code executed in C# does not contain windows processes like svchost.exe.
Of course, both my C# Form and Powershell ISE are running as Administrator.
Also, I made sure to code my form to launch with administrative privileges.
To be double sure, I executed my C# by right click - Run as Administrator (what I also did with Powershell ISE)
Command/s: Powershell and C#
get-process | get-item -erroraction silentlycontinue | format-table name, directory
get-process | format-table name, directory
Although this particular command shows all the process:
get-process
Unfortunately, combining it with the syntax above will show different output from C#.
private string RunScript(string script)
{
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(script);
pipeline.Commands.Add("Out-String");
Collection<PSObject> results = pipeline.Invoke();
runspace.Close();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject pSObject in results)
stringBuilder.AppendLine(pSObject.ToString());
return stringBuilder.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
output.Clear();
output.Text = RunFilePs1(input.Text);
}
For some reason, Get-Process doesn't return the Path of some processes (probably the 64-bit ones) when running in 32-bit mode, so passing those to Get-Item fails to find anything.
You can see this by running your PS script from the x86 PS ISE.
So if you switch your C# Form to 64-bit, it will return all processes.
I need to start a powershell script from C# and get the PSSSecurityException on pipeline.Invoke()
AuthorizationManager check failed.
My code:
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
using (Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration))
{
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
Command scriptCommand = new Command(scriptfile);
pipeline.Commands.Add(scriptCommand);
pipeline.Invoke();
}
Questions
I suspect that I need to set PSCredential. But I can not promt for it, so I have to handle this in code. Can this be done in a secure way? (This was not the case)
Check out this SuperUser post: https://superuser.com/questions/106360/how-to-enable-execution-of-powershell-scripts
You probably just need to allow unsigned scripts to run. In the PS console, type the following:
set-executionpolicy remotesigned
Another resource echoes this: http://tgnp.me/2011/09/powershell-authorizationmanager-check-failed-resolution/
Give that a try and let me know what happens.
To capture the output from the script, try this:
Collection output = pipeline.Invoke();
foreach (PSObject psObject in output)
{
<here you can ToString the psObject for the output and write it line by line to your log>
}
The problem was that the script was placed on a share. To run scripts on this share I needed to add the share to Trusted Sites.
I'm working on a c# project where i'm trying to run powershell scripts, output them to a CSV and read the CSV and output it to a Checked list box.
I've added a powershell file as a resource with Build Action 'Compile' and Copy to output directory 'Do Not Copy'.
The basic content of the file is :
Get-CimInstance -Query "SELECT * from Win32_Service where name LIKE 'sql%'" | select Name, State , StartMode | convertto-csv > proctest.csv
i try to access this file using this string
string ps_path = System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + "\\GetSvc.ps1";
The PS code i use is
RunspaceConfiguration runspaceconfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceconfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
Command mycommand = new Command(ps_path);
pipeline.Commands.Add(mycommand);
pipeline.Invoke();
runspace.Close();
This works fine during compilation but when i build an exe and try to run it, i get an error saying the GetSvc.ps1 file is not found.
How do i make the file a part of the build ?!
Make the build action for the script be Embedded Resource. Then take a look at lines 149-155 on how to extract the script inside the C# exe. In this example, I had zipped the script to compact it. If you skip that step then you can remove line 152 and in line 153 use stream instead of gZipStream.
So a while back I wrote a Powershell script that would Parse an IIS Log and then do some stuff (email, create a report, and other nifty stuff). Well I am working on excuting that from a C# console app. Before I post my code I just wanted to make one thing clear, i would like to try and stay away from log parser to parse this log cause of many reasons but one specifically, why use something when you can write something else to your liking ;). So here is my code
PS Script:
$t1 =(get-date).AddMinutes(-10)
$t2 =$t1.ToUniversalTime().ToString("HH:mm:ss")
$IISLogPath = "C:\inetpub\logs\LogFiles\W3SVC1\"+"u_ex"+(get-date).AddDays(-3).ToString("yyMMdd")+".log"
$IISLogFileRaw = [System.IO.File]::ReadAllLines($IISLogPath)
$headers = $IISLogFileRaw[3].split(" ")
$headers = $headers | where {$_ -ne "#Fields:"}
$IISLogFileCSV = Import-Csv -Delimiter " " -Header $headers -Path $IISLogPath
$IISLogFileCSV = $IISLogFileCSV | where {$_.date -notlike "#*"}
$tape = $IISLogFileCSV | Format-Table time,s-ip,cs-uri-stem | Out-Host
C# app thus far:
Runspace runSpace = RunspaceFactory.CreateRunspace();
runSpace.Open();
Pipeline pipeline = runSpace.CreatePipeline();
pipeline.Commands.AddScript(#"D:\PS-Scripts\IIS\IISLogScan.ps1");
Collection<PSObject> results = pipeline.Invoke();
foreach (PSObject obj in results)
{
Console.WriteLine(results);
}
Console.ReadLine();
Now when I run my App it just sits and doesnt display anything and i Set my breakpoints and it says that there is nothing to display within my foreach which i am completely hung up on cause running my ps1 script it works perfectly and shows many lines. Any insight anyone can give would be great.
Try changing in .ps1 file:
$global:tape =$IISLogFileCSV | Format-Table time,s-ip,cs-uri-stem
and in c#
pipeline.Commands.AddScript(#"D:\PS-Scripts\IIS\IISLogScan.ps1");
pipeline.Commands.AddScript("$tape");
pipeline.Commands.AddScript("out-string");
or in .ps1:
$tape =$IISLogFileCSV | Format-Table time,s-ip,cs-uri-stem
$tape
and in c#
pipeline.Commands.AddScript(#"D:\PS-Scripts\IIS\IISLogScan.ps1");
pipeline.Commands.AddScript("out-string");