Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when running Exchange Scripts #33

Open
salwaharif opened this issue Nov 23, 2021 · 0 comments
Open

Error when running Exchange Scripts #33

salwaharif opened this issue Nov 23, 2021 · 0 comments

Comments

@salwaharif
Copy link

salwaharif commented Nov 23, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant