Running exchange import script in the powershell MA ends up with the following error :
"You cannot call a method on a null-valued expression."
This is coming from the line that contains : $Global:DirSyncCookieString = [System.Convert]::ToBase64String($Searcher.DirectorySynchronization.GetDirectorySynchronizationCookie())
The cookie variable is returning a null value.
When I ran the script separately, I saw that when $Searcher.FindAll() were not assigned to a variable (and just runs on the script as an output) the cookie is well assigned. But everytime a variable is assigned before that, the script ends up with a "null-valued" error.
So the solution was to assign $Global:AllUsers and then to output its value.
Then, when I did this on the import powershell script, I got another error :
"An error occurred while enumerating through a collection: Access is denied."
--> It seems this time to be an error from the account that's being used : MA Connector has not enough rights to run the findall() command.
Workaround
I did find a workaround for the last error (I'm sure it can be way more better... ) :
This is the old code :
`$Searcher = New-Object -TypeName 'System.DirectoryServices.DirectorySearcher' -ArgumentList $DirectoryEntry, "(&(objectCategory=person)(objectClass=user))", $DeltaPropertiesToLoad, $SearchScope
if($OpenImportConnectionRunStep.ImportType -eq 'Delta') {
$Searcher.TombStone = $true
}
$Searcher.CacheResults = $false
if ($null -eq $CustomData.watermark.DirSyncCookie) {
$Searcher.directorysynchronization = new-object -TypeName system.directoryservices.directorysynchronization
} else {
# grab the watermark from last run and pass that to the searcher
$DirSyncCookie = ,[System.Convert]::FromBase64String($CustomData.WaterMark.DirSyncCookie)
$Searcher.directorysynchronization = new-object -TypeName system.directoryservices.directorysynchronization -ArgumentList $DirSyncCookie
}
$Global:AllUsers = $Searcher.FindAll()
$null = $Global:AllUsers.Count
$Global:DirSyncCookieString = [System.Convert]::ToBase64String($Searcher.DirectorySynchronization.GetDirectorySynchronizationCookie())
`
And this is the new one :
`
$Global:results = Invoke-Command -Credential $Credential -ComputerName "MYACTIVEDIRECTORYSERVERNAME" -ScriptBlock {
param([Parameter(Position=0)]$dir,[Parameter(Position=1)]$filter,[Parameter(Position=3)]$DeltaProperties,[Parameter(Position=4)]$Scope)
$Searcher = New-Object -TypeName 'System.DirectoryServices.DirectorySearcher' -ArgumentList $dir,$filter, $DeltaProperties,$Scope
if($Using:OpenImportConnectionRunStep.ImportType -eq 'Delta') {
$Searcher.TombStone = $true
}
$Searcher.CacheResults = $false
if ($null -eq $Using:CustomData.watermark.DirSyncCookie) {
$Searcher.directorysynchronization = new-object -TypeName system.directoryservices.directorysynchronization
} else {
# grab the watermark from last run and pass that to the searcher
$DirSyncCookie = ,[System.Convert]::FromBase64String($Using:CustomData.WaterMark.DirSyncCookie)
$Searcher.directorysynchronization = new-object -TypeName system.directoryservices.directorysynchronization -ArgumentList $DirSyncCookie
}
$value = "" | Select-Object -Property Users,Cookie
$value.Users=$Searcher.FindAll()
$value.Users
$value.Cookie=$Searcher.DirectorySynchronization.GetDirectorySynchronizationCookie()
$objObjects = @()
foreach ($objResult in $value.Users)
{
$objObjects += $objResult.Properties
}
$value.Users=$objObjects
return $value
} -ArgumentList $DirectoryEntry.path,$filter,$DeltaPropertiesToLoad,$SearchScope
$Global:AllUsers = $Global:results.Users
$null = $Global:AllUsers.Count
$Global:DirSyncCookieString = [System.Convert]::ToBase64String($Global:results.Cookie) `
And also replace in the section below that this value $User = $Global:AllUsers[$i] by this one:
$User = $Global:results[$i]
And finally :
1 - Be sure to put the name of an active directory DC in the configuration of the MA (server attribute)
2 - Be sure to choose the root partition