PI Services

Le blog des collaborateurs de PI Services

SCOM 18xx–Voir les alertes dans la console web

Encore un souci lié à la nouvelle console web, introduite dans SCOM 1801 : lors de la création d’une Notification pour envoyer des alertes par mail, il est d’usage d’intégrer dans le corps du mail l’URL permettant d’ouvrir la console web sur l’URL en question, en utilisant le raccourci généré par le wizard :

image

image

Seulement voilà, l’URL insérée ici est incorrecte, elle ne correspond pas à la nouvelle console Web et cette adresse renvoie donc à la page d’accueil de la console !

Ce bug a été corrigé lors du passage à SCOM 1807 :

image

On voit ici que le bon format d’URL à utiliser est en réalité $Target/Property[Type="Notification!Microsoft.SystemCenter.AlertNotificationSubscriptionServer"]/WebConsoleUrl$/#/monitoring/drilldown/alert/$UrlEncodeData/Context/DataItem/AlertId$ , ce qui correspond au nouveau dashboard “Alert Drilldown”, auquel on accède normalement à partir d’un dashboard Alerts “nouvelle génération” (plus d’explications sur les nouveaux dashboards et les relations entre eux ici : https://blogs.technet.microsoft.com/momteam/2018/02/12/new-scom-web-console-blog-series-post4-the-all-new-drilldown-experience/ ) :

image


Malheureusement, cela engendre un nouveau problème : si l’utilisateur qui reçoit ce mail mais n’a qu’un accès limité à SCOM (permission accordée uniquement à quelques dossiers/vues), il risque fort de se trouver face à cet écran :

image

Ou, dans le meilleur des cas, celui-ci qui n’est pas beaucoup plus utile :

image

La raison en est que ce nouveau dashboard Alert Drilldown contient une série de widgets qui nécessitent également que l’utilisateur aie le droit d’y accéder individuellement. Or, cette permission n’est accordée par l’assistant User Roles que lorsqu’on accorde la permission à un dashboard qui y fait appel… dont aucun n’existe par défaut. Et même s’il en existait, vous pourriez très bien ne pas vouloir les montrer à tout le monde!

Un contournement serait donc de créer un dashboard Alerts “nouvelle génération”, de le cibler sur un groupe vide créé également pour l’occasion et d’en déléguer l’accès à tous les User Roles susceptibles de devoir accéder au Drilldown d’une alerte :

image


image

L’utilisateur devrait maintenant avoir accès au dashboard Drilldown alert :

image


En espérant que Microsoft corrige cela dans la prochaine version…

PowerShell/SQL–Script générant un .csv contenant le résultat d’une requête

Introduction

Le script suivant permet :

  • de récupérer le résultat d’une requête SQL dans un fichier .csv,
  • de renseigner les actions réalisées dans l’EventViewer,
  • de retourner un code d’erreur (0 ou 1) suite à l’exécution du script.

Prérequis

  • Powershell
  • SQL

Présentation du script

Variables :

[string] $server = "localhost" : Serveur SQL
[string] $database = "base" : Base SQL
[string] $query = "SELCT * FROM Table" : Requête ou procédure stockée
[string] $extractFilePath = "C:\test.csv" : Emplacemnt de génération du fichier .csv
[string] $delimiter = ";" : Délimiteur à utiliser pour la génération du fichier .csv
[int] $skipline = 1 : Nombre de ligne à tronquer (utile si l’on souhaite retirer la ligne d’entête.

Script

 

# Variables d'entrée
param
    (
    [string] $server = "localhost", 
    [string] $database = "base",
    [string] $query = "SELECT * FROM Table",
    [string] $extractFilePath = "C:\test.csv",
    [string] $delimiter = ";",
    [int] $skipline = 1

    )

#MAIN
function main
{

#Variables calculées
$full_date = Get-Date;
$custom_date = $full_date.ToString("yyyyMMdd");
$DataSet = New-Object System.Data.DataSet;
$eventsource ="CsvFromSQL_Powershell";
$eventlogname = "Application";
[int] $errorcode = 1;


#Génération de la source d'evenements si inexistante
if ([System.Diagnostics.EventLog]::SourceExists($eventsource) -eq $false) 
    {
        #write-host "Creating event source $eventsource on event log $eventlogname"
        [System.Diagnostics.EventLog]::CreateEventSource($eventsource, $eventlogname)
        #write-host -foregroundcolor green "Event source $eventsource created"
    }
        else
    {
        #write-host -foregroundcolor yellow "Warning: Event source $eventsource already exists. Cannot create this source on Event log $eventlogname"
    }

<#
$logFileExists = Get-EventLog -list | Where-Object {$_.logdisplayname -eq $eventlogname} 
if (! $logFileExists) 
    {
        New-EventLog -LogName $eventlogname -Source $eventsource
    }
#>

#Execution des fonctions et récupération du code d'erreur
$errorcode = Test-SQLConn -_server $server -_database $database;
$errorcode = sql_to_dataset -_server $server -_database $database -_query $query -_dataset $DataSet;
$errorcode = dataset_to_csv -_dataset $DataSet -_extractFilePath $extractFilePath;
return $errorcode;
}

#Test connection SQL
Function Test-SQLConn ($_server, $_database)
{
    $errorcode=0;
    $connectionString = "Data Source=$_server;Integrated Security=true;Initial Catalog=$_database;Connect Timeout=3;";
    $sqlConn = new-object ("Data.SqlClient.SqlConnection") $connectionString;
    trap
        {
        Start-Sleep -s 1;
        Write-EventLog -LogName $eventlogname -Source $eventsource -EventID 1 -EntryType Error -Message "Cannot connect to server $_server or database $_database.";
        $errorcode=1;
        Write-Host $errorcode;
        exit
        }
    $sqlConn.Open()
    if ($sqlConn.State -eq 'Open')
        {
        $sqlConn.Close();
        Start-Sleep -s 1;
        Write-EventLog  -LogName $eventlogname -Source $eventsource -EventID 0 -EntryType Information -Message "Connected to server $_server on database $_database.";
        }
}

#Rempli un dataset à partir d'une requête SQL
function sql_to_dataset
    {
    param($_server, $_database, $_query, $_dataset);
    $connectionTemplate = "Data Source={0};Integrated Security=SSPI;Initial Catalog={1};";
    $connectionString = [string]::Format($connectionTemplate, $_server, $_database);
    $errorcode=0;
    try
        {
        $connection = New-Object System.Data.SqlClient.SqlConnection -ErrorAction stop;
        Start-Sleep -s 1;
        Write-EventLog -LogName $eventlogname -Source $eventsource -EventID 0 -EntryType Information -Message "The SQL connection has been created successfully.";
        }
    catch
        {
        Start-Sleep -s 1;
        Write-EventLog -LogName $eventlogname -Source $eventsource -EventID 1 -EntryType Error -Message "An error occurred when creating the SQL connection. Error Message : $_.Exception.Message";
        $errorcode=1;
        Write-Host $errorcode;
        exit;
        }

    $connection.ConnectionString = $connectionString;

    try
        {
        $command = New-Object System.Data.SqlClient.SqlCommand -ErrorAction stop;
        Start-Sleep -s 1;
        Write-EventLog -LogName $eventlogname -Source $eventsource -EventID 0 -EntryType Information -Message "The SQL command has been created successfully.";
        }
    catch
        {
        Start-Sleep -s 1;
        Write-EventLog -LogName $eventlogname -Source $eventsource -EventID 1 -EntryType Error -Message "An error occurred when creating the SQL command. Error Message : $_.Exception.Message";
        $errorcode=1;
        Write-Host $errorcode;
        exit;
        }
    
    $command.CommandText = $_query;
    $command.Connection = $connection;

    try
        {
        $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter -ErrorAction stop;
        Start-Sleep -s 1;
        Write-EventLog -LogName $eventlogname -Source $eventsource -EventID 0 -EntryType Information -Message "The SQL DataMapper has been created successfully.";
        }
    catch
        {
        Start-Sleep -s 1;
        Write-EventLog -LogName $eventlogname -Source $eventsource -EventID 1 -EntryType Error -Message "An error occurred when creating the SQL DataMapper. Error Message : $_.Exception.Message"; 
        $errorcode=1;
        Write-Host $errorcode;
        exit;
        }
    
    $SqlAdapter.SelectCommand = $command;

    try
        {
        $SqlAdapter.Fill($_dataSet) | Out-Null -ErrorAction stop;
        Start-Sleep -s 1;
        Write-EventLog -LogName $eventlogname -Source $eventsource -EventID 0 -EntryType Information -Message "The Dataset has been filled successfully.";
        }
    catch
        {
        Start-Sleep -s 1;
        Write-EventLog -LogName $eventlogname -Source $eventsource -EventID 1 -EntryType Error -Message "An error occurred when filling the Dataset. Error Message : $_.Exception.Message";
        $errorcode=1;
        Write-Host $errorcode;
        exit;
        }

    $connection.Close();
    return $errorcode;
    }

#Rempli un csv avec un dataset
function dataset_to_csv
{
param($_dataset, $_extractFilePath);
$errorcode=0;
    try
        {
        $_dataSet.Tables[0] | ConvertTo-Csv -NoTypeInformation -Delimiter $delimiter | select -Skip $skipline  | Set-Content $_extractFilePath -ErrorAction stop;
        Start-Sleep -s 1;
        Write-EventLog -LogName $eventlogname -Source $eventsource -EventID 0 -EntryType Information -Message "The CSV file has been created successfully.";
        }
    catch
        {
        Start-Sleep -s 1;
        Write-EventLog -LogName $eventlogname -Source $eventsource -EventID 1 -EntryType Error -Message "An error occurred when generating the CSV file. Error Message : $_.Exception.Message";
        $errorcode=1;
        Write-Host $errorcode;
        exit;
        }
        return $errorcode;
}

main



 

SCCM–Modifier depuis SQL le Maximum package processing threads.

Introdution

ATTENTION, l’action proposée par cet article ne fait pas l’objet d’une KB.

La valeur “Maximum package processing threads” permet de limiter le nombre de distribution concurrente de packages.

Cette valeur est bornée de 1 à 50, elle peut être modifiée depuis le console d’administration dans “Configure Site Components”

image

Problématique

Suite à une mauvaise manipulation, cette valeur a été modifiée à 0. La valeur 0 étant en dehors de [0..50], l’erreur suivante apparait :

clip_image001

Résolution

Le script suivant permet de récupérer la valeur actuelle :

Select * from SC_Component_Property cp join SC_Component c on c . ID = cp . ComponentID join SC_SiteDefinition sd on sd . SiteNumber = c . SiteNumber where cp . name = 'Thread Limit' and ComponentName = 'SMS_DISTRIBUTION_MANAGER' and sd . SiteCode = 'SITECODE'
 

Le script suivant permet de modifier la valeur à 3 :

Update CP Set Value3 = 3 from SC_Component_Property cp join SC_Component c on c . ID = cp . ComponentID join SC_SiteDefinition sd on sd . SiteNumber = c . SiteNumber where cp . name = 'Thread Limit' and ComponentName = 'SMS_DISTRIBUTION_MANAGER' and sd . SiteCode = 'SITECODE'
 

SCCM/WMI – Modifier depuis WMI le Maximum package processing threads.

Introdution

ATTENTION, l’action proposée par cet article ne fait pas l’objet d’une KB.

La valeur “Maximum package processing threads” permet de limiter le nombre de distribution concurrente de packages.

Cette valeur est bornée de 1 à 50, elle peut être modifiée depuis le console d’administration dans “Configure Site Components”

image_thumb5_thumb

Problématique

Suite à une mauvaise manipulation, cette valeur a été modifiée à 0. La valeur 0 étant en dehors de [0..50], l’erreur suivante apparait :

clip_image001_thumb1_thumb

Résolution

La valeur peut être modifié depuis SQL (cf. article précèdent), mais également depuis WMI :

Lancer l’outil WMI Tester :

image_thumb1[1]

Se connecter à “root\SMS\site_NOMDUSITE” puis cliquer sur “Enum Classes…” :

image_thumb4

Rechercher la classe “SMS_SCI_Component” puis double cliquer dessus :

image_thumb8

Cliquer sur “props” puis cliquer sur “Instances” :

image_thumb10

Choisir “SMS_Distribution_Manager” :

image_thumb12

Double cliquer sur “Props” :

image_thumb1

Cliquer sur “view embedded” :

image_thumb16

Vérifier les entrées suivantes jusqu’à trouver une valeur appelée “Thread Limit”

image_thumb18

image_thumb20

Modifier la valeur “Value” à la valeur souhaitée, dans cet exemple on passe de 0 (0x0) à 3 (0x0)  :

image_thumb22

image_thumb24

Fermer toutes les fenêtre en sauvegardant chacune.

SCOM - Script de Fermeture des alertes liées a des monitors en état Healthy

Ci-dessous une nouvelle version d'un script de fermeture des alertes liées a des monitors en état Healthy. En effet meme si le cas contraire est plus fréquent (alerte fermée alors que le monitor est encore en état Warning ou Critical), il se peut que l'on doivent fermer les alertes de monitors en état Healthy.

Le script affiche clairement la sortie des alertes a traiter et log cette sortie dans l'eventlog.

 

# SCRIPT TO CHECK INCONSISTENCY BETWEEN NOT CLOSED ALERTS AND HEALTHY MONITORS 


Param(
# Treat alerts that has been modified since less than $LastModifHours
$LastModifHours = 2
)

$ScriptName = "CloseAlertsFromHealthyMonitors.ps1"


# FUNCTIONS

# Check if a source with script name exist in operationsmanager eventlog to log some specific events 
         Function NewEventSource 
         { 
         if(!(Test-Path "HKLM:\SYSTEM\CurrentControlSet\services\eventlog\Operations Manager\$ScriptName")) 
         { 
         New-EventLog -LogName "Operations Manager" -Source $ScriptName 
         }
         } 


# END FUNCTIONS



#Log of script execution 
NewEventSource 
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1000 -Message "Execution of script $ScriptName (Value of LastModifHours is $LastModifHours hours)" -EntryType Information

# Import of Scom Module
Import-Module OperationsManager


# Get list of closed alerts with following criterias:
# - Not Closed
# - Generated by a monitor

$NotClosedAlerts = Get-SCOMAlert -ResolutionState (0..254)  | where { ($_.ismonitoralert -eq $true) -and $_.LastModified -gt (Get-Date).addhours(-$LastModifHours)}


# Variable to store the result of alert treatment.
# Header
$Result = "`n*********** CHECK INCONSISTENCY BETWEEN NOT CLOSED ALERTS AND HEALTHY MONITORS ***********"

$Result += "`n START `n"


for ($i=0;$i -le $NotClosedAlerts.GetUpperBound(0);$i=$i+1) 
{
# Display alert Nb
$NotClosedAlert = $NotClosedAlerts[$i]
$Result +=  "`n`nalert $i ------------------------------"



# Get IDs from Closed alert 
$mrid = $NotClosedAlert.monitoringruleid 
$mcid = $NotClosedAlert.monitoringclassid 
$moid = $NotClosedAlert.monitoringobjectid 



# Get corresponding class 
$monitoringclass = Get-SCOMClass -id $mcid

# Get the corresponding instance with following criterias:
# - HealthState equal Success 
$MyInstance = Get-SCOMMonitoringObject -Class $monitoringclass | where {$_.id -eq $moid -and $_.HealthState -eq "Success"} 

# If there is no instances no need to reset (exit the loop and treat the next closed alert)
If(!($MyInstance))
{
$Result += "No Instance found in Success state for the alert `"$($NotClosedAlert.Name)`" - NO NEED TO CLOSE ALERT"
}
Else
{
$Result += "`nThe following alert must be closed: `n"
$Result += "NAME: $($NotClosedAlert.Name)`n"
$Result += "ID: $($NotClosedAlert.Id)`n"
$Result += "COMPUTER OR OBJECT: $($NotClosedAlert.MonitoringObjectDisplayName)`n"
$Result += "COMPUTER OR OBJECT FULL PATH: $($NotClosedAlert.MonitoringObjectFullName)`n"
$Result += "COMPUTER OR OBJECT HEALTH STATE: $($NotClosedAlert.MonitoringObjectHealthState)`n"
$Result += "TIME RAISED: $($NotClosedAlert.TimeRaised)`n"
$Result += "TIME LAST MODIFIED: $($NotClosedAlert.LastModified)`n"



    try
    {
    Set-SCOMAlert -Alert $NotClosedAlert -ResolutionState 255
    $Result += "Closing of alert `"$($NotClosedAlert.Name)`"..."
    $Result += "-------------------------------------------------------`n`n`n"
    # Update of Alert History Text
    $NotClosedAlert.Update("Alert closed by $ScriptName script")
    }
    catch
    {
    $Result += "Error during the close of alert `"$($NotClosedAlert.Name)`" (ALERT ID: $($NotClosedAlert.Id))"
    }
}

}

$Result += "`n`n END `n"

# Check if $Result contains error of alert closing
if ($($Result | Out-String).Contains("Error during the close of alert"))
{
$Result += "At least one Error has been encountered during closing of some alerts"
NewEventSource 
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1001 -Message $Result -EntryType Warning
}
Else
{
$Result += "`n OK - Treatment of Alerts has ending without Error"
NewEventSource 
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1002 -Message $Result -EntryType Information

}

# Display Result
$Result

 

 

Zabbix API with Powershell – Example

L'API de Zabbix, basée sur le standard JSON-RPC 2.0 peux bien sur etre intérrogée aussi avec Powershell.

 Ci-dessous un script montrant le principe d'interrogation de l'API, en recuperant certaines infos.

 Vous devez renseigner un compte (<my_zabbix_account>) avec au minimum les droits de lecture sur Zabbix, et le nom ou l'ip du serveur Front Web (<zabbix_frontweb_server>).

 

### Query Zabbix Through native zabbix json api

    $credential = Get-Credential -Credential "my_zabbix_account"

$baseurl = 'https://<name_or_ip_of_front_server>/zabbix'
$params = @{
    body =  @{
        "jsonrpc"= "2.0"
        "method"= "user.login"
        "params"= @{
            "user"= $credential.UserName
            "password"= $credential.GetNetworkCredential().Password
        }
        "id"= 1
        "auth"= $null
    } | ConvertTo-Json
    uri = "$baseurl/api_jsonrpc.php"
    headers = @{"Content-Type" = "application/json"}
    method = "Post"
}

[System.Net.ServicePointManager]::SecurityProtocol = 'tls12'
[Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

$result = Invoke-WebRequest @params -UseBasicParsing



$params.body = @{
    "jsonrpc"= "2.0"
    "method"= "host.get"
    "params"= @{
        output = "extend"
		selectFunctions = "extend"
		selectLastEvent = "extend"
		selectGroups = "extend"
		selectHosts = "extend"
    }
    auth = ($result.Content | ConvertFrom-Json).result
    id = 2
} | ConvertTo-Json

$result = Invoke-WebRequest @params -UseBasicParsing
$result = $result.Content | ConvertFrom-Json

 

 

 

Active Directory : Migration SYSVOL de FRS vers DFS-R - Etape Eliminated (Partie 5)

Bonjour à tous,

Aujourd'hui nous abordons la partie 5 de notre série sur la migration du dossier SYSVOL du mécanisme de réplication FRS vers DFS-R, elle sera consacrée à la dernière étape Eliminated.

En théorie

Déroulement de la migration

La migration se compose de 4 états globaux qui sont les suivants :

Etat  Actions  Dossier SYSVOL Dossier SYSVOL_DFSR Dossier utilisé par les services AD DS
 Start (Etat 0)  Etat par défaut, FRS réplique le dossier SYSVOL. Présent Non présent SYSVOL
 Prepared (Etat 1)
 FRS réplique le dossier SYSVOL et celui-ci est toujours utilisé par les services AD DS.
DFS-R réplique une copie de ce dossier.
 Présent Créé SYSVOL
 Redirected (Etat 2)
FRS réplique le dossier SYSVOL.
DFS-R réplique toujours sa copie et celle-ci devient le
dossier utilisé par les services AD DS.
 Présent  Présent SYSVOL_DFSR
 Eliminated (Etat 3)
Le dossier SYSVOL répliqué par FRS est supprimé.
DFS-R réplique le dossier SYSVOL.
 Supprimé  Présent SYSVOL_DFSR
 

Particularités

Comme vous pouvez le voir ci-dessus, l'état 3 (Eliminated) n'est pas le plus impactant :
  • En arrière-plan, le mécanisme de réplication DFS-R réplique une copie du dossier SYSVOL (cette copie étant devenue depuis l'étape Redirected celle utilisée par les services AD DS), la version répliquée par le mécanisme FRS est supprimée.
  • En façade, c'est le dossier SYSVOL répliqué par le mécanisme DFS-R qui est présenté aux postes clients via les partages NETLOGON et SYSVOL
Il faut souligner les points suivants :
  • Tout retour arrière est impossible une fois cette etape éffectuée.
  • Il convient de vérifier que la copie du dossier SYSVOL répliquée par le mécanisme DFS-R est intègre avant de supprimer la version répliquée par FRS. A toute fin utile, on pourra éxécuter un Rapport de Propagation de la Réplication DFS dans la console DFS Management pour le groupe de réplication Domain System Volume.
  • Les commandes de migration sont à lancer depuis le contrôleur de domaine possédant le rôle PDC.

En pratique

Etat Redirected

Si l'étape précédente a été correctement réalisée, l'état de migration au niveau du domaine AD ainsi que celui de tous les contrôleurs de domaine doit être Redirected.

Etat global (Domaine AD) : dfsrmig /getglobalstate

Etats de migration locaux (Contrôleurs de domaine) : dfsrmig /getmigrationstate

Une fois ces deux points vérifiés, nous pouvons démarrer la migration vers l'état Eliminated.

Passage vers l'état Eliminated

Etat global (Domaine AD) : dfsrmig /setglobalstate 3

Le passage vers l'état Eliminated est bien indiqué ainsi que son irréversibilité.
Si malgré un certain délai, les RODCs ne passent pas en état Eliminated, il faudra forcer la suppression des objets FRS correspondant avec la commande dfsrmig /DeleteRoNtfrsMember (à éxécuter seulement une fois depuis le PDC)
 

Etats de migration locaux (Contrôleurs de domaine) : dfsrmig /getmigrationstate

On voit ici que la migration est en cours car aucun contrôleur de domaine n'est dans l'état defini au niveau du domaine Active Directory (Etat Global).

Etat Eliminated atteint

Etat global (Domaine AD) : dfsrmig /getglobalstate

La commande dfsrmig /setglobalstate avait déjà configuré l'état de migration au niveau du domaine Active Directory à Eliminated. Celui-ci reste donc inchangé.

Etats de migration locaux (Contrôleurs de domaine) : dfsrmig /getmigrationstate

Le message est explicite, tous les contrôleurs de domaine sont dans l'état Eliminated, le même que celui défini au niveau du domaine AD (état global).
On dit que la migration a atteint un état consistant sur tous les contrôleurs de domaine.
 
A partir de ce moment, la migration du dossier SYSVOL du mécanisme de réplication FRS vers DFS-R est officiellement terminée.
 
Bonus :
En cas de succès, on constate également la présence sur tous les controleurs de domaine de l'évènement 8019 dans le journal d'évènements Applications and Servicies logs -> DFS Replication

La console DFS Management pour le groupe de réplication Domain System Volume nous confirme que la version du dossier SYSVOL présentée aux postes clients est celle répliquée par le mécanisme DFS-R.

 

Exchange 2010 - Erreur de synchronisation des bases après la migration d'un serveur Mailbox virtualisé

Contexte

Après la migration d'un serveur Mailbox virtualisé vers un nouvel hoster, la réplication des bases Exchange ne fonctionne plus et le message d'erreur suivant est présent lorsque la commande Test-ReplicationHealth est utilisée :

The log copier was unable to continue processing for database DAG\MBX because an error occured on the target server: Continuous replication - block mode has been terminated. Error : the log file sector size does not match the current volume's sector size (-546)

Problèmatique

Ce problème est causé par un changement de la taille de secteur physique des disques sur lesquels les bases sont. Le problème intervient lorsque le nouvel hoster est plus récent que l'ancien et qu'il ne possède pas le même firmware pour le stockage. Exchange n'est pas en capacité de supporter automatiquement le changement d'un disque avec des secteurs de 512 bytes vers un disque avec des secteurs de 4096 bytes.

Pour vérifier cela, lancer la commande suivante : fsutil fsinfo ntfsinfo <Disk>

On remarque que le paramètre Bytes Per Physical Sector n'est pas supporté.

Solution

La solution pour reprendre la synchronisation des bases est de désactiver la réplication granulaire dans un premier temps. Pour cela, créer la clé de registre DWORD suivante avec la valeur 1 :

HKLM\Software\Microsoft\ExchangeServer\v14\Replay\Parameters\DisableGranularReplication

Après avoir redémarré le serveur, si on relance la commande fsutil fsinfo ntfsinfo <Disk> le paramètre Bytes Per Physical Sector accepte désormais les secteurs en 4096 bytes.

A la suite de ce changement, la réplication fonctionne de nouveau correctement.

Remarque : Attention, Microsoft ne supporte pas que la méthode de réplication ne soit pas la même sur l'ensemble des noeuds d'un DAG. Il est donc nécessaire de revenir en arrière une fois le changement effectué ou de désactiver la réplication granulaire sur l'ensemble des noeuds.

L'ensemble de ce problème est expliqué plus en détails sur le lien TechNet : https://blogs.technet.microsoft.com/exchange/2013/04/24/exchange-2010-database-availability-groups-and-disk-sector-sizes/

Active Directory : Migration SYSVOL de FRS vers DFS-R - Etape Redirected (Partie 4)

Bonjour à tous,

Aujourd'hui nous abordons la partie 4 de notre série sur la migration du dossier SYSVOL du mécanisme de réplication FRS vers DFS-R, elle sera consacrée à l'étape Redirected.

En théorie

Déroulement de la migration

La migration se compose de 4 états globaux qui sont les suivants :

Etat  Actions  Dossier SYSVOL Dossier SYSVOL_DFSR Dossier utilisé par les services AD DS
 Start (Etat 0)  Etat par défaut, FRS réplique le dossier SYSVOL. Présent Non présent SYSVOL
 Prepared (Etat 1)
 FRS réplique le dossier SYSVOL et celui-ci est toujours utilisé par les services AD DS.
DFS-R réplique une copie de ce dossier.
 Présent Créé SYSVOL
 Redirected (Etat 2)
FRS réplique le dossier SYSVOL.
DFS-R réplique toujours sa copie et celle-ci devient le
dossier utilisé par les services AD DS.
 Présent  Présent SYSVOL_DFSR
 Eliminated (Etat 3)
Le dossier SYSVOL répliqué par FRS est supprimé.
DFS-R réplique le dossier SYSVOL.
 Supprimé  Présent SYSVOL_DFSR
 

Particularités

Comme vous pouvez le voir ci-dessus, l'état 2 (Redirected) est le plus impactant :
  • En arrière-plan, le mécanisme de réplication DFS-R réplique une copie du dossier SYSVOL, toujours en parallèle de la version répliquée par le mécanisme FRS.
  • En façade, c'est le dossier SYSVOL répliqué par le mécanisme DFS-R qui est présenté aux postes clients via les partages NETLOGON et SYSVOL
Il faut souligner les points suivants :
  • Un retour arrière reste possible (il faut utiliser la commande dfsrmig /setglobalstate X où X est le numéro de l'étape voulue)
  • Il convient de vérifier que la copie du dossier SYSVOL répliquée par le mécanisme DFS-R est intègre avant d'effectuer la bascule vers celle-ci. A toute fin utile, on pourra éxécuter un Rapport de Propagation de la Réplication DFS dans la console DFS Management pour le groupe de réplication Domain System Volume.
  • Le dossier SYSVOL est copié une seule et unique fois lors de la premiere étape. Toute modification faite sur les GPOs ou le dossier SYSVOL lui même entre l'état 1 (Prepared) et l'état 2 (Redirected) est perdue.
  • Les commandes de migration sont à lancer depuis le contrôleur de domaine possédant le rôle PDC

En pratique

Etat Prepared

Si l'étape précédente a été correctement réalisée, l'état de migration au niveau du domaine AD ainsi que celui de tous les contrôleurs de domaine doit être Prepared.

Etat global (Domaine AD) : dfsrmig /getglobalstate

Etats de migration locaux (Contrôleurs de domaine) : dfsrmig /getmigrationstate

Une fois ces deux points vérifiés, nous pouvons démarrer la migration vers l'état Redirected.

Passage vers l'etat Redirected

Etat global (Domaine AD) : dfsrmig /setglobalstate 2

On remarque que la bascule vers la version du dossier SYSVOL répliquée par le mécanisme DFS-R est bien indiquée.

Etats de migration locaux (Contrôleurs de domaine) : dfsrmig /getmigrationstate

On voit ici que la migration est en cours car aucun contrôleur de domaine n'est dans l'état defini au niveau du domaine Active Directory (Etat Global).

Etat Redirected atteint

Etat global (Domaine AD) : dfsrmig /getglobalstate

La commande dfsrmig /setglobalstate avait déjà configuré l'état de migration au niveau du domaine Active Directory à Redirected. Celui-ci reste donc inchangé.

Etats de migration locaux (Contrôleurs de domaine) : dfsrmig /getmigrationstate

Le message est explicite, tous les contrôleurs de domaine sont dans l'état Redirected, le même que celui défini au niveau du domaine AD (état global).
On dit que la migration a atteint un état consistant sur tous les contrôleurs de domaine.
 
Bonus :
En cas de succès, on constate également la présence sur tous les controleurs de domaine de l'evenement 8017 dans le journal d'évènements Applications and Servicies logs -> DFS Replication

La commande net share executée sur un contrôleur de domaine nous confirme que la version du dossier SYSVOL présentée aux postes clients est celle répliquée par le mécanisme DFS-R.

Dans le prochain billet, nous entrerons plus en détail sur le déroulement de la troisième étape, Eliminated.

Active Directory : Migration SYSVOL de FRS vers DFS-R - Etape Prepared (Partie 3)

Bonjour à tous,

Aujourd'hui nous abordons la partie 3 de notre série sur la migration du dossier SYSVOL du mécanisme de réplication FRS vers DFS-R, elle sera consacrée à l'étape Prepared.

En théorie

Déroulement de la migration

La migration se compose de 4 états globaux qui sont les suivants :

Etat  Actions  Dossier SYSVOL Dossier SYSVOL_DFSR Dossier utilisé par les services AD DS
 Start (Etat 0)  Etat par défaut, FRS réplique le dossier SYSVOL. Présent Non présent SYSVOL
 Prepared (Etat 1)
 FRS réplique le dossier SYSVOL et celui-ci est toujours utilisé par les services AD DS.
DFS-R réplique une copie de ce dossier.
 Présent Créé SYSVOL
 Redirected (Etat 2)
FRS réplique le dossier SYSVOL.
DFS-R réplique toujours sa copie et celle-ci devient le
dossier utilisé par les services AD DS.
 Présent  Présent SYSVOL_DFSR
 Eliminated (Etat 3)
Le dossier SYSVOL répliqué par FRS est supprimé.
DFS-R réplique le dossier SYSVOL.
 Supprimé  Présent SYSVOL_DFSR
 

Particularités

Comme vous pouvez le voir ci-dessus, l'état 1 (Prepared) n'est pas le plus impactant :
  • En arrière-plan, le mécanisme de réplication DFS-R est mis en place pour répliquer une copie du dossier SYSVOL, en parallèle de la version répliquée par le mécanisme FRS.
  • En façade, c'est toujours le dossier SYSVOL répliqué par le mécanisme FRS qui est présenté aux postes clients via les partages NETLOGON et SYSVOL
En revanche, il faut souligner les points suivants :
  • Un retour arrière reste possible (il faut utiliser la commande dfsrmig /setglobalstate X où X est le numéro de l'étape voulue)
  • Une copie du dossier SYSVOL actuel sera réalisée. Il convient de vérifier que le dossier SYSVOL est intègre avant de commencer les étapes de migration sinon vous vous retrouverez avec un dossier SYSVOL qui sera toujours corrompu en fin de migration.
  • Le dossier SYSVOL est copié une seule et unique fois lors de la premiere étape. Toute modification faite sur les GPOs ou le dossier SYSVOL lui même entre l'état 1 (Prepared) et l'état 2 (Redirected) est perdue.
  • Les commandes de migration sont à lancer depuis le contrôleur de domaine possédant le rôle PDC

En pratique

Etat Start

Si aucune tentative de migration n'a été faite auparavant, l'état de migration au niveau du domaine AD ainsi que celui de tous les contrôleurs de domaine doit être Start.

Etat global (Domaine AD) : dfsrmig /getglobalstate

Etats de migration locaux (Contrôleurs de domaine) : dfsrmig /getmigrationstate

Une fois ces deux points vérifiés, nous pouvons démarrer la migration vers l'état Prepared.

Passage vers l'etat Prepared

Etat global (Domaine AD) : dfsrmig /setglobalstate 1

On remarque qu'il est indiqué un délai concernant le début de la migration pour les contrôleurs de domaine.
Ceci est parfaitement normal car les contrôleurs vont aller lire l'information sur l'état de la migration depuis la partition Active Directory qu'ils auront répliqué.
Vous pouvez donc avoir un début de migration tardif à cause :
  • D'une réplication Active Directory lente
  • D'un RODC ne voulant pas passer en état Prepared. Les RODCs ne pouvant pas modifier les objects Active Directory par eux mêmes (création des objets DFS-R leur correspondant), c'est le PDC qui est chargé de le faire à leur place. Toutefois, si malgré un certain délai, les RODCs ne passent pas en état Prepared, il faudra forcer la création des objets DFS-R correspondant avec la commande dfsrmig /CreateGlobalObjects (à éxécuter seulement une fois depuis le PDC)

Etats de migration locaux (Contrôleurs de domaine) : dfsrmig /getmigrationstate

On voit ici que la migration est en cours car aucun contrôleur de domaine n'est dans l'état defini au niveau du domaine Active Directory (Etat Global).

Etat Prepared atteint

Etat global (Domaine AD) : dfsrmig /getglobalstate

La commande dfsrmig /setglobalstate avait déjà configuré l'état de migration au niveau du domaine Active Directory à Prepared. Celui-ci reste donc inchangé.

Etats de migration locaux (Contrôleurs de domaine) : dfsrmig /getmigrationstate

Le message est explicite, tous les contrôleurs de domaine sont dans l'état Prepared, le même que celui défini au niveau du domaine AD (état global).
On dit que la migration a atteint un état consistant sur tous les contrôleurs de domaine.
 
Bonus : 
En cas de succès, on constate également la présence sur tous les controleurs de domaine de l'evenement 8014 dans le journal d'évènements Applications and Servicies logs -> DFS Replication

 

La commande net share executée sur un contrôleur de domaine nous confirme que la version du dossier SYSVOL présentée aux postes clients est toujours celle répliquée par le mécanisme FRS.

Dans le prochain billet, nous entrerons plus en détail sur le déroulement de la deuxieme étape, Redirected.