Invoke-CvCommand and Get-CvAdObject

  • Last update on April 10th, 2024

This article offers an in-depth exploration of two internal PowerShell functions: “Invoke-CvCommand” and “Get-CvAdObject”. These functions are designed to help you perform tasks more efficiently when dealing with multiple forests.

Introduction

The “Invoke-CvCommand” and “Get-CvAdObject” commands are essential components of our system, created to handle customized PowerShell instructions. “Invoke-CvCommand” serves as an enhanced wrapper for the “Invoke-Command” cmdlet, while “Get-CvAdObject” wraps the “Get-AdObject” cmdlet.

Use of “Invoke-CvCommand”

“Invoke-CvCommand” executes commands on remote computers, akin to the “Invoke-Command” cmdlet, but with some differences.

Parameters

typeEnv

This parameter defines the environment for command execution. It accepts two values: ActiveDirectory and Exchange.

scriptblock

It specifies the commands to run. Given that typeEnv can accept ActiveDirectory or Exchange, a script block must not contain a mix of Active Directory and Exchange commands. Each script block should contain cmdlets for only one context.

argumentLists

It provides the values of parameters for the script block. The parameters in the script block are passed by position from the array value supplied to argumentLists.

source

It identifies the source used to establish a remote PowerShell session. The source can be a distinguished name, a security identifier (SID), or a fully qualified domain name (Fqdn).

externalFunctionsNames

It provides an array of function names that can be used in the script block.

Example 1: Invoke a command using a script block stored in a variable without any parameters. 

In this example, the script block does not require any parameters, so we can exclude the argumentLists argument from the Invoke-CvCommand. The script block contains an Active Directory command: Get-AdUser, so the Invoke-CvCommand specifies the value ActiveDirectory as typeEnv. The Invoke-CvCommand uses a distinguished name as the source.

$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

The Invoke-CvCommand uses a FQDN as the 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

The Invoke-CvCommand uses a SID as the 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

Example 2: Invoke a command using a script block and the argumentLists parameter to pass variable values. 

In this scenario, the Param keyword and the argumentLists parameter are used to pass variable values to a script block. The Invoke-CvCommand uses a script block that defines a single variable: $var1. The Get-AdUser cmdlet uses the named parameter Identity with the variable name. The argumentLists passes the values to the variable.

$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

Example 3: Invoke a command that includes the Credential parameter

In this example, the Invoke-CvCommand automatically passes the appropriate credential object to the script block, specifying a PsCredential object named $cred as the last variable in the Param. 

$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

Example 4: Invoke a script block with external PowerShell functions

This example demonstrates how to include external PowerShell functions within a script block. Split-DisplayName is a PowerShell function defined outside the script block, it accepts the parameter $displayName and calls the Split method. The ExternalFunctionsNames can be used to include one or more PowerShell functions into a script block as an array. In this example, we're passing an array containing a single element: “Split-DisplayName”.

Note: you can pass the helper functions described in the following article: Custom action cheat sheet.

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

Example 5: Invoke a script block with on-premises Exchange commands

This example illustrates how to invoke the on-premises Exchange cmdlet in a script block. The on-premises Exchange cmdlets must specify the prefix “onprem”; for example, the “Get-User” cmdlet becomes “Get-onpremUser” in the script block.

$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

Example 6: Get the domain controller from a source

This example demonstrates how to retrieve and use the domain controller. The DomainController parameter is only available in on-premises Exchange and specifies the domain controller used by a cmdlet to read or write data to Active Directory. Get-CvFqdnFromForestCache can retrieve the domain controller from a distinguished name or a security identifier. 

Note: this example is applicable only in an “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

Use of “Get-CvAdObject”

The “Get-CvAdObject” function is designed to fetch a single Active Directory object by leveraging the Global Catalog. The Global Catalog is a centralized information repository for an entire forest in Active Directory. It contains a partial representation of every object, so the Get-CvAdObject can help to identify objects without requiring a reference that pinpoints the domain that stores the complete version of the object. When a client sends a request to the Global Catalog, it connects via port 3269. By default, the Global Catalog is accessed over port 3268 for standard LDAP queries, and port 3269 for LDAP 
over SSL.

Note: This function may take some time to locate an object. Therefore, it’s recommended to use the Invoke-CvCommand cmdlet frequently.

Parameters

typeAdObject

This parameter determines the type of object to retrieve. It can accept one of the following values: User, Group, and Contact.

target

It specifies the Full Qualified Domain Name (FQDN) of the forest where the search will be executed.

identity

It defines the identity to be retrieved. Depending on the “typeAdObject” set, the identity can be: 

  • “sAMAccountName”, “UserPrincipalName” or “objectGUID” if the typeAdObject is set to “User”;
  • “sAMAccountName” if typeAdObject is set to “Group”;
  • “Name” or “Mail” field if typeAdObject is set to “Contact”.

Example 1: Retrieve user information using UserPrincpalName as identity

$target = "Contoso.DC1.Local"
$upn = "user@contoso.com"
$params = @{
 "typeAdObject" = "User"
 "target" = $target
 "Identity" = $upn
}
return Get-CvAdObject @params

This command retrieves and displays a subset of information for the user identified by “user@contoso.com”.

Example 2: Retrieve group information using sAMAccountName as identity

$target = "Contoso.DC1.Local"
$group = "group test"
$params = @{
 "typeAdObject" = "Group"
 "target" = $target
 "Identity" = $group
}
return Get-CvAdObject @params

Example 3: Retrieve contact information using Mail as identity

$target = "Contoso.DC1.Local"
$mailContact = "user@contoso.onmicrosoft.com"
$params = @{
 "typeAdObject" = "Contact"
 "target" = $target
 "Identity" = $mailContact
}
return Get-CvAdObject @params

Output

The Output will include the following properties: “RunspaceId”, “DistinguishedName”, “Name”, 
“ObjectClass” and “ObjectGUID”.