Le blog technique

Toutes les astuces #tech des collaborateurs de PI Services.

#openblogPI

Retrouvez les articles à la une

Manipuler les enregistrements DNS en Powershell 2

Problème rencontré

Lors d’un changement complet du plan d’adressage des serveurs d’un datacenter, il était nécessaire de changer les enregistrements DNS. Au delà des enregistrements NS des serveurs DNS, il fallait aussi mettre à jour l’intégralité des enregistrements statiques A et PTR. Il était nécessaire de proposer une solution qui soit simple à mettre en œuvre (peu d’intervention utilisateur), puisque près de 600 enregistrements était à modifier. Il n’était pas faisable de faire cela manuellement.

Solution proposée

Comme indiqué dans l’intitulé, il a été choisi que cette opération serait réalisée par un script Powershell. Actuellement, il y a encore peu de parcs informatique utilisant Powershell 3 avec le module DNS pour Windows 8/2012. Le module DNS fournit par Powershell 3 peut donc seulement être utilisé dans des cas très limités. La solution proposée utilisait les classes WMI. Il s’agissait ensuite de loguer un maximum d’informations pour avoir un maximum de contrôle sur les modifications apportées.

Les classes WMI

Voici un listing des classes WMI pour les enregistrements DNS les plus courants :
– Enregistrements PTR : MicrosoftDNS_PTRType
– Enregistrements A : MicrosoftDNS_AType
– Enregistrements CNAME : MicrosoftDNS_CNAMEType
– Enregistrements MX : MicrosoftDNS_MXType
– Enregistrements NS : MicrosoftDNS_NSType

Récupération d’enregistrements DNS

Voici un exemple de récupération d’un enregistrement A.

On déclare la zone dans laquelle on veut effectuer la recherche.

001
002
$DNSZone = « myenterprise.lan »

 

On définit le serveur DNS sur lequel on effectue la recherche.

001
002
$DNSServer = « SRVDNS01 » 

 

On cherche l’enregistrement via l’attribut OwnerName qui est le nom DNS complet.

001
002
$OwnerName = « SRV01.$DNSZone » 

 

On utilise une requête WMI sur le serveur DNS avec un filtre sur la zone et l’enregistrement à chercher.

001
002
003
004
$Record = Get-WMIObject -Computer $DNSServer `
-Namespace « root\MicrosoftDNS » -Class « MicrosoftDNS_AType » `
-Filter « ContainerName=’$DNSZone’ AND OwnerName=’$OwnerName' » 

Si l’on souhaite obtenir toutes les propriétés de cet enregistrement et notamment voir les autres attributs sur lesquels on peut effectuer une recherche il suffit d’appeler la variable : $Record

Mis à jour d’enregistrements DNS :

En reprenant l’enregistrement précédent, on peut rapidement modifier son addresse IP (ou TTL) via la méthode Modify().

001
002
$NewRecord = $Record.Modify($Record.TTL, « 10.0.1.1 ») 

 

Détecter si un enregistrement est dynamique :

Aussi, il peut être intéressant de ne mettre à jour que les enregistrements statiques. On peut détecter les enregistrements dynamiques via leur timestamp qui n’est pas nulle :

001
002
003
004
if($Record.Timestamp -ne 0){ 
    $NewRecord = $Record.Modify($Record.TTL, « $newRecordAddress ») 
} 

Il suffit donc juste d’utiliser une structure conditionnelle si sinon sur l’attribut timestamp de notre enregistrement DNS.

Exemple avec un enregistrement PTR :

Pour réaliser cette opération on réutilise les variables $DNSServer, $DNSZone et $OwnerName déclarées plus haut et définir la zone où chercher l’enregistrement PTR.

001
002
$DNSZonePTR = « 10.in-addr.arpa » 

 

La syntaxe pour rechercher un enregistrement PTR est similaire. Seuls la classe WMI et le champ de recherche (PTRDomainName au lieu de Ownername).

001
002
003
004
$PTRRecord = Get-WMIObject -Computer $DNSServer `
-Namespace « root\MicrosoftDNS » -Class « MicrosoftDNS_PTRType » `
-Filter « ContainerName=’$ZonePTR’ AND PTRDomainName=’$OwnerName.' » 

 

Attention, il n’est pas possible de modifier l’IP d’un enregistrement PTR, il faut d’abord supprimer l’enregistrement puis le recréer.

Avant, on récupère la TTL pour la réutiliser afin qu’elle soit identique lors du nouvel enregistrement :

001
002
$TTL = $PTRRecord.TTL 

 

On supprime l’enregistrement DNS en supprimant l’objet WMI

001
002
$PTRRecord | Remove-WmiObject 

 

On déclare la nouvelle valeur de notre enregistrement. Si IP vaut 10.B.C.D dans la zone « 10.in-addr.arpa » alors celui-ci vaudra D.C.B.10.in-addr.arpa

001
002
$PTROwnerName = « 1.1.0.10.in-addr.arpa »

 

On déclare le type de notre enregistrement, ici PTR :

001
002
003
$PTRTypeClass = [WMIClass]« \\$DNSServer\root\MicrosoftDNS:MicrosoftDNS_PTRType » 

$PTRNewRecord = $PTRTypeClass.CreateInstanceFromPropertyData(« $DNSServer.myenterprise.lan »,$ZonePTR,$PTROwnerName,$null,$TTL,« $OwnerName. ») 

 

Le 4ème attribut est dénommé record class : par défaut il s’agit de IN. La valeur à insérer est 1 ou $null.

Exemple sous Powershell v3 avec module DNS :

Pour terminer, voici comment réaliser les mêmes opérations (Récupération/Mis à jour d’enregistrements DNS) avec le module DNS Powershell v3. Il faut posséder un poste sous Windows 8/2012 pour exécuter ses commandes et avoir installé l’outil de gestion des serveurs DNS (via les outils d’administration).

On commence par déclarer la zone, le serveur DNS et le nom de l’enregistrement :

001
002
003
004
005
$DNSZone = « myenterprise.lan » 
$DNSServer = « DNS01 » 
$RecordName = « SERV01 » 
$NewRecordAddress = « 10.0.1.1 » 

 

Le type est renseigné dans le paramètre RRType. Attention, il est important de stocker l’objet dans une variable car nous allons le réutiliser pour le modifier.

001
002
003
$Record = Get-DnsServerResourceRecord -ZoneName « $DNSZone » -Name « $RecordName » `
-RRType « A » -ComputerName « $DNSServer » 

 

Pour valider les modifications nous aurons besoin de l’enregistrement DNS avant et après sa mise à jour. Il faut donc réaliser une deuxième récupération de l’enregistrement DNS dans une autre variable.

001
002
003
$NewRecord = Get-DnsServerResourceRecord -ZoneName « $DNSZone » -Name « $RecordName » `
-RRType « A » -ComputerName « $DNSServer » 

 

Ensuite, il faut modifier la propriété qui nous intéresse, ici l’adresse IP.

001
002
$NewRecord.RecordData.IPv4Address.IPAddressToString = « $NewRecordAddress » 

 

Enfin, on enregistre les modifications en passant les 2 objets (avant et après modification), la zone et le nom du serveur DNS :

001
002
003
Set-DnsServerResourceRecord -NewInputObject $NewRecord -OldInputObject $Record -ZoneName « $DNSZone » `
-ComputerName « $DNSServer » 

SQL Server : BULK INSERT – Msg 4861 – Operating system error code 5

Problématique

Dans certains cas nous somme amené à utiliser l’instruction BULK INSERT pour injecter dans une table des enregistrements qui proviennent d’un fichier texte stocké sur un partage réseau

Supposons maintenant que nous disposons de 3 serveurs :

  • 1 contrôleur de domaine DC01
  • 2 serveurs SQL 2008 R2 SQL01 et SQL02, le serveur SQL01

Dans le premier scénario nous allons exécuter une requête BULK INSERT sur le serveur SQL01 qui injectera dans la table #TEST les lignes d’un fichier texte nommé ListCustomers.txt accessible via le chemin UNC \\SQL01\FILES\Input

Dans ce premier scénario la requête aboutit sans aucun problème  

image

Dans le deuxième scénario nous allons exécuter une requête BULK INSERT sur le serveur SQL01 mais depuis le serveur SQL02 qui injectera dans la table #TEST les lignes d’un fichier texte nommé ListCustomers.txt accessible via le chemin UNC \\SQL01\FILES\Input

Dans ce deuxième scénario la requête aboutit sans aucun problème

image

Dans le troisième scénario nous allons exécuter une requête BULK INSERT sur le serveur SQL01 mais depuis le serveur SQL02 qui injectera dans la table #TEST les lignes d’un fichier texte nommé ListCustomers.txt accessible via le chemin UNC \\SQL02\FILES\Input

Dans ce troisième scénario une erreur est générée, en effet l’instruction BULK INSERT n’arrive pas à ouvrir le fichier source pour y lire les enregistrements !

image 

Le message complet de l’erreur peut être:

 image

Explication

L’erreur enregistrée dans le scénario 3 est dû au fait que lorsqu’un utilisateur se connecte à SQL Server avec l’authentification Windows il n’est autorisé à lire que les fichiers accessibles par le biais de son compte utilisateurs, quelque soit le profil de sécurité du processus SQL Server.

Résolution

Pour remédier à ce problème on pourra procéder de deux manières, soit qu’on utilise une connexion SQL Server au lieu de l’authentification Windows soit configurer Windows pour activer la délégation des comptes de sécurité.

Pour la configuration de Windows il faudra procéder comme suit :

Supposons  que le compte de service utilisé pour le démarrage du service SQL sur le serveur  SQL01 est SvcSQL01 alors il faudra créer un SPN sur ce compte en utilisant la commande suivante :

SETSPN –A MSSQLSvc/SQL01.domain.lan:1433 DOMAIN\SvcSQL01

Pour vérifier que l’SPN a été bien créé on peut exécuter la commande suivante :

SETSPN –L DOMAIN\SvcSQL01

    image

Une fois le nom principal de service créé il faudra approuver le compte SvcSQL01 à la délégation et le compte de la machine  SQL01 à la délégation, ceci se fait via la console Utilisateurs et Ordinateurs Active Directory

Attention : l’onglet “Delegation” n’apparaitra sur le compte SvcSQL01 qu’après avoir créé le nom principal de servie avec la commande SETSPN 

imageimage

On peut vérifier maintenant que la requête ne gènère plus d’erreur comme le montre la figure suivante.

l’exécution de la requête

SELECT session_id, auth_scheme FROM sys.dm_exec_connections nous permet de confirmer l’authentification utilisé pour nitre session est bien KERBEROS 

image

Remarque

Nous avons pu remarquer que si nous créons le nom principal de service avec le nom de l’instance et non le numéro de port d’une instance nommée l’erreur 4861 persiste, il a fallut fixer le port utilisé par l’instance et l’utiliser pour la configuration du nom principal du service lié au compte de service SQL. 

Quest Resource Updating Manager : The RPC server is unavailable

Introduction

La phase de réacélisation d’un serveur est utile lorsque vous avez migré des comptes ou groupes d’un domaine à un autre. Les ACL d’un dossier sont généralement associé à un groupe, lors du déplacement du groupe dans l’autre domaine, l’ACL n’est pas traduite automatiquement. Pour ce faire on utilise un logiciel tel que Quest Migration Manager, plus exactement Quest Resource Updating Manager pour traiter par lot des serveurs contenant des ACL (serveurs de fichiers par exemple).

Lors de la réacélisation d’un parc de serveurs, j’ai été confronté à l’erreur “The RPC Server is unavailable”. Après avoir longtemps cherché, voici les points clés pour résoudre cette erreur.

Résolution

  1. Réinitialiser le serveur cible depuis la console Quest

Exécutez une tache “Cleanup” sur les serveurs cible impactés par cette erreur. Cela aura pour effet de supprimer l’agent installé automatiquement.

  1. Activer NetBIOS over TCP/IP

Pour ce faire, dans les propriétés de la carte réseau, propriétés TCP/IPv4, Avancée…, onglet WINS, choisissez l’option Enable NetBIOS over TCP/IP.

  1. Les règles de pare-feu pour RPC

Le must est de désactiver le pare-feu le temps du traitement. Si ce n’est pas possible, veillez a ce que les règles Remote Administration (RPC) et Remote Service Management (RPC) soient activées dans le profil de votre carte réseau.

  1. Le service RPC

Démarrez le service Remote Procedure Call (RPC).

  1. Le fichier HOST

Dans le fichier HOST de la machine à traiter, ajoutez l’adresse IP et le nom du serveur Quest.

  1. L’agent

L’installation manuelle de l’agent Quest peut aider. En effet j’ai pu remarquer que l’agent déployé automatique via la tâche Discovery ne se lançait pas. Depuis le serveur à traiter, accédez au dossier d’installation de Quest RUM (C:\Program Files (x86)\Common Files\Aelita Shared\Migration Tools\Resource Updating) et installez le package QsResourceUpdatingAgent.msi. Ne pas oublier de changer le compte de service pour le faire correspondre au compte de service Quest, autrement vous aurez l’erreur Access Denied.

Points de vérification :

  1. Sur le serveur cible, exécutez la commande “nbtstat –a <IP_du_serveur_Quest>”. Vous devez obtenir un résultat. Si vous obtenez “Host not found”, vérifiez les points ci dessous.
  2. Dans la console Quest, lancez la tâche Discovery. Vous devez obtenir un statut OK, sans erreur ni avertissements. Une fois que vous avez le statut OK, lancez la tâche de Processing. Patientez et normalement vous devriez voir la progression et un statut OK une fois la tâche terminée.