Powershell: Execute exe on remote server and capture output

5

I am trying to script the execution of an installer on remote web servers. The installer in question is also a Windows Service that hosts NServiceBus. If RDP'd into the server, the application is installed by the following command:

&"$theInstaller" /install /serviceName:TheServiceName

The installer prints output about its progress registering the service and connecting to the database to stdout, among other things.

This works fine from an RDP session, but when I execute it remotely via PS, I get a you-can't-do-this-over-the-network message if I execute it directly or via Invoke-Command -computername $theRemoteServer:

System.IO.FileLoadException: Could not load file or assembly 'file://\\theRemoteServer\c$ \thePath\AutoMapper.dll' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515) ---> System.NotSupportedException: An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information.

(Note: I added an additional "\" to the path in the first line in order to get it to show up correctly in the preview on this site.)

This, and other DLLs, are loaded by the service, and the service's execution context cannot, apparently, be remotified.

I have also tried using Invoke-WmiMethod, which does something, but it's not clear what, and the output from the installer is lost:

Invoke-WMIMethod win32_process create '"$theInstaller" /install /serviceName:TheServiceName' -ComputerName $server (with and without cmd.exe /k before the intaller reference):

__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 2
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ProcessId :
ReturnValue : 9

How does one remotely execute such an EXE and capture the output?

powershell
remote
asked on Server Fault Sep 28, 2012 by user364825 • edited Sep 28, 2012 by Starfish

3 Answers

3

Remotely execute it locally... by which I mean, execute it on the remote server in a local context, remotely, from your local machine. Well, maybe it'd just be less confusing to read on...

Sounds like your best bet here is to use PSExec to open a remote PowerShell console or command line from your local machine, which would be executing on the remote server.

So, for example:

psexec \\remoteserver cmd.exe

or

psexec \\remoteserver powershell.exe

You end up with an instance of PowerShell or cmd running on the remote server, that you'd be manipulating on your screen.

answered on Server Fault Sep 28, 2012 by HopelessN00b
3

Okay...this works:

invoke-command $remoteServer { param($installer)  cmd /c "$installer" /install /serviceName:TheServiceName } -ArgumentList $installer

where $remoteServer is the name of the remote server, $installer is the UNC path to the installer on that remote server, and TheServiceName is the service name.

However, I also had to supply special configuration to enable the exe to be invoked over the network, as in this article: http://through-the-interface.typepad.com/through_the_interface/2011/07/loading-blocked-and-network-hosted-assemblies-with-net-4.html

So this trick is to configure the service to be remotifiable, and then you can invoke-command it.

answered on Server Fault Sep 28, 2012 by user364825 • edited Sep 28, 2012 by Starfish
1

Another way to crack the nut without having to change the application-under-deployment configuration:

# increase memory available to WsMan (run from elevated PS instance on remote machine)
set-item wsman:localhost\Shell\MaxMemoryPerShellMB 2048

# for PowerShell v3 or higher this line is also necessary
Set-Item WSMan:\localhost\Plugin\Microsoft.PowerShell\Quotas\MaxMemoryPerShellMB 2048

# add remote work to script on remote server, and then call that script from the local script
invoke-command $remoteServer { param($remoteScript, $arg1, $arg2, $arg3) powershell $script $arg1  $arg2 $arg3 } -ArgumentList $remoteScript, $arg1, $arg2, $arg3
answered on Server Fault Sep 30, 2012 by user364825 • edited Jul 23, 2013 by Community

User contributions licensed under CC BY-SA 3.0