Invoke-CvCommand et Get-CvAdObject

  • Last update on June 4th, 2025

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”.