Say you want to use the DPM “SAN recovery” option. This requires storage management steps for which it is useful to know which Windows disks (LUN’s) hold the associated DPM volumes for a given data source. First a generic recap of the potential ‘DPM SAN recovery’ advantages and steps;
Note: during this operation DPM likely synchronized other (unrelated) data sources that happen to have protected data on the same DPM storage pool disks. Therefore we need be careful removing the hardware snapshot, let’s examine that a bit closer.
Suppose we are recovering a data source represented by “V2” in the illustration below which requires a hardware snapshot of “Disk-1”. Say we successfully complete the SAN recovery between T0 and T1 but in that time-span DPM may also execute protection jobs and apply changes to unrelated data sources represented by “V1” and “V3” also on “Disk-1”. For this discussion it does not really matter whether these volumes are replica or recovery point volumes or a combination.
Typically we want to release the hardware resources (reserved LUN’s) by removing the no longer needed hardware snapshot. This has 2 possible results;
DPM allocates replica and recovery point volumes on different disks (if possible) and DPM volumes may span disks like “V3” above. So, which disks do you need to snap? To help with this you can use the script posted below that reports for each data source which ‘NTdisks’ (as in Disk Manager) and Windows volume ID’s are involved. If a suitable hardware VSS provider is installed and configured on DPM and target server this can be used to automate the entire recovery (particularly step 3 and 4 above) but is outside the scope of this blog.
Cut & past the script text between “#begin script” and “#end script” into a Powershell script to run in the DPM Management Shell; say “MyScript,Ps1” as shown below.
If you run this script like:
.\Myscript.Ps1 | format-list
you get output for each data source similar to the screenshot below;
If you run this script like:
$mydata = .\Myscript.Ps1
$mydata will be an array each element of which has the following properties;
- Datasource : description of the data source
- NTdisks : comma separated list of disk manager numbers (3,2)
- Inactive : whether or not it is an inactive data source on disk
- Replica : Replica volume ID you could use with DISKSHADOW
- Diff : Recovery point volume ID you could use with DISKSHADOW
#begin script
function GetDpmMP {
param([string]$volumetype = "ShadowCopy" )
# Get DPM mount points by type: Diffarea or Replica or Shadowcopy, defaults to shadowcopy
# (parsing mountvol appreared most predictable across windows versions and conditions)
# builds $Vols array of $dpmmp structures
# <obj>.Target = volume ident in format \\?\Volume{guid} without trailing slash
# <obj>.Path = mount point path including trailing slash
switch ($volumetype) {
ShadowCopy {$paths = @(mountvol | ?{($_ -match "Microsoft DPM") -and ($_ -match "ShadowCopy") }) }
Replica {$paths = @(mountvol | ?{($_ -match "Microsoft DPM") -and ($_ -match "Replica") }) }
Diffarea {$paths = @(mountvol | ?{($_ -match "Microsoft DPM") -and ($_ -match "Diffarea") }) }
Default {$paths = @(mountvol | ?{($_ -match "Microsoft DPM") -and ($_ -match "ShadowCopy") }) }
}
$paths = $paths | ?{$_} #ensure no blanks
if ($paths.Count -lt 1) {
if ($skipdpmbackup) {Throw "No volume paths found, run at least once without -SkipDPMBackup switch"}
Throw "No $volumetype paths found!"
}
#Ensure we have unique paths to query volumes for
$paths = @($paths | sort -Unique)
#build array of target volumes and paths
$Vols = @()
foreach ($p in $paths) {
$dpmmp = "" | Select Target, Path
#retrieve volume for path
$dpmmp.Target=(mountvol ("`"{0}`" /L" -f , $p.trimend("\").trim())).trimend("\").trim()
$dpmmp.Path=$p.trim()
$Vols += $dpmmp
}
return $Vols
}
$dss = @(Get-ProtectionGroup (&hostname) | foreach {Get-Datasource $_})
$dss += Get-Datasource (&hostname) -Inactive
$disks = Get-DPMDisk (&hostname)
$dpmvols = GetDpmMp "Replica"
$dpmdiffs = GetDpmMp "Diffarea"
$list=@()
foreach ($ds in $dss) {
$item = "" | select Datasource, NTdisks, Inactive, Replica, Diff
$item.Replica = ($dpmvols | ? {$_.path -match $ds.AssociatedReplica.PhysicalReplicaId}).Target
$item.Diff = ($dpmdiffs | ? {$_.path -match $ds.AssociatedReplica.PhysicalReplicaId}).Target
$item.Inactive = $ds.IsDiskInactive
$item.Datasource = "$($ds.DisplayPath) on $($ds.ProductionServername)"
$item.NTdisks = (($disks | ?{ ($_.PgMember | select DatasourceId) -match $ds.Id}) | foreach {$_.NtdiskId}) -join ","
$list += $item
}
return $list
#end script
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.