Skip to content

Error when running Exchange Scripts #33

@salwaharif

Description

@salwaharif

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions