Je vous propose de voir aujourd’hui comment automatiser l’exécution des tâches d’import / synchronisation et export dans MIM 2016 en PowerShell.
Etape 1 – Contexte et prérequis
Pour cela, vous devez disposer d’une installation de MIM fonctionnelle. Mon cas d’utilisation est la suivant : je dispose de 2 Management Agent. Chacun est connecté en source à un Active Directory. Mon objectif est de lire les AD et pour certains ADUsers, ADGroups de créer des contacts associés que j’exporte ensuite dans les autres AD Sources en fonction de critères spécifiques et avec une convention de nommage précise (concrètement c’est pour populer les différentes GAL sur des critères précis).
J’ai donc mes 2 Management Agents prêts à fonctionner (avec des règles bien précises au niveau de l’import, des join and projection rules ainsi que sur le flow attributes).
Et, je dispose des profiles d’exécution suivants :
- DELTA_IMPORT
- DELTA_SYNC
- EXPORT
- FULL_IMPORT
- FULL_SYNC
Ces 5 profiles me permettent de définir 2 scénarios de fonctionnement :
- Scénario dit Weekly/weekend : c’est le scénario le plus lourd qui va exécuter 1 fois par semaine la succession d’actions suivantes : FULL_IMPORT, FULL_SYNC, EXPORT. Il s’agit d’un scénario qui peut-être assez lourd (selon le volume d’informations dans les AD Sources) puisque l’on effectue l’ensemble des actions depuis 0 : on ré-importe TOUS les AD et on re-effectue TOUTES les synchronisation. Dans ce mode là, les comptes sont de nouveaux tous analysés et passent dans toutes les règles de provisioning.
- Scénario dit Daily : c’est un scénario plus léger qui effectue uniquement un delta des opérations qui n’auraient pas encore été exécutées. C’est un scénario plus léger qui peut donc être exécutée en semaine. Il exécutera successivement les profiles suivants : DELTA_IMPORT, DELTA_SYNC puis EXPORT.
L’objectif maintenant est de traduire l’exécution de ces 2 scénarios en PowerShell. Donc finalement, on doit réaliser un script qui sera capable d’appeler l’exécution de chaque Management Agent avec 1 profile différent. Et l‘appel successif d’un MA avec les 3 profiles souhaités, nous permet alors de traduire soit le scénario daily ou weekly :
- Scénario Daily :
- Foreach MA :
- Appel MA n avec Profile DELTA_IMPORT
- Foreach MA :
- Appel MA n avec Profile DELTA_SYNC
- Foreach MA :
- Appel MA n avec Profile EXPORT
- Foreach MA :
- Scénario Weekly :
- Foreach MA :
- Appel MA n avec Profile FULL_IMPORT
- Foreach MA :
- Appel MA n avec Profile FULL_SYNC
- Foreach MA :
- Appel MA n avec Profile EXPORT
- Foreach MA :
Etape 2 – PowerShell : vérifier qu’aucun MA n’est en cours d’exécution
Nous allons commencer par préparer une fonction qui nous permettra de vérifier si nous n’avons pas déjà un Management Agent en cours d’exécution. Ceci afin de générer des erreurs en appelant plusieurs fois un même MA ou en tentant de démarrer l’exécution d’un Profile alors qu’il y en a déjà 1 en cours d’exécution.
function Check-IfMAisRunning ()
{
$MIMHistory = get-wmiobject -Class 'MIIS_RunHistory' -namespace “root\MicrosoftIdentityIntegrationServer”
[bool]$MaRunning = $false
foreach ($object in $MIMHistory)
{
if ($object.RunStatus -eq "in-progress" -or $object.RunStatus -eq "stopping" )
{
$MaRunning = $true
Break
}
}
return $MaRunning
}
Il existe divers codes erreurs dans MIM qui peuvent indiquer plein de choses comme notamment une impossibilité à se connecter aux sources de données (AD non disponible, mauvais login/mdp, …) mais globalement, vous aurez 2 status qui peuvent traduire qu’un Management Agent est en cours d’exécution : in-progress (en cours d’exécution) ou stopping (en cours d’arrêt suite à arrêt manuel demandé par utilisateur).
En récupérant donc l’historique des exécutions de MIM, on peut voir quels sont les différents status d’exécution $MIMHistory.RunStatus et on retourne True si on voit qu’un MA est déjà en cours d’exécution. Et la classe WMI suivante MIIS_RunHistory permet de récupérer l’historique des exécutions des MA de la même façon que nous pouvons le voir graphiquement dans la console dans l’onglet Operations.
Etape 3 – PowerShell : Fonction qui permet d’exécuter un MA avec 1 profile d’exécution donné
Nous allons maintenant créer une fonction qui nous permettra d’appeler l’exécution d’un MA avec une profile donné.
$ProfilesAllowed = @("FULL_IMPORT","FULL_SYNC","DELTA_IMPORT","DELTA_SYNC","EXPORT")
function Launch-ManagementAgent ()
{
param(
[parameter(mandatory=$true)]
[string]$AskedManagementAgent,
[parameter(mandatory=$true)]
[string]$Profile
)
# Check if no MA is currently running - Otherwise, we break
$isMARunning = Check-IfMAisRunning
if ($isMARunning -eq $true)
{
Write-Host "[ERROR] - One MA is currently running - Please wait every MA are stopped before trying to launch another - Exiting"
Break
}
# Check if the Profil requested exist - Otherwise, we break
$isThisProfileExist = $ProfilesAllowed.Contains($Profile)
if ($isThisProfileExist -ne $true)
{
Write-Host "[ERROR] - Only the following Profiles are supported : FULL_IMPORT, FULL_SYNC, DELTA_IMPORT, DELTA_SYNC, EXPORT"
Break
}
# Getting the object MA requested
$MA = get-wmiobject -class "MIIS_ManagementAgent" -namespace "root\MicrosoftIdentityIntegrationServer" -computername $MIMComputer | where { $_.Type -eq 'Active Directory' -and $_.Name -eq $AskedManagementAgent }
# Check if Management Agent exist
if (!$MA)
{
Write-Host "[ERROR] - The Management Agent you request does not exist in MIM ! - Exiting"
Break
}
# If all the previous requirements are respected and the script hasn't been break
# We can lauch our Management Agent with requested Profile
try
{
# Launching the Management Agent with the Action Required
$dateStart = date
Write-Host ("[DEBUG] - Starting " + $Profile + " for : " + $MA.Name)
$tempResult = $MA.Execute($Profile) # Execute Management Agent with Requested Profile Type
$dateEnd = date
$duration = $dateEnd - $dateStart # Get the duration
Write-Host ("[DEBUG] - Ending " + $Profile + " for : " + $MA.Name + " - Status : " + $tempResult.ReturnValue + " - Duration : " + $Duration)
}
catch
{
# Problem : displaying the Exception and Breaking the execution
Write-Host $($_.Exception.Message)
Break
}
return $ExecutionResult = @{
'MAName' = $MA.Name
'Type' = $MA.Type
'ReturnValue' = $tempResult.ReturnValue;
'Profile' = $Profile;
'dateStart' = $dateStart;
'dateEnd' = $dateEnd;
'Duration' = $duration;
}
}
Les commentaires sont à priori suffisamment clairs mais revenons sur les détails de cette fonction. L’objectif est le suivant :
- Je dispose d’un tableau classique qui me permet de stocker les types de profiles qui sont autorisés à être exécutés (à adapter selon votre cas donc),
- La fonction prend en paramètres le nom du Management Agent ainsi que le profile à éxecuter,
- On effectue ensuite les contrôles suivants :
- On vérifie que nous n’avons pas déjà un MA en cours d’exécution (avec la précédente function),
- On vérifie que le MA et le profile demandé existent bien,
- L’appel de la classe WMI MIIS_ManagementAgent permet d’obtenir la liste des MA disponibles (et donc de vérifier pour nous que le MA demandé existe bien),
- Si toutes les conditions sont réunies, on exécute le Management Agent et on mesure le temps d’exécution (la version de script présentée dans cet article est un peu épurée du fait qu’en situation réelle, je log davantage de choses).
On obtient alors la sortie ci-dessous le MA s’est bien exécuté avec le profil souhaité. Nous avons la durée totale et nous savons que c’était une success.
Dans cet exemple, j’ai choisi de Break au moindre problème. Mais libre à vous de throw ou d’effectuer un log ou une remontée à l’utilisateur en fonction des problèmes que vous pourriez rencontrer dans votre cas d’utilisation.
Etape 4 – PowerShell : Création d’un fonction pour gérer nos 2 scénarios : Weekly / Daily
Il nous reste à créer une fonction pour appeler successivement les MA avec les profiles souhaités en fonction des cas de figure.
$MIMMAList = get-wmiobject -class "MIIS_ManagementAgent" -namespace "root\MicrosoftIdentityIntegrationServer" -computername $MIMComputer | where {$_.Type -eq 'Active Directory'}
function LaunchScenario ()
{
param(
[parameter(mandatory=$true)]
[string]$Scenario
)
$AllMA = $MIMMAList
$results = @()
switch ($Scenario)
{
'weekly'
{
Write-Host "[DEBUG] - Lauching Weekly scenario - composed of : FULL_IMPORT + FULL_SYNC + EXPORT"
# Full_Import for all MA
foreach ($ma in $AllMA)
{
Launch-ManagementAgent -AskedManagementAgent $ma.name -Profile "FULL_IMPORT"
}
# Full_Sync for all MA
foreach ($ma in $AllMA)
{
Launch-ManagementAgent -AskedManagementAgent $ma.name -Profile "FULL_SYNC"
}
# Export for all MA
foreach ($ma in $AllMA)
{
Launch-ManagementAgent -AskedManagementAgent $ma.name -Profile "EXPORT"
}
}
'daily'
{
Write-Host "[DEBUG] - Lauching Daily scenario - composed of : DELTA_IMPORT + DELTA_SYNC + EXPORT"
# Delta_Import for all MA
foreach ($ma in $AllMA)
{
Launch-ManagementAgent -AskedManagementAgent $ma.name -Profile "DELTA_IMPORT"
}
# Delta_Sync for all MA
foreach ($ma in $AllMA)
{
Launch-ManagementAgent -AskedManagementAgent $ma.name -Profile "DELTA_SYNC"
}
# Export for all MA
foreach ($ma in $AllMA)
{
Launch-ManagementAgent -AskedManagementAgent $ma.name -Profile "EXPORT"
}
}
} # End of Switch
}
Cette dernière fonction prendra en paramètre le nom du scénario souhaité et en fonction de ce dernier, nous exécuterons successivement chaque Management Agent avec le profile souhaité correspondant au scénario demandé.
On appelle donc maintenant la fonction avec le paramètre LaunchScenario -Scenario daily. On a le retour suivant :
On passe exécute donc bien le scénario comme souhaité pour chaque MA / profile donné. On peut également le vérifier dans la console MIM :
Etape 5 – Planifier l’exécution automatique du script
C’est terminer pour le script à proprement parlé.
Vous pouvez maintenant aller plus loin en planifiant l’exécution automatique de ce script en fonction de vos besoins. Soit avec un orchestrateur spécifique ou directement depuis l’outil de tâches planifiées disponible dans Windows Server.
Pour ce faire, je vous inviter à consulter ce lien.
L’ensemble du script est disponible en téléchargement :
- Ici : LaunchMIM_blog_version ;
- Et sur GitHub.