PI Services

Le blog des collaborateurs de PI Services

MECM (SCCM) : Remettre à zéro l'indicateur d'installation

Une des bonne pratiques SCCM est d'activer la tâche de maintenance "Remettre à zéro l'indicateur d'installation".

Cette tâche permet d'effacer les indicateurs d'installation lorsque la découverte par pulsations d'inventaire ne découvre aucun client au cours de la période de redécouverte.

L'avantage d'avoir activé cette tâche de maintenance est de garder les indicateurs d'installation des agents MECM à jour et de détecter les agents qui ne sont plus en bonne santé et les réinstaller.

Pour activer cette tâche, sur la console MECM, cliquer sur Administration > Configuration de site > Sites > Cliquer sur le site primaire puis sur Maintenance de site.

Chercher la tâche avec le nom "Remettre à zéro l'indicateur d'installation" et cliquer sur activer. il est possible également de définir la planification pour contrôler la fréquence d'exécution de la tâche.

Dans la capture d'écran ci-dessus, la tâche de maintenance a été activée pour détecter les agents qui n'ont pas contacté le site primaire MECM depuis 40 jours par pulsation d'inventaire, si c'est le cas, l'indicateur d'installation passera de "Oui" à "Non".

- Si l'agent n'existe plus, l'indicateur reste "Non" jusqu'au nettoyage des objets obsolètes

- Si l'agent existe toujours mais était déconnectée pendant plus de 40 jours, à la prochaine connexion l'indicateur passera à "Oui"

- Si l'agent existe toujours mais ne communique pas avec MECM car il n'est plus en bonne santé, il sera réinstallé puisque l'indicateur d'installation est passé à "Non" mais la machine est connectée pour recevoir un nouveau push du client

 

ADMT : Contrôleur de domaine à utiliser lors d'une migration ordinateur

Durant une migration ordinateur avec l'outil ADMT d'un domaine source vers un domaine cible, il est possible de rencontrer l’erreur ci-dessous :

ERR3:7075 Failed to change domain affiliation, hr=80070005 Access is denied

Cette erreur sera enregistrée dans le fichier log de migration ADMT sous c:\windows\admt\logs.

Lors de la migration des objets ordinateurs avec ADMT, l'outil demande de choisir les contrôleurs de domaine source et cible à utiliser. Le choix du DC cible est très important !

Il ne faut pas choisir n'importe quel DC cible, il faut plutôt utiliser le nom du DC où la configuration ci-dessous a été faite.

Resolution de l'erreur:

Cette erreur peut être résolue par deux méthodes :

1. Activer la stratégie de groupe (GPO) suivante sur tous les contrôleurs de domaine cible (Default domain policy) :

“Computer Settings\Windows Settings\Security Settings\Local Policies\Security Options\NetWork Access: Named Pipes that can be accessed anonymously” avec au moins les services “netlogon,lsarpc” inclus.

2. Choisir un des contrôleurs de domaine cible (qui sera utilisé lors de la migration ordinateur) et créer la clé de registre suivante : "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters\NullSessionPipes" avec les valeurs "netlogon,lsarpc"

Source : https://santhoshsivarajan.wordpress.com/2010/10/30/admt-err37075-failed-to-change-domain-affiliation-access-is-denied/

Explication de l’erreur:

ADMT agents sync the computer with the target domain using anonymous connections to the LSARPC and NETLOGON named pipes on the target domain's DC.

Source : https://social.technet.microsoft.com/Forums/ie/en-US/304f25a2-cb85-4570-b616-669a5a874ba0/admt-computer-migration-failures?forum=winserverMigration

 

Remarque :

Le fait d'installer l'outil ADMT PES (Paswword Export Server) sur un contrôleur de domaine, la clé de registre ci-dessus sera créée automatiquement.

SCCM - SQL Query - 'Last Enforcement State' pour tout les déploiements/computers.

La requete SQL ci-dessous liste l'état d'application (Enforcement) pour toutes les machines et les deploiements correspondant.

 

/*** SCCM - QUERY TO DISPLAY ALL COMPUTERS 'LAST ENFORCEMENT STATE' FOR ALL DEPLOYMENTS  ***/


DECLARE @StartDate DATETIME, @EndDate DATETIME
	
-- Since 12 months
SET @StartDate = DATEADD(mm, -12,GETDATE())
SET @EndDate = GETDATE() 


SELECT

vrs.Name0,

CASE vrs.Active0
	WHEN 0 THEN 'NO'
	WHEN 1 THEN 'YES'
	END AS Client_Active,

a.AssignmentName as DeploymentName,
a.StartTime as Deploy_Available,
a.EnforcementDeadline as Deploy_Deadline,
sn.StateName as LastEnforcementState,
wsus.LastErrorCode as 'LasErrorCode'


FROM v_CIAssignment a
JOIN v_AssignmentState_Combined assc on a.AssignmentID=assc.AssignmentID
JOIN v_StateNames sn on assc.StateType = sn.TopicType and sn.StateID=isnull(assc.StateID,0)
JOIN v_R_System vrs on vrs.ResourceID = assc.ResourceID
JOIN v_GS_WORKSTATION_STATUS wks on wks.ResourceID = assc.ResourceID
JOIN v_UpdateScanStatus wsus on wsus.ResourceID = assc.ResourceID


AND CreationTime BETWEEN @StartDate AND @EndDate -- IN A SPECIFIC TIME WINDOW FOR THE DEPLOYMENT CREATION TIME

ORDER BY Deploy_Available DESC

 

 

Active Directory - À quels attributs LDAP correspondent les friendly name dans l'AD ?

Vous êtes-vous déjà mordus les doigts dans l'utilitaire de délégation de permissions Active Directory (AD) en essayant désespérément de savoir à quel attribut LDAP correspond tel attribut sous sa forme "friendly" name ?

 

Le tableau de correspondance attribut LDAP et friendly name

 

LDAP_name Friendly_name
c Country Abbreviation
cn Name
co Country
comment Comment
company Company
department Department
description Description
directReports Direct Reports
displayName Display Name
distinguishedName Distinguished Name
division Division
employeeID Employee ID
facsimileTelephoneNumber Fax Number
generationQualifier Generational Suffix
givenName First Name
homeDirectory Home Folder
homeDrive Home Drive
homePhone Home Phone
homePostalAddress Home Address
info Notes
initials Initials
internationalISDNNumber International ISDN Number (Others)
ipPhone IP Phone Number
l City
mail E-Mail Address
manager Manager
memberOf Member Of
middleName Middle Name
mobile Mobile Number
mSDS-PhoneticCompanyName Phonetic Company Name
mSDS-PhoneticDepartment Phonetic Department
mSDS-PhoneticDisplayName Phonetic Display Name
mSDS-PhoneticFirstName Phonetic First Name
mSDS-PhoneticLastName Phonetic Last Name
msRTCSIP-PrimaryHomeServer Office Communications Server
msRTCSIP-PrimaryUserAddress Office Communications Server Address
msRTCSIP-UserEnabled Enabled for Office Communications Server
otherFacsimileTelephoneNumber Fax Number (Others)
otherHomePhone Home Phone Number (Others)
otherIpPhone IP Phone Number (Others)
otherMailbox E-Mail Address (Others)
otherMobile Mobile Number (Others)
otherPager Pager Number (Others)
otherTelephone Phone Number (Others)
pager Pager Number
personalTitle Title
physicalDeliveryOfficeName Office Location
postalCode ZIP/Postal Code
postOfficeBox Post Office Box
primaryInternationalISDNNumber International ISDN Number
primaryTelexNumber Telex Number
samAccountName Logon Name (pre-Windows 2000)
sn Last Name
st State/Province
streetAddress Street Address
telephoneNumber Telephone Number
telexNumber Telex Number (Others)
title Job Title
url Web Page Address (Others)
userPrincipalName Logon Name
userWorkstations Logon Workstations
wWWHomePage Web Page Address

 

Remarque : certains attributs ne sont pas disponibles par défaut dans l'utilitaire de délégation de permission, il faut modifier le fichier dssec.dat sur un contrôleur de domaine

PowerShell - Convertir les signes diacritiques

Un signe diacritique ou diacritique est un élément ajouté à une lettre, par exemple dans la langue française, les biens connus : à, é, ç mais également les ł, ø, ß utilisés dans d'autres langues. La plupart des logiciels ne sont pas capables de traiter les diacritiques correctement ce qui peut avoir pour conséquence une simple gêne utilisateur ou dans le pire des cas des accès non fonctionnels.

Comment alors se débarrasser de ces diacritiques ? Hors de question de les retirer complétement, car ils font partie intégrante des mots, il faut alors essayer de les convertir vers des caractères connus par les logiciels. 

 

La fonction de conversion des diacritiques

function Convert-Diacritic #Fonction qu'il faudra appeler pour convertir le diacritique
{
    [CmdletBinding()] #Déclaration des paramètres qu'il faudra fournir à la fonction pour qu'elle puisse s'exécuter
    Param
    (
        [Parameter(Mandatory=$true)] #Indique que ce paramètre est facultatif
        [ValidateNotNullOrEmpty()] #Indique que ce champ ne peut pas être vide ou null, s'il est obligatoire
        [string]$InputString #Paramètre qui attend la chaîne de caractères qui contient les diacritiques à convertir
    )

    Begin 
    {
        $Return = @{} #Tableau de retour qui contient la chaîne de caractères sans diacritiques
        
        $DiacriticsArray = @{ #Hashtable, aussi appelé tableau de conversion dans ce script, qui contient à droite du signe égal le caractère avec diacritique et à gauche du signe égale, le caractère cible post conversion
            #Par exemple à deviendra a après conversion
            #Pour déterminer vers quel caractère convertir un diacritique, une simple recherche internet peut être utilisé
            a = 'à', 'á', 'â', 'ã', 'ā', 'ă', 'ą'
            aa = 'å'
            ae = 'ä', 'æ'
            c = 'ç', 'ć', 'ĉ', 'ċ', 'č'
            d = 'ď', 'đ'
            e = 'è', 'é', 'ê', 'ë', 'ē', 'ĕ', 'ė', 'ę', 'ě'
            g = 'ĝ', 'ğ', 'ġ', 'ģ'
            h = 'ĥ', 'ħ'
            i = 'ì', 'í', 'î', 'ï', 'ĩ', 'ī', 'ĭ', 'ı', 'į'
            ij = 'ij'
            j = 'ĵ'
            k = 'ķ', 'ĸ'
            l = 'ĺ', 'ļ', 'ľ', 'ŀ', 'ł'
            n = 'ñ', 'ń', 'ņ', 'ň', 'ŋ'
            o = 'ò', 'ó', 'ô', 'õ', 'ō', 'ŏ', 'ő'
            oe = 'ö', 'ø', 'œ'
            r = 'ŕ', 'ŗ', 'ř'
            s = 'ś', 'ŝ', 'ş', 'š'
            ss = 'ß'
            t = 'ţ', 'ť', 'ŧ'
            th = 'þ'
            u = 'ù', 'ú', 'û', 'ũ', 'ů', 'ū', 'ŭ', 'ű', 'ų'
            ue = 'ü'
            w = 'ŵ'
            y = 'ý', 'ÿ', 'ŷ'
            z = 'ź', 'ż', 'ž'
        }
    }

    Process
    {
        $OutputString = $InputString.ToLower() #Transforme tous les caractères majuscules de la chaîne de caractères d'entrée en minuscule
        #Le tableau ne peut convertir que les diacritiques minuscules, cela simplifie également la maintenabilité du tableau de conversion et du code

        foreach ($Letter in $DiacriticsArray.GetEnumerator()) #On parcourt chaque paire lettres/diacritiques du tableau de conversion
        #La méthode GetEnumerator permet de générer deux propriétés Key et Value pour chaque paire du tableau de conversion, ci-après appelé $Letter.Value et $Letter.Key
        {
            $DiacriticsLetter = $Letter.Value #Letter.Value contient l'ensemble des diacritiques d'une paire (ligne) du tableau de conversion
            foreach ($Diacritic in $DiacriticsLetter) #On parcourt chaque diacritique d'une ligne
            {
                if ($OutputString -match $Diacritic) #Si le diacritique qui est en train d'être parcouru est contenu dans la chaîne de caractères d'entrée, le code suivant sera exécuté
                {
                    $OutputString = $OutputString.Replace($Diacritic, $Letter.Key) #Le diacritic qui en train d'être parcouru est remplacé par le caractère cible de conversion contenu dans la propriété $Letter.Key 
                }
            }
        }

        #La boucle précédente va donc répéter les actions décrites précédemment pour chaque paire et chaque diacritique du tableau de conversion

        $Return.outputStringObject = $OutputString #Attribution de la chaîne de caractères sans diacritiques à la variable de sortie
        Return $Return #Retourne la chaîne de caractères sans diacritiques
    }
}

 

Exemple d'utilisation de la fonction de conversion

Le script suivant appelle la fonction de conversion de diacritique lorsque lui-même est appelé

. .\Convert-Diacritic_article.ps1 #Permet de déclarer (dot source) la fonction de conversion de diacritique pour qu'elle puisse être utilisée

$String = Convert-Diacritic -InputString "DébutăîœăßøFin" #Appelle de la fonction de conversion de diacritique et lui passe en paramètre une chaîne de caractères qui contient des diacritiques 

$String.outputStringObject #La chaîne de caractères sans diacritiques est contenu dans la propriété outputStringObject, elle est donc appelée pour afficher le résultat

 

Appel du script précédent

PS D:\A_folder> .\Just_call_me_already.ps1 #Appel du script précédent qui contient l'appelle de la fonction de conversion de diacritique
debutaioeassoefin #Les diacritiques dans la chaîne de caractères ont été convertis selon les règles du tableau de conversion 

 

Remarque : les scripts qui manipulent des diacritiques, tels que les scripts ci-avant, doivent être encodés avec du BOM, par exemple UTF-8 with BOM, sans quoi les diacritiques seront mal convertis par l'IDE (integrated development environment) et empêcheront la bonne exécution du code.

PowerShell - Déchiffrer un mot de passe

Comme vu dans l'article Powershell - Chiffrer un mot de passe la santé de votre équipe de sécurité a été préservé car vos mots de passe sont désormais chiffrés dans vos scripts. Un mot de passe chiffré c'est bien mais comment le déchiffrer pour pouvoir l'utiliser ?

 

La fonction de déchiffrement

function Get-SecureStringFromEncryptedFile #Fonction qu'il faudra appeler pour déchiffrer le mot de passe
{
    [CmdletBinding()] #Déclaration des paramètres qu'il faudra fournir à la fonction pour qu'elle puisse s'exécuter
    Param
    (
        [Parameter(Mandatory=$true)] #Indique que ce paramètre est obligatoire
        [ValidateNotNullOrEmpty()] #Indique que ce champ ne peut pas être vide ou null
        [string]$Name, #Paramètre qui attend le nom de l'utilisateur, il est utilisé pour créer un credential object

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$PwdPath #Paramètre qui attend le chemin complet du fichier qui contient le mot de passe chiffré
    )

    Begin 
    {
        $Return = @{} #Tableau de retour qui contient le mot de passe sous forme de secure string et le credential object généré à partir du nom du compte de service et de son mot de passe
    }

    Process
    {
        $PwdSecureString = Get-Content $PwdPath | ConvertTo-SecureString #Récupére le mot de passe chiffré depuis le fichier txt fourni et le convertit en secure string
        $Return.pwdSecureString = $PwdSecureString #Attribution de la secure string générée dans la variable de sortie de la fonction

        $Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Name, $PwdSecureString #Génére un credential object à partir de l'utilisateur et de son mot de passe
        $Return.credentials = $Credentials #Attribution du credential object générée dans la variable de sortie de la fonction

        Return $Return #Retourne le mot de passe ainsi que la secure string en sortie de la fonction
    }
}

 

 

Exemple d'utilisation de la fonction de déchiffrement

. .\Get-SecureStringFromEncryptedFile_article.ps1 #Permet de déclarer (dot source) la fonction de chiffrement pour qu'elle puisse être utilisée

$Password = Get-SecureStringFromEncryptedFile -Name "Svc-test-01" -PwdPath "D:\A_folder\Svc-test-01_encrypted_password.txt" #Appelle de la fonction de déchiffrement et lui passe en paramètre le nom de l'utilisateur le chemin complet du fichier qui contient le mot de passe chiffré

#Le mot de passe sous forme de secure string est conservé dans la propriété pwdSecurestring, on peut y accéder comme ceci $Password.pwdSecureString
#Le credential object qui contient le jeu d'identifiant nom d'utilisateur et mot de passe est conservé sous forme de credential object dans la propriété credentials, on peut y accéder comme ceci $Password.credentials

$Credentials = $Password.Credentials #Attribution du credential object à la variable $Credentials
Get-ADUser -Identity "Toto" -Credential $Credentials #Utilisation de la cmdlet Get-ADUser avec le credential object précédemment généré

 

Remarque : lorsque le fichier est généré, une combinaison du compte utilisateur et du compte machine est utilisée. Cela implique que le mot de passe ne peut être déchiffré que par l'utilisateur qui l'a chiffré et sur la machine sur laquelle le chiffrement a eu lieu.

PowerShell - Chiffrer un mot de passe

À moins que votre but ne soit d'essayer de causer une crise cardiaque à votre équipe sécurité et d'entre autres faciliter le travail des hackers, il est conseillé de conserver les mots de passe dans les scripts chiffrés.

 

La fonction de chiffrement

function New-EncryptedPasswordFile #Fonction qu'il faudra appeler pour générer un fichier txt qui contiendra le mot de passe chiffré
{
    [CmdletBinding()] #Déclaration des paramètres qu'il faudra fournir à la fonction pour qu'elle puisse s'exécuter
    Param
    (
        [Parameter(Mandatory=$true)] #Indique que ce paramètre est obligatoire
        [ValidateNotNullOrEmpty()] #Indique que ce champ ne peut pas être vide ou null
        [string]$User, #Paramètre qui attend le nom de l'utilisateur, il n'est utilisé que pour le nom du txt de sortie ainsi n'importe quelle valeur peut être renseigné

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [securestring]$Password #Paramètre qui attend une secure string, 
    )

    Process
    {
        $EncryptedPasswordPath = $PSScriptRoot + "\" + $User + "_encrypted_password.txt" #Génére dynamiquement le chemin complet du txt qui contiendra le mot de passe chiffré
        $Password | ConvertFrom-SecureString | Out-File $EncryptedPasswordPath #Génére le txt qui contient le mot de passe chiffré
    }
}

 

Exemple d'utilisation de la fonction de chiffrement

Le script suivant appelle la fonction de chiffrement lorsque lui-même est appelé 

. .\New-EncryptedPasswordFile_article.ps1 #Permet de déclarer (dot source) la fonction de chiffrement pour qu'elle puisse être utilisée

New-EncryptedPasswordFile -User "Svc-test-01" #Appelle de la fonction de chiffrement et lui fournit volontairement uniquement le nom de l'utilisateur
#Le mot de passe sera demandé sous forme de secure string

 

 

Appel du script précédent

PS D:\A_folder> .\Call_me_maybe.ps1 #Appel du script précédent qui contient l'appelle de la fonction de chiffrement

cmdlet New-EncryptedPasswordFile at command pipeline position 1
Supply values for the following parameters: #La saisie du mot de passe sous forme de secure string est demandé
Password: ****

 

Le résultat

Le mot de passe contenu dans le fichier txt généré est chiffré

 

Remarque : lorsque le fichier est généré, une combinaison du compte utilisateur et du compte machine est utilisée. Cela implique que le mot de passe ne peut être déchiffré que par l'utilisateur qui l'a chiffré et sur la machine sur laquelle le chiffrement a eu lieu.

[O365] - Extraire la liste des OneDrive qui sont partagés avec des externes.

Si un jour vous souhaitez faire un état des lieux de ce qui est déjà en place en terme de partage, voici quelques liges de Powershell qui permettent de sortir la liste des OneDrive ayant un partage avec un invité.

Prenez soin de remplacer l'url de connexion au portail d'admin Sharepoint.

# Connect to Sharepoint Online
Connect-SPOService -Url https://MonTenant-admin.sharepoint.com/

# Collect all Sharepoint Sites and filter on OneDrive
$AllOneDrive = Get-SPOSite -IncludePersonalSite $true -Limit all -Filter "Url -like '-my.sharepoint.com/personal/'"

# Define variabes 
$ArrayOneDriveMembers = @()
$SortOneDrive = $AllOneDrive | sort Url

$SortOneDrive | foreach {
    $OneDriveUrl = $_.Url
    $OneDriveOwner = $_.Owner
    $OneDriveStorageQuota = $_."Storage Quota"
    $OneDriveTitle = $_.Title
    # Get the list of members for the current OneDrive
    Try {
        $OneDriveMembers = Get-SPOUser -Site $OneDriveUrl -ErrorAction stop
        }
    Catch {
        Write-Output "$OneDriveUrl;$OneDriveTitle" | Add-Content C:\temp\Onedriveerrors.txt
        }
    
    # Define a new variable
    $OneDriveExternal = $OneDriveMembers.where({$_.Usertype -eq "Guest"})

    # Check if the new variable is empty, if not collect logs
    If ($OneDriveExternal.count -ne 0) {
        
        # Display some informations
        Write-Host "External Users are present in $OneDriveTitle" -ForegroundColor Green
        $OneDriveExternal.count

        # Store Data
        $OneDriveExternal | foreach {
            $DisplayName = $_.DisplayName
            $LoginName = $_.LoginName
            
            $ArrayOneDriveMembers += New-Object psobject -Property @{
                OneDriveUrl = $OneDriveUrl
                OneDriveOwner = $OneDriveOwner
                OneDriveStorageQuota = $OneDriveStorageQuota
                OneDriveTitle = $OneDriveTitle
                DisplayName = $DisplayName
                LoginName = $LoginName
                }
            # Release Variables
            $DisplayName = $null
            $LoginName = $null
            }
        }
    
    # Release variables
    $OneDriveUrl = $null
    $OneDriveOwner = $null
    $OneDriveStorageQuota = $null
    $OneDriveTitle = $null
    $OneDriveMembers = $null
    }

$ArrayOneDriveMembers | Export-Csv c:\temp\ExternalOneDriveMembers.csv -Encoding UTF8 -Delimiter ";" -NoTypeInformation

 

[Azure Active Directory] - Définir le lieu d'utilisation

Lorsque vous synchronisez vos utilisateurs via "Azure AD Connect", que vos utilisateurs sont dans différents pays et que vous utilisez l'audioconférence dans Teams, il semblerait logique que vos utilisateurs se voient attribuer un numéro "locale", plutôt qu'un numéro "Français".

 

Pour ce faire il est important de définir le lieu d'utilisation (Usage Location) dans Azure Active Directory, il est donc important de remplir l'attribut "Country" dans votre Active Directory OnPremise.

La construction est basé sur deux lettres, vous pourrez trouver la correspondance des pays et des lettres dans le lien ci-dessous:

Attention : Vous devrez utiliser les deux lettres en majuscule de la colonne "Language Culture Name"

https://docs.microsoft.com/en-us/previous-versions/commerce-server/ee825488(v=cs.20)?redirectedfrom=MSDN

 

Vous pouvez fixer cet attribut à l'aide de Powershell via la commande ci-dessous (en prenant soin de remplacer "Mathieu" par le nom de votre utilisateur) :

Get-ADUser Mathieu | Set-ADUser -Replace @{‘Country’=”US”}

Ou alors en important un fichier csv pour une modification en masse, exemple de code ci-dessous.

# Import Csv and Set PreferredLanguage Attribute for each user
Import-csv C:\Temp\ToFixed.csv | foreach {
    $SamAccountName = $_.SamAccountName
    $Attribute = $_.Attribute
    Try {
        # Modifying PreferredLanguage Attribute
        Set-ADUser -Identity $SamAccountName -Replace @{‘Country’=$Attribute} -ErrorAction Stop 
        }
    Catch {
        $SamAccountName | Add-Content C:\temp\ErrorUsageLocation.txt
        }
    # Release
    $SamAccountName = $null
    $Attribute = $null
    }

 

[Office 365] - Fixer la langue par défaut pour OneDrive

Lorsque vous synchronisez vos utilisateurs via "Azure Ad Connect" et, que vous avez des utilisateurs dans différents pays, la langue par défaut pour chacun des utilisateurs dépend d'un attribut de votre Active Directory OnPremise, cet attribut est le "preferredLanguage".

Il devra être construit en suivant la nomenclature "Language Culture Name" du lien ci-dessous :

https://docs.microsoft.com/en-us/previous-versions/commerce-server/ee825488(v=cs.20)?redirectedfrom=MSDN

Vous pouvez fixer cet attribut à l'aide de Powershell via la commande ci-dessous (en prenant soin de remplacer "Mathieu" par le nom de votre utilisateur) :

Get-ADUser Mathieu | Set-ADUser -Replace @{‘preferredLanguage’=”en-US”}

Ou alors en important un fichier csv pour une modification en masse, exemple de code ci-dessous.

# Import Csv and Set PreferredLanguage Attribute for each user
Import-csv C:\Temp\ToFixed.csv | foreach {
    $SamAccountName = $_.SamAccountName
    $Attribute = $_.Attribute
    Try {
        # Modifying PreferredLanguage Attribute
        Set-ADUser -Identity $SamAccountName -Replace @{‘preferredLanguage’=$Attribute} -ErrorAction Stop 
        }
    Catch {
        $SamAccountName | Add-Content C:\temp\ErrorPreferredLanguage.txt
        }
    # Release
    $SamAccountName = $null
    $Attribute = $null
    }