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?

3 Answers 3

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.

2
  • Interesting. I had tried a remote PS session, but not a remote PS shell instance. I will try that. Thanks!
    – user364825
    Sep 28, 2012 at 15:42
  • Okay, finally got a chance to try this. Both of your suggested lines (using our server name, obviously) cause PS to hang. I did the get the following to work psexec \\ourServer cmd /c “echo . | powershell dir ‘c:\program files’” although PSExec returns an error at the start: PsExec.exe : At line:1 char:7 + psexec <<<< \\ourServer cmd /c “echo . | powershell dir ‘c:\program files’” + CategoryInfo : NotSpecified: (:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError
    – user364825
    Sep 28, 2012 at 19:29
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.

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .