Pegar informações de uma maquina remota Windows por WMI utilizando a API JACOB

Ola Pessoal do GUJ ,

Boa tarde !

Estou com uma duvida GRANDE , estou tentando usar a API JACOB para pegar informações por WMI de outra maquina windows na rede , mas não estou conseguindo , só consigo pegar da maquina local.

Segue o fonte de exemplo para mostrar informações das contas de usuario na maquina local:


import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.EnumVariant;
import com.jacob.com.Variant;

/**
 * Quick little example of using JACOB (an open source Java-COM bridge) to access
 * the windows WMI interface.
 * <br>
 * To use this snippet you will need to download and install JACOB. This is relatively easy:
 * I just uncompressed the zip and put the jacob.jar and the dll into my classpath.
 * 
 * @author NickDMax (at) DreamInCode
 */
public class ListUsers {

	/**
	 * List the services currently running on the host computer.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		String host = "localhost"; //Technically you should be able to connect to other hosts, but it takes setup
		String connectStr = String.format("winmgmts:\\\\%s\\root\\CIMV2", host);
		String query = "SELECT * FROM Win32_UserAccount"; //Started = 1 means the service is running.
		//String query = "SELECT * FROM Win32_Account WHERE Name=\"Rafael\""; //Started = 1 means the service is running.
		ActiveXComponent axWMI = new ActiveXComponent(connectStr); 
		//Execute the query
		Variant vCollection = axWMI.invoke("ExecQuery", new Variant(query));
		
		//Our result is a collection, so we need to work though the.
		EnumVariant enumVariant = new EnumVariant(vCollection.toDispatch());
		Dispatch item = null;
		while (enumVariant.hasMoreElements()) { 
			System.out.println("*****Testando*****");
			item = enumVariant.nextElement().toDispatch();
			//Dispatch.call returns a Variant which we can convert to a java form.
			String sid = Dispatch.call(item,"SIDType").toString();
			System.out.println(sid);
			if( sid.equals("1") ) {
			try {
			String Nome = Dispatch.call(item,"Name").toString();
			String FullNome = Dispatch.call(item,"FullName").toString();
			String Descricao = Dispatch.call(item,"Description").toString();

			Boolean Habilitado = Dispatch.call( item,"Disabled").getBoolean();
			//int servicePID = Dispatch.call(item,"ProcessId").getInt();
			System.out.println("Login:"+Nome);
			System.out.println("Nome:"+FullNome);
			System.out.println("Descricao:"+Descricao);
			System.out.println("Desabilitado:"+Habilitado);
			} catch( Exception e ) {
				e.printStackTrace();
			}
			//System.exit(0);
			} // fim do if
				
		} 
			System.exit(0);
		
	}
	
}

Segue abaixo o fonte de uma das tentativas de tentar pegar de uma maquina remota:


import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.EnumVariant;
import com.jacob.com.Variant;

/**
 * Quick little example of using JACOB (an open source Java-COM bridge) to access
 * the windows WMI interface.
 * <br>
 * To use this snippet you will need to download and install JACOB. This is relatively easy:
 * I just uncompressed the zip and put the jacob.jar and the dll into my classpath.
 * 
 * @author NickDMax (at) DreamInCode
 */
public class ListUsers {

	/**
	 * List the services currently running on the host computer.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		String host = "192.168.1.3"; //Technically you should be able to connect to other hosts, but it takes setup
		String connectStr = String.format("WbemScripting.SWbemLocator");
//		String connectStr = String.format("winmgmts:\\\\%s\\root\\CIMV2", host);
//		String connectStr = String.format("winmgmts:root\\CIMV2:Win32_AccountUser");
		String query = "SELECT * FROM Win32_UserAccount"; //Started = 1 means the service is running.
		//String query = "SELECT * FROM Win32_Account WHERE Name=\"Rafael\""; //Started = 1 means the service is running.
		ActiveXComponent axWMI = new ActiveXComponent(connectStr); 
		//Execute the query
//		Variant vCollection = axWMI.invoke("ConnectServer", new Variant(host),new Variant("root\\cimv2"), new Variant("usuario"),new Variant("senha"));
		Variant vCollection = axWMI.invoke("ConnectServer",new Variant("\"192.168.1.3\",\"usuario\",\"senha\""));
		//vCollection.toDispatch();
		vCollection = axWMI.invoke("ExecQuery", new Variant(query));
		
		//Our result is a collection, so we need to work though the.
		EnumVariant enumVariant = new EnumVariant(vCollection.toDispatch());
		Dispatch item = null;
		while (enumVariant.hasMoreElements()) { 
			System.out.println("*****Testando*****");
			item = enumVariant.nextElement().toDispatch();
			//Dispatch.call returns a Variant which we can convert to a java form.
			String sid = Dispatch.call(item,"SIDType").toString();
			System.out.println(sid);
			if( sid.equals("1") ) {
			try {
			String Nome = Dispatch.call(item,"Name").toString();
			String FullNome = Dispatch.call(item,"FullName").toString();
			String Descricao = Dispatch.call(item,"Description").toString();

			Boolean Habilitado = Dispatch.call( item,"Disabled").getBoolean();
			//int servicePID = Dispatch.call(item,"ProcessId").getInt();
			System.out.println("Login:"+Nome);
			System.out.println("Nome:"+FullNome);
			System.out.println("Descricao:"+Descricao);
			System.out.println("Desabilitado:"+Habilitado);
			} catch( Exception e ) {
				e.printStackTrace();
			}
			//System.exit(0);
			} // fim do if
				
		} 
			System.exit(0);
		
	}
	
}

Mensagem de erro (e trava o prompt de comando):


E:\Testes_java>java -classpath .;jacob-1.15-M4\jacob.jar ListUsers
Exception in thread "main" com.jacob.com.ComFailException: Invoke of: ConnectSer
ver
Source: SWbemLocator
Description: O servidor RPC nÒo estß disponÝvel.

        at com.jacob.com.Dispatch.invokev(Native Method)
        at com.jacob.com.Dispatch.invokev(Dispatch.java:625)
        at com.jacob.com.Dispatch.callN(Dispatch.java:453)
        at com.jacob.activeX.ActiveXComponent.invoke(ActiveXComponent.java:476)
        at ListUsers.main(ListUsers.java:32)

Ja pesquisei no Google e em outros lugares mas não consegui fazer funcionar e com um outro programa eu consigo acessar as informações de uma maquina remota

Por favor se alguem puder me ajudar com um exemplo agradeço.

Desde já agradeço a todos !!!

Pessoal ,

Depois de muito quebrar a cabeça consegui fazer funcionar com a api com4j.

Segui a orientação do leofiuza nesse topico:

Peguei o exemplo e consegui pegar as informações tanto da maquina local como de uma maquina remota
O problema é que no exemplo , ele joga toda a informação na tela , provavelmente tem uma maneira de pegar somente o item desejado , mas como não sei ainda direito acabei implementando um metodo para tratar a informação ( um verdadeiro P.O.G (Programação Orientada a Gambiarras)no codigo rsrsrs…).

Segue a classe Main:



package usa_wmi;

import java.util.Vector;

/*
import wmi.ClassFactory;
import wmi.ISWbemLocator;
import wmi.ISWbemObject;
import wmi.ISWbemObjectSet;
import wmi.ISWbemServices;

import com4j.Com4jObject;
import com4j.stdole.IEnumVARIANT;
*/
public class Main {
    /**
     * 
     * @param args
     * @throws Exception
     */
	 
	 static StringBuffer texto_final = new StringBuffer(500);
	 static char letra;
	public static void main(String[] args) throws Exception {
    	try{
		
		Wmi wmi = new Wmi();
		Vector vetor = new Vector();
		vetor.add("Name");
		vetor.add("State");
		//vetor.add("Disabled");
		//System.out.println(wmi.executa("SELECT * FROM Win32_UserAccount",vetor,"localhost","",""));
		System.out.println(wmi.executa("SELECT * FROM Win32_Service",vetor,"animedesk","Rafael","abacaxi"));
		//System.out.println(wmi.executa("SELECT * FROM Win32_Service",vetor,"localhost","",""));
		//System.out.println(wmi.executa("SELECT * FROM Win32_Service",vetor,"localhost","",""));
		//System.out.println(wmi.executa("SELECT * FROM Win32_Service",vetor,"localhost","",""));
			/*
			 * Processor que vc pode executar:
			 * Win32_Processor | Win32_bios | Win32_Service | Win32_timezone | Win32_ComputerSystem
			 * Win32_OperatingSystem | Win32_Product
			 */
			}catch(Exception e){
    		e.printStackTrace();
    	}
	
	}
	
}
	

Segue a classe Wmi abaixo:


package usa_wmi;

import java.util.Vector;
import wmi.ClassFactory;
import wmi.ISWbemLocator;
import wmi.ISWbemObject;
import wmi.ISWbemObjectSet;
import wmi.ISWbemServices;

import com4j.Com4jObject;
import com4j.stdole.IEnumVARIANT;

public class Wmi {
    /**
     * 
     * @param args
     * @throws Exception
     */
	 
	public Vector executa (String str,Vector item_selecionado,String host,String user,String senha) throws Exception {
    	
		String item = new String();
		Vector vetor = new Vector();
		try{
			/*
			 * Processor que vc pode executar:
			 * Win32_Processor | Win32_bios | Win32_Service | Win32_timezone | Win32_ComputerSystem
			 * Win32_OperatingSystem | Win32_Product
			 */
			String strQuery = str;
	    	
	        ISWbemLocator wbemLocator = ClassFactory.createSWbemLocator();
	        ISWbemServices wbemServices = wbemLocator.connectServer(host,"Root\\CIMv2",user,senha,"","",0,null);
	        //para acessar outra máquina utilize:
	        //ISWbemServices wbemServices = wbemLocator.connectServer("ipmaquinadestino","Root\\CIMv2","usuario","senha","","",0,null);
	        ISWbemObjectSet result = wbemServices.execQuery(strQuery, "WQL", 16, null);
	        int i = 0;
			//item = new String();
	        for( Com4jObject obj : result ) {
	            ISWbemObject wo = obj.queryInterface(ISWbemObject.class);
				//wo.execMethod_("StopService",obj,0,obj);
	            System.out.println(wo.getObjectText_(0));
				//System.out.println("Teste:");
				//String valor = new String();
				
			
				item = wo.getObjectText_(0);
				
				while ( i < item_selecionado.size()  ) {
					System.out.println( item_selecionado.size());
					vetor.add( trata_info(item,(String) item_selecionado.get(i) ) );
					i++;
				
				}
				i = 0;
				
				//vetor.add(item);
				//int comeco = item.lastIndexOf("\n");
				//int ultimo = item.lastIndexOf(';');
				//System.out.println(comeco);
				//System.out.println(ultimo);
				//System.out.println(item.substring( 0, comeco ) );
				//System.out.println(item.length());
				
				//int i=1;
				
				
				
				/*
				while( i < item.length() ) {
					System.out.println("UIIIIIUIIOIIIIIII!!!!!");
					
					letra = item.charAt(i);
					texto_final.append(letra);
					System.out.println(texto_final);
					
					if( letra == '\n') {
					
						trata_info(item,"DomainRole");
						//return;
					}
				i++;
			    }
				*/
			//return;
			}
			//return;
		// trata_info(item,"Status");
		
    	}catch(Exception e){
    		e.printStackTrace();
    	}
		
//	return trata_info(item,item_selecionado);
	return vetor;
	
    }

// ***** DAQUI EM DIANTE É TUDO P.O.G
	
	public String trata_info (String source,String item) {
	
		StringBuffer texto_final = new StringBuffer(500);
		char letra;

		String resultado = "1";
		boolean liga_coleta = false;
		boolean chave_continua = false;
		
		int indice = source.indexOf(item);
		System.out.println("Valor do indice: " + indice);
		if( indice < 0 ) {
			
			return null;
		
		}
		

		while( source.charAt(indice-1) != '\t'  && source.charAt(indice+item.length()+1) != ' ' ) {
		System.out.println(indice);
			indice = source.indexOf(item,indice+1);
			chave_continua = true;
		
		} 
		
		if ( ! chave_continua ) {
			return null;
		}
		//indice = source.indexOf(item,indice+1);
		//System.out.println("Indice:"+indice);
		//System.out.println("Source:"+source.length());
		
		while( indice < source.length() ) {
				
			//System.out.println("******   UIIIIIUIIOIIIIIII!!!!!");
				
			letra = source.charAt(indice);
			
			if( letra == '=' ) {
			
				liga_coleta = true;
				indice++;
				indice++;
				letra = source.charAt(indice);
				
			}
			
			if(liga_coleta) {
			
				if( letra != '"' && letra != ';' ) {
				texto_final.append(letra);
				//System.out.println(texto_final);
				}
				
			}
			
			if( letra == '\n') {
				
				resultado = (String) texto_final.toString();
				return resultado;

					
			}
			
			indice++;
			
			}

	resultado = (String) texto_final.toString();
	return resultado;
	}
			

    
}

Agora estou tentando descobrir como mudar uma configuração da maquina local e remota por Wmi (pelo com4j) ( exemplo: stopar e startar serviço do windows , ativar e bloquear usuarios da maquina , etc…) se alguem tiver uma luz agradeço.

Senhores Gujeiros ,

Consegui pegar as informações do jeito correto (sem P.O.G) peguei o exemplo nesse link:

http://www.koders.com/java/fidD8CA01E7C8C8FB1F8B1D86620799B5739A056F16.aspx?s=main+args

E fiz uma leve modificação segue abaixo a classe WmiConnect:




import java.util.Vector;
import wmi.ClassFactory;
import wmi.ISWbemLocator;
import wmi.ISWbemObject;
import wmi.ISWbemObjectSet;
import wmi.ISWbemServices;
import wmi.ISWbemProperty;

import com4j.Com4jObject;
import com4j.stdole.IEnumVARIANT;

public class WmiConnect {
    /**
     * 
     * @param args
     * @throws Exception
     */
	 
	public Vector executa (String str,Vector item_selecionado,String host,String user,String senha) throws Exception {
    	
		String item = new String();
		Vector vetor = new Vector();
		try{
			/*
			 * Processor que vc pode executar:
			 * Win32_Processor | Win32_bios | Win32_Service | Win32_timezone | Win32_ComputerSystem
			 * Win32_OperatingSystem | Win32_Product
			 */
			String strQuery = str;
	    	
	        ISWbemLocator wbemLocator = ClassFactory.createSWbemLocator();
	        ISWbemServices wbemServices = wbemLocator.connectServer(host,"Root\\CIMv2",user,senha,"","",0,null);
	        //para acessar outra máquina utilize:
	        //ISWbemServices wbemServices = wbemLocator.connectServer("ipmaquinadestino","Root\\CIMv2","usuario","senha","","",0,null);
	        ISWbemObjectSet result = wbemServices.execQuery(strQuery, "WQL", 16, null);
	        int i = 0;
			//item = new String();
	        for( Com4jObject obj : result ) {
	            ISWbemObject wo = obj.queryInterface(ISWbemObject.class);
				//wo.execMethod_("StopService",obj,0,obj);
	            System.out.println(wo.getObjectText_(0));
				//System.out.println("Teste:");
				//String valor = new String();
				
			
				item = wo.getObjectText_(0);
				
				while ( i < item_selecionado.size()  ) {
					System.out.println( item_selecionado.size());

                                   // AQUI ele pega a informação que eu quero

		            ISWbemProperty s = wo.properties_( (String) item_selecionado.get(i), 0); // This is ok ...

					//vetor.add( trata_info(item,(String) item_selecionado.get(i) ) );
		            System.out.println("Valor:" + s.value());
		            
					vetor.add( s.value() );
					i++;
				
				}
				i = 0;
				
				
				//vetor.add(item);
				//int comeco = item.lastIndexOf("\n");
				//int ultimo = item.lastIndexOf(';');
				//System.out.println(comeco);
				//System.out.println(ultimo);
				//System.out.println(item.substring( 0, comeco ) );
				//System.out.println(item.length());
				
				//int i=1;
				
				
				
				/*
				while( i < item.length() ) {
					System.out.println("UIIIIIUIIOIIIIIII!!!!!");
					
					letra = item.charAt(i);
					texto_final.append(letra);
					System.out.println(texto_final);
					
					if( letra == '\n') {
					
						trata_info(item,"DomainRole");
						//return;
					}
				i++;
			    }
				*/
			//return;
			}
			//return;
		// trata_info(item,"Status");
		
    	}catch(Exception e){
    		e.printStackTrace();
    	}
		
//	return trata_info(item,item_selecionado);
	return vetor;
	
    }
	
}

Espero ter ajudado mais alguem.

Se for para fazer algo parecido com isso…
https://sites.google.com/site/lucasportela/home/controle-patrimonio-informatica
então podemos trocar algumas dicas.

lucasportela ,

Bom dia !!!

Na verdade estou desenvolvendo um pequeno aplicativo para implantar no meu trabalho.

Trabalho como Operador de infra-estrutura Jr. , e aonde trabalho temos 2 maquinas windows que são acessadas remotamente e todos os usuarios devem estar com acesso bloqueado , somente é liberado acesso quando o usuario for utilizar o acesso remoto.

O Procedimento antes era (levava aproximadamente 5 minutos) :

  • Usuário (Suporte/DBAs/etc…) precisa acessar remotamente.
  • Usuário entre em contato com operador
  • Operador entra em cada uma das 2 maquinas via VNC.
    -> acessa o VNC
    -> coloca a senha do VNC
    -> coloca o usuário e senha de administrador da maquina
    -> clica com direito em meu computador.
    -> e clica em gerenciar
    -> clica em usuários e grupos.
    -> procura o usuário na lista der usuarios da maquina
    -> clica com o botão direito e clica em propriedades.
    -> desmarca a opção usuário desabilitado.
    -> efetua logoff
    -> repete esse mesmos passos para a 2ª maquina
    -> Entra em contato com Usuário para informar que seu acesso esta liberado.
  • Apos usuário terminar de utilizar o acesso remoto
  • Usuário entra em contato com operador o qual efetua todos os procedimentos acima para bloquear o usuário nas 2 maquinas.

Desenvolvi um pequeno aplicativo (que esta em produção) em linguagem de script (TCL/TK) que habilita e bloqueia usuários com apenas o clique de um botão.

Veja procedimento atual ( menos de 10 segundos):

  • Usuario (Suporte/DBAs/etc…) precisa acessar remotamente.
  • Usuario entre em contato com operador
  • Operador inicia o aplicativo Adm Remote User.
    -> seleciona o usuário em um ComboBox.
    -> clica em ativar
    -> Avisa usuário que seu acesso esta liberado.
  • Apos utilização do usuário o mesmo entre em contato com operador o qual executa o procedimento acima e clica em bloquear.

O que eu estou desenvolvendo agora é uma segunda versão desse aplicativo reescrito em java usando WMI e adicionar algumas funcionalidades como:

  • Especificar um dia e horário para bloquear usuário automaticamente.
  • Visualizar quem esta logado nessas 2 maquinas (por WMI)
  • Por enquanto o utiliza o comando net user < usuário > /active:[yes|no] para ativar e bloquear usuários. ( !!! Alguém sabe fazer isso por WMI com Java e Com4j ?).

Conheço pouco de WMI a maioria dos exemplos que eu encontra é em VBS.

Desde já agradeço.

Boa tarde,

Muito interessante este software, se eu entendi bem, ele funciona como um gerenciador de acesso remoto, indicando quem e quando pode ser acessado, seria essa a idéia?

Este site pode te ajudar na implementação das suas funcionalidades…

http://www.robvanderwoude.com/ntadmincommands.php#Cmd01

Exatamente !!!

Obrigado pelo link estarei verificando.

Se alguém souber como bloquear e ativar usando o proprio Java/Wmi/Com4j ou outra API , ficarei agradecido.
Estarei pesquisando caso encontre a solução posto aqui.