Running PowerShell Script From A Batch File Using C# - c#

i have a powershell script file, and a bat file, the bat file runs the script, so when i double click
the bat file the script get executed.
in my code i do the following:
ProcessStartInfo info = new ProcessStartInfo(#batchfilename + ".bat");
Process processToStart = new Process();
processToStart.StartInfo = info;
processToStart.Start();
the batch gets executed and the powershell scripts starts, but it crashes telling me somthing about policy issue.
allthoug my policy is unrestrected, any ideas?

You need to set Execution Policy to unrestricted MSDN.
Execution Policies (From the above MSDN link)
Restricted - No scripts can be run. Windows PowerShell can be used only in interactive mode.
AllSigned - Only scripts signed by a trusted publisher can be run.
RemoteSigned - Downloaded scripts must be signed by a trusted publisher before they can be run.
Unrestricted - No restrictions; all Windows PowerShell scripts can be run.
For 64 bit system, it needs to be set separately for x86, and x64.
PowerShell 32 and 64 bit have different execution policy settings

powershell.exe c:\FULL_PATH\send.ps1

Related

System.Diagnostics.Process closing powershell immediately

I have an issue where I'm trying to deploy a driver installation via an MSI Installer, it contains the .CAT and .INF files and outputs them to a directory, typically from here an infrastructure engineer could right click the .INF file and press install, however we're trying to streamline this process and automate this step.
Via C# I have a class utilising the System.Diagnostics.Process namespace to spawn a powershell process to run a powershell script containing a simple command as follows:
var process = new System.Diagnostics.Process();
var newProcessInfo = new System.Diagnostics.ProcessStartInfo();
string powerShellScript = #"C:\PowershellScript\DriverInstall.ps1"
newProcessInfo.FileName = #"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
newProcessInfo.Verb = "runas";
string newArgs = "-File " + powerShellScript;
newProcessInfo.Arguments = newArgs;
process.StartInfo = newProcessInfo;
process.Start();
Powershell script command is as follows:
Get-ChildItem "C:\DriverLocation" -Recurse -Filter "*inf" | ForEach-Object {PNPUtil.exe /add-driver $_.FullName /install }
when running this from powershell it works as expected, however if I try and spawn a powershell process from a C# class it doesn't work, comes up with some red error message text but the process windows spawns and closes immediately so I can't identify what the error is.
Essentially I either need the output from the powershell process to a text file or I need the powershell window to persist so I can identify why the script won't work when running from the System.Diagnostics.Process namespace.
I have tried editing the registries so that powershell will remain open to no avail.
Please don't suggest using the System.Management.Automation.Powershell namespace because utilisation of .NET core is unavailable in our project scenario.
Thanks for taking the time to read this, any help is much appreciated.
Resolution was to specify the execution policy within the powershell script, when running from the powershell window it had local admin rights and therefore didn't need an execution policy specified, however because it was being spawned from a separate process it only had remote access rights, therefore it wouldn't allow the script to execute.. never managed to output the particular error message but by process of elimination identified the resolution.
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine

Python virtual-environment and py file doesn't start when run batch file from c#

I have a batch file that has these commands to start a virtual environment and run a python file. when I start batch files manually through CMD it is running as expected. I have a different program (.NET web application) to start this batch file and arguments are passed from the web application to the batch file. However, the batch file takes the arguments but doesn't start the virtual-environment or python file.
#echo on
set filename="D:\test.txt"
echo %1_%2_%3 >%filename%
set root=C:\Users\TMF\Anaconda3
call %root%\Scripts\activate.bat %root%
call activate sales_analysis
C:\Users\TMF\Anaconda3\envs\sales_analysis\python.exe D:/sales/prediction_client.py %1 %2 %3
pause
After few hours of google search,I found that there are some restrictions with the default IIS user (usually it’s called “ApplicationPoolIdentity”).So I created a new service account on the server and assign my web application to new user and restart the application pool.After that batch file was able to start the python process as expected.

C# - Executing a exe file which further invokes a msi file

I have a .exe file which checks the system architecture and based on the system architecture it calls the corresponding msi file.
I am trying to run this exe file from C# using the code below
Process process = new Process();
process.StartInfo.FileName = "my.exe";
process.StartInfo.Arguments = "/quiet";
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.WorkingDirectory = "path//to//exe//directory";
Console.WriteLine(process.StartInfo.WorkingDirectory);
process.Start();
process.WaitForExit();
The exe is getting invoked. i can see the application logs and there are no errors in the logs.
But the msi is not getting started or installed.
When I try to run the same exe file manually the msi is installed.
Note: There are other dependency files for this my.exe which are placed in the same directory.
Why am i not able to install the msi from C# program while i am able to do this manually.
I am running the VisualStudios in administrator mode.
You need to execute .exe (and msi) as an administrator.
To ensure that, use:
process.StartInfo.Verb = "runas"
Also, try it removing quiet arguments to see any possible errors.
Is "my.exe" installing your MSI if you call it, isn't it?
I got this resolved after i added Thread.Sleep(). before "process.WaitForExit()"

How do I get a windows service to update itself

I'm working on an application that will run as a windows service, and I'm trying to get it to update itself automatically.
My current approach is to to execute a powershell script, which will stop the service, run a msi installer, and then restart the service.
This is what the powershell script looks like at this time
Start-Sleep -s 10
Write-Host "update start"
Stop-Service ServiceName1
msiexec /i c:\ProgramData\ProgramName\Install\ServiceName.Setup.msi /passive /l*v C:\ProgramData\ProgramName\Install\log.txt | Out-Null
Start-Service ServiceName1
Write-Host "update finished"
This is how I'm running it from the app
Process.Start("Powershell", #"C:\ProgramData\ProgramName\Install\UpdateApp.ps1");
What happens, is the service stops and restarts, but it doesn't update. It's as though the msi never gets run. The log file doesn't even appear.
When I run the Service as a command line app from an elevated command prompt it works as expected and the app gets updated, so My current theory is that the service isn't running the powershell script with administrator privileges.
Other questions suggest that I set up the log on settings for the service to use an administrator account, so I set the service to run as the account that I was currently logged in under, who was able to open an elevated command prompt and/or manually run the installer, but doing that didn't change anything.
Is there any way to do what I'm trying to do?
I'm currently not committed to any particular automatic update strategy, but I do know that I want this service to update itself. So if I'm doing something completely wrong, I'm 100% open to attempting a different approach.
UPDATE:
I made the following change to log the error and output for msiexecc
Try{
c:\windows\system32\msiexec.exe /i c:\ProgramData\ProgramName\Install\ServiceName.msi /passive /l*v C:\ProgramData\ProgramName\Install\log.txt | Out-File -filepath C:\ProgramData\ProgramName\Install\output.txt
}
Catch {
$_ | Out-File C:\ProgramData\ProgramName\Install\errors.txt -Append
}
After running that script, I found the following error:
The term 'msiexec' is not recognized as the name of a cmdlet, function, script file, or operable program..
It looks like the call to msiexec isn't actually targeting c:\windows\system32\msiexec.exe
As per this question it seems that Powershell does not use the standard PATH environment variable, but has its own scheme, which perhaps doesn't work as expected in the context of a system service.
The simplest resolution, as you say, is to specify the full path, which is probably c:\windows\system32\msiexec.exe.
However, in production, it would probably be wise to avoid the use of a hardcoded path, since you might run into problems with localization, operating system changes, and so on. You could perhaps use SearchPath or a .NET equivalent from your service and either write out the Powershell script in real time or pass the path to msiexec as a command-line option, or there may be a sensible Powershell solution.

.ps1 cannot be loaded because the execution of scripts is disabled on this system

I run this code to execute PowerShell code from an ASP.NET application:
System.Management.Automation.Runspaces.Runspace runspace = System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace();
runspace.Open();
System.Management.Automation.Runspaces.Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(#"\\servername\path");
pipeline.Commands.Add("Out-String");
Collection<PSObject> results = pipeline.Invoke();
runspace.Close();
But I am getting an error:
.ps1 cannot be loaded because the execution of scripts is disabled on
this system. Please see "get-help about_signing" for more details.
The same code runs fine from a command prompt or a windows (Windows Forms) application.
Your script is blocked from executing due to the execution policy.
You need to run PowerShell as administrator and set it on the client PC to Unrestricted. You can do that by calling Invoke with:
Set-ExecutionPolicy Unrestricted
There are certain scenarios in which you can follow the steps suggested in the other answers, verify that Execution Policy is set correctly, and still have your scripts fail. If this happens to you, you are probably on a 64-bit machine with both 32-bit and 64-bit versions of PowerShell, and the failure is happening on the version that doesn't have Execution Policy set. The setting does not apply to both versions, so you have to explicitly set it twice.
Look in your Windows directory for System32 and SysWOW64.
Repeat these steps for each directory:
Navigate to WindowsPowerShell\v1.0 and launch powershell.exe
Check the current setting for ExecutionPolicy:
Get-ExecutionPolicy -List
Set the ExecutionPolicy for the level and scope you want, for example:
Set-ExecutionPolicy -Scope LocalMachine Unrestricted
Note that you may need to run PowerShell as administrator depending on the scope you are trying to set the policy for.
The problem is that the execution policy is set on a per user basis. You'll need to run the following command in your application every time you run it to enable it to work:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned
There probably is a way to set this for the ASP.NET user as well, but this way means that you're not opening up your whole system, just your application.
(Source)
You need to run Set-ExecutionPolicy:
Set-ExecutionPolicy Unrestricted <-- Will allow unsigned PowerShell scripts to run.
Set-ExecutionPolicy Restricted <-- Will not allow unsigned PowerShell scripts to run.
Set-ExecutionPolicy RemoteSigned <-- Will allow only remotely signed PowerShell scripts to run.
I had a similar issue and noted that the default cmd on Windows Server 2012 was running the x64 one.
For Windows 7, Windows 8, Windows Server 2008 R2 or Windows Server 2012, run the following commands as Administrator:
x86
Open C:\Windows\SysWOW64\cmd.exe
Run the command: powershell Set-ExecutionPolicy RemoteSigned
x64
Open C:\Windows\system32\cmd.exe
Run the command powershell Set-ExecutionPolicy RemoteSigned
You can check mode using
In CMD: echo %PROCESSOR_ARCHITECTURE%
In Powershell: [Environment]::Is64BitProcess
I hope this helps you.
Try This:
Set-ExecutionPolicy -scope CurrentUser Unrestricted
If you faced this error while running json-server and landed here on this page.
one alternate solution is to run it using npx directly without installing it.
npx json-server --watch db.json

Categories