Home Service Manager

Only primary smtp address get synced

Mikkel_MadsenMikkel_Madsen Customer Advanced IT Monkey ✭✭✭

Hi

We have users who has more than one email adderess.

Primary smtp address is my.longNameEmail@domain.dk

second smtp address could be my.short@domain.dk

third smtp address my.third@domain.dk

My problem is that only the primary smtp address got synced to the user - why is that? I'm sure that in the past all of the emails got synced from AD to Service Manager.

We have changed from Exchange on-prem to Exchange online - is this why it's "not working"?

Best Answers

  • Mikkel_MadsenMikkel_Madsen Customer Advanced IT Monkey ✭✭✭
    Answer ✓

    We don't use Orchestrator but I have made this script to sync emails from AD to SCSM

    # Uncomment the line below if running in an environment where script signing is required.
    Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force
    
    #Import SMLets module for powershell (needs to be installed on the server first)
    Import-Module SMLets
    #Import Active Directory module for powershell (needs to be installed on the server first)
    Import-Module ActiveDirectory
    
    #To format datetime object in Danish culture
    $dkCulture = New-Object System.Globalization.CultureInfo("da-DK")
    
    #Total emails added counter variable
    $totalEmailsAdded = 0
    #Total users not in scsm db counter
    $totalErrorCount = 0
    
    #Folder path for simple logfile
    $logFolderPath = "Microsoft.PowerShell.Core\FileSystem::C:\SCSM\Scripts\SyncEmailAddressesFromAD\Logfiles"
    #Name of logfile - adds timestamp på make unique log files
    $logfileName = "Email sync results - " + [datetime]::now.ToString("ddMMyyyy_HHmm") + '.txt'
    #Full logfile path
    $logfilePath = "$logFolderPath/$logfileName"
    
    #Adds start on logfile
    $logfileStartTime = [datetime]::now
    Add-Content -Path $logfilePath -Value "$($logfileStartTime.ToString('G', $dkCulture)) -> Start sync of user emails from Active Directory to SCSM"
    
    
    #The User class has a relation called “User has Preference” which we are storing in a variable.
    $userpreferenceclass = get-scsmrelationshipclass -name system.userhaspreference$
    #The User class - We are using Microsoft.AD.User class id (can't get to work by getting it by name, therefor getting it by id)
    $userClass = Get-SCSMClass -id '10a7f898-e672-ccf3-8881-360bfb6a8f9a'
    
    #Get SID and Emails addreses of all active users from AD that starts with 'dr'
    $activeDrUsers = get-aduser -Properties 'proxyAddresses' -Filter "SamAccountName -like 'dr*' -AND Enabled -eq 'True'" | select -Property SID, proxyAddresses
    
    #For each user we extract only the addresses that starts with 'smtp:' and ends with '.dk' 
    foreach ($activeDrUser in $activeDrUsers)
    {
      #Only addresses that starts with 'smtp:' and ends with '.dk' - CaseSentive so we don't get primary SMTP address
      $emailsFromAD = $activeDrUser.proxyAddresses | Select-String -Pattern 'smtp:' -CaseSensitive -SimpleMatch | Select-String -Pattern '.dk' -CaseSensitive -SimpleMatch
       
      #The SID of the user from AD
      $userSID = $activeDrUser.SID
    
      #Get the user object from SCSM by SID from AD
      $user = Get-SCSMObject -class $userClass -filter “SID -eq $userSID”
    
      #if user is found we check the addresses else we write the info to the log
      if($user)
      {
        #Get the smtp email addresses from the scsm user object.
        $emailsFromSCSM = (Get-scsmrelatedobject –smobject $user –relationship $userpreferenceclass | where{$_.displayname –match “smtp”}).targetaddress
    
    
        #Testing each mailaddress to see if it already exist - else adding it to the user as smtp notification endpoint
        foreach ($email in $emailsFromAD)
        {
          #Get clean email address without 'smtp:'
          $tmpEmail = "$email".Substring(5)
    
          ##Here we have to test for existence of the email address in the scsm - if already existe then skip - else add email address to the users by the SID 
          #If email address from the ad not in array om addresses from scsm then add it to the user
          if(!($emailsFromSCSM.Contains($tmpEmail)))
          {
            #Write to logfile that we will add the email address to the user
            Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> We are going to add the address $tmpEmail to the user $($user.DisplayName)"
    
    
            #Create at new guid for the object
            $newGUID = ([guid]::NewGuid()).ToString()
            #The displayname attribute
            $displayName = $tmpEmail + "_smtp"
            #The projection of the email address 
            $projection = @{__CLASS = "System.Domain.User";
                    __SEED = $user;
                    Notification = @{__CLASS = "System.Notification.Endpoint";
                             __OBJECT = @{Id = $newGUID;
                                   DisplayName = $displayName;
                                   ChannelName = "SMTP";
                                   TargetAddress = $tmpEmail;
                                   Description = "Added by Powershell sync script";
                             }
                    }
            }
            #Submit the new address to the user object in scsm 
            New-SCSMObjectProjection -Type "System.User.Preferences.Projection" -Projection $projection
            #Adds to total emails added counter
            $totalEmailsAdded += 1
          }
        }
      }
      else
      {
        #Add info to logfile of users from AD that doesn't exist in SCSM
        Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> ERROR: User with SID: $userSID not found in SCSM DB"
        Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> ERROR: $(get-aduser -Filter 'SID -eq $userSID')"
        $totalErrorCount += 1
      }
    }
    #Total sync time
    $syncTime = ([datetime]::now).Subtract($logfileStartTime)
    
    #Add some info to the log
    Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> Total users from AD Checked: $($activeDrUsers.Length)"
    Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> Total emails added to scsm: $totalEmailsAdded"
    Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> Total users not in SCSM DB: $totalErrorCount"
    
    #Add total sync time to the logfile and end sync
    Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> Total sync time $($syncTime.Days) Days, $($syncTime.Hours) Hours, $($syncTime.Minutes) Minutes, $($syncTime.Seconds) Seconds, $($syncTime.Milliseconds) Milliseconds"
    Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> End of sync"
    


Answers

  • Adam_DzyackyAdam_Dzyacky Product Owner Contributor Monkey ✭✭✭✭✭

     I'm sure that in the past all of the emails got synced from AD to Service Manager.

    I'm actually not so sure about that. To be fair, I don't this for 100% certain but the AD Connector is syncing users out AD along with several of their properties. Seeing as they only have one Email Address property on an AD User Object, I would guess that translates only to a single SMTP Object that is related to the User in SCSM.

    In the land of Exchange, they could clearly have as many addresses as they want but they'll only ever have a single primary which is what is written to Active Directory.


    Again I don't know this for 100% fact. But it feels right.

  • Mikkel_MadsenMikkel_Madsen Customer Advanced IT Monkey ✭✭✭

    Anyone else? @Konstantin_Slavin-Bo what email adresses do you have in your system? /mikkel

  • Brian_WiestBrian_Wiest Customer Super IT Monkey ✭✭✭✭✭

    Why not have SCORCH run a sync job that copies all the addresses into SCSM and relate to the user object?

  • Adam_DzyackyAdam_Dzyacky Product Owner Contributor Monkey ✭✭✭✭✭
    edited March 2020

    Brian just took the thought right out of my head.

  • James_JohnsonJames_Johnson Customer Advanced IT Monkey ✭✭✭

    That's a terrific question, why don't I do that.. sorry for the thread hijack Mikkel 😁

  • Brian_WiestBrian_Wiest Customer Super IT Monkey ✭✭✭✭✭

    We are still mid migration to O365 and havn't started to use them yet but curious to see how O365 groups will come into play with SCSM.

  • Adam_DzyackyAdam_Dzyacky Product Owner Contributor Monkey ✭✭✭✭✭
    edited March 2020

    @Brian_Wiest - AFAIK they won't... and that is definitely it's own thread 😁

  • Mikkel_MadsenMikkel_Madsen Customer Advanced IT Monkey ✭✭✭

    Thank you @James_Johnson

    That was all I had to know :)

  • Mikkel_MadsenMikkel_Madsen Customer Advanced IT Monkey ✭✭✭
    Answer ✓

    We don't use Orchestrator but I have made this script to sync emails from AD to SCSM

    # Uncomment the line below if running in an environment where script signing is required.
    Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force
    
    #Import SMLets module for powershell (needs to be installed on the server first)
    Import-Module SMLets
    #Import Active Directory module for powershell (needs to be installed on the server first)
    Import-Module ActiveDirectory
    
    #To format datetime object in Danish culture
    $dkCulture = New-Object System.Globalization.CultureInfo("da-DK")
    
    #Total emails added counter variable
    $totalEmailsAdded = 0
    #Total users not in scsm db counter
    $totalErrorCount = 0
    
    #Folder path for simple logfile
    $logFolderPath = "Microsoft.PowerShell.Core\FileSystem::C:\SCSM\Scripts\SyncEmailAddressesFromAD\Logfiles"
    #Name of logfile - adds timestamp på make unique log files
    $logfileName = "Email sync results - " + [datetime]::now.ToString("ddMMyyyy_HHmm") + '.txt'
    #Full logfile path
    $logfilePath = "$logFolderPath/$logfileName"
    
    #Adds start on logfile
    $logfileStartTime = [datetime]::now
    Add-Content -Path $logfilePath -Value "$($logfileStartTime.ToString('G', $dkCulture)) -> Start sync of user emails from Active Directory to SCSM"
    
    
    #The User class has a relation called “User has Preference” which we are storing in a variable.
    $userpreferenceclass = get-scsmrelationshipclass -name system.userhaspreference$
    #The User class - We are using Microsoft.AD.User class id (can't get to work by getting it by name, therefor getting it by id)
    $userClass = Get-SCSMClass -id '10a7f898-e672-ccf3-8881-360bfb6a8f9a'
    
    #Get SID and Emails addreses of all active users from AD that starts with 'dr'
    $activeDrUsers = get-aduser -Properties 'proxyAddresses' -Filter "SamAccountName -like 'dr*' -AND Enabled -eq 'True'" | select -Property SID, proxyAddresses
    
    #For each user we extract only the addresses that starts with 'smtp:' and ends with '.dk' 
    foreach ($activeDrUser in $activeDrUsers)
    {
      #Only addresses that starts with 'smtp:' and ends with '.dk' - CaseSentive so we don't get primary SMTP address
      $emailsFromAD = $activeDrUser.proxyAddresses | Select-String -Pattern 'smtp:' -CaseSensitive -SimpleMatch | Select-String -Pattern '.dk' -CaseSensitive -SimpleMatch
       
      #The SID of the user from AD
      $userSID = $activeDrUser.SID
    
      #Get the user object from SCSM by SID from AD
      $user = Get-SCSMObject -class $userClass -filter “SID -eq $userSID”
    
      #if user is found we check the addresses else we write the info to the log
      if($user)
      {
        #Get the smtp email addresses from the scsm user object.
        $emailsFromSCSM = (Get-scsmrelatedobject –smobject $user –relationship $userpreferenceclass | where{$_.displayname –match “smtp”}).targetaddress
    
    
        #Testing each mailaddress to see if it already exist - else adding it to the user as smtp notification endpoint
        foreach ($email in $emailsFromAD)
        {
          #Get clean email address without 'smtp:'
          $tmpEmail = "$email".Substring(5)
    
          ##Here we have to test for existence of the email address in the scsm - if already existe then skip - else add email address to the users by the SID 
          #If email address from the ad not in array om addresses from scsm then add it to the user
          if(!($emailsFromSCSM.Contains($tmpEmail)))
          {
            #Write to logfile that we will add the email address to the user
            Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> We are going to add the address $tmpEmail to the user $($user.DisplayName)"
    
    
            #Create at new guid for the object
            $newGUID = ([guid]::NewGuid()).ToString()
            #The displayname attribute
            $displayName = $tmpEmail + "_smtp"
            #The projection of the email address 
            $projection = @{__CLASS = "System.Domain.User";
                    __SEED = $user;
                    Notification = @{__CLASS = "System.Notification.Endpoint";
                             __OBJECT = @{Id = $newGUID;
                                   DisplayName = $displayName;
                                   ChannelName = "SMTP";
                                   TargetAddress = $tmpEmail;
                                   Description = "Added by Powershell sync script";
                             }
                    }
            }
            #Submit the new address to the user object in scsm 
            New-SCSMObjectProjection -Type "System.User.Preferences.Projection" -Projection $projection
            #Adds to total emails added counter
            $totalEmailsAdded += 1
          }
        }
      }
      else
      {
        #Add info to logfile of users from AD that doesn't exist in SCSM
        Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> ERROR: User with SID: $userSID not found in SCSM DB"
        Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> ERROR: $(get-aduser -Filter 'SID -eq $userSID')"
        $totalErrorCount += 1
      }
    }
    #Total sync time
    $syncTime = ([datetime]::now).Subtract($logfileStartTime)
    
    #Add some info to the log
    Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> Total users from AD Checked: $($activeDrUsers.Length)"
    Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> Total emails added to scsm: $totalEmailsAdded"
    Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> Total users not in SCSM DB: $totalErrorCount"
    
    #Add total sync time to the logfile and end sync
    Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> Total sync time $($syncTime.Days) Days, $($syncTime.Hours) Hours, $($syncTime.Minutes) Minutes, $($syncTime.Seconds) Seconds, $($syncTime.Milliseconds) Milliseconds"
    Add-Content -Path $logfilePath -Value "$([datetime]::now.ToString('G', $dkCulture)) -> End of sync"
    


  • James_JohnsonJames_Johnson Customer Advanced IT Monkey ✭✭✭

    @Mikkel_Madsen

    Thanks for posting this, I'll check it out!

Sign In or Register to comment.