Rinominare Cluster Shared Volumes da VHD Set in guest cluster Hyper‑V con PowerShell

Rinominare i Cluster Shared Volumes (CSV) creati da VHD Set in un guest cluster Hyper‑V su Windows Server può diventare sorprendentemente complesso. In questa guida trovi un metodo affidabile e script PowerShell pronti all’uso per mappare ogni CSV al relativo file .vhds e rinominare in modo coerente risorsa e mount‑point.

Indice

Scenario e sintomi

In un guest cluster Hyper‑V che utilizza VHD Set (.vhds) come storage condiviso, quando si aggiunge il disco condiviso al cluster questo viene convertito in CSV e riceve un nome generico (ad esempio Cluster Disk 1, Cluster Disk 2, …). La cartella di montaggio creata sotto C:\ClusterStorage\ segue lo stesso schema predefinito (Volume1, Volume2, …). Fin qui tutto funziona, ma si presentano tre difficoltà operative:

  • i nomi predefiniti non esprimono cosa contenga il volume (es. Data1, Logs, Quorum), rendendo difficile l’operatività e la conformità agli standard aziendali;
  • PowerShell non mostra a colpo d’occhio la relazione tra il CSV (Cluster Disk X), la sua cartella di montaggio (C:\ClusterStorage\VolumeX) e il file .vhds di origine;
  • automatizzare la rinomina senza conoscere tale relazione può introdurre errori nei failover e negli script di provisioning.

Perché i cmdlet standard non bastano

  • Get-VMHardDiskDrive mostra i dischi virtuali collegati alle VM ma non elenca i VHD Set condivisi.
  • Get-ClusterSharedVolume restituisce stato e mount‑point del CSV, ma non il percorso del file .vhds.
  • rinominare a mano la cartella in C:\ClusterStorage non aggiorna il nome della risorsa del cluster: si perde la coerenza e si moltiplicano gli errori umani.

Mappa delle entità da collegare

  • File VHD Set → un file .vhds su storage accessibile dagli host Hyper‑V;
  • Risorsa disco del cluster → di tipo Shared Virtual Hard Disk con parametro VirtualDiskPath che punta al .vhds;
  • CSV → volume condiviso a cui il cluster assegna un nome (Cluster Disk X) e una cartella di montaggio (C:\ClusterStorage\VolumeX).

Il punto chiave: il legame tra CSV e VHD Set esiste ed è il parametro VirtualDiskPath della risorsa. Una volta ottenuto quel valore, possiamo rinominare sia la risorsa CSV sia la relativa cartella di montaggio in modo coerente e automatizzabile.

Strategia operativa in breve

ObiettivoComando o tecnicaNote
Individuare il file .vhds associatoGet-ClusterResource | Where-Object ResourceType -eq 'Shared Virtual Hard Disk' | ForEach-Object { [pscustomobject]@{ ResourceName = $_.Name VirtualDiskPath = (Get-ClusterParameter -InputObject $_ -Name VirtualDiskPath).Value } }Lo stesso percorso è rintracciabile anche nel registro di un nodo in HKLM\Cluster\Resources<GUID>\Parameters\VirtualDiskPath.
Ottenere il mount‑point del CSV$csv = Get-ClusterSharedVolume -Name 'Cluster Disk 1' $csv.SharedVolumeInfo.FriendlyVolumeName # es. C:\ClusterStorage\Volume1È il percorso visualizzato anche nella GUI del cluster.
Rinominare la risorsa del clusterRename-ClusterResource -Name 'Cluster Disk 1' -NewName 'Data1'Cambia il nome della risorsa; la cartella in C:\ClusterStorage resta invariata.
Allineare la cartella di montaggio$csv = Get-ClusterSharedVolume -Name 'Data1' Get-Item $csv.SharedVolumeInfo.FriendlyVolumeName | Rename-Item -NewName 'Data1'Eseguire a carico nullo per evitare handle aperti; tutti i nodi vedranno subito il nuovo mount‑point.

Ricetta rapida e verifiche di sicurezza

  1. Esegui come amministratore su un nodo del cluster.
  2. Verifica lo stato dei volumi e la proprietà corrente della risorsa. Get-ClusterSharedVolume | Select-Object Name, OwnerNode, State Get-ClusterResource -Name 'Cluster Disk 1' | Format-Table Name, State, OwnerGroup, ResourceType
  3. Controlla che nessuna VM o servizio stia usando percorsi legati al mount‑point che rinominerai. Get-VM | Where-Object { $_.Path -like 'ClusterStorage\Volume1' } | Select-Object Name, Path Consiglio: rinomina subito dopo la creazione del CSV, prima di caricarci dati o VM.
  4. Rinomina risorsa e mount‑point come mostrato sopra.
  5. Conferma che tutti i nodi vedano il nuovo percorso. $nodes = (Get-ClusterNode).Name Invoke-Command -ComputerName $nodes -ScriptBlock { Test-Path 'C:\ClusterStorage\Data1' }

Automazione completa con PowerShell

Di seguito uno script end‑to‑end che:

  • mappa tutti i CSV creati da VHD Set al relativo VirtualDiskPath;
  • applica una naming convention basata sul nome del file .vhds (personalizzabile);
  • rinomina in modo coerente sia la risorsa del cluster sia la cartella di montaggio;
  • offre modalità -WhatIf per il dry‑run e controlli di sicurezza.
function Get-CsvVhdSetMap {
  [CmdletBinding()]
  param()

  $csvs = Get-ClusterSharedVolume
  foreach ($csv in $csvs) {
    $res = Get-ClusterResource -Name $csv.Name -ErrorAction SilentlyContinue
    if (-not $res) { continue }

    $vhdsParam = $res | Get-ClusterParameter -Name VirtualDiskPath -ErrorAction SilentlyContinue
    $vhdsPath  = $vhdsParam.Value

    [pscustomobject]@{
      CsvName          = $csv.Name
      MountPoint       = $csv.SharedVolumeInfo.FriendlyVolumeName.TrimEnd('\')
      ResourceType     = $res.ResourceType
      VirtualDiskPath  = $vhdsPath
      ProposedName     = if ($vhdsPath) {
                           # Esempio di naming convention: base name del file .vhds
                           [IO.Path]::GetFileNameWithoutExtension($vhdsPath)
                         } else {
                           $csv.Name
                         }
    }
  }
}

function Rename-CsvAndMount {
  [CmdletBinding(SupportsShouldProcess)]
  param(
    [Parameter(Mandatory)][string]$CsvName,
    [Parameter(Mandatory)][string]$NewName
  )

  $csv = Get-ClusterSharedVolume -Name $CsvName -ErrorAction Stop
  $oldMount = $csv.SharedVolumeInfo.FriendlyVolumeName.TrimEnd('\')
  $parent   = Split-Path $oldMount -Parent
  $target   = Join-Path $parent $NewName

  if (Test-Path $target) {
    throw "Il mount-point di destinazione esiste già: $target"
  }

  if ($PSCmdlet.ShouldProcess("Risorsa '$($csv.Name)'", "Rename-ClusterResource -> '$NewName'")) {
    Rename-ClusterResource -Name $csv.Name -NewName $NewName -ErrorAction Stop
  }

  if ($PSCmdlet.ShouldProcess("Mount-point '$oldMount'", "Rename-Item -> '$NewName'")) {
    Get-Item -LiteralPath $oldMount | Rename-Item -NewName $NewName -ErrorAction Stop
  }

  # Verifica
  $reloaded = Get-ClusterSharedVolume -Name $NewName
  $ok = $reloaded.SharedVolumeInfo.FriendlyVolumeName.TrimEnd('\') -eq $target
  [pscustomobject]@{
    CsvNameBefore  = $CsvName
    CsvNameAfter   = $NewName
    MountPoint     = $reloaded.SharedVolumeInfo.FriendlyVolumeName
    Verified       = $ok
  }
}

function Invoke-CsvBulkRenameFromVhdSet {
  [CmdletBinding(SupportsShouldProcess)]
  param(
    [ValidateNotNullOrEmpty()][scriptblock]$NameRule = {
      param($vhdsPath)
      # Regola predefinita: nome file .vhds senza estensione (es. Data1.vhds -> "Data1")
      [IO.Path]::GetFileNameWithoutExtension($vhdsPath)
    },
    [switch]$WhatIf
  )

  $map = Get-CsvVhdSetMap | Where-Object { $_.ResourceType -eq 'Shared Virtual Hard Disk' }

  # Normalizza e garantisce unicità dei nomi proposti
  $used = @{}
  foreach ($row in $map) {
    $base = if ($row.VirtualDiskPath) { & $NameRule $row.VirtualDiskPath } else { $row.CsvName }
    $clean = $base -replace '\s+', '' -replace '[^A-Za-z0-9\-]', ''
    if ([string]::IsNullOrWhiteSpace($clean)) { $clean = $row.CsvName }

    $name = $clean
    $i = 1
    while ($used.ContainsKey($name)) {
      $i++
      $name = "{0}_{1}" -f $clean, $i
    }
    $used[$name] = $true
    $row | Add-Member -NotePropertyName FinalName -NotePropertyValue $name
  }

  # Report preliminare
  $report = $map | Select-Object CsvName, MountPoint, VirtualDiskPath, ProposedName, FinalName
  $report | Sort-Object CsvName | Format-Table -AutoSize | Out-String | Write-Verbose

  # Applica rinomina dove necessario
  $results = foreach ($row in $map) {
    if ($row.CsvName -ne $row.FinalName) {
      Rename-CsvAndMount -CsvName $row.CsvName -NewName $row.FinalName -WhatIf:$WhatIf
    } else {
      [pscustomobject]@{
        CsvNameBefore = $row.CsvName
        CsvNameAfter  = $row.CsvName
        MountPoint    = $row.MountPoint
        Verified      = $true
      }
    }
  }

  $results
}

Esempio d’uso:

# Solo anteprima (nessuna modifica)
Invoke-CsvBulkRenameFromVhdSet -WhatIf -Verbose

Applica rinomina secondo la regola predefinita

Invoke-CsvBulkRenameFromVhdSet

Esempio con regola personalizzata: prefisso aziendale e indice

Invoke-CsvBulkRenameFromVhdSet -NameRule {
param($vhdsPath)
$base = [IO.Path]::GetFileNameWithoutExtension($vhdsPath)
"PRD_{0}" -f $base
}

Workflow consigliato per il provisioning

Per evitare rinome manuali successive e mantenere massima coerenza, integra la rinomina subito nel processo di provisioning del disco condiviso:

  1. Creazione del VHD Set New-VHD -Path 'X:\ClusterDisks\Data1.vhds' -VHDType Fixed -SetType Shared -SizeBytes 200GB
  2. Collegamento alle VM del guest cluster Add-VMHardDiskDrive -VMName 'SQL-01' -Path 'X:\ClusterDisks\Data1.vhds' -ShareVirtualDisk Add-VMHardDiskDrive -VMName 'SQL-02' -Path 'X:\ClusterDisks\Data1.vhds' -ShareVirtualDisk
  3. Conversione in CSV della risorsa disco $svhd = Get-ClusterResource | Where-Object ResourceType -eq 'Shared Virtual Hard Disk' | Where-Object { (Get-ClusterParameter -InputObject $_ -Name VirtualDiskPath).Value -eq 'X:\ClusterDisks\Data1.vhds' } Add-ClusterSharedVolume -Name $svhd.Name
  4. Rinomina immediata di risorsa e mount‑point Rename-ClusterResource -Name $svhd.Name -NewName 'Data1' $csv = Get-ClusterSharedVolume -Name 'Data1' Get-Item $csv.SharedVolumeInfo.FriendlyVolumeName | Rename-Item -NewName 'Data1'

Verifiche post‑attività

  • stato CSV e proprietà: Get-ClusterSharedVolume | Select-Object Name, OwnerNode, State
  • parametro VirtualDiskPath ancora coerente: Get-ClusterResource -Name 'Data1' | Get-ClusterParameter VirtualDiskPath
  • accesso da tutti i nodi: $mp = (Get-ClusterSharedVolume -Name 'Data1').SharedVolumeInfo.FriendlyVolumeName Invoke-Command -ComputerName (Get-ClusterNode).Name -ScriptBlock { param($p) Test-Path $p } -ArgumentList $mp

Considerazioni importanti prima della rinomina

  • Finestra di manutenzione: rinomina quando il carico è fermo; evita handle aperti su file all’interno del volume.
  • Impatto sui percorsi: la rinomina del mount‑point cambia il percorso logico (ad es. da C:\ClusterStorage\Volume1\... a C:\ClusterStorage\Data1\...). Aggiorna eventuali script, job o configurazioni che hardcodano il percorso.
  • Idempotenza: gli script sopra saltano i volumi già allineati; puoi rieseguirli in sicurezza.
  • Backup del database cluster: prima di modifiche su larga scala è prudente eseguire un backup del cluster DB.
  • Ruolo del nodo: non è obbligatorio, ma spesso è più lineare eseguire la rinomina sul nodo proprietario della risorsa.

Indizi utili nel registro

Se i parametri della risorsa non risultano disponibili via cmdlet (raro, ma possibile in ambienti con policy restrittive), puoi ricavare il percorso del VHD Set dal registro:

$res = Get-ClusterResource -Name 'Cluster Disk 1'
$guid = $res.Id
$regPath = "HKLM:\Cluster\Resources\{0}\Parameters" -f $guid
Get-ItemProperty -Path $regPath -Name VirtualDiskPath

Questo conferma la mappatura tra CSV e file .vhds anche quando gli strumenti standard non la esibiscono chiaramente.

Checklist di controllo qualità

  • Naming convention decisa e approvata (prefissi, suffissi, caratteri consentiti).
  • Unicità verificata: nessun doppione di nomi nel cluster.
  • Coerenza tra nome risorsa e nome cartella di montaggio.
  • Monitoraggio: aggiorna le sonde che leggono i counter partendo da percorsi CSV.
  • Documentazione: annota il legame VirtualDiskPathCsvName nella CMDB o nel repository del team.

Diagnostica e ripristino

Se qualcosa non torna dopo la rinomina:

  1. controlla che il mount‑point esista e punti al volume corretto: Get-ClusterSharedVolume -Name 'Data1' | Select-Object -ExpandProperty SharedVolumeInfo
  2. verifica che nessun file sia bloccato nel vecchio percorso (usa open files o Handle.exe se necessario).
  3. come ripiego, puoi tornare al nome precedente sia sulla risorsa che sulla cartella e riprovare nella prossima finestra.

Alternative architetturali

Se l’obiettivo primario è disporre di volumi condivisi maneggevoli in guest cluster, valuta l’adozione di Storage Spaces Direct. Vantaggi pratici:

  • nessun VHD Set da gestire, meno componenti da orchestrare;
  • volumi creati e rinominati nativamente con New-Volume e Rename-Volume;
  • migliore integrazione con resilienza e performance lato host, riducendo la complessità negli script.

Domande frequenti

Posso rinominare solo la cartella in C:\ClusterStorage?
Tecnicamente sì, ma è sconsigliato: rimarrebbe disallineata dal nome della risorsa del cluster. Allinea sempre entrambi.

La rinomina influisce su dischi non basati su VHD Set?
Gli script saltano i volumi senza VirtualDiskPath. Per altre tipologie (es. pass‑through) va predisposta una logica ad hoc.

La rinomina interrompe l’I/O?
La modifica del nome risorsa è istantanea; la rinomina del mount‑point è un’operazione sul file system. Esegui a carico nullo e verifica che non ci siano processi con handle aperti nei percorsi interessati.

Conclusioni operative

La difficoltà nel rinominare CSV creati da VHD Set nasce più dalla scarsa visibilità della relazione tra oggetti che da un limite tecnico. Identificando il parametro VirtualDiskPath nella risorsa di tipo Shared Virtual Hard Disk e usando PowerShell per orchestrare la rinomina di risorsa e mount‑point, ottieni un processo ripetibile, sicuro e conforme allo standard aziendale. Integra questa logica direttamente nel provisioning dei dischi condivisi e avrai ambienti più ordinati, script più semplici e meno sorprese durante i failover.


Esempio di playbook sintetico

# 1) Inventario e mappatura
Get-CsvVhdSetMap | Format-Table -AutoSize

2) Dry run

Invoke-CsvBulkRenameFromVhdSet -WhatIf -Verbose

3) Esecuzione

Invoke-CsvBulkRenameFromVhdSet

4) Verifica da tutti i nodi

$mp = (Get-ClusterSharedVolume -Name 'Data1').SharedVolumeInfo.FriendlyVolumeName
Invoke-Command -ComputerName (Get-ClusterNode).Name -ScriptBlock { param($p) Test-Path $p } -ArgumentList $mp

Risultato: CSV con nomi parlanti (Data1, Logs, …), mount‑point coerenti (C:\ClusterStorage\Data1, ...\Logs), processi di failover più leggibili e meno rischi d’errore.

In caso di ambienti in crescita o con requisiti elevati su resilienza e prestazioni, prendi in considerazione l’adozione di Storage Spaces Direct per semplificare ulteriormente il modello operativo eliminando i VHD Set dal percorso critico.


In sintesi
Il legame tra CSV e file VHD Set non è immediato ma esiste: si trova nel parametro VirtualDiskPath della risorsa di tipo Shared Virtual Hard Disk. Una volta recuperato, si possono rinominare in modo coerente sia la risorsa CSV sia la relativa cartella di montaggio. Automatizzare questo workflow con PowerShell (oppure migrare a S2D) elimina la necessità di interventi manuali e riduce il rischio di errori nei failover.

Indice