Le Chtonk de Blog

Aller au contenu | Aller au menu | Aller à la recherche

Développement

Il s'agit de discuter de développement, scripting, ...

Fil des billets - Fil des commentaires

jeudi, février 2010

Importer des rendez vous dans Outlook 2007

Lors de l'installation d'un serveur Exchange 2007 chez un client, ce dernier m'a demandé de reprendre dans les calendriers de chacun des utilisateurs tous les événements d'une application d'agenda au format web.
Cette application web s'appelle Ovidentia. C'est une application fonctionnant sous Apache/PHP/MySQL. Ma première idée était de trouver un moyen d'exporter ces événements au format csv (format universellement connu et facilement manipulable par la suite pour automatiser d'une manière ou d'une autre un import). Fonctionnant sous MySQL, je pouvais utiliser un connecteur ODBC pour faire une requête dans Excel pour générer ce csv.
Toutefois, cela ne réglait pas mon souci pour importer les événements dans Outlook, lié à l'Exchange. Surtout, étant donné que j'avais plus de 50 utilisateurs à traiter, comment l'automatiser, sachant que je devais récupérer tous les événements depuis début 2009...
Enfin, j'ai réussi à trouver le script qui allait bien, qui plus est en PowerShell ! En fait, je me suis basé sur ce script Create Calendar Appointments Automatically Based on Existing Calendar Appointments.

Puis, je l'ai modifié, pour intégrer la requête ODBC qui va bien et les traitements qui vont bien pour la création des événements.
Pour cet exemple, les prérequis sont :
- pilote ODBC MySQL
- Powershell 2.0

J'ai donc créé 3 fichiers pour me permettre tout ça :

requete.sql :

SELECT
		bab_users.id,
		bab_users.nickname,
		bab_users.email,
		bab_cal_events.id,
		bab_cal_events.title,
		bab_cal_events.description,
		bab_cal_events.location,
		bab_cal_events.start_date,
		bab_cal_events.end_date,
		bab_cal_events.bprivate
	FROM bab_users, bab_cal_events, bab_cal_events_owners, bab_calendar
	WHERE bab_calendar.owner=bab_users.id
	AND bab_cal_events_owners.id_cal = bab_calendar.id
	AND bab_cal_events.id = bab_cal_events_owners.id_event
	AND bab_cal_events.start_date >= '#startdate#'
	AND bab_users.nickname ='#username#'
	GROUP BY
		bab_users.id,
		bab_users.nickname,
		bab_users.email,
		bab_cal_events.id,
		bab_cal_events.title,
		bab_cal_events.description,
		bab_cal_events.location,
		bab_cal_events.start_date,
		bab_cal_events.end_date,
		bab_cal_events.bprivate
	ORDER BY bab_cal_events.start_date

agenda.ps1 (LE script d'importation) Il est important d'exécuter ce script sur le poste de l'utilisateur et connecté avec sa session :

param($username, $action="synchro", $reel=$false)
 
function HelpCommand($value) {
$howto = @"
agenda.ps1 username action [reel ($false|$true)]
	"username" : le nom de l'utilisateur dans Ovidentia
 
	"action" : quelle action doit-on effectuer :
		import : il s'agit d'une première synchronisation, complète, depuis le 01/01/2009
		synchro (par défaut) : il s'agit d'une synchronisation Ovidentia->Outlook pour tous les nouveaux événements 
							   (ou événements modifiés) de la date du jour jusqu'à ....
 
	"reel" : doit-on réellement mettre à jour ou non (presque équivalent à -Whatif)
		$false (par défaut) : juste pour tester
		$true  : mettre réellement à jour
 
Exemple 1 :
agenda.ps1 gmaison import $false
	Cet exemple permet de simuler l'import de l'agenda de gmaison depuis le 01/01/2009
 
Exemple 2 :
agenda.ps1 gmaison synchro $true
	Cet exemple permet de synchroniser l'agenda de gmaison pour tous les événements à venir depuis la date d'exécution du script
 
"@
$howto
}
trap [Exception] {
	Write-error "Une erreur est arrivée. Veuillez vérifier vos paramètres"
	HelpCommand
	break;
}
 
if ($username.tolower() -eq "-help") {
   HelpCommand
   break
}
 
#si on a oublié de préciser le username
if ($username -eq $null) {
	[string]$username = read-host -prompt "veuillez saisir le nom réseau de l'utilisateur "
}
 
#ici, on récupère la requête pour l'utilisateur
$filepath = "requete.sql"
# ou bien si les noms utilisateurs sont identiques au login réseau
#[string]$nomutilisateur = [environment]::username
 
[string]$requete = get-content $filepath
 
$requete = $requete.replace("#username#",$username).tolower()
if ($action -eq "import") {
	$startdate = "2009-01-01"
} else {
	$startdate = (Get-Date -Format "yyyy-MM-dd").toString()
}
$requete = $requete.replace("#startdate#",$startdate).tolower()
 
#ici, on crée la connexion pour pouvoir récupérer tous ses rendez vous
$commande = $null
$connexion = $null
 
$commande = new-object system.data.odbc.odbccommand
$connexion = new-object system.data.odbc.odbcconnection
$commande.connection = $connexion
 
# attention : il faut créer l'entrée odbc pour ovidentia
$dsn = "driver=mysql odbc 5.1 driver;uid=exchange;pwd=exchange;port=3306;database=ovidentia;server=serveur"
$connexion.connectionstring = $dsn
 
$connexion.open()
 
#ici, on exécute la requête et on récupère les données
$commande.commandtext = $requete
$dataadapter = new-object system.data.odbc.odbcdataadapter($commande)
$dataset = new-object system.data.dataset
$nombre= $dataadapter.fill($dataset)
 
# on démarre outlook
if ($reel) {
	$outlookapp = new-object -comobject outlook.application
	$allcalitems = $outlookapp.getnamespace("MAPI").getdefaultfolder(9).items
}
 
#puis on insère les données dans le calendrier
foreach ($table in $dataset.tables)
{
	$max_lignes = $table.rows.count
	$i=0
 
	foreach ($row in $table.rows)
    {
 
		$iduser = $row.id
		$nickname = $row.nickname
		$email = $row.email
		$eveid = $row.id1
		$titre = $row.title
		$desc = $row.description
		$lieu = $row.location
		$datedeb = $row.start_date
		$datefin = $row.end_date
		$prive = $row.bprivate
 
		#write-host $nickname" - "$eveid" -> "$datedeb
 
		# on a récupéré toutes les données liées à l'événement
		# maintenant, on crée l'événement
 
		if ($reel) {
 
			if ($action -eq "synchro") {
 
				# ici, on va rechercher si l'événement utilisateur existe
				$event = $allcalitems | where-object{$_.userproperties.find("OvidentiaID", $true).value -eq $eveid -and $_.start -ge [datetime]$startdate}
			} else {
				$event = $null
			}
 
			# s'il n'existe pas, on le crée
			if ($event -eq $null) {
				$event = $outlookapp.createitem(1)
				$prop = $event.userproperties.add("OvidentiaID", 20)
 
			}else{
				$prop = $event.userproperties.find("OvidentiaID", $true)
			}
 
			# quoiqu'il arrive, on le met à jour
			$event.subject = "$titre"
			$event.location = $lieu
			$event.body = $desc
			$event.start = [datetime]$datedeb
			$event.end = [datetime]$datefin
			if ($prive -eq "y") {
				$event.sensitivity = 2
			} else {
				$event.sensitivity = 0
			}
			$maintenant = get-date
			if ($datedeb -ge $maintenant) {
				$event.reminderset = $true
			} else {
				$event.reminderset = $false
			}
 
			$prop.Value = $eveid;
 
			$event.close(0)
		} else {
			write-host @"
$iduser 
$nickname 
$email 
$eveid 
$titre 
$desc 
$lieu 
$datedeb 
$datefin 
$prive 
"@
			$todisplay
		}
 
 
		[int]$pourcent = $i++ / $max_lignes *100
		write-progress "importation des événements du calendrier" "en cours" -percentcomplete $pourcent -id 1
    }
}

J'ai également créé un script qui me permet, sur un poste d'un utilisateur, d'automatiser l'exécution du script ci-dessus par l'intermédiaire du planificateur de tâche. exec_task.ps1 la tâche doit être configurée pour être exécutée avec le compte de l'utilisateur :

param($username, $action, $reel)
#Récupération de la date du jour
$dt = Get-Date -format "yyyyMMdd_hhmm"
 
# construction du chemin où se trouve ce script et celui d'import de l'agenda
# mais également le chemin du fichier de log
$MyPath = (split-path $myinvocation.Mycommand.Definition)
$file = $MyPath +"\"+[Environment]::UserName+"_"+$dt + ".log"
 
#Démarrage de la récupération de la console (pour le log)
start-transcript $file
#en cas d'erreur on arrête la récupération du log
trap { stop-transcript; break}
 
Set-Location $MyPath
.\agenda.ps1 $username $action $reel
 
stop-transcript

mercredi, mai 2008

VBScript: Créer une signature personnalisée par utilisateur sous Outlook 2003/2007 sur SBS

Souvent, chaque utilisateur veut voir, dans sa signature, son nom, sa ligne directe, le nom de son poste, ... Pour autant, il existe une charte graphique d'entreprise qui doit être commune à l'ensemble de ces signatures. Si chaque utilisateur crée sa propre signature, il faut alors qu'une personne vérifie chacune des signatures et la mette correctement en forme sur l'ensemble des postes. Cela peut devenir fastidieux, notamment si l'entreprise doit changer de signature en fonction d'événéments la concernant (présence sur un salon, présence de publicités pour de nouveaux produits, etc...).

Voici donc un petit script, qui fonctionne avec Outlook 2003 et Outlook 2007, en environnement Active Directory (donc également sur SBS), qui permet de personnaliser la signature, par utilisateur, tout en gardant la cohérence de la charte graphique d'entreprise.

Lire la suite...

jeudi, juin 2007

WebCast PowerShell

Il s'agit du WebCast du séminaire PowerShell qui a eu lieu le 14 mai 2007. Très intéressant si vous voulez vous lancer dans de l'administration système et réseau "à la mode unix" et a priori en encore plus puissant !

Lire la suite...

lundi, juin 2007

PowerShell : Mapper des lecteurs réseau en fonction des groupes d'un utilisateur

Idem que celui en VBScript mais en PowerShell. Attention, cela nécessite toutefois d'avoir déployé le PowerShell sur l'ensemble des postes de travail (PowerShell mais bien sûr avant .Net).

Lire la suite...

VBScript : Mapper des lecteurs réseau en fonction des groupes d'un utilisateur

Il s'agit contourner les GPO - enfin une tellement infime partie que c'est même pas un contournement mais une autre manière de voir dira-t-on - d'un serveur Windows 2003 par l'intermédiaire d'un script. Celui-ci, sous réserve de modifications, peut être exécuté à l'ouverture d'une session

Lire la suite...