Home General Discussion

Portal language

Andreas_VoigtAndreas_Voigt Customer IT Monkey ✭

Hello there,


I work in a 3-language company and so i have to create every ARO in 3 seperate languages.

On top of that not every language-region gets every ARO provided, so basically I have 3 different front-ends.

My problem now is, as soon as a user gets the "wrong" language he actually cant use the portal efficient.

Is there a way to sort of bind-the portal language to the OS-language ?


Thanks in advance


Andreas

Answers

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

    I think I can help here. In my SCSM Translate project, I built a wholly new Work Item/Action Log notification mechanism that determines if the Assigned To/Affected speak the same language or not. If they don't, it hits Azure Translation Services so both parties can seamlessly work together. If they speak the same language, ATS is skipped and parties are notified as you'd expect. To accomplish this, I had to:

    • Retrieve the User's Language per the Portal API (I opted to go directly to the ServiceManagementDB)
    • Set the User's Language Code on their SCSM AD Object

    This is due to the fact that there is no native sync of sorts between the two. Not only that, Cireson supports 20ish languages whereas SCSM has Languages + Dialect (e.g. Locales). So the sync/match process is vague (and you can change it), but it gets the job done. The other reason I went for the DB directly as opposed to the API is that the API assumes I already know the single user/group of user's I want to retrieve. Going the DB route, I can just get all of the users + their language code and then use that to populate SCSM. Maybe their is a way to achieve this with the API, but the SQL route was just faster for me in this case. The other tricky thing here that took some practice was understanding the Language object/relationship to a User in SCSM. In SCSM it's a UserPreference that actually contains the Language Code (int) + TimeZone (string).

    Anyway, to accomplish this the following PowerShell should help you out:

    <#
        .SYNOPSIS
         Retrieve a user's Language setting from the SCSM Cireson Portal database to write into SCSM
        .DESCRIPTION
         This script retrieves the user language setting as defined through the Cireson SCSM portal database (ServiceManagement).
         Using this, a translation of sorts is performed to convert the IETF language code to a LocaleID that can be set on the
         user object within SCSM for each user record. This script will only sync users who have a locale defined.
        .NOTES
         Author: Adam Dzyacky
         Version: 1
         Requires: SMlets and SQL PowerShell
             Install-Module SMLets
             Install-Module SqlServer
    
         Data Sources used
            Cireson Supported languages = https://cireson.com/localization-and-globalization-in-cireson-portal/
            Microsoft Azure Translate supported languages = https://docs.microsoft.com/en-us/azure/cognitive-services/translator/language-support
            Microsoft Locale IDs = https://docs.microsoft.com/en-us/openspecs/office_standards/ms-oe376/6c085406-a698-4e12-9d4d-c3b0ee3dbc4a
    #>
    
    
    #define SCSM classes to work with
    $mgmtServer = "localhost"
    $domainUserClass = Get-SCSMClass -name "System.Domain.User$" -computername $mgmtServer
    $localeClass = Get-SCSMClass -name "System.UserPreference.Localization$" -computername $mgmtServer
    $userHasPrefProjection = Get-SCSMTypeProjection -name "System.User.Preferences.Projection$" -ComputerName $mgmtServer
    #define Cireson ServiceManagementDB variables
    $ciresonDB = "ServiceManagement"
    $ciresonServerInstance = "nameOfYourSQLServerWithORWithout\instance"
    
    
    #### FUNCTIONS ####
    #sets a user's locale within SCSM and preserves timezone
    function Set-SCSMUserLocale
    {
        param (
            [parameter(Mandatory=$true, Position=0)]
            $SCSMUser,
            [parameter(Mandatory=$true, Position=1)]
            [int] $LocaleID
        )
    
    
        #make sure the user doesn't have a defined preference, if they do we need to clear it
        $userLocaleRel = Get-SCSMRelationshipObject -BySource $SCSMUser -Filter "RelationshipID -eq '649e37ab-bf89-8617-94f6-d4d041a05171'" -computername $mgmtServer | ?{$_.TargetObject.ClassName -eq "System.UserPreference.Localization"}
        
        #user has a language/timezone preference to preserve
        if ($userLocaleRel)
        {
            #if they have a timezone defined, keep it
            $currentLocalePref = Get-SCSMObject -id $userLocaleRel.TargetObject.Id -computername $mgmtServer | select-object localeid, timezone
            if ($currentLocalePref.LocaleId -ne $LocaleID)
            {
                #the locale on the portal does not match the locale in SCSM, update
                if ($currentLocalePref.TimeZone)
                {
                    $TimeZone = $currentLocalePref.TimeZone
                }
                else
                {
                    $TimeZone = ""
                }
                Remove-SCSMRelationshipObject -SMObject $userLocaleRel -computername $mgmtServer
                New-SCSMUserPreference -localeid $LocaleID -timezone $TimeZone -scsmuser $SCSMUser
            }
            <#
            else
            {
                Write-Output "No update required for: $($SCSMUser.DisplayName)/$($SCSMUser.Username)"
            }
            #>
        }
        #user has no language preference, create one
        else
        {
            New-SCSMUserPreference -localeid $LocaleID -timezone "" -scsmuser $SCSMUser
        }
    }
    
    
    function New-SCSMUserPreference ($LocaleID, $Timezone, $SCSMUser)
    {
        #define the properties of the new locale
        $localeGuid = New-Guid
        $localePrefName = "Preference." + $localeGuid.guid.Replace("-","")
    
    
        #create the user locale preference projection
        $userLocaleProjection = @{__CLASS = "$($domainUserClass.Name)";
                                    __SEED = $SCSMUser;
                                    Preference = @{__CLASS = "$($localeClass)";
                                                        __OBJECT = @{"ID" = $localePrefName; "LocaleID" = $LocaleID; "DisplayName" = "$localePrefName"; "Timezone" = $TimeZone}
                                                    }
                                    }
    
    
        #create the user's locale preference
        New-SCSMObjectProjection -Type "$($userHasPrefProjection.Name)" -Projection $userLocaleProjection -computername $mgmtServer
        #Write-Output "Updated $LocaleID for $($SCSMUser.DisplayName)/$($SCSMUser.Username)"
    }
    #### END FUNCTIONS ####
    
    
    #SQL query to run against Cireson Service Management db
    $query = @"
    select u.username, userpref.Preferences
    from CI`$User as u
        inner join UserPreferences as userpref on u.Id = userpref.UserId
    "@
    
    
    #go get the users from the Cireson Service Management DB
    $ciresonUsers = Invoke-sqlcmd -query $query -serverinstance $ciresonServerInstance -Database $ciresonDB
    
    
    #loop through each user to build a new object consisting of their username and two letter language code
    foreach ($ciresonUser in $ciresonusers)
    {
        #create a custom psobject
        $ciresonUserObject = New-Object System.Object
        $ciresonUserObject | Add-Member -type NoteProperty -name UserName -value $ciresonUser.username
        $ciresonUserObject | Add-Member -type NoteProperty -name LanguageCode -value ($ciresonUser.Preferences | ConvertFrom-Json | select LanguageCode -ExpandProperty LanguageCode | select Id -ExpandProperty Id)
        $ciresonUserObject | Add-Member -type NoteProperty -name IetfLanguageTag -value ($ciresonUser.Preferences | ConvertFrom-Json | select culture -ExpandProperty culture | select IetfLanguageTag -ExpandProperty IetfLanguageTag)
    
    
        #get the user from SCSM
        $scsmUserObject = Get-SCSMObject -class $domainUserClass -filter "username -eq '$($ciresonUserObject.UserName)'" -computername $mgmtServer
        
        #figure out the Locale ID to set from the Cireson User Preference
        switch ($ciresonUserObject.LanguageCode)
        {
            "ENU" {$localeID = "1033" } #united states
            "PLK" {$localeID = "1045" } #poland
            "ESN" {$localeID = "20490"} #puerto rico
            "RUS" {$localeID = "1049" } #russia
            "ARA" {$localeID = "1025" } #arabic, saudi arabia
            "CHS" {$localeID = "3076" } #chinese
            "CSY" {$localeID = "1029" } #czech
            "DAN" {$localeID = "1030" } #danish
            "NLD" {$localeID = "2067" } #dutch
            "DEU" {$localeID = "1031" } #german
            "FIN" {$localeID = "1035" } #finnish
            "FRA" {$localeID = "1036" } #french
            "HUN" {$localeID = "1038" } #hungarian
            "ITA" {$localeID = "1040" } #italian
            "JPN" {$localeID = "1041" } #japanese
            "KOR" {$localeID = "1042" } #korean
            "NOR" {$localeID = "1044" } #norwegian
            "PTB" {$localeID = "1046" } #portuguese
            "SVE" {$localeID = "1053" } #swedish
            "TRK" {$localeID = "1055" } #turkish
        }
    
    
        #write the user's new Locale into their SCSM User record
        Set-SCSMUserLocale -SCSMUser $scsmUserObject -LocaleID $localeID
    }
    


Sign In or Register to comment.