Have you ever had to find dependencies in a Recovery Plan using a SQL Query?

I have several reports that are either focused on SRM or they include SRM information. It is easy to get the group and plan information for a given machine, but finding where the dependencies are was not the easiest thing to find. I searched the Internet and found nothing. I searched the database and found "dependentvmmoids" in the recovery settings table, but it wasn't clear what that value was. I ran a trace using the Profiler utility and saw it hitting the g_string_array table many times, but that didn't tell me much. Since I found no information on this via Internet search I thought I would share it here so that others don't have such a hard time getting this information.

The profiler trace will show you the select statements against the string table that occur while you are browsing SRM information in the web client, but they be of any value. In order to capture where this stuff actually lives it is necessary to alter a recovery plan and add a dependency. Once I did that I was able to find how the system stores this information. Below is the insert statement that was executed when I added a dependency to a particular VM and saved the record:

declare @p1 int

set @p1=NULL

exec sp_prepexec @p1 output,N'@P1 int,@P2 ntext,@P3 int,@P4 int,@P5 int,@P6 ntext,@P7 int,@P8 int,@P9 int,@P10 ntext,@P11 int,@P12 int',N'INSERT INTO g_string_array SELECT @P1, @P2, @P3, @P4 UNION ALL  SELECT @P5, @P6, @P7, @P8 UNION ALL  SELECT @P9, @P10, @P11, @P12',440804,N'protected-vm-23105',0,1,440804,N'protected-vm-27551',1,1,440804,N'protected-vm-435668',2,1

select @p1

435668 is the ID of the dependency I added and the others are the existing records. It seems the system creates a new record set for all the dependents for a given VM and in this case the SEQ_ID is 440804. In the table pdr_vmrecoverysettings there is a column named "dependentvmmoids" that is updated with that SEQ_ID. This is how you join a VM to the dependencies.

The query below will return information about plans and groups and the associated VMs and will include the dependencies as a single field. I'm sure this query could be written better, but the point is to provide an example of how to get this information without having to use PowerCLI or Powershell. I hope it helps.

;with CTE_Depends as (select Seq_ID, Replace(convert(varchar(100),String_Val),'protected-vm-','') as VMLinker,

                            Name as DepName, g_string_array.Array_Index, g_string_array.Ref_Count

                        from .[VCSRM].[dbo].g_string_array inner join .[VCSRM].[dbo].[pdr_placeholdervm]

                            on Replace(convert(varchar(100),String_Val),'protected-vm-','') = replace(convert(varchar(100),MO_ID),'protected-vm-','')

                        where convert(varchar(100),String_Val) like 'protected-vm%'),

CTE_P2R as (SELECT PP.[db_id], PP.[mo_id], PP.[name], PP.[description], PP.[contents],

                    PC.ProtectionGroups-1 as Mapper, PGM.LocalGroupMoid

                    FROM .[VCSRM].[dbo].[pdr_planproperties] PP inner join .[VCSRM].[dbo].[pdr_plancontents] PC

                        on PP.[contents]= PC.DB_ID

                    inner join .[VCSRM].[dbo].[pdr_protectiongroupmap] PGM

                        on PGM.DB_ID= PC.ProtectionGroups-1)

,CTE_Final as (SELECT replace(PV.Mo_ID,'protected-vm-','') as VMIF, [dependentvmmoids] as DependentKey,

                cast(PG.[mo_id] as varchar) as [mo_id], cast(PG.[name] as varchar) as PGName,

                cast(PG.[description] as varchar) as PGDesc, cast(CTE_P2R.[mo_id] as varchar) as RPMO_ID,

                cast(CTE_P2R.[name] as varchar) as RPName, cast(CTE_P2R.[description] as varchar) as RPDesc,

                cast(PH.Name as varchar) as VMName, cast(PH.ProductionVMMoid as varchar) as VMID,

                case [recoverypriority]

                    when 25 then 1 when 40 then 2 when 50 then 3 when 60 then 4 when 75 then 5 end as [recoverypriority]

            FROM .[VCSRM].[dbo].[pdr_protectiongroup] PG inner join .[VCSRM].[dbo].[pdr_protectedvm] PV  

                on PG.[mo_id] = convert(varchar,PV.[ParentGroupMoid])

            inner join .[VCSRM].[dbo].[pdr_placeholdervm] PH

                on PV.[mo_id] = PH.[mo_id]  

            inner join .[VCSRM].[dbo].[pdr_vmrecoverysettings] VR

                on replace(VR.[protectedvmmoidint],'protected-vm-','') = replace(convert(varchar,PH.[mo_id]),'protected-vm-','')

            inner join CTE_P2R

                on cast(CTE_P2R.LocalGroupMoid as varchar) = cast(PG.[mo_id] as varchar))

select case when len(RU.EmailTo)=0 then null else  left(RU.EmailTo,LEN(RU.EmailTo)-1) end as Dependents,


from CTE_Final

CROSS APPLY (SELECT convert(varchar(100),DepName)+ ';'

                    FROM CTE_Depends t2

                    where DependentKey = Seq_ID

                FOR XML PATH('')) as RU(EmailTo)

order by RecoveryPriority, VMName


0 Kudos
0 Replies