Search code examples
javapowershellactive-directorycommandcommand-execution

executing ADS related Powershell command through Java does not work giving 2 different errors when using 2 different ways


I have been trying to execute a set of commands in a powershell session through java, with no luck yet. My aim is to search a computer object in AD with the domain = "domain.com".

I started with a single command. Unfortunately, the following command successfully runs in my powershell prompt:

Get-ADComputer -Filter { Name -like "hostname" } –Server a.b.c.d:3268 -SearchBase 'DC=domain,DC=com' | FT DNSHostName
# hostname is actual hostname provided by user and accepted in argument of Java methods
# a.b.c.d is the IP-Address of my domain controller, and I'm trying to search a computer object in AD with the domain = "domain.com".

But, it produces different exceptions/errors with 2 different approaches.

  1. I have tried the basic way of executing powershell commands, and then passing the command as argument to it. That did not work, resulted in different error described below.

  2. Next, I tried using jPowerShell library (profesorfalken) with no luck again. Check the error in the last


Code for first attempt:

public String executeCommand(String hostname){
        String output = "";
        try{
//          String firstPartCommand = "Get-ADComputer -Filter { Name -like (", secondPartCommand = ") } –Server a.b.c.d:3268 -SearchBase 'DC=domain,DC=com' | FT DNSHostName"; 
            String firstPartCommand = "Get-ADComputer -Filter { Name -like \""+hostname+"\" } –Server a.b.c.d:3268 -SearchBase \'DC=domain,DC=com\' | FT DNSHostName"; 

            Runtime rt = Runtime.getRuntime();
            String[] cmds = new String[]{
                "powershell.exe", firstPartCommand.trim()
            };
            System.out.println(firstPartCommand);

            Process pr = rt.exec(cmds);
            pr.getOutputStream().close();
            BufferedReader stdInput = new BufferedReader(new InputStreamReader(pr.getInputStream()));
            BufferedReader stdError = new BufferedReader(new InputStreamReader(pr.getErrorStream()));

            System.out.println("Here is the standard output of the command:\n");
            String s = null;
            while ((s = stdInput.readLine()) != null) {
            System.out.println(s+" -> OUTPUT");
            output+=s;
            //displayTF.setText(s);
            }
            stdInput.close();
            System.out.println("Here is the standard error of the command (if any):\n");
            while ((s = stdError.readLine()) != null) {
            System.out.println(s+" -> ERROR");
            }
            stdError.close();
            return output;
        }
        catch(Exception ex){
            ex.printStackTrace(System.out);
            output = "Some exception occured, SORRY!";
            return output;
        }
    }

Output:

Get-ADComputer -Filter { Name -like "hostname" } –Server a.b.c.d:3268 -SearchBase 'DC=domain,DC=com' | FT DNSHostName

Here is the standard output of the command:

Here is the standard error of the command (if any):

Get-ADComputer : Error parsing query: ' Name -like hostname' Error Message: 'syntax error' at position: '13'. -> ERROR At line:1 char:1 -> ERROR + Get-ADComputer -Filter { Name -like hostname} -Server a.b.c.d ... -> ERROR + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -> ERROR + CategoryInfo : ParserError: (:) [Get-ADComputer], ADFilterParsingException -> ERROR + FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADFilterParsingException,Micr -> ERROR osoft.ActiveDirectory.Management.Commands.GetADComputer -> ERROR -> ERROR


Code for second attempt:

public String execute(String hostname){
        String output = "";
        PowerShell powershell = null;
        try{            
            powershell = PowerShell.openSession();
//            String cmd = "$variable = \""+hostname+"\"";
//            //Execute a command in PowerShell session
//            PowerShellResponse response = powershell.executeCommand(cmd);
//            //Print results
//            System.out.println("Variable Initialisation:" + response.getCommandOutput());
            String firstPartCommand = "Get-ADComputer -Filter { Name -like \"", secondPartCommand = "\" } –Server 10.0.239.236:3268 -SearchBase 'DC=AD,DC=SBI' | FT DNSHostName"; 
            String finalCommand = firstPartCommand+hostname+secondPartCommand;
            System.out.println(finalCommand);
            PowerShellResponse response = powershell.executeCommand(finalCommand);
            //PowerShellResponse response = powershell.executeCommand("Get-Process powershell -FileVersionInfo");
            output = response.getCommandOutput();
            System.out.println("Search result: "+hostname+"\n" + output);
            return output;
        }
        catch(Exception ex){
            return "Failed!";
        }
        finally {
       //Always close PowerShell session to free resources.
            if (powershell != null)
                powershell.close();
        }
    }

Output:

Get-ADComputer -Filter { Name -like "hostname" } –Server a.b.c.d:3268 -SearchBase 'DC=domain,DC=com' | FT DNSHostName

Search result: hostname

Get-ADComputer : A positional parameter cannot be found that accepts argument '–Server'. At line:1 char:1 + Get-ADComputer -Filter { Name -like "hostname" } –Server a.b.c.d ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Get-ADComputer], ParameterBindingException + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.ActiveDirectory.Management.Commands.GetADComputer


From what I've searched and understood, the hostname which is passed to the Java method is not getting treated as a string in the powershell. These errors are pertaining to powershell, which I'm not much experienced with.


EDIT: After Mathias R. Jessen's reply, I'm not getting any error in the 2nd case; but, it seems the library itself is not correct up to the mark.

So, talking about the first method, I'm getting the error as mentioned in the first case. I want to get on with the first method only!

I have, almost, lost my faith in the external jPowershell JAR. I'm not getting the error in the 2nd output; but, neither getting the output. It behaves as if there is no output of the command!

Request to kindly help me solve this problem!


Solution

  • After struggling for almost 3 days, I found the problem to be in the command string, as expected.

    The correct command (for the first case) should be:

    String firstPartCommand = "Get-ADComputer -Filter { Name -eq \'"+hostname+"\' } 
    -Server a.b.c.d:3268 -SearchBase \'DC=domain,DC=com\' | Select DNSHostName";
    

    The correct command (for the second case) should be:

    String firstPartCommand = "Get-ADComputer -Filter { Name -eq \'", 
    secondPartCommand = "\' }  -Server a.b.c.d:3268 -SearchBase \'DC=domain,DC=com\' |
     Select DNSHostName";