Export X509Certificate with Powershell and C# - c#

I have a Powershell script that exports an X509Certificate of user abc and it works fine when running in terminal.
$user = "abc"
$pfx_file = "pfxFilePath.pfx"
$pass = ConvertTo-SecureString -String "123" -Force -AsPlainText
(Get-ChildItem -Path cert:\currentuser\my\) | where-object { $_.subject -like "*$user*"} | Export-PfxCertificate -FilePath $pfx_file -Password $pass -Verbose
However, it doesn't export anything when I invoke it with my C# test(with PowerShell SDK) in Visual Studio, there is no message - no message, no error message, no verbose message. And I really don't know how to troubleshoot the problem. Here is my code
var ps = PowerShell.Create();
await ps.AddCommand("Set-ExecutionPolicy").AddParameter("ExecutionPolicy", "Unrestricted").InvokeAsync();
ps.AddScript("".\\test.ps1");
var results = await ps.InvokeAsync();
I think this is related to user permissions, but I used the same user for both Visual Studio and terminal, how can I check which user is running the test in Visual Studio? Is there anything can help me troubleshoot this problem?
Thanks!
Edit: After some digging, I realized the problem is with PowerShell SDK. It doesn't use regular Windows PowerShell instance, it has a different PSModulePath and it is missing a lot of default modules.

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.

How to build Visual Studio 2019 C# solution command line invoked from Windows PowerShell or PowerShell ISE

If I launch Developer PowerShell for VS2019, I can build my C# solution and control is given back when the devenv process exits.
$argsList = "/build Debug mysolution.sln"
$process = Start-Process devenv.exe -ArgumentList $argsList -PassThru -Wait
if ($process.ExitCode -eq 0) {
Write-Host "completed"
} else {
Write-Host "failed"
}
I want to be able to do the same from Windows 2016 server PowerShell or PowerShell ISE, so I can debug a more complex script. First, Visual Studio binaries are not in the path, but what bothers me is that the devenv process exits without giving back control after Start-Process.
$devenvPath = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\devenv.exe"
$argsList = "/build Debug mysolution.sln"
$process = Start-Process $devenvPath -WorkingDirectory . -ArgumentList $argsList -PassThru -Wait
if ($process.ExitCode -eq 0) {
Write-Host "completed"
} else {
Write-Host "failed"
}
How can I invoke from 'regular' PS the Visual Studio Power shell that comes with extra modules loaded and paths set for my build job?
How can I redirect the build output to the PS window? -NoNewWindow passed to Start-Process doesn't do it. I can redirect to a file with 'devenv /Out file' option though.
What am I doing wrong that devenv exits but script doesn't come back or comes after a very long time?

How to make a batch script to run commands on a remote machine using credentials

I have wrote some batch scripts to perform docker commands on a machine and made it run using c# program. I can successfully run those batch scripts in my local machine, but I want it to run on a remote machine. How can I do that by giving remote machine access credentials? I am looking for batch commands that will first connect to the remote machine and then execute its body in remote machine.
A sample batch script is as below.
::Start an exited container
::Iam expecting some code here to connect to a remote machine
#echo off
docker start %1
Or, Is there any option to do it through c# program?
I failed to find a method to run batch scripts on a remote machine, but I used powershell scripting instead of batch scripts. If you can use powershell scripts instead of batch scripts, you can use this method.
set-item wsman:localhost\client\trustedhosts -value <Remote_computer_name> -Force
$pword = ConvertTo-SecureString -String <Remote_machine_password> -AsPlainText -Force
$user = <Remote_userName>
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $user, $pword
Set-ExecutionPolicy -ExecutionPolicy Bypass
Invoke-Command -ComputerName <Remote_computer_name> -filepath <ps1_file_path> -Credential $Credential
Running the above commands in a powershell administrator window will run the scripts in <ps1_file_path> in a remote machine.
You have to take into consider that, the command
set-item wsman:localhost\client\trustedhosts -value <Remote_computer_name> -Force
will add the remote machine into trusted hosts list.
Also, the command Set-ExecutionPolicy -ExecutionPolicy Bypass will allow all powershell scripts to run on our machine and I'm not sure it is safe to use.
Hope it help somebody in some way, but you must do research to make sure this method is safe.
Refer:
Execution Policies
Try using PsExec
https://learn.microsoft.com/en-us/sysinternals/downloads/psexec
This is a light weight replacement for telnet
Please try connecting using WinRM. Some sample info-
remote command execution
and
winrm-command referance
Or ssh server on Windows server - example
WinSCP
Hope it helps.

Windows Server 2012 R2 running a *.cmd file from a UNC path issue

I have machine A and machine B. I am trying to run an executable (Install.exe) file from machine A, to perform some action on machine B without logging on to B and without the need to copy the exe on to machine B. I am using below powershell script to do that:-
$securePassword= ConvertTo-SecureString "mypassword" -AsPlainText -force
$cred = New-Object System.Management.Automation.PsCredential("Domain\username",$securePassword)
Invoke-Command -Authentication credssp -Credential $cred -ComputerName "MachineB" `
-ScriptBlock { & '\\MachineA\myFolder\Install.exe'}
The exe runs without any issue and generates a text file on MachineB. But that exe in-turn calls a deploy.cmd file, this is where I do not see any action specified in the deploy.cmd file happens on machine B. Following is the code in the Install.exe (Written in C#) that calls the deploy.cmd file. As can be seen I am specifying the UNC path on Machine A where both the Install.exe and deploy.cmd files reside.
StringBuilder myStr = new StringBuilder("deploy.cmd ");
ProcessStartInfo psf = new ProcessStartInfo("cmd.exe", "/k " + myStr.ToString());
psf.WorkingDirectory = #"\\MachineA\myFolder";
Process p = Process.Start(psf);
p.WaitForExit();
Any Idea what’s the issue is?

Office 365: Connecting to Office Online 365 service using Power Shell Script issue

I have Windows Server 2008 R2 machine and it has Power Shell v1.0. I wanted to connect to MS 365 online service using Power Shell with C#. I have installed Office 365 cmdlets and Microsoft Online Services Sign-In Assistant. ( Ref: http://onlinehelp.microsoft.com/en-us/office365-enterprises/hh124998.aspx#BKMK_install )
My script is:
$password = ConvertTo-SecureString "xxxxx" -AsPlainText –Force
$credential = New-Object System.Management.Automation.PsCredential("xxxx#xxxx.onmicrosoft.com",$password)
$cred = Get-Credential -cred $credential
Import-Module MSOnline
Connect-Msolservice -cred $cred
I can successfully run this script in the Power Shell Command window. But I have problem running this script in c# application.
Here is my c# code:
public void RunScript()
{
StringBuilder ss = new StringBuilder();
ss.AppendLine("$password = ConvertTo-SecureString \"" + pwd + "\" -AsPlainText –Force");
ss.AppendLine("$credential = New-Object System.Management.Automation.PsCredential(\"" + userName + "\",$password)");
ss.AppendLine("$cred = Get-Credential -cred $credential");
ss.AppendLine("Import-Module MSOnline");
ss.AppendLine("Connect-Msolservice -cred $cred");
using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
Collection<PSObject> results = null;
try
{
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(ss.toString());
results = pipeline.Invoke();
}
finally
{
runspace.Close();
}
}
}
I get the following exception:
The term 'Connect-Msolservice' 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.
Is there anything missing?
Thanks
InitialSessionState iss = InitialSessionState.CreateDefault();
iss.ImportPSModule(new string[] { "MSOnline" });
using (Runspace runspace = RunspaceFactory.CreateRunspace(iss))
{
// blah
}
Please make sure you have installed following things:
1. SharePoint Online Management Shell
2. Microsoft Online Services Sign-In Assistant version 7.0 or greater version
3. Windows Azure Active Directory Module

Categories