jeudi 23 août 2018

Quelques billes pour automatiser la préparation d'un serveur en Powershell

Je déploie régulièrement des VM à partir d'un template, seulement il reste pas mal d'opérations à faire à la main, comme le changement de nom, la configuration du réseau, l'installation de certaines applications et paramètres qui redescendent pas forcément par GPO.

Je vais donc présenter plusieurs instructions et snippets Powershell qui pourront fournir une bonne base pour la création d'un script complet pouvant être intégré dans un template et exécuté directement après le déploiement.

Tout d'abord, le changement du nom du serveur. On peut faire quelque chose de sympa comme ceci :

$hostname = $env:computername
Write-Host "Current Server name: $hostname"
$newhostname = Read-Host "New hostname"
Rename-Computer -NewName $newhostname
Write-Host "A reboot is required and will be performed in approx. 10 seconds. The script will automatically start after reboot to continue post-deployment operations."
shutdown -r -t 10

On affiche le nom actuel du serveur, puis un prompt permettant de saisir le nouveau nom de machine. Un reboot permettra de prendre en compte le changement.

Après le redémarrage, on peut passer à la configuration de la carte réseau. En fonction de la configuration de la machine, cela peut être délicat puisqu'il faut être sûr d'affecter l'IP à la bonne carte réseau ; pour cela, on va donc récupérer toutes les cartes réseaux branchées sur le système, puis faire un filtre par nom et qui fonctionnent en IPv4. Par exemple, si la carte réseau s'appelle Ethernet0 :

$ipv4 = Read-Host "IPV4 address"
$gateway = Read-Host "Gateway"
$dnsprim = Read-Host "Primary DNS"
$dnssec = Read-Host "Secondary DNS"

$networkcards = Get-NetIPInterface | Where-Object {$_.InterfaceAlias -eq "Ethernet0" -and $_.AddressFamily -eq "IPv4"}
$interfaceindex = $networkcards[0].ifIndex
New-NetIPAddress -InterfaceIndex $interfaceindex -IPAddress $ipv4 -PrefixLength 24 -DefaultGateway $gateway
Set-DnsClientServerAddress -InterfaceIndex $interfaceindex -ServerAddresses ($dnsprim,$dnssec)

Get-NetIPInterface avec son pipe nous permet de rechercher les interfaces ayant pour nom Ethernet0 et configurées en IPv4. On récupère donc la carte qui est retournée par l'instruction et son index (qui n'est naturellement pas 1, ce serait trop facile !), qui nous permet ensuite de pouvoir le passer en paramètre de l'instruction New-NetIPAddress qui va se charger de coller la configuration IP à la carte. Le masque de sous réseau ne s'exprime pas en 255.255.255.0 mais notation CIDR, soit 24. Des tables de conversion sont facilement accessibles grâce à n'importe quel moteur de recherche, vous pouvez utiliser celle-ci. Si l'instruction est bien passée, elle retournera alors plusieurs informations quant à l'interface.

Ensuite, maintenant que le réseau est configuré, on peut joindre la machine au domaine.

Add-Computer -DomainName "super-domaine.local"
if ($?){ Write-Host "A reboot is required and will be performed in approx. 10 seconds. The script will automatically start after reboot to continue post-deployment operations."
    shutdown -r -t 10 }

Un prompt devrait apparaître pour demander un identifiant et un mot de passe d'un compte autorisé à ajouter des machines au domaine. Si la jonction se fait bien, alors le code dans la boucle if est exécuté et la machine redémarre après environ 10 secondes.

La machine mise sur le domaine, les divers paramètres poussés par GPO devraient redescendre (il faut bien évidemment pas oublier de déplacer l'objet Ordinateur qui s'est créé dans l'AD dans la bonne OU, sinon ça risque de ne pas bien marcher 😱). Cependant, d'autres opérations ou paramètres peuvent être modifiés par Powershell ; en voici quelques-uns.

Autorisation de l'exécution de scripts Powershell sans restriction :

Write-Host "Setting Powershell execution policy to Unrestricted..."
Set-ExecutionPolicy Unrestricted

Désactivation du pare-feu pour le domaine :

Set-NetFirewallProfile -Profile Domain -Enabled False 

Si on souhaite tout automatiser et placer dans un même script, il faut prévoir la phase de reboot suite au changement de nom de la machine et la jonction au domaine (bien que la commande Add-Computer tolère un renommage de la station dans l'instruction). Pour n'utiliser qu'un seul script, et faire en sorte qu'il reprenne exactement là où il s'était arrêté, on peut placer chaque étape dans une fonction, et placer en paramètre facultatif le numéro de l'étape sur laquelle le script démarre ; ensuite une tâche planifiée démarre le script à l'ouverture de session de l'administrateur local.

Déclaration du paramètre :

Param
    ([string]$step)

Ensuite, une fonction pour créer la tâche, qui elle-même va prendre un paramètre :

function createtask{
    param($rebootstep)
        $TaskDetails = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType ServiceAccount -RunLevel Highest
    $TaskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "C:\post-deployment.ps1 -s $rebootstep"
    $TaskSched = New-ScheduledTaskTrigger -AtLogOn
    $TaskName = "PostDeployReboot"
    Register-ScheduledTask -Action $TaskAction -Principal $TaskDetails -Trigger $TaskSched -TaskName $TaskName
}

Et on appelle cette fonction après le renommage de la machine par exemple :

Rename-Computer -NewName $newhostname
createtask(2)

Ainsi, au début du script, on peut placer cette instruction qui appellera la fonction setnetwork dans laquelle le code pour paramétrer la carte réseau sera placé :

if ($step -eq "2") { setnetwork }

La tâche planifiée exécutant le script avec le paramètre -s 2, le script démarrera directement sur cette étape.

Aucun commentaire:

Enregistrer un commentaire