I'm trying to run a basic powershell script in a c# application, but I can't seem to get it to run. I've tried this code with and without the added execution policy code in the pipeline creation and have gotten the same results.
static void Main(string[] args)
{
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline("Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned");
pipeline.Commands.Add(#"C:\Users\Bob\Desktop\testScript.ps1");
// Execute PowerShell script
var results = pipeline.Invoke();
}
The error I receive is this:
System.Management.Automation.PSSecurityException: 'File C:\Users\Bob\Desktop\testScript.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https://go.microsoft.com/fwlink/?LinkID=135170.'
When I run "get-executionpolicy -list", my execution policy seems to be fine.
Normally, the persistently configured script execution policy applies to PowerShell SDK-based projects such as yours, too.
While your Get-ExecutionPolicy -List output implies that RemoteSigned is the effective policy (as reported when you omit -List), the color of your screenshots suggest that you were asking for Windows PowerShell's policy, which is separate from the execution policy for the cross-platform, install-on demand PowerShell (Core) v6+ edition.
Therefore, your inability to execute a local script - which RemoteSigned should allow - can have one of two causes:
If you project is based on the SDK for PowerShell (Core) v6+ (via the Microsoft.PowerShell.SDK NuGet package), you'd have to consult - and possibly modify - its effective execution policy (run pwsh -c Get-ExecutionPolicy to see the policy in effect)
If you don't actually have PowerShell (Core) 6+ itself installed (i.e if you're only using its SDK), use the solution in the bottom section - which may be preferable anyway.
As Mathias points out in a comment, another possible reason is that your local script may have been downloaded from the web, via a web browser, in which case it is considered a remote file for the purpose of the execution policy. Passing its file path to Unblock-File as a one-time action should fix the problem.
Taking a step back:
If you trust the local script to invoke, you can bypass the execution policy for your application only, by configuring your PowerShell SDK session accordingly - see this answer.
Related
I wrote a PowerShell script it works just fine when I run it in PowerShell ISE as an admin.
But when I run it from my C# code it doesn't work:
InitialSessionState runspaceConfiguration = InitialSessionState.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
string rawScript = File.ReadAllText(scriptPath);
using (PowerShell posh = PowerShell.Create().AddCommand(#scriptPath))
{
string script = "Set-ExecutionPolicy -Scope Process -ExecutionPolicy Unrestricted; Get-ExecutionPolicy"; // the second command to know the ExecutionPolicy level
posh.AddScript(script);
foreach (DictionaryEntry de in parameters)
{
posh.AddArgument($"{(string)de.Key}, {de.Value}");
}
posh.Invoke();
Collection<PSObject> psObjects = pipeline.Invoke();
runspace.Close();
}
I tried setting ExecutionPolicy to unrestricted, and running Visual Studio as an admin but it didn't work
You can use the Turn on Script Execution Group Policy setting to manage the execution policy of computers in your enterprise. The Group Policy setting overrides the execution policies set in PowerShell in all scopes.
The Turn on Script Execution policy settings are as follows:
If you disable Turn on Script Execution, scripts do not run. This is equivalent to the Restricted execution policy.
If you enable Turn on Script Execution, you can select an execution policy. The Group Policy settings are equivalent to the following execution policy settings:
The PowerShellExecutionPolicy.adm and PowerShellExecutionPolicy.admx files add the Turn on Script Execution policy to the Computer Configuration and User Configuration nodes in Group Policy Editor in the following paths.
For Windows XP and Windows Server 2003:
Administrative Templates\Windows Components\Windows PowerShell
For Windows Vista and later versions of Windows:
Administrative Templates\Classic Administrative Templates\Windows Components\Windows PowerShell
Policies set in the Computer Configuration node take precedence over policies set in the User Configuration node.
I have written a Console application that makes an HTTP POST to a ASMX Web Service (within Sharepoint) that I am looking to invoke remotely with WinRM. I have written a PowerShell process that bundles up the built application, moves it to the destination server, and executes it locally. The process works completely fine (ie moving copying, what-have-you), but fails when it gets to the Web Service call. Looking at logs on Fiddler, the HTTP Post request has no credentials in it at all, even though the application is being ran with an account that has all the proper permissions.
Since the application is moved to the destination server locally, I can run it locally, which I have done, and it works completely fine, as the Fiddler logs show the correct credentials in the header.
I am not sure where the issue resides, but I am having a hard time thinking its my code, since it works fine when ran locally. It may be with the WinRM process, but the exact same process works for other environments (this project is part of a larger deployment solution that deploys databases, ssis packages , etc).
I am happy to provide code of certain pieces if needed, and any basic troubleshooting advice would be greatly appreciated.
EDIT
The user credentials I specify in a xml file that contains the username and a hashed password, like this in Powershell
powershell.exe -version 3.0 -ExecutionPolicy RemoteSigned -command "& { $cred=Import-Clixml '%CREDENTIAL_FILENAME%' ; $cred.Password=ConvertTo-SecureString $cred.Password ; $Credential=New-Object System.Management.Automation.PsCredential($cred.UserName, $cred.Password) ; invoke-command -computername %MACHINE% -filepath %Result% -Credential $Credential }"
I am trying to run EMC commands in C#. I am running this from my personal PC that has exchange management tools installed on it.
Our exchange servers have 2007 running on them.
The thing is, when I run Powershell or EMC, I need to run as a different user that has exchange server 2007 permissions since my individual profile doesn't have these permissions.
That being said, this is my code I have running on my personal PC:
RunspaceConfiguration config = RunspaceConfiguration.Create();
PSSnapInException snapEx = null;
PSSnapInInfo info = config.AddPSSnapIn("Microsoft.Exchange.Management.Powershell.Admin", out snapEx);
Runspace runspace = RunspaceFactory.CreateRunspace(config);
runspace.Open();
Command createCMD = new Command("Get-Mailbox ID");
Pipeline pipe = runspace.CreatePipeline();
pipe.Commands.Add(createCMD);
Collection<PSObject> results = pipe.Invoke();
The error I am getting is:
The Windows PowerShell snap-in Microsoft.Exchange.Management.Powershell.Admin is not installed on this computer.
I am getting it when I try and add the Microsoft.Exchange.Management.Powershell.Admin snapIn.
I feel this has something to do with my permissions on my individual profile, but I am not entirely sure. If it is true, how do I fix this.
EDIT
The reason I say it sounds like permissions is because I am able to open powershell and add the snapin. However when I run a command such as get-mailboxstatistics myUserId it throws an error saying MyServer\MyStorageGroup does not exist. However, when I shift-rightCLick and run as different user and use the credentials of my exchange admin account, I am able to run these commands.
If an error says it is not installed on your computer, why do you suspect it has something to do with permissions?
As this post suggests, please check if you have installed the 2007 version of the tools, as the Snapin in question is not available on the 2010 version.
Try the following steps:
Open up a powershell editor of your choice and add the PSSnapin there. If it works, the Snapin is available, if not, it is really not installed on your machine.
If it is available try to set your build configuration from x86 to 64bit or vice versa.
Eventually you can install the .dll in question by hand. Referring to this answer from Keith hill you have to issue the following Powershell commands
$snapinPath = 'Microsoft.Exchange.Management.PowerShell.Admin.dll'
C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe /i $snapinPath
Errors like this are often a 32 bit/64 bit problem. For example, the snapin might be registered as a 32 bit and your C# program is 64 bit or vice versa.
Sometimes you can fix this by running the other version of InstallUtil, e.g.
$snapinPath = 'Microsoft.Exchange.Management.PowerShell.Admin.dll'
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\InstallUtil.exe /i $snapinPath
After fixing that, I think you'll hit another problem with how you're creating the command. You don't specify arguments when creating a command. Instead, you write something like:
Command createCMD = new Command("Get-Mailbox");
createCMD.Parameters.Add(null, "ID");
I have been running my code for past few months by doing this -
Set-ExecutionPolicy Unrestricted
But, something weird is happening and I am getting this error always -
Windows PowerShell updated your execution policy successfully, but the
setting is overridden by a policy defined at a more specific scope.
Due to the override, your shell will retain its current effective
execution policy of "Unrestricted". Type "Get-ExecutionPolicy -List"
to view your execution policy settings. For more information, please
see "Get-Help Set-ExecutionPolicy."
I have referred these links but no luck -
http://blogs.msdn.com/b/pasen/archive/2011/12/07/set-executionpolicy-windows-powershell-updated-your-execution-policy-successfully-but-the-setting-is-overridden-by-a-policy-defined-at-a-more-specific-scope.aspx
http://blog.whatsupduck.net/2010/09/issues-with-configuring-powershell.html
http://www.howtogeek.com/106273/how-to-allow-the-execution-of-powershell-scripts-on-windows-7/
I am loading the Powershell using C# on a 64-bit Windows 7 via a 32-Bit Winforms Application using .Net 4.0
What is the exact setting which I need to do such that I do not get this error on any system ? [Everything was working fine]. What should these values be on any system such that I am able to call Powershell from C# seamlessly -
Get-ExecutionPolicy -List
MachinePolicy
UserPolicy
Process
CurrentUser
LocalMachine
You should see output like this from Get-ExecutionPolicy -List:
Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser Undefined
LocalMachine RemoteSigned
Once you see the scope that has the undesired setting, you can reset it like so:
Set-ExecutionPolicy Undefined -Scope <scope-name>
That is assuming you have permission to do so.
I am trying to create a setup package that not only installs our app but also copies files to a remote app server and installs a service there. I thought that I would just override the install method in a custom action to have it kick off a powershell script to copy the files. Unfortunately when the code calls the powershell script I get this CmdletProviderInvocationException:
The system detected a possible attempt to compromise security. Please ensure that you can contact the server that authenticated you.
I was able to copy the code I am using to call the powershell script into a test project and it ran just fine, as I would expect since I have logged in to the server through windows explorer and so my user should be authenticated. I think the reason the script won't work when called by the installer must be that the installer switches users in order to get admin permissions to install the app, and the admin user is not authenticated (although I could be wrong).
Does anyone know how I could get this to work?
Here's the custom action code:
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
string scriptLoc = "c:\\sampleLocation";
pipeline.Commands.AddScript("&\"" + scriptLoc + "\\script.ps1\"");
Collection<PSObject> results = pipeline.Invoke();
runspace.Close();
and here's the script:
$RemotePath = "\\SERVER\C$\Shared\Service"
$Source = "C:\sampleLocation\Service"
Get-ChildItem $Source -Recurse | Copy-Item -Destination $RemotePath
There are two major requirements for copying files to a network location:
your custom action should run without impersonation
the network location should have full permissions for Everyone
A MSI installation runs under the local system account. So it doesn't matter if you have permissions or not.
Since it's not easy to give permissions to SYSTEM account from a network machine, the easiest approach is to give full permissions to Everyone. This needs to be done on the machine which contains the shared folder.
According to #Cosmin Pirvu and Microsoft documentation :
The LocalSystem account is a predefined local account used by the service control manager. It has extensive privileges on the local computer, and acts as the computer on the network.
If your shared folder is on a computer that is on a domain, you can give full permissions to the client computer in spite giving it to Everyone.