Description
Dans les dernières mises à jour des versions Microsoft Office 2016, lorsqu’un utilisateur ajoute un nouveau compte Exchange 2016 , il est invité à plusieurs reprises à saisir son nom d’utilisateur et son mot de passe pour aboutir finalement à un échec.
Ce problème est lié à la configuration de découverte automatique qu'Outlook utilise. Microsoft semble avoir défini Outlook pour utiliser leurs serveurs Office 365 comme point de configuration initial indépendamment de la façon dont la découverte automatique est configurée.
Résolution
La résolution consiste à définir une entrée du Registre sur l’ordinateur qui rencontre le problème ayant la valeur dessous:
[HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Outlook\AutoDiscover]
"ExcludeExplicitO365Endpoint"=dword:00000001
Attention: Cette modification ne doit se faire que si un compte Exchange On-Premise est utilisé.
Symptômes
Lorsque les boîtes aux lettres sont déplacées depuis Exchange 2010 vers Exchange Server 2013/2016, les utilisateurs ne peuvent plus accéder à leur boîtes aux lettres.
Ce problème se produit dans le scénario suivant:
- Un utilisateur utilise généralement Outlook Anywhere pour se connecter à sa boîte aux lettres Exchange Server 2010.
- La boîte aux lettres de l'utilisateur est déplacée vers Exchange Server 2013 ou Exchange Server 2016.
- Une fois la boîte aux lettres déplacée et l'utilisateur tente de se connecter, le message «L'administrateur Microsoft Exchange a effectué une modification qui requiert que Microsoft Outlook soit fermé puis redémarrer » apparaît.
- Après le redémarrage d'Outlook, le client reste déconnecté.
Cause
ce problème n’arrive pas trop souvent mais il peut être gênant: Une fois le déplacement de la boîte aux lettres terminé, Exchange Server 2013 ou 2016 continue à transmettre par proxy la demande Autodiscover à Exchange Server 2010 qui rebondit ensuite sur Exchange 2016. Il s’agit de ping-pong des demandes de reconfiguration de profil Outlook jusqu’à ce que le cache d’application de découverte automatique expire et que les informations soient actualisées.
Résolution
Le recyclage du pool d’applications actualise le cache et Outlook se connecte avec succès. Ainsi, pour résoudre ce problème, redémarrer le pool d’applications de découverte automatique sur les serveurs Exchange Server 2013 ou Exchange Server 2016 en exécutant la commande:
Restart-WebAppPool MSExchangeAutodiscoverAppPool
A noter qu'Exchange 2016 est un serveur combinant tous les rôles, mais il s’affiche comme serveur de boîtes aux lettres, ainsi, il faut redémarrer le pool Autodiscover sur chaque serveur Exchange 2016.
Dans un environnement hybride, un utilisateur avait une boîte aux lettres Exchange Online. La BAL est marquée en tant que boîte aux lettres distante (visible sur Exchange Onpremise) mais la boîte aux lettres Office 365 n'était pas disponible. Dans ce cas, le GUID Exchange Onpremise doit être mis à jour.
Pour ce faire, les étapes ci-dessous ont été réalisées :
- Accéder à Exchange Management Shell (Onpremise) et sauvegarder les paramètres de la BAL via la commande suivante:
Get-Mailbox "affectedUser" | fl > mailboxinfo.txt
- Mettre à jour le GUID Exchange à Null sur la boîte aux lettres affectée via l'exécution de la commande:
Set-remotemailbox "affectedUser" -ExchangeGuid 00000000-0000-0000-0000-0000-0000000000000000000
- S’assurer que Exchange Guid se reflète correctement :
Get-RemoteMailbox "affectedUser" | Fl ExchangeGuid
Get-MailUser "affectedUser" | fl ExchangeGuid
- L’étape suivante consiste à supprimer la licence exchange Online, synchroniser, puis à ré ajouter la licence et vérifier l’état :
Get-Mailbox "affectedUser" | fl exchangeGuid,RecipientTypeDetails
- Récupérer la valeur d'ExchangeGuid
- Dans Exchange Management Shell (Onpremise), rétablir l’attribut Exchange Online GUID sur la boîte aux lettres distante Set-RemoteMailbox "affectedUser" -ExchangeGuid " ExchangeGuidRecupéré" Puis vérifier le paramètre via la commande: Get-RemoteMailbox "affectedUser" | Fl ExchangeGuid
- Dans la console Exchange Online, vérifier aussi que l'objet s'affiche en tant que boîte aux lettres utilisateur.
Sous ce titre qui peut prêter à sourire se cache une fonctionnalité peu connue et finalement pas vraiment indispensable, mais qui donnera une touche un peu plus finie et professionnelles à vos management packs.
Lorsque vous exécutez une tâche basée sur un script Powershell, il peut arriver que ce dernier échoue à remplir son but pour diverses raisons. Dans ce cas, par défaut, la tâche présentera malgré tout un résultat en succès ou, au mieux, un résultat ressemblant au suivant :
Vous avez cependant déjà vu des tâches qui échouent « proprement », avec un symbole d’échec et le message d’erreur associé dans la sortie de la tâche.
Pour obtenir le même résultat dans vos propres développements, c’est très simple, il y a deux conditions à remplir :
- Lever une exception dans le script, via une commande Throw
- Ajouter le paramètre <StrictErrorHandling>true</StrictErrorHandling> à la WriteAction ou à la Probe utilisée dans votre tâche :
Et vous obtiendrez alors une sortie indiquant bien un Status Failed, avec l’icone « rouge » et le texte envoyé dans le Throw dans la sortie lorsque la tâche échoue :
Vous souhaitez exporter la liste de vos numéros Teams et les utilisateurs associés, vous devrez utiliser les commandes SkypeOnline (et oui pas Teams...) suivantes :
# Define variable
$Domain = Read-Host -Prompt "Quel est votre domain ?"
$Csv = "C:\temp\TeamsPhoneNumbers.csv"
# Skype Online Connection
Import-Module SkypeOnlineConnector
$sessionCS = New-CsOnlineSession -OverrideAdminDomain $Domain
Import-PSSession $sessionCS
# Collect All Voice User
$AllVoiceUsers = Get-CsOnlineVoiceUser
# Export to Csv
$AllVoiceUsers | Export-Csv $Csv -Delimiter ";" -Encoding UTF8 -NoTypeInformation
Dans certains cas de figure nous avons besoin de mettre en pause les synchronisations entre Active Directory et son Azure AD (par exemple: une montée de version du client AD Connect, une modification des droits d'accès du compte de synchro, modification des règles de synchronisation...).
Dans l'ensemble rien de bien compliqué mais dans les faits... L'utilisation de la mauvaise cmdlet Powershell peut vous mettre dans l'embarras si ce n'est plus.
En effet pour stopper les cycles de synchronisation entre l'Active Directory et Azure AD plusieurs commandes sont possibles.
La commande A NE PAS UTILISER
Set-MsolDirSyncEnabled -EnableDirSync $false
Cette commande ne doit pas être utilisée, en cas d'utilisation vous devrez attendre 72 heures avant de pouvoir rétablir le service!!!!
La commande utilisable
Set-ADSyncScheduler -SyncCycleEnabled $false
Une fois votre opération réalisée, vous pourrez réactiver les synchronisations en utilisant la commande ci-dessous.
Set-ADSyncScheduler -SyncCycleEnabled $true
Bonne modification sur vos configurations.
L'idée du script ci-dessous est de proposer une forme d'inventaire des applications couvertes par une infra SCOM, en utilisant une liste, a maintenir, des principales classes d'objets tel que 'Active Directory Domain Controller Computer Role' ou encore 'IIS Server Role'.
Il est donc necessaire de maintenir un minimum dans le temps, le contenu de $ClassList, et la correspondance faites entre les pattern de nom de classes et les application correspondantes.
SCOM_Inventory_with_Main_Classes.ps1 (12,71 kb)
### SCOM INVENTORY USING APPLICATION MAIN CLASS ###
#Parameters
Param(
$MS= "MyMS.MyDomain",
$cred = $(Get-Credential "MyDomain\")
)
# List of all 'Top' Classes for which we need to get instances
$ClassList=(
# ACTIVE DIRECTORY
'Active Directory Domain Controller Computer Role',` # ACTIVE DIRECTORY
'Certificate Service', # ACTIVE DIRECTORY CERTIFICATE SERVICES
'Federation Server', # ACTIVE DIRECTORY FEDERATION SERVICES
# CITRIX
'Managed Citrix Presentation Server', # CITRIX
# EXCHANGE
'Microsoft Exchange 2010 Server', # EXCHANGE
'Exchange 2007 Server Role', # EXCHANGE
'Exchange 2013 Server', # EXCHANGE
# LYNC/SKYPE
'LS Server Role', # LYNC/SKYPE
# SHAREPOINT
'SharePoint Server', # SHAREPOINT
# SQL
'SQL Server 2008 DB Engine', # SQL (SQL 2008)
'SQL Server 2012 DB Engine', # SQL (SQL 2012)
'SQL Server 2014 DB Engine', # SQL (SQL 2014)
'SQL Server 2016 DB Engine', # SQL (SQL 2016)
'MSSQL on Windows: DB Engine', # SQL (SQL 2017+)
# SQL SSIS
'SQL Server 2014 Integration Services', # SQL SSIS (SQL 2014)
'SQL Server 2016 Integration Services', # SQL SSIS (SQL 2016)
'MSSQL on Windows Integration Services: Local Instance', # SQL SSIS (SQL 2017+)
# SQL SSAS
'SSAS 2008 Instance', # SQL SSAS (SQL 2008)
'SSAS 2012 Instance', # SQL SSAS (SQL 2012)
'SSAS 2014 Instance', # SQL SSAS (SQL 2014)
'SSAS 2016 Instance', # SQL SSAS (SQL 2016)
'MSSQL Analysis Services: Generic Instance', # SQL SSAS (SQL 2017+)
# SQL SSRS
'Microsoft SQL Server 2008 Reporting Services (Native Mode)', # SQL SSRS (SQL 2008)
'Microsoft SQL Server 2012 Reporting Services (Native Mode)', # SQL SSRS (SQL 2012)
'Microsoft SQL Server 2014 Reporting Services (Native Mode)', # SQL SSRS (SQL 2014)
'Microsoft SQL Server 2016 Reporting Services (Native Mode)', # SQL SSRS (SQL 2016)
'MSSQL Reporting Services: Instance (Native Mode)' , # SQL SSRS (SQL 2017)
# WINDOWS CLUSTER NODES
'Cluster Node', # WINDOWS CLUSTER
# IIS
'IIS Server Role', # IIS
# WINDOWS PRINT SERVER
'Print Services Role', # WINDOWS PRINT SERVER
# WINDOWS DNS
'Windows DNS Server', # WINDOWS DNS
# WSUS
'WSUS 3.0 Server', # WSUS
'Microsoft Windows Server Update Services 2012 R2', # WSUS
'Microsoft Windows Server Update Services 2016' # WSUS
)
#Import of SCOM module
try
{
Import-Module -Name OperationsManager -ErrorAction stop
}
catch
{
write-host -ForegroundColor red "Error during import of SCOM Module"
}
#Connection to $MS management server
New-SCOMManagementGroupConnection -ComputerName $MS -Credential $cred
# Create an empty tableau
$Finaltableau = @()
# Get All Instances for each class
foreach ($classname in $ClassList)
{
$class = Get-SCOMClass -DisplayName $classname
# If class is found we can go on
If($class)
{
$instances += Get-SCOMClassInstance -Class $class -ErrorAction SilentlyContinue
foreach ($inst in $instances)
{
$obj = New-Object psobject
switch -Regex ($classname)
{
# ACTIVE DIRECTORY
"Active Directory Domain Controller Computer Role"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.path
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "ACTIVE DIRECTORY"
}
# ACTIVE DIRECTORY CERTIFICATE SERVICES
"Certificate Service"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.displayname
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "ACTIVE DIRECTORY CERTIFICATE SERVICES"
}
# ACTIVE DIRECTORY FEDERATION SERVICES
"Federation Server"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.displayname
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "ACTIVE DIRECTORY FEDERATION SERVICES"
}
# CITRIX
".*Citrix.*"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.displayname
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "CITRIX"
}
# EXCHANGE
".*Exchange.*"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.displayname
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "EXCHANGE"
}
# LYNC/SKYPE
".*LS Server.*"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.Path
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "LYNC/SKYPE"
}
# SHAREPOINT
".*sharepoint.*"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.Path
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "SHAREPOINT"
}
# SQL DB ENGINE
"SQL Server.*DB Engine"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.Path
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "SQL"
}
"MSSQL on Windows: DB Engine"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.'[Microsoft.SQLServer.Windows.DBEngine].PrincipalName'.value
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "SQL"
}
# SQL BI
".*(SQL Server.*Integration Services|Analysis Services|Reporting Services|SSAS).*"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.Path
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "SQL BI"
}
"MSSQL on Windows Integration Services: Local Instance"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.'[Microsoft.SQLServer.IS.Windows.LocalInstance].PrincipalName'.value
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "SQL BI"
}
# WINDOWS CLUSTER
".*Cluster Node.*"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.DisplayName
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "WINDOWS CLUSTER"
}
# IIS
".*IIS Server Role.*"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.Path
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "IIS"
}
# WINDOWS PRINT SERVER
".*Print Services Role.*"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.Path
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "WINDOWS PRINT SERVER"
}
# WINDOWS DNS
".*Windows DNS Server.*"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.Path
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "WINDOWS DNS"
}
# WSUS
".*(Windows Server Update|WSUS).*"
{
$obj | Add-Member -Name "COMPUTER" -membertype Noteproperty -Value $inst.Path
$obj | Add-Member -Name "CLASS" -membertype Noteproperty -Value $classname
$obj | Add-Member -Name "MAIN ROLE" -membertype Noteproperty -Value "WSUS"
}
}
$Finaltableau += $obj
}
}
Else
{
$ClassError = "'$classname' class was not found`n"
}
# Clear of $instances variable for each $classname loop
Clear-Variable instances
}
# Display Final Result
$Finaltableau
# Display If some class was not found
If ($ClassError)
{
Write-Host -F Red "SOME CLASSES WAS NOT FOUND:`n$ClassError"
}