Running PowerShell from Java loading 3rd party Modules - ResourceUnavailable: FileNotFoundException

772 views Asked by At

I'm porting over a PS4 script that is leveraging a 3rd party modules (NetCmdlets) and works perfectly fine from the Powershell window, but seems to have lost track of how to load 3rd party modules when run from a Java Program.

I'd be interested in anyone's thoughts as to a potential cause and solution to this...

Here is the Calling Java PGM:

package ImagineOne.PSJava2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ExecuteCommand {

 /**
  * @param args
  * @throws IOException 
  */
 public static void main(String[] args) throws IOException {

  // This is the command
 //  String command = "powershell.exe  $PSVersionTable.PSVersion | Get-Member";
 // String command = "powershell.exe  C:\\Users\\versaggi\\Desktop\\PowerCLI\\DevScripts\\CANES_VMWare_Extraction_Functions.ps1";
 String command = "powershell.exe  C:\\Users\\versaggi\\Desktop\\PowerCLI\\DevScripts\\CANES_IBM_RackSwitch_Extraction_Functions.ps1";

  Process powerShellProcess = Runtime.getRuntime().exec(command);
  powerShellProcess.getOutputStream().close();
  String line;

  System.out.println("Output:");
  BufferedReader stdout = new BufferedReader(new InputStreamReader(powerShellProcess.getInputStream()));

  while ((line = stdout.readLine()) != null) {
   System.out.println(line);
  }

  stdout.close();
  System.out.println("Error:");
  BufferedReader stderr = new BufferedReader(new InputStreamReader(powerShellProcess.getErrorStream()));

  while ((line = stderr.readLine()) != null) {
   System.out.println(line);
  }

  stderr.close();
  System.out.println("Done");

 }

} //End Class

This is the OUTPUT:

Output:
** NetCmdlets Modules Loaded ** 
** Disconnected from RackSwitch ** 
Error:
Import-Module : **The specified module 'C:\Windows\System32\WindowsPowerShell\v1.
0\Modules\NetCmdlets\NetCmdlets.psd1' was not loaded because no valid module 
file was found in any module directory**.At C:\Users\versaggi\Desktop\PowerCLI\De
vScripts\CANES_IBM_RackSwitch_Extraction_Functions.ps1:732 char:1
+ Import-Module 
C:\Windows\System32\WindowsPowerShell\v1.0\Modules\NetCmdlets\NetC ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~
    + CategoryInfo          : ResourceUnavailable: (C:\Windows\Syst...NetCmdle 
   ts.psd1:String) [Import-Module], FileNotFoundException
    + FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Comm 
   ands.ImportModuleCommand

Done

This is the PowerShell Script: (which is only supposed to load the modules as a test [proof of concept])

Import-Module C:\Windows\System32\WindowsPowerShell\v1.0\Modules\NetCmdlets\NetCmdlets.psd1

write-host "** NetCmdlets Modules Loaded ** "

Some R&D I've perused to consider:

http://technirman.blogspot.com/2014/06/invoke-powershell-commands-through-java.html

https://blogs.oracle.com/vaibhav/entry/not_as_easy_as_we

https://social.technet.microsoft.com/Forums/windowsserver/en-US/d32537bd-0aef-440e-8760-6b3085390c37/executing-powershell-script-via-java?forum=winserverpowershell

1

There are 1 answers

0
ProfVersaggi On

I have fixed the Java/Powershell interoperability issue just now. On a hunch (after some digging into what VMware did w/their modules which never had problem) I surmised that the NetCmdlets had installed their modules in a protected space (see dir below) in the Windows OS by default. After moving to an unprotected user space (See dir Below) it worked just fine. I even did some stress testing and it stood up well.

Protected Win OS Space:

$PSHome\Modules (%Windir%\System32\WindowsPowerShell\v1.0\Modules) 

Unprotected Space:

C:\Users\versaggi\Desktop\PowerCLI\windowspowershell\modules

Per the Windows Docs on the Subject:

Install Modules in PSModulePath

Whenever possible, install all modules in a path that is listed in the PSModulePath environment variable or add the module path to the PSModulePath environment variable value. The PSModulePath environment variable ($env:PSModulePath) contains the locations of Windows PowerShell modules. Cmdlets rely on the value of this environment variable to find modules.

By default, the PSModulePath environment variable value contains the following system and user module directories, but you can add to and edit the value.

$PSHome\Modules (%Windir%\System32\WindowsPowerShell\v1.0\Modules)

Warning Caution:

This location is reserved for modules that ship with Windows. Do not install modules to this location.