Migration de la définition des shares Windows

C'est ballot, mais Robocopy est incapable de faire une copie d'un répertoire en conservant son statut de répertoire partagé et les détails associés. Lorsqu'on migre un serveur de fichiers avec par exemple des homedirs, il faut donc transférer les dossiers vers le nouveau avec Robocopy, puis ensuite, appliquer les partages. Plutôt contraignant si il y a des centaines de répertoires à refaire.

Heureusement, si le serveur d'origine et de destination ont exactement la même configuration disque et les mêmes chemins, il est possible d'extraire la définition des shares et donc de l'importer sur le nouveau serveur pour que les répertoires soient de nouveau partagés.

La clef HKLM\System\CurrentControlSet\Services\LanmanServer\Shares contient ces définitions :

Ces clés contiennent le nom du partage, ainsi que d'autres informations (chemin, description)... Il est donc important que les chemins concordent ; en effet, ouvrir le fichier .reg contenant la clef et ses valeurs avec un éditeur de texte ne permettra pas une modification directe.

Un redémarrage est nécessaire après l'import de la clef sur le nouveau serveur afin que les partages soient visibles dans la console Computer Management.

Fausse alerte de quota maximal atteint sur un répertoire partagé

J'ai eu le cas aujourd'hui d'un répertoire partagé limité par un quota d'1 Go sur un serveur Windows 2008 R2 qui était considéré comme plein par la station de travail l'ayant monté alors que la taille des fichiers présents n'excède pas 200 Mo. Un démontage et remontage du répertoire ainsi qu'un redémarrage de la station n'ayant rien changé, je me suis connecté sur le serveur pour vérifier l'occupation réelle du répertoire : même résultat que sur la station cliente, et pourtant, dans la console des partages, j'obtiens un espace libre de 670 Ko.

Afin de forcer un rafraîchissement des données du quota, il existe l'outil utilisable en ligne de commande dirquota qui est installé en même temps que le rôle de serveurs de fichiers. Pour rafraîchir le quota du répertoire, en assumant que son chemin local soit C:\sharesengue :

dirquota quota scan /path:C:\sharesengue

Ensuite, un petit tour dans la console permet de voir que le quota a bien été mis à jour et qu'on ne se fera plus jeter par l'OS client pour cause d'espace disque insuffisant :

Powershell : obtention de la taille d'un share

Voici un petit script Powershell permettant de récupérer la taille d'un ou plusieurs share.

Ce script peut être appelé de deux manières :

  • sans arguments : le script va chercher un fichier texte dans le répertoire d’exécution pour passer sur TOUS les répertoires indiqués dans le fichier (un partage par ligne) ; le but est donc de renseigner tous les partages pour lesquels on souhaite connaître la volumétrie dans le fichier. Le script retourne ensuite un fichier CSV :
  •  avec des arguments : en donnant en argument d’exécution du script le serveur et le partage, on récupère la taille dans la console directement :

param([string]$shareHost, [string]$shareName)

function folderSize()
{
param($path)
try {
$byteSize = (Get-ChildItem -path "$path" -Recurse -ErrorAction SilentlyContinue | Measure-Object Length -sum).Sum
if ($byteSize.ToString().Length -lt 4) { return "$byteSize B." }
if ($byteSize.ToString().Length -ge 4 -and $byteSize.ToString().Length -lt 7) { $kbSize = [math]::Round($byteSize/1024,1) ; return "$kbSize KB." }
if ($byteSize.ToString().Length -ge 7 -and $byteSize.ToString().Length -lt 10) { $mbSize = [math]::Round($byteSize/1048576,1) ; return "$mbSize MB." }
if ($byteSize.ToString().Length -ge 10 -and $byteSize.ToString().Length -lt 13) { $gbSize = [math]::Round($byteSize/1073741824,1) ; return "$gbSize GB." }
if ($byteSize.ToString().Length -ge 13) { $tbSize = [math]::Round($byteSize/1099511627776,2) ; return "$tbSize TB." }
}
catch { return "Share doesn't exist or is unreachable or you don't have the required privileges." }
}

Write-Host "Share size retriever Powershell script"
Write-Host "======================================"
Write-Host "Usage: .\win_foldersize.ps1 <SERVER> <SHARE>"
Write-Host "If any parameter is missing, the script will look for a sharelist.txt file in the execution folder and will detect the size of all the folders inside the file."

if ($shareHost -eq "" -or $shareName -eq "")
{
Write-Host "You didn't provide both parameters while running the script. I will now try to read directly the shares from sharelist.txt in the script folder."
$today = Get-Date -f "yyMMdd"
$CsvOutputFile = "share-size-$today.csv"
$InputFile = "sharelist.txt"
$CsvHeader = "Share,Size"
Add-Content $CsvOutputFile $CsvHeader
try { $ShareList = Get-Content $InputFile -ErrorAction Stop }
catch { Write-Host "Unable to read sharelist.txt. Aborting." ; break }
foreach ($Share in $ShareList)
{
$sizeDump = folderSize($Share)
$Dump = "$Share,$sizeDump"
Add-Content $CsvOutputFile $Dump
}
Write-Host "Done, output file : $CsvOutputFile"
}
else {
Write-Host "Both parameters detected."
Write-Host "Server specified: $shareHost"
Write-Host "Share: $shareName"
$shareString = "\\"+"$shareHost"+"\"+"$shareName"
$displaySize = folderSize($shareString)
Write-host $displaySize
}

Une version commentée du script est disponible en téléchargement. 💾