Powershell Permissions not working remotely - c#

Have the same issue as here:
Run PowerShell script from ASP.NET
I am trying to run powershell scripts on the server through an asp.net webpage. It works on the local server but does not work remotely. Remotely it returns nothing as if the script worked.
I tried modifying the permissions with icacls.exe
icalc.exe c:\test.ps1 /grant "IIS AppPool\DefaultAppPool:(OI)(CI)F"
This had no effect. When I read what the permissions are:
icalcs c:\test.ps1
NT AUTHORITY\Authenticated Users:(I)(M)
NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Administrators:(I)(F)
BUILTIN\Users:(I)(RX)
I always get the same return even after I try and modify it. Where is IIS AppPool\DefaultAppPool?
Update
I have been using a script that just opens notepad for testing. When I run this locally notepad pops up. Remotely nothing seems to happen, but then I noticed in task manager there were tons of instances of notepad running. So it would seem that it is working but not how I expected. The end function I am trying accomplish is to add minimal remote capabilities. I also play movies off of my webserver and it would be nice to be able to remote some functions through my existing web interface. So the scripts would have to run on the current user. I suppose this may be better suited using WCF or another type of architecture, but it would be nice just to use my web interface for everything.

Make sure that PowerShell script execution has been updated on the remote server to allow script execution. If the web server runs as 32-bit then fire up an x86 PowerShell console on the machine in elevated (admin) mode and execute:
Set-ExecutionPolicy RemoteSigned
If the web page runs as 64-bit then do the same using a 64-bit elevated PowerShell console.

Related

Windows Server 2019 calling elevated powershell Hyper-V scripts from IIS (c# mvc)

as part of c# mvc application I'm merging hyper-v machines manager, start/stop maybe in future provisioning, however though as I am able to run powershell scripts in their simplest scope I cannot manage to get around the hyper-v cmdlets to work.
I have already tried to add my application pool to Hyper-V Administrators as this is WS2019 and administrators itself and that doesn't seem to work either. Moreover I've tried to create self-elevating ps scripts to get me through, running batch files failed and still nothing. I am using anonymous auth and don't know this might cause some issues, as I'm not so enthusiastic about.
c#
ps.AddScript(scriptPath);
ps.Invoke();
for start I need to be able to manage start/stop in some most elegant way possible. Best practices are most welcomed.
I will recommend that you create a dedicated Windows service application to run the Hyper-V cmdlets. This service can be configured to run with a proper user account that has sufficient privileges to run the cmdlets. Your webapp should communicate with this service via WCF. In this way, you will be able to run your webapp with the default low-privilege account and guarantee the security of your system.

Remote PowerShell sessions from C# under ApplicationPoolIdentity

Using a Library I found from Microsoft, I have been attempting (with C#) to provision email accounts for my users with Live#Edu and the library uses remote PowerShell sessions to do this. I have wrapped the PowerShell calls with a using() { } block that impersonates a local administrator account. When I run the code on my own development machine it works great and provisions the account on Live#Edu, yet when I run the same code on the production server I get an Access is Denied error from PowerShell.
What I just noticed is if I change the IIS Application Pool user on the server to my own domain account everything works fine on the production server, but leaving it as ApplicationPoolIdentity does not work. So it appears that even though in my code I impersonate a local administrator, those credentials are not being passed on to the PowerShell session. Oddly enough, when the scripts run on my own machine, also under ApplicationPoolIdentity, there is no problem and that leads me to believe that the script is actually running under my own account on my machine (and I am a local administrator).
I did have the code spit out the value of $env:username and it gave me the machine name and I was expecting it to give me the actual username it runs under since that is what I get when I type that command directly into a PowerShell window.
When logged in to the remote server interactively using the credentials that I have been impersonating in code, I can manually type all of the PowerShell cmdlts into a PowerShell window and they work fine.
I don't want to have my IIS Application Pool always running under an administrator account as that sees foolish so is there a way of running the PowerShell script as an administrator that goes further than the current impersonation that I am doing?
UPDATE:
There was an odd thing that happened that sees to work as a solution for me. After deploying my code to the server I created added a local administrator account. I then went to the IIS Application Pool and changed the owner from ApplicationPoolIdentity to the admin account I just created. After that the page would work fine to run the PowerShell script. I already knew this from before, but didn't want to have IIS using an admin account. I then proceeded to set the Application Pool back to ApplicationPoolIdentity and removed the Local Admin account and the page still works!? I restarted IIS, and the Web Server itself, and everything works. All I can think is that moving the Application Pool over to an Admin account changed some attribute in the App pool permanently. I have now put a modified question on ServerFault.
Turns out the issue had to do with the Load User Profile option in the IIS App Pool for my app being set to False on the server (False is the default for Windows Server 2008). After reading up on this property I am not entirely sure why this matters for my scenario, but that was the one setting different in IIS on my local machine from what the Web Server had. Now all the PowerShell calls work flawlessly on the server.

C# - command line application calls

I have done plenty of C# shell command calls, apps, batch files etc. The other day I was asked if it would be a problem if an executable that I currently run from my web site app, would move to another server on our intranet.
In other words the web site app and the executable that I am running through Process.Start(...) are located on the same box currently - all good there. Now there is a wish to separate the two on two different servers.
I done a few futile attempts to execute an app (located on server B) from server A (where the web site resides).
Is there a way that I have not run cross yet to do this ?
Thanks
PsExec is one way with minimal coding. Using System.Diagnostic.Process, you can call this command:
psexec \\ServerB (path)\myapp.exe arg0 arg1 ...
To control the processes of server A by running an application on server B, you would need an application running on server B that would get controlled remotely somehow.
As an example, let's say server A runs unix, so you could write a application that would connect to server A using ssh, authenticate and then control the processes and whatnot like you do in a shell. If server A does not allow ssh connection, you could write your own application that would be running on server A listening to some connection and commands that would come from an application in server B.
It's quite hard to understand what are your current settings and why would you even want to switch the application from server A to server B, so a little more information would wield you a better answer.
Austin's PSExec approach is probably the easiest approach to executing an EXE on a remote machine, but you may want to consider a potentially more robust solution:
You could modify your command-line app to run as a service and to respond to requests for work and/or data via a WCF (binaryXML/TCP or XML/HTTP) call.

How to start process from ASP.NET Web Service (and allow to it to do everything what it wants to do)?

There is a Web Service installed on Amazon Server. Exposed WebMethod should start an executable. But, it seems that process (executable) started by WebMethod has not permissions to finish its job. If a WebMethod is called locally (using IE on Amazon VM) I can trace some events into log file placed on the path: C:\\LogFiles. But, if it is called from remote machine, there is no even log files. Locally, on my machine all works fine.
The question: is there any way or settings in IIS7 to allow to my WebService to create process that can do everything I want to do? In web.config file I added a line:
<identity impersonate="true" userName="USERNAME" password="password"/>
(userName and password are, of course, written correctly in the file).
Also, I tried to use impersonization as it is explained here, but there is no result. My process can't do its job, it cannot even trace actions into log file. Locally, on my machine, everything works fine.
Any idea how to change settings or whatever into IIS7?
EDIT: In addition to the main question: my WebService is not able even to create log files on the path: C:\\LogFiles - although it is able if it started locally, but remotely there is no simple log file that contains some string. How to allow it to create simple text files?
If all else fails, you may start such a process separately and make it wait for a signal. You can supply a signal in many ways — via an IP socket, via a mailslot, via a named pipe. The web service will post requests to the command pipe (or queue), and the 'executor' process will pop commands, execute them, and wait for more commands.
You should avoid trying to start external processes from ASP.NET - if anything, because your application will then be running under the context of the ASP.NET account. (Yes, you could use impersonation to launch into another account, but, lets not go there)
Instead, install a Windows Service which can receive a signal* to launch the executable you wish.
This has the advantage that you can customise what account the service runs under, without putting passwords inside your code.
(*) Signalling could be achieved through a number of means:
WCF Service Call (using a WCF Service being hosted by the Windows service)
Monitoring for a filesystem change to a known directory.
If you were using Linux, I would have given you the smartest solution ever, setting SUID flag, which is not possible in Windows.
The problem with impersonation is that it works as soon as you have some control over the server machine, more than having appropriate credentials.
You mentioned Amazon VM: I'm pretty certain that they won't allow, for security reasons, to perfrom impersonation. [Add] Or, better, they won't allow anybody to write in C:\
Option 1
Switch to Mono/Linux, set SUID bit using chmod from console and rock!!
Option 2
If you can run the executable other way than ASP.NET (ie. you have a Remote Desktop, SSH*) as privileged account (note: privileged doesn't mean Administrator) then you can redesign your application to have ASP.NET invoke services from your daemon process using WCF, Web Services or Remoting. But, in this case, you have to redesign your executable to be a stand-alone server.
[Add] None of the solution fix if your hosting provider doesn't allow you to write in paths such as C:\, but only allows you to write under your home directory.
*It works on Windows too!!!! And I mean the server!!!

invoke exe(with GUI) on remote machine

can we invoke exe of application(made in .net) on remote server using local machine.
we have full credentail on all machine to execute process.
how can we achive that ?its require to open GUI on remote machine.
we tried using WMI/.dat file invoke but all opens process on Task Manager & could not lunch GUI..
anyone have idea to accomplish same??
You can use psexec for this.
http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx
At one point in time, you could write a Windows Service, run it under the local system account, and allow it to interact with the desktop. However, this will only work on Windows XP. Vista (and I assume Windows 7) show the UAC prompt first, which is annoying and sometimes only shows up on the taskbar until it's clicked.
We got around this by writing a WinForms app that had no visibility on its own, but this app watches for a trigger. When the trigger occurs, the program then launches the appropriate exe.
For example, the trigger may specify to open up a web page on our intra net. The program uses the System.Diagnostics.Process.tart() to launch the web page in the default browser.
The trigger can be one of many things... The exe can poll a database, web service, etc. The exe can host a WCF host use remoting, or it could use a FileSystemWatcher.
The most complicated part of writing such an app is figuring out the appropriate trigger. Launching the app is trivial using the System.Diagnostics.Process.
For our situation, we set the program up to just launch when Windows starts, USG a registry setting.
Use PsExec tools
with -i switch
Like
psexec \\remotecomputer -u username -p password -i 2 "your exe loacation"

Categories