Question Lotus Notes et Powershell

Plus d'informations
il y a 10 ans 2 mois #16970 par Nicolas Lang
Bien le bonjour à tous!

Je suis actuellement en train de faire un script pour pouvoir lister les utilisateurs de chaque groupe de mon serveur Domino et enregistrer dans un fichier les différences avec la liste précedente...

Mais c'est la cata!

Comme je teste et découvre lotus je 'tâtonne' ... et comme résultat, c'est le service entier qui part en vrille!

Je n'ai pas terminé le script, mais je pense savoir d'ou vient le souci... J'ouvre la base, mais à aucun moment je ne la referme, et résultat => verrouillée en lecture / écriture et c'est l'ensemble des utilisateurs qui se retrouve sans messagerie.

Voila la manière dont j'ouvre ma base names.nsf depuis le serveur.
[code:1]
$notes = New-Object -ComObject Lotus.Notessession
$notes.initialize()
$names = $notes.addressbooks | Where-Object {$_.filename -eq \"names.nsf\"}
$names.open()
[/code:1]


Et voila donc comment je la verrouille :D

La question que je vous pose sera donc double :

1) Comment puis-je \"fermer\" proprement ma base ouverte?
2) Est-il possible d'accéder à la base names.nsf sans se l'approprier?

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 10 ans 2 mois #16972 par Laurent Dardenne
Salut,
Darum écrit:

1) Comment puis-je \"fermer\" proprement ma base ouverte?

S'il existe une méthode Open, celle nommée Close doit exister.
Darum écrit:

2) Est-il possible d'accéder à la base names.nsf sans se l'approprier?

Consulte la doc de ton Objet COM et vérifie si tu peux paramétrer le mode d'accès, Open donc, en lecture uniquement.

Message édité par: Laurent Dardenne, à: 14/02/14 11:25<br><br>Message édité par: Laurent Dardenne, à: 14/02/14 11:58

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 10 ans 2 mois #16974 par Nicolas Lang
Réponse de Nicolas Lang sur le sujet Re:Lotus Notes et Powershell
Laurent Dardenne écrit:

1) Comment puis-je \&quot;fermer\&quot; proprement ma base ouverte?

S'il existe une méthode Open, celle nommée Close doit exister.


Justement non! Ça aurait tellement simple :D

Darum écrit:

2) Est-il possible d'accéder à la base names.nsf sans se l'approprier?

Consulte la doc de ton Objet COM et vérifie si tu peux paramétrer le mode d'accès, Open donc, en lecture uniquement.


Voui, peut être voir de ce coté, mais j'ai pas l'impression que la doc fourmille en ce qui concerne Domino et Powershell!

Merci pour les conseils en tout cas

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 10 ans 2 mois #16975 par Laurent Dardenne
Darum écrit:

Voui, peut être voir de ce coté, mais j'ai pas l'impression que la doc fourmille en ce qui concerne Domino et Powershell!

J'ai mis a jour mon post précédent avec un lien sur la doc (à vérifier si c'est la bonne).
Je connais pas ce produit et du peu que j'ai compris de la doc, il semble que le mode d'accès doive être configuré via une propriété.

Quant à PS, lorsqu'on ne sait comment fonctionne des API/objet COM, le langage importe peu...
Je pense que tu as devant qq heures de recherche sur le net :)

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 10 ans 1 mois #17158 par Nicolas Lang
Réponse de Nicolas Lang sur le sujet Re:Lotus Notes et Powershell
Reuh!

Après bien des efforts et bien des frayeurs, j'ai lâché l'approche de l'attaque de la base de donnée directement. J'ai préféré passer par le LDAP pour récupérer les informations nécessaires.
Je pose ce code ici, pour qui veut, en guise de référence. J'ai glâné quelques informations de ci de la, et après un paquet non mesurable d'effort et de patience, je suis enfin arrivé à faire que mon code tourne comme je l'entends.

C'est peut être brouillon, mal construit à certains endroits, certains commentaires sont peut être à corriger mais ... ça marche et je suis à l'écoute des commentaires et des remarques!

Bref, ce script a pour but de lister les modifications faites sur la liste des groupes domino entre sa dernière exécution et la suivante.

[code:1]
$debugging = $false #a mettre sur true pour avoir des infos sur la zone de code qui crée l'enregistrement
$date = Get-Date -Format \&quot;dd/MM/yyyy HH:mm:«»ss\&quot;
set-location $([Environment]::GetFolderPath(\&quot;Mydocuments\&quot;«»)) #se place dans le repertoire \&quot;mes documents\&quot; de l'utilisateur actuel
try
{
$base = Import-Clixml referencegroupes.xml
}
catch
{
Write-Host \&quot;Le fichier de réference n'existe pas, ou n'est pas disponible , il sera regénéré à la fin de ce script. Aucun fichier de modification ne se créera.\&quot;
}

#ce bloc crée un message pour signifier qu'il n'a pas pu accéder au fichier de base. Si c'est le premier lancement, ou si le fichier n'est plus accessible, il le recréera avec ce que le script aura récupéré

$base = $base | Sort-Object -Property groupe -Unique

$Connection = New-Object -Com \&quot;ADODB.Connection\&quot; #création d'un objet de connexion à une source de données
$Connection.Provider = \&quot;ADsDSOObject\&quot; #Utilisé pour une connexion LDAP
$Connection.Properties.Item(\&quot;User ID\&quot;«»)=\&quot;CN=Darum,O=Ma Société\&quot; #authentifiant à préciser
$Connection.Properties.Item(\&quot;Password\&quot;«»)=\&quot;P@ssw0rd!\&quot; #Votre mot de passe
$Connection.Open(\&quot;Active Directory Provider\&quot;«»)
$Command = New-Object -Com \&quot;ADODB.Command\&quot; #on initialise la commande qui sera fournie à la connexion $Connection
$Command.ActiveConnection = $Connection #On lie la commande à la connexion
$Query = \&quot;SELECT displayname, mail, member FROM 'LDAP://lotusserveur.mondomaine.com' WHERE objectclass='dominogroup'\&quot; #nous enregistrons un texte qui sera pris comme commande, et qui précise que nous sélectionnons les propriétés displayname mail et member sur le serveur LDAP pour tout ce qui est un dominogroup
$Command.Commandtext = $Query
$Command.Commandtimeout = 60 #Ce timeout est le temps de validité de la commande avant qu'elle soit précisée comme perdue. Si votre base est imposante ou que votre connexion vers le serveur est lente, augmentez la valeur.
$execute = $Command.execute() #On exécute la commande et on l'enregistre dans $execute
$tab = @() #on crée un tableau qui recueillera les données
$execute.MoveFirst() #nous nous déplaçons au premier enregistrement

function ajoutligne ($groupe=$null,$ajout=$null,$retrait=$null,$creation=$null,$suppression=$null,$reference=\&quot;???\&quot;«») #Cette fonction permettra d'ajouter dans chaque colonne l'attribut et la valeur désirée
{

$obj = New-Object PSOBJECT
$obj | add-member -MemberType NoteProperty -Name \&quot;Date\&quot; -Value $date
$obj | add-member -MemberType NoteProperty -Name \&quot;Groupe\&quot; -Value $groupe
$obj | add-member -MemberType NoteProperty -Name \&quot;Ajout de\&quot; -Value $ajout
$obj | add-member -MemberType NoteProperty -Name \&quot;Retrait de\&quot; -Value $retrait
$obj | add-member -MemberType NoteProperty -Name \&quot;Création\&quot; -Value $creation
$obj | add-member -MemberType NoteProperty -Name \&quot;Suppression\&quot; -Value $suppression
if ($debugging -eq $true) {$obj | add-member -MemberType NoteProperty -Name \&quot;Debbuging only\&quot; -Value $reference}
return $obj
}
while ($execute.eof -eq $false) #cette boucle s'execute tant que nous ne sommes pas arrivés sur le EOF (End Of File) qui indique la fin des enregistrements. Une valeur BOF (Begin Of File) existe pour préciser le premier enregistrement.
{
$member = $execute.Fields | Where-Object {$_.name -eq \&quot;member\&quot;} #nous selectionnons dans l’élément de la boucle la valeur \&quot;member\&quot;
$displayname = $execute.Fields | Where-Object {$_.name -eq \&quot;displayname\&quot;} #idem pour displayname
$addresse = $execute.Fields | Where-Object {$_.name -eq \&quot;mail\&quot;} #idem pour mail

if ($member.Value -isnot [System.DBNull]) #Pour un enregistrement de base de donnée vide, $null n'est pas valide. Le type pour une entrée vide est [System.DBNull]
{
$objet = New-Object PSOBJECT
$objet |add-member -Name \&quot;Groupe\&quot; -MemberType NoteProperty -Value $($displayname.value)
$objet |Add-Member -Name \&quot;Adresse\&quot; -MemberType NoteProperty -Value $($addresse.value)
$objet |add-member -Name \&quot;Membres\&quot; -MemberType NoteProperty -Value $($member.value)
$tab += $objet
}

$execute.MoveNext()

}
if ($base -eq $null) #crée la première référence si elle n'existe pas
{
$tab | Export-Clixml referencegroupes.xml
#(get-date).toshortdatestring()+\&quot;;\&quot;+(get-date).toshorttimestring()+\&quot;;Ecriture du fichier de reference\&quot; &gt;&gt; debug.txt
}
else #execute le script s'il trouve la première reference
{ $tab = $tab |Sort-Object -Property Groupe -Unique
$tab | Export-Clixml newbase.xml
#(get-date).toshortdatestring()+\&quot;;\&quot;+(get-date).toshorttimestring()+\&quot;;Ecriture du fichier de comparaison\&quot; &gt;&gt; debug.txt

$newbase = Import-Clixml newbase.xml


$recap =@()

foreach ($entree in $base)
{

if ($newbase.groupe -notcontains $entree.groupe) #si la nouvelle base ne comporte pas le groupe, alors c'est qu'il est supprimé
{
$recap += ajoutligne -groupe $entree.groupe -suppression $true -reference '$newbase.groupe -contains $entree.groupe'
}
else #si le groupe existe, on en vérifie les utilisateurs en appelant l'autre base
{
$comparaison = $newbase | Where-Object {$_.groupe -eq $entree.groupe}
$changements = $null
$changements = Compare-Object $entree.membres $comparaison.membres

foreach ($changement in $changements)
{

if ($changement.sideindicator -eq \&quot;=&gt;\&quot;«»)
{

$recap += ajoutligne -groupe $entree.groupe -ajout $changement.inputobject -reference '$changement.sideindicator -eq \&quot;=&gt;\&quot;'
}
else
{

$recap += ajoutligne -groupe $entree.groupe -retrait $changement.inputobject -reference 'else ($changement.sideindicator -eq \&quot;&lt;=\&quot;«»)'
}
} # fin foreach ($changement in $changements)
} #fin else
} #foreach ($groupe in $entree.groupe)

foreach ($entree in $newbase)
{

if ($base.groupe -notcontains $entree.groupe) #si l'ancienne base ne comporte pas le groupe, alors c'est qu'il est crée
{
$recap += ajoutligne -groupe $entree.groupe -creation $true -reference '$base.groupe -notcontains $entree.groupe'
}

} # foreach ($entree in $newbase)

$recap | Export-Csv \&quot;Changements comptes.csv\&quot; -Encoding UTF8 -notypeinformation -Append -Delimiter \&quot;;\&quot; #export du fichier de suivi des modifications sur le compte
Move-Item -Path newbase.xml -destination referencegroupes.xml -Force #remplacement du fichier
} #fin else
[/code:1]

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 10 ans 1 mois #17159 par Laurent Dardenne
Darum écrit:

je suis à l'écoute des commentaires et des remarques!

En voici qq uns.

Dans le code suivant un test-path devrait suffire (fonctionnel) et le try doit être dédié aux erreurs (technique). Si le fichier est verrouillé ton traitement ne pourra se faire et tu ne sauras pas pourquoi :
[code:1]
try
{
$base = Import-Clixml referencegroupes.xml
}
catch
{
Write-Host \&quot;Le fichier de réference n'existe pas, ou n'est pas disponible , il sera regénéré à la fin de ce script. Aucun fichier de modification ne se créera.\&quot;
}
[/code:1]
Si tu utilises uniquement la V2 la création de PSobject peut être simplifiée.

Le mode d'insertion suivant :
[code:1]
$tab += $objet
[/code:1]
est à éviter si tu manipules plusieurs centaines d'objets. L'utilsation d'un Arraylist est préférable:
[code:1]
$tab=new-object System.Collections.Arraylist
$null=$tab.Add('un')
$tab[0]
[/code:1]
Idem pour $recap

Pour les lignes similaire à :
[code:1]
$member = $execute.Fields | Where-Object
[/code:1]
Itére une seule fois la colllection en remplaçant le Where par un Foreach couplé à un switch. :
[code:1]
$member=$displayname=$addresse =$null
$execute.Fields |
Foreach {
switch ($_.Name)
{
#Ici $_ pointe sur $_.Name du foreach
\&quot;member\&quot; {$member = $_}} #nous selectionnons dans l’élément de la boucle la valeur \&quot;member\&quot;
\&quot;displayname\&quot; {$displayname = $_} #idem pour displayname
\&quot;mail\&quot; {$addresse =$_} #idem pour mail
}
}
[/code:1]
Pour ceci :
[code:1]
if ($changement.sideindicator -eq \&quot;=&gt;\&quot;«»)
{
$recap += ajoutligne -groupe $entree.groupe -ajout $changement.inputobject -reference '$changement.sideindicator -eq \&quot;=&gt;\&quot;'
[/code:1]
tu peux simplifier en :
[code:1]
$recap += ajoutligne -groupe $entree.groupe -ajout $changement.inputobject -reference $changement.sideindicator
[/code:1]
S'il s'agit de DEBUG tu sais ce que cela signifie et tu te laisses la possibilité de trier de nouveau sur le contenu de ce champ.
Enfin il manque un try catch global pour le support.

Je te laisse tester ces propositions, je ne l'ai pas fait.

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.075 secondes
Propulsé par Kunena