Cet article propose une exploration approfondie de deux fonctions internes PowerShell : “Invoke-CvCommand” et “Get-CvAdObject”. Ces fonctions sont conçues pour vous aider à réaliser des tâches efficacement, notamment dans les environnements multi-forêts.
Introduction
Les commandes “Invoke-CvCommand” et “Get-CvAdObject” sont des briques essentielles de notre système, destinées à gérer des instructions PowerShell personnalisées. “Invoke-CvCommand” sert de wrapper enrichi pour le cmdlet “Invoke-Command”, tandis que “Get-CvAdObject” encapsule le cmdlet “Get-AdObject”.
Utilisation de “Invoke-CvCommand”
“Invoke-CvCommand” exécute des commandes sur des ordinateurs distants, à la manière du cmdlet “Invoke-Command”, avec quelques différences.
Paramètres
typeEnv
Ce paramètre définit l’environnement d’exécution. Il accepte deux valeurs : ActiveDirectory et Exchange.
scriptblock
Définit les commandes à exécuter. Comme typeEnv accepte ActiveDirectory ou Exchange, un scriptblock ne doit pas contenir de mixte entre cmdlets AD et Exchange. Chaque scriptblock doit contenir des cmdlets d’un seul contexte.
argumentLists
Permet de transmettre les variables au scriptblock. Les paramètres du scriptblock sont passés par position depuis le tableau fourni à argumentLists.
source
Identifie la source utilisée pour établir la session PowerShell distante. La source peut être un distinguished name, un Security Identifier (SID) ou un Fully Qualified Domain Name (FQDN).
externalFunctionsNames
Permet de fournir un tableau de noms de fonctions utilisables dans le scriptblock.
Exemple 1 : Invoquer une commande avec un scriptblock stocké dans une variable sans paramètres
Ici, le scriptblock n’attend aucun paramètre, donc argumentLists n’est pas requis. Le scriptblock contient une commande AD (“Get-AdUser”), et typeEnv est “ActiveDirectory”. La source utilisée est un distinguished name.
$sb = {
param()
Get-AdUser -Identity "CN=user,OU=OU_1,DC=Contoso,DC=local" | Select-Object
UserPrincipalName
}
$job = Invoke-CvCommand -typeEnv ActiveDirectory -scriptBlock $sb -source
"CN=user,OU=OU_1,DC=Contoso,DC=local"
return $job
Exemple avec le FQDN en source :
$fqdn = "Contoso.DC1.Local"
$sb = {
param()
Get-AdUser -Identity "CN=test user,OU=OU_1,DC=Contoso,DC=local" | Select-Object
UserPrincipalName
}
$job = Invoke-CvCommand -typeEnv ActiveDirectory -scriptBlock $sb -source $fqdn
return $job
Exemple avec le SID en source :
$UserSid = "S-1-5-21-507672319-2510724776-1356001139-3178"
$sb = {
param()
Get-AdUser -Identity "CN=test user,OU=OU_1,DC=Contoso,DC=local" | Select-Object
UserPrincipalName
}
$job = Invoke-CvCommand -typeEnv ActiveDirectory -scriptBlock $sb -source $userSid
return $job
Exemple 2 : Invoquer une commande avec scriptblock et utilisation de argumentLists pour passer la valeur d’une variable
Ici, le paramètre Param et argumentLists sont utilisés pour transmettre une variable au scriptblock. Le scriptblock attend une variable $var1.
$userDn = "CN=user,OU=OU_1,DC=Contoso,DC=local"
$sb = {
param($var1)
Get-AdUser -Identity $var1 | Select-Object UserPrincipalName
}
$job = Invoke-CvCommand -typeEnv ActiveDirectory -scriptBlock $sb -argumentLists $userDn
-source $userDn
return $job
Exemple 3 : Invoquer une commande qui utilise un paramètre Credential
Le paramètre d’identification (objet PsCredential nommé $cred) se place en dernière position dans le paramètre Param du scriptblock.
$userDn = "CN=test,OU=OU_1,DC=Contoso,DC=local"
$sb = {
param($var1, [System.Management.Automation.PSCredential]$cred)
Get-AdUser -Identity $var1 -Credential $cred | Select-Object UserPrincipalName
}
$job = Invoke-CvCommand -typeEnv ActiveDirectory -scriptBlock $sb -argumentLists $userDn
-source $userDn
return $job
Exemple 4 : Invoquer un scriptblock avec des fonctions PowerShell externes
Exemple d’inclusion d’une fonction PowerShell externe dans un scriptblock. Ici, Split-DisplayName (définie plus haut) est passée à “externalFunctionsNames”. Voir l’article Astuces actions personnalisées.
function Split-DisplayName( $displayName){
$split = $displayName.Split(" ", [System.StringSplitOptions]::RemoveEmptyEntries)
return $split[0]
}
$userDn = "CN=test user,OU=OU_1,DC=Contoso,DC=local"
$displayName = "test user"
$sb = {
param($displayName, [System.Management.Automation.PSCredential]$cred)
$firstName = Split-DisplayName -displayName $displayName
Get-AdUser -Filter "givenName -eq '$firstName'" -Credential $cred | Select-Object
UserPrincipalName
}
$job = Invoke-CvCommand -typeEnv ActiveDirectory -scriptBlock $sb -argumentLists
$displayName -source $userDn -externalFunctionsNames "Split-DisplayName"
return $job
Exemple 5 : Utiliser les cmdlets Exchange on-premises dans un scriptblock
Les cmdlets Exchange on-premises doivent être préfixées par “onprem”. Par exemple, "Get-User
" devient "Get-onpremUser
".
$userDn = "CN=user test,OU=OU_1,DC=Contoso,DC=local"
$sb = {
param($var1)
Get-onpremRemoteMailbox -Identity $var1 | Select-Object RecipientTypeDetails
}
$job = Invoke-CvCommand -typeEnv Exchange -scriptBlock $sb -argumentLists $userDn -
source $userDn
return $job
Exemple 6 : Récupérer le contrôleur de domaine à partir d’une source
Voici comment récupérer et utiliser le contrôleur de domaine. Le paramètre DomainController, uniquement disponible pour Exchange On-Premises, spécifie le contrôleur de domaine utilisé par un cmdlet pour lire/écrire dans AD. Get-CvFqdnFromForestCache permet de récupérer le contrôleur de domaine à partir d’un distinguished name ou d’un SID.
Note : cet exemple s’applique uniquement au “Organizational forest model”.
$userDn = "CN=user test,OU=OU_1,DC=Contoso,DC=local"
$domainController = Get-CvFqdnFromForestCache -target $userDn
$sb = {
param( $identity, $domainController)
$user = Get-onpremUser -Identity $identity -DomainController $domainController |
Select-Object DistinguishedName
$recipientType = Get-onpremRemoteMailbox -Identity $user.DistinguishedName -
DomainController $domainController
return $recipientType
}
$job = Invoke-CvCommand -typeEnv Exchange -scriptBlock $sb -argumentLists "user test",
$domainController -source $userDn
return $job
Utilisation de “Get-CvAdObject”
La fonction “Get-CvAdObject” est conçue pour récupérer un objet Active Directory via le Global Catalog. Le Global Catalog est un référentiel centralisé d'une forêt Active Directory. Il contient une représentation partielle de chaque objet, ce qui permet à Get-CvAdObject d’identifier un objet sans référence au domaine d’origine. Par défaut, le Global Catalog est accessible sur le port 3268 pour les requêtes LDAP standard, et 3269 pour LDAP over SSL.
Note : Cette fonction peut prendre un certain temps pour localiser un objet. Il est donc recommandé d’utiliser le cmdlet Invoke-CvCommand dès que possible.
Paramètres
typeAdObject
Définit le type d’objet à récupérer : User, Group ou Contact.
target
Indique le Fully Qualified Domain Name (FQDN) de la forêt dans laquelle s’effectue la recherche.
identity
Définit l’identité à récupérer. Selon « typeAdObject » :
- “sAMAccountName”, “UserPrincipalName” ou “objectGUID” si typeAdObject = “User”
- “sAMAccountName” si typeAdObject = “Group”
- “Name” ou “Mail” si typeAdObject = “Contact”
Exemple 1 : Récupérer les informations d’un utilisateur via le UserPrincipalName
$target = "Contoso.DC1.Local"
$upn = "user@contoso.com"
$params = @{
"typeAdObject" = "User"
"target" = $target
"Identity" = $upn
}
return Get-CvAdObject @params
Cette commande récupère et affiche un sous-ensemble d’informations pour l’utilisateur “user@contoso.com”.
Exemple 2 : Récupérer les informations d’un groupe via sAMAccountName
$target = "Contoso.DC1.Local"
$group = "group test"
$params = @{
"typeAdObject" = "Group"
"target" = $target
"Identity" = $group
}
return Get-CvAdObject @params
Exemple 3 : Récupérer les infos d’un contact via son adresse mail
$target = "Contoso.DC1.Local"
$mailContact = "user@contoso.onmicrosoft.com"
$params = @{
"typeAdObject" = "Contact"
"target" = $target
"Identity" = $mailContact
}
return Get-CvAdObject @params
Résultat
La sortie comprend les propriétés suivantes : “RunspaceId”, “DistinguishedName”, “Name”, “ObjectClass” et “ObjectGUID”.