fusioninventory / fusioninventory-agent

FusionInventory Agent
http://fusioninventory.org/
GNU General Public License v2.0
254 stars 126 forks source link

Création de tâche de collect #325

Closed yann83 closed 5 years ago

yann83 commented 7 years ago

Bonjour,

Serait il possible de rajouter dans la documentation un guide des bonnes pratique pour créer une tâche de collect.

J'ai sur un serveur de test uWAMP Glpi0.91.1 avec le plugin fusioninventory-for-glpi_9.1.1.1.tar et fusioninventory-agent_windows-x64_2.3.20, installé avec le module Collect. L'inventaire fonctionne mais impossible de faire fonctionner la Collect, dans le log il indique qu'il ne trouve pas de Tâche de collect ou bien que c'est désactiver côté serveur.

g-bougard commented 7 years ago

Salut @yann83 oui, il faut avouer que la création des tâches de "Collect" n'est pas toujours intuitive et qu'il est facile de mélanger les concepts. Un tutoriel sur ce sujet aiderait probablement.

Pour t'aider, as-tu au moins validé que la machine sur laquelle faire la collecte a remonté un inventaire et que c'est elle que tu as définie comme "acteur" sur la tâche ? Enfin, il faut aussi s'assurer que le module "Collecte de donnée" est bien activé sur la fiche de l'agent concerné dans le plugin Fusioninventory.

yann83 commented 7 years ago

Merci pour ta réponse En effet dans la gestion des agents :

J'ai créé un groupe dynamique GroupeRegistre dont le nom contient POSTE (pour POSTE1,POSTE2 ect..)

Dans Informations de l'ordinateur j'ai créé une information de collecte nommée LOCALES Type : Base de registre et Actif J'ai associé deux base de registre :

J'ai créé une tache Registre active ce jour de 08h00 à 16h00 avec Intervalle de réveil 1 Nb Agents 1

J'ai ajouté à la tâche le job "job" : Méthode du module : Collecte de donnée Cibles : Informations de collect APPLINAT Acteurs : Groupe d'ordinateurs GroupeRegistre

J'ai relancé l'inventaire sur le poste pour mettre à jour les informations.

Ma tâche reste toujours stoppé, elle n'est pas en état préparé.

ddurieux commented 7 years ago

Vérifie dans la conf générale du plugin fusioninventory, dans l'onglet 'modules' que le module de collecte est bien activé ;)

yann83 commented 7 years ago

Dans la configuration général , Modules des agents j'ai bien la case Activation de cochée pour Inventaire ordinateur Collecte de donnée

Dans le log du client j'ai : [Wed Jun 28 15:23:01 2017][info] running task Collect [Wed Jun 28 15:23:01 2017][info] No Collect job enabled or Collect support disabled server side.

et pourtant ma tâche est bien active , je l'ai même modifié pour un Créneau horaire : du lundi au Vendredi de 08;00 a 16:00

ddurieux commented 7 years ago

Si la tache n'est pas préparée, ça ne fonctionnera pas ;)

yann83 commented 7 years ago

Ha , mais s'il ne suffit pas qu'elle soit active, où se trouve le bouton pour la préparer du coup ?

ddurieux commented 7 years ago

Ca n'existe plus depuis 2 ans....

Cf le cron GLPI http://fusioninventory.org/documentation/fi4g/cron.html

yann83 commented 7 years ago

Oui j'ai essayé : "c:\path\to\php.exe c:\path\to\glpi\front\cron.php" dans une tache planifié sous windows pour un serveur AMP local (uWAMP) mais j'ai eu un retour 0xFF de la tâche.

Par contre je vient de lancer la tache manuelle dans GLPI : TaskScheduler et ma tâche est passé en "preparé" et "à faire"

ddurieux commented 7 years ago

Sous windows en même temps :p

yann83 commented 7 years ago

J'aime me faire du mal :) Malgré tout je suis obligé de tester sous cet environnement avant le passage sous Centos. Du coup je dois apporter la preuve que ça marche. J'ai relancé l'inventaire du client, j'ai relancé le TaskScheduler dans GLPI mais rien à faire la Tâche reste sur préparé/a faire.

yann83 commented 7 years ago

autant pour moi j'ai cliqué sur fusioninventory-inventory.bat pensant forcé l'inventaire alors qu'il fallait que j'aille sur http://127.0.0.1:62354/. Merci pour votre aide. Pensez vous pouvoir un jour faire une aide détaille sur les tâches ? Quand vous aurez le temps ?

ddurieux commented 7 years ago

Et t'as bien installé le module collect au niveau de l'agent?

yann83 commented 7 years ago

Oui je l'ai bien installé. La tâche a fonctionné du coup il me reste à comprendre pourquoi les informations du registre ne sont pas remontés. 1 HKEY_LOCAL_MACHINE /SOFTWARE/LOCALES/ CurrentVersion
2 HKEY_LOCAL_MACHINE /SOFTWARE/LOCALES/TEST/10/ CurrentVersion

yann83 commented 7 years ago

L'information de collecte sur la base de registre ne fonctionne pas ou bien y a un truc.

Dans ma base de registre j'ai une clé et des sous clés de cette façon : HKLM\SOFTWARE _\LOCALES ___\Programme1 avec une valeur CurrentVersion et une donnée 01.00.00 ___\01.00.00 _\Programme2 avec une valeur CurrentVersion et une donnée 02.00.00 ___\02.00.00

Il y a 4 champs .

Et si je veux récupérer tout ce qui se trouve dans HKLM\SOFTWARE\LOCALES est ce possible au moins possible ?

j'avoue être un peu perdu.

yann83 commented 7 years ago

J'ai vu que pour une information de collecte sur : Nom Ruche Chemin/clé Clé Version HKEY_LOCAL_MACHINE /SOFTWARE/LOCALES/Programme1/ CurrentVersion

En fait j'ai le retour d'information dans Tâches => Informations de l'ordinateur => Contenu de la base de registre

Qui me renvoi : Ordinateur Valeur Donnée POSTE1 CurrentVersion 01.00.00

Mais rien dans l'inventaire logiciel du poste. Ce qui finalement ne sert pas à grand chose.

Il faudrait faire le lien comme OCS avec l'inventaire logiciel. Peut être plus tard.

g-bougard commented 7 years ago

@yann83 Tu as un nouvel onglet ("Informations de collecte" si je me rappelle bien) sur la fiche de la machine qui devrait avoir été ajouté.

yann83 commented 7 years ago

Oui en effet il s'agit de l'onglet Contenu de la base de registre, mais j'ai les informations Chemin : HKEY_LOCAL_MACHINE/SOFTWARE/LOCALES/Programme1/
Valeur : CurrentVersion
Donnée : 01.00.00

A la rigueur ce qui serait bien c'est d'avoir le NOM en plus pour que ça ressemble en peu plus à la partie logiciel. Le souçi c'est que malgré tout il faudrait déclarer chaque logiciel de l'entreprise se trouvant dans la clé LOCALES, vu qu'il n'y a pas de système automatique de remonté qui associé le nom de la clé à une valeur et la donnée qu'elle retourne.

yann83 commented 7 years ago

aprés quelques recherche il faudrait ajouter/modifier les fichiers perl ici : C:\Program Files\FusionInventory-Agent\perl\agent\FusionInventory\Agent\Task\Inventory\Win32

J'y comprend rien en perl, un developpeur aurait une idée de comment faire ?

g-bougard commented 7 years ago

Salut @yann83 question idiote, le chemin de clé "HKEY_LOCAL_MACHINE/SOFTWARE/LOCALES/", c'est un truc bien à toi, ce n'est pas du standard windows ? A quelle occasion sont renseignées les clés et valeurs de ton arbo ?

wawax commented 7 years ago

Bonjour,

Regardez du côté du moteur de règle d'informations utilisateurs. Il permet par exemple d'ajouter un logiciel à l'inventaire après avoir joué la règle de collecte.

yann83 commented 7 years ago

@g-bougard on fait des package de logiciels maison avec Innosetup, on a standardiser l'arborescence afin de faciliter les mises à jour et la vérification de la conformité du parc. @wawax merci j'ai regardé mais le problème est en amont, il faudrait que je collecte tout ce qui se trouve dans la racine de la clé "HKEY_LOCAL_MACHINE/SOFTWARE/LOCALES/" sans avoir a entrer les informations logiciel par logiciel. Il faut que je modifie Softwares.pm pour l'enregistrement ça serait génial.

wawax commented 7 years ago

ou alors faire un module perl qui va collecter toutes ces clefs et rajouter les logiciels à l'inventaire. si vous avez besoin de plus de précision là dessus, contactez-moi

ddurieux commented 7 years ago

Mais la ca remonte ou pas dans GLPI?

g-bougard commented 7 years ago

@yann83 Il est en principe possible d'utiliser "*" comme valeur pour récupérer toutes les valeurs sous la clés désignées, mais je ne pense pas que ça te soit utile ici.

Une autre piste pour toi et d'utiliser l'option "additional-content" pour inclure l'inventaire de tes logiciels que tu auras pu constituer dans un langage que tu maitrises.

yann83 commented 7 years ago

@wawax Vous sauriez modifier une fonction Perl ? Ca serait super. Sachant que j'ai les clés dans cet ordre : HKEY_LOCAL_MACHINE/SOFTWARE/LOCALES ___/Programme1 Valeur:CurrentVersion Donnée:01.00.00 __/01.00.00 Valeur:Publisher Donnée:Service

Je sais que la fonction à modifier est la suivante : `sub getSoftwaresList{ my (%params) = @;

my $softwares = $params{softwares};

my @list;

return unless $softwares;

foreach my $rawGuid (keys %$softwares) {
    # skip variables
    next if $rawGuid =~ m{^/};

    # only keep subkeys with more than 1 value
    my $data = $softwares->{$rawGuid};
    next unless keys %$data > 1;

    my $guid = $rawGuid;
    $guid =~ s/\/$//; # drop the tailing /

    my $software = {
        FROM             => "registry",
        NAME             => encodeFromRegistry($data->{'/DisplayName'}) ||
                            encodeFromRegistry($guid), # folder name
        COMMENTS         => encodeFromRegistry($data->{'/Comments'}),
        HELPLINK         => encodeFromRegistry($data->{'/HelpLink'}),
        RELEASE_TYPE     => encodeFromRegistry($data->{'/ReleaseType'}),
        VERSION          => encodeFromRegistry($data->{'/DisplayVersion'}),
        PUBLISHER        => encodeFromRegistry($data->{'/Publisher'}),
        URL_INFO_ABOUT   => encodeFromRegistry($data->{'/URLInfoAbout'}),
        UNINSTALL_STRING => encodeFromRegistry($data->{'/UninstallString'}),
        INSTALLDATE      => _dateFormat($data->{'/InstallDate'}),
        VERSION_MINOR    => hex2dec($data->{'/MinorVersion'}),
        VERSION_MAJOR    => hex2dec($data->{'/MajorVersion'}),
        NO_REMOVE        => hex2dec($data->{'/NoRemove'}),
        ARCH             => $params{is64bit} ? 'x86_64' : 'i586',
        GUID             => $guid,
        USERNAME         => $params{username},
        USERID           => $params{userid},
        SYSTEM_CATEGORY  => $data->{'/SystemComponent'} && hex2dec($data->{'/SystemComponent'}) ?
            CATEGORY_SYSTEM_COMPONENT : CATEGORY_APPLICATION
    };

    # Workaround for #415
    $software->{VERSION} =~ s/[\000-\037].*// if $software->{VERSION};

    # Set install date to last registry key update time
    if (!defined($software->{INSTALLDATE})) {
        $software->{INSTALLDATE} = _dateFormat(_keyLastWriteDateString($data));
    }

    push @list, $software;
}

return \@list;

}`

J'ai essayé de changer : VERSION => encodeFromRegistry($data->{'/DisplayVersion'}), en VERSION => encodeFromRegistry($data->{'/CurrentVersion'}),

Par contre je séche pour récupérer la sous clé, pour obtenir la Valeur de "Publisher".

yann83 commented 7 years ago

@ddurieux les données de collecte remonte bien dans GLPI dans les ordinateurs , section "contenu de la base de registre". Si je parviens à modifier software.pm en modifiant la fonction ci-dessus j'aurai mes logiciels directement avec les autres installés dans la machine.

yann83 commented 7 years ago

@g-bougard Je n'ai pas trouvé l'option "aditionnal content", où se trouve t elle ?

ddurieux commented 7 years ago

ok, donc si ça remonte, tu peux utiliser les règles d'information additionnel des ordinateurs, ca te permettra d'ajouter des logiciels lors du prochain inventaire qui remontera...

g-bougard commented 7 years ago

@yann83 pour tester, depuis le dossier d'install de l'agent, il faut lancer manuellement le script perl/bin/fusioninventory-agent avec l'option en question (un --help donnera la liste exacte des options supportées). Mais comme l'indique @ddurieux , si l'info remonte, autant te simplifier la vie en utilisant le moteur de règle des infos additionnelles.

yann83 commented 7 years ago

merci @ddurieux et @g-bougard mais si la régle additionnel fonctionne il faut encore que je crée une information de collecte pour chaque programmes enregistrés, le caractére * n'a pas fonctionné. Du coup j’essaie de modifier le script Softwares.pm

g-bougard commented 7 years ago

@yann83 très bien, je te suggère de forker le projet et de faire tes propres modifications dans ton fork. Ton travail pourra servir d'exemple pour d'autres membres de la communauté. Ne le fais évidemment pas si tu penses que des informations trop sensibles pourraient être exposées. Mais cela pourrait aussi nous permettre de revoir ton code et te suggérer des améliorations ou même de le corriger.

yann83 commented 7 years ago

J'aurai besoin d'aide pour modifier softwares.pm.

En effet je ne connais pas Perl du tout alors j'ai commencé à apprendre un peu, et pour travailler sur mon problème, à savoir la prise en compte d'autre clé de registre pour l'inventaire, j'ai décider de me faire un petit laboratoire, qui en fait un gros unit test sur la fonction _getApplisList (_getSoftwaresList)

use strict;
use warnings;

use lib qw(/perl);

use English qw(-no_match_vars);
use Win32::TieRegistry (
    Delimiter   => '/',
    ArrayValues => 0,
    qw/KEY_READ/
);
use File::Basename;

use FusionInventory::Agent::Tools;
use FusionInventory::Agent::Tools::Win32;
use FusionInventory::Agent::Tools::Win32::Constants;

my $seen = {};
my $is64bit = is64bit();

#Partie APPLIS
    if ($is64bit) {

        # I don't know why but on Vista 32bit, KEY_WOW64_64 is able to read
        # 32bit entries. This is not the case on Win2003 and if I correctly
        # understand MSDN, this sounds very odd

        my $CVmachKey64 = $Registry->Open('LMachine', {
            Access => KEY_READ | KEY_WOW64_64 ## no critic (ProhibitBitwise)
        }) ;
        my $appliKey64 =
            $CVmachKey64->{"SOFTWARE/APPLI"};
        my $applis64 =_getapplisList(
            softwares => $appliKey64,
            is64bit   => 1,
        );

        my %h64 = @$applis64;
        my @t64 = keys(%h64);
        for my $family64 ( keys %h64 ) {
            print "$family64: \n";
            for my $role64 ( keys %{ $h64{$family64} } ) {
                if (!defined $h64{$family64}->{$role64}) {
                    delete $h64{$family64}->{$role64};
                    next;
                }           
                print "$role64=$h64{$family64}{$role64} ";
            }
            print "\n\n";
        }

        my $CVmachKey32 = $Registry->Open('LMachine', {
            Access => KEY_READ | KEY_WOW64_32 ## no critic (ProhibitBitwise)
        }) ;
        my $appliKey32 =
            $CVmachKey32->{"SOFTWARE/APPLI"};
        my $applis32 = _getapplisList(
            softwares => $appliKey32,
            is64bit   => 0,
        );

        my %h32 = @$applis32;
        my @t32 = keys(%h64);
        for my $family32 ( keys %h32 ) {
            print "$family32: \n";
            for my $role32 ( keys %{ $h32{$family32} } ) {
                if (!defined $h32{$family32}->{$role32}) {
                    delete $h32{$family32}->{$role32};
                    next;
                }
                print "$role32=$h32{$family32}{$role32} ";
            }
            print "\n\n";
        }       

    } else {
        my $CVmachKey = $Registry->Open('LMachine', {
            Access => KEY_READ
        });
        my $appliKey =
            $CVmachKey->{"SOFTWARE/APPLI"};
        my $applis = _getapplisList(
            softwares => $appliKey,
            is64bit   => 0,
        );

        my %h = @$applis;
        my @t = keys(%h);
        for my $family ( keys %h ) {
            print "$family: \n";
            for my $role ( keys %{ $h{$family} } ) {
                if (!defined $h{$family}->{$role}) {
                    delete $h{$family}->{$role};
                    next;
                }           
                print "$role=$h{$family}{$role} ";
            }
            print "\n\n";
        }       

    }

#sub routine
sub _getapplisList {
    my (%params) = @_;

    my $softwares = $params{softwares};

    my @list;

    return unless $softwares;

    foreach my $rawGuid (keys %$softwares) {
        # skip variables
        next if $rawGuid =~ m{^/};

        # only keep subkeys with more than 1 value
        my $data = $softwares->{$rawGuid};
        next unless keys %$data > 1;

        my $guid = $rawGuid;
        $guid =~ s/\/$//; # drop the tailing /

        my $software = {
            FROM             => "registry",
            NAME             => encodeFromRegistry($data->{'/DisplayName'}) ||
                                encodeFromRegistry($guid), # folder name
            #COMMENTS         => encodeFromRegistry($data->{'/Comments'}),
            #HELPLINK         => encodeFromRegistry($data->{'/HelpLink'}),
            #RELEASE_TYPE     => encodeFromRegistry($data->{'/ReleaseType'}),
            VERSION          => encodeFromRegistry($data->{'/CurrentVersion'}),#recupere CurrentVersion
            PUBLISHER        => encodeFromRegistry($data->{'/Publisher'}),
            #URL_INFO_ABOUT   => encodeFromRegistry($data->{'/URLInfoAbout'}),
            #UNINSTALL_STRING => encodeFromRegistry($data->{'/UninstallString'}),
            INSTALLDATE      => _dateFormat($data->{'/InstallDate'}),
            #VERSION_MINOR    => hex2dec($data->{'/MinorVersion'}),
            #VERSION_MAJOR    => hex2dec($data->{'/MajorVersion'}),
            #NO_REMOVE        => hex2dec($data->{'/NoRemove'}),
            ARCH             => $params{is64bit} ? 'x86_64' : 'i586',
            GUID             => $guid,
            USERNAME         => $params{username},
            USERID           => $params{userid},
            SYSTEM_CATEGORY  => $data->{'/SystemComponent'} && hex2dec($data->{'/SystemComponent'}) ?
               CATEGORY_SYSTEM_COMPONENT : CATEGORY_APPLICATION
        };

        # Workaround for #415
        #$software->{VERSION} =~ s/[\000-\037].*// if $software->{VERSION};

        # Set install date to last registry key update time
        if (!defined($software->{INSTALLDATE})) {
            $software->{INSTALLDATE} = _dateFormat(_keyLastWriteDateString($data));
        }

        push @list, $software;
    }

    return \@list;
}
sub _dateFormat {
    my ($date) = @_;

    ## no critic (ExplicitReturnUndef)
    return undef unless $date;

    if ($date =~ /^(\d{4})(\d{1})(\d{2})$/) {
        return "$3/0$2/$1";
    }

    if ($date =~ /^(\d{4})(\d{2})(\d{2})$/) {
        return "$3/$2/$1";
    }

    # Re-order "M/D/YYYY" as "DD/MM/YYYY"
    if ($date =~ /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/) {
        return sprintf("%02d/%02d/%04d", $2, $1, $3);
    }

    return undef;
}
sub _keyLastWriteDateString {
    my ($key) = @_;

    return unless ($OSNAME eq 'MSWin32');

    return unless (ref($key) eq "Win32::TieRegistry");

    my @lastWrite = FileTimeToSystemTime($key->Information("LastWrite"));

    return unless (@lastWrite > 3);

    return sprintf("%04s%02s%02s",$lastWrite[0],$lastWrite[1],$lastWrite[3]);
}

En sortie j'ai ça :

HASH(0x35c9200):
FROM=registry ARCH=x86_64 NAME=TEST1 INSTALLDATE=18/05/2017 GUID=TEST1 SYSTEM_CATEGORY=application VERSION=13.24.01

HASH(0x35c92a8):
VERSION=05.07.01 SYSTEM_CATEGORY=application GUID=TEST2 NAME=TEST2 INSTALLDATE=18/05/2017 ARCH=x86_64 FROM=registry

HASH(0x35c8e08):
ARCH=x86_64 FROM=registry INSTALLDATE=29/05/2017 NAME=JRE VERSION=13.02.04 GUID=JRE SYSTEM_CATEGORY=application

Odd number of elements in hash assignment at L:\Perl\Softwares_mod.pl line 62.
HASH(0x36ad330):
VERSION=02.00.00 GUID=AC SYSTEM_CATEGORY=application INSTALLDATE=23/05/2017 NAME=AC ARCH=i586 FROM=registry

HASH(0x36ad768):

Il me manque des clés qui pourtant sont bien remontés dans GLPI. J'aimerai bien travailler sur un"unit test" solide pour commencer à modifier le code, quelqu'un pourrait il m'aider ?