Migration de serveur DHCP sous Windows Server 2012 R2

Afin de remplacer un serveur DHCP physique défaillant, j’ai monté un nouveau serveur DHCP basé sur une machine virtuelle. Grâce à Powershell, on peut s’occuper de la migration des données propres au serveur DHCP (paramètres, plages, baux…) en 2 coups de cuillère à pot.

Sur l’ancien serveur, on exporte les données :

Export-DhcpServer –ComputerName dhcp-srv -Leases -File C:\dhcp-mig\DhcpSrv-Export.xml -verbose

Puis on importe sur le nouveau serveur ce fichier XML ; à noter que le paramètre -BackupPath permet de spécifier un emplacement où Powershell va sauvegarder la configuration avant importation :


Si jamais l’importation renvoie une erreur « There are no more endpoints available« , il faut alors passer en valeur du paramètre ComputerName le nom NetBIOS de la machine et non son nom DNS (p. ex. : dhcp-srv01 et non dhcp-srv01.domain.com). Pour plus d’informations, vous pouvez consulter ce lien.

Ensuite, pour vérifier que tout est bien importé, en plus d’un contrôle visuel pour les scopes et réservations, cette instruction permet de compter le nombre d’enregistrements : si ils sont identiques avant l’export et après l’importation, cela veut dire que tout s’est bien déroulé (attention, il est possible d’obtenir tout de même une valeur différente si des baux ont expiré depuis l’importation sur le nouveau serveur) :

(Get-DhcpServerv4Scope -Computername dhcp-srv-new | Get-DhcpServerv4Lease -Computername dhcp-srv-new).Count

Vous pouvez trouver tous les cmdlets Powershell propres à DHCP sur le TechNet.

Un serveur d’un pool DFSR n’est plus synchronisé avec les autres

J’ai rencontré depuis quelques temps des soucis par rapport à un
partage réseau porté par DFSR sur 4 serveurs 2008 R2. Tout d’abord, un premier
dysfonctionnement concernant le Staging Quota plutôt simple à résoudre, et
ensuite un des 4 serveurs qui n’était plus synchronisé avec les 3 autres,
résultant en des différences notables entre les répertoires et les fichiers.

Tout d’abord, la résolution du Staging Quota et une
rapide explication de ce que c’est. Il s’agit d’un espace dont a besoin DFSR
pour opérer proprement la réplication, en fait DFSR s’en sert comme file
d’attente par rapport aux changements qui vont être propagés par la suite sur
tout le pool. La préconisation de Microsoft (voir ce
lien
) est d’avoir une taille au minimum équivalente aux 32 plus gros
fichiers du partage répliqué. DFSR fait régulièrement du nettoyage dans cette
file d’attente mais il se peut qu’avec la croissance du partage, le Staging
Quota
décidé au départ ne soit pas suffisant. Cette alerte est remontée
dans le journal d’événements (Source : DFSR, Event ID : 4206). J’ai donc
dû l’agrandir ; rien de complexe, cela peut être réalisé en pleine journée car
cela ne nécessite pas de redémarrer le service DFSR. 
Dans dfsmgmt.msc (ou via le Server Manager), on
déroule les réplications, puis en sélectionnant celle qui nous intéresse, on
aura les partages et les serveurs qui constituent ce pool.

L’accès au réglage du Staging Pool s’obtient avec un simple
clic-droit sur le partage, puis Staging.

Maintenant que ce problème est réglé, j’ai réalisé quelques tests
pour d’abord confirmer que le serveur ayant un nombre incohérent de fichiers
dans son partage par rapport aux autres était bien désynchronisé. Un simple
fichier unique créé chacun des 4 serveurs s’est retrouvé propagé sur tous les
autres… sauf un, et celui placé sur le serveur hors synchronisation ne s’est
pas propagé, ce qui signifie que le serveur est désynchronisé à la fois en
envoi comme en réception. Dans la suite de l’exemple, je vais appeler D le serveur
désynchronisé et S le serveur lié qui est en bon état de marche.

D et S sont
deux serveurs Windows 2008 R2 hébergeant un partage DFSR nommé partage ; D et S
doivent avoir les mêmes fichiers (sauf .BAK, .TMP et fichiers commençant par
une tilde car non répliqués par DFSR) et l’un et l’autre opèrent les
transactions en envoi comme en réception. J’ai vérifié si des fichiers
étaient programmés en envoi ou en réception avec cette instruction :

dfsrdiag ReplicationState

Rien. Je vérifie si il reste des fichiers en attente de synchronisation, autrement appelés backlog :

dfsrdiag backlog /SendingMember:D /ReceivingMember:S /RGName:partage
/RFName:partage

Et en effet, de nombreux fichiers étaient en attente de synchronisation, et dans les deux sens ; un état des lieux des fichiers a confirmé cette différence.

Il a donc été décidé de procéder à la suppression et
recréation des liens du serveur D au niveau DFSR. Tout d’abord, on procèdera à
la désactivation du partage dans la console DFS avant de procéder à sa suppression.

En choisissant la première option, non seulement on indique
que l’on ne souhaite plus que le serveur D ne se réplique plus, mais en plus,
on supprime ses liens avec le serveur S (ou le reste du pool, le cas échéant).
En choisissant la deuxième option, on pourrait toujours tomber sur le serveur D
en appelant le partage, ce qui n’est pas souhaitable.
Une fois la suppression effectuée, on procède au rajout de D
comme membre du pool DFS aux côtés de S, en prenant bien soin d’y appliquer les
mêmes paramètres. Rien de complexe, je lie le serveur D à S (qui lui-même peut
être relié à d’autres serveurs du pool), dans les deux sens (envoi et
réception). Quelques captures d’écran du wizard à titre d’exemple :

Un petit tour dans le journal d’événements de S m’indique
qu’il arrête la communication avec son partenaire D à cause d’une erreur
(Source : DFSR, Event ID : 5014).
Je dois donc attendre la réplication entre les ActiveDirectory pour qu’ils enregistrent tous la suppression du membre et son retour dans le pool. Ensuite, cette instruction exécutée sur D et S me permet de les forcer à bien actualiser les informations DFSR afin qu’ils soient totalement à jour.

dfsrdiag pollad

Tout ça, pour rien. Toujours pas une trace de
synchronisation entre D et S. Et dans le journal d’événements de D, je trouve une entrée
m’indiquant qu’il communique bien avec S ; mais ce n’est pas réciproque puisque
S me dit que D n’est plus membre du pool DFS. Je décide donc de regarder au
niveau ActiveDirectory pour voir si je peux y trouver les paramètres DFS. Le
journal d’évènements permet de savoir avec quel DC les serveurs communiquent (Event
ID
: 1206).
Un petit coup d’ADSI Edit sur chaque DC sur lequel un
serveur est connecté permet d’en savoir plus : les informations propres à DFSR
se trouvent dans l’objet du serveur. Les réplications sont bonnes car les mêmes
objets sont disponibles sur le DC où D et S sont connectés. A noter que cette
référence au DC ne change que lorsque le service DFSR démarre ; si le DC en
question est arrêté ou supprimé, il faut redémarrer le service DFSR pour que la
prise en compte soit effective et cela peut occasionner des désynchronisations
si ce n’est pas fait.

 

Par acquis de conscience, je vérifie tout de même mes
réplications : repadmin /showrepl * ne me renvoie rien de particulier, toutes
les réplications sont valides et datent de 30 minutes tout au plus. Par ailleurs, le bilan de santé effectué à partir de la
console d’administration DFSR m’indique toujours le même message : « This member is
waiting for initial replication for replicated folder partage and is not
currently participating in replication.
This delay can occur because the member is waiting for the DFS
Replication service to retrieve replication settings from Active Directory Domain
Services. After the member detects that it is part of replication group, the
member will begin initial replication.
« 
Il est possible d’avoir ce message lorsqu’il n’y a plus de
membre primaire sur le pool DFS ; le membre principal étant celui qui sert
de maître par rapport aux fichiers et qui écrasera les autres lors de la
réplication initiale seulement. Je ne trouve aucune trace dans les journaux
d’évènements (Event ID à chercher : 4002 puis 4112). Je décide alors de
faire du serveur DFS principal le membre primaire :
dfsradmin
Membership Set /RGname:partage /RFName:partage /MemName:ServPrim
/IsPrimary:True

Je force une réplication sur tous les contrôleurs de domaine
afin que l’information se propage sur tous les sites et ensuite je demande aux
serveurs DFS de requêter l’AD pour obtenir le nouveau serveur primaire. Toujours pas mieux.

Finalement, j’ai décidé de supprimer complètement mon partage DFSR, liens et namespace et je l’ai recréé de zéro : les serveurs se synchronisent désormais proprement.

Disques RAID invisibles par le setup de 2012 R2 sur HPE ProLiant Gen10

Je devais installer un Windows Server 2012 R2 sur un serveur HPE ProLiant DL360 Gen10 flambant neuf, équipé d’un contrôleur RAID HP SmartArray P408i-a SR Gen10. Une fois le RAID configuré proprement, impossible pour le setup d’install de 2012 R2 de voir la configuration.

La carte RAID n’est plus détectée directement par le wizard d’installation ; il faut donc télécharger un driver externe, extraire le contenu de l’exécutable fraîchement téléchargé, le monter en tant que répertoire sur la carte ILO, et ensuite, spécifier lors de la recherche des disques que l’on souhaite utiliser un driver externe. En choisissant le répertoire monté plus tôt, on installe donc ces 2 pilotes :

Une fois le driver installé, la configuration RAID est visible et l’OS est installable.

A noter que le driver est également nécessaire pour installer Windows Server 2016 ; celui-ci n’étant pas disponible pour des versions plus anciennes que 2012 R2, je doute qu’il soit possible d’installer autre chose que les 2 dernières versions sur un stockage RAID.

Tous les crédits aux participants de ce thread sur les forums HPE pour la résolution de ce problème.

Powershell : déploiement d’un script et création de tâche planifiée, sur machine distante

Sous ce titre un peu barbare, je vais partager un script que j’ai brodé aujourd’hui. En local sur ma station, j’utilisais un script Powershell me permettant de fermer des sessions RDP simplement déconnectées (que j’ai d’ailleurs publié dans cet article 😉). Seulement, il a été décidé de le modifier de manière à ce que le script ne demande plus un nom de machine particulière, mais de simplement s’occuper de la machine sur laquelle il est exécuté. En contrepartie, l’idée était de le déployer sur tous les serveurs, afin de pouvoir l’appeler via une tâche planifiée de manière à ce que tous les jours les sessions RDP inactives soient shuntées.

Le script ci-dessous va donc effectuer les tâches suivantes :

  • demander un nom de serveur
  • créer un répertoire sur le disque local C:
  • copier le script dans le répertoire fraîchement créé
  • créer une tâche planifiée, exécutée par l’utilisateur SYSTEM, avec une élévation de droits, qui va donc appeler le script qui a été copié.

Plusieurs choses :

  • Les instructions propres au planificateur de tâches ne fonctionnent qu’à partir de Windows 2012 R2 ou 8.1, indépendamment de la version de PS.
  • J’ai utilisé les partages administratifs au lieu d’un PS-Session pour la copie car un Copy-Item -ToSession nécessite PowerShell V5, or mon environnement est hybride V4 et V5 et je ne peux pas tout déployer directement depuis un hôte en V5.
  • Les commandlets du planificateur de tâches ne fonctionnent qu’en local, il faut donc les appeler sur le système distant via Invoke-Command.
$RemoteServer = Read-Host "Destination Server to install script and create scheduled task ?"
$ScriptDir = "\\"+$RemoteServer+"\c$\"
New-Item -Path $ScriptDir -Name "Scripts" -ItemType "directory"
$FinalDest = "\\"+$RemoteServer+"\c$\Scripts"
Copy-Item "script.ps1" -Destination $FinalDest -Force
if ($?){ Write-Host "Copy successful." }
else { Write-Host "Copy failed." ; break }
Invoke-Command -ComputerName $RemoteServer -ScriptBlock {
$TaskDetails = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
$TaskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "C:\Scripts\script.ps1"
$TaskSched = New-ScheduledTaskTrigger -Daily -At 4am
$TaskName = "AutoDisconnectSession"
Register-ScheduledTask -Action $TaskAction -Principal $TaskDetails -Trigger $TaskSched -TaskName $TaskName }
if ($?) { Write-Host "Task successfully created." }
else { "There was an error creating the task." }