{"id":195,"date":"2009-08-07T08:15:58","date_gmt":"2009-08-07T13:15:58","guid":{"rendered":"http:\/\/nukeitmike.com\/blog\/2009\/08\/07\/follow-up-to-the-dpm-recovery-point-expiration-issues\/%20"},"modified":"2009-08-07T08:15:58","modified_gmt":"2009-08-07T13:15:58","slug":"follow-up-to-the-dpm-recovery-point-expiration-issues","status":"publish","type":"post","link":"https:\/\/blog.nukeitmike.com\/index.php\/2009\/08\/07\/follow-up-to-the-dpm-recovery-point-expiration-issues\/","title":{"rendered":"Follow up to the DPM recovery point expiration issues"},"content":{"rendered":"<p>Previously, I blogged about issues I was having where old recovery points were not being expired\/removed from my DPM servers.&#160; I had to open a ticket with Microsoft, and worked with them to determine the cause, and since then, they have released a fix.<\/p>\n<p>The fix that Microsoft developed is here: <a href=\"http:\/\/www.microsoft.com\/downloads\/details.aspx?FamilyID=aee949aa-d3e7-4b0f-b718-00b7c20f1257&amp;displayLang=en\">http:\/\/www.microsoft.com\/downloads\/details.aspx?FamilyID=aee949aa-d3e7-4b0f-b718-00b7c20f1257&amp;displayLang=en<\/a><\/p>\n<p>A few people have asked for the PowerShell script \u201cshow-pruneshadowcopies.ps1\u201d that Microsoft provided and I mentioned in my previous post <a href=\"http:\/\/nukeitmike.com\/blog\/2009\/04\/12\/dpm-does-not-remove-expired-recovery-points\/\" target=\"_blank\" rel=\"noopener\">(here)<\/a>.&#160; The script looks like this:<\/p>\n<blockquote>\n<p>#displays all RP for data sources and shows which RP&#8217;s would be deleted by the regular pruneshadowcopies.ps1      <br \/># Outputs to a logfile:&#160; C:\\Program Files\\Microsoft DPM\\DPM\\bin\\SHOW-PRUNESHADOWCOPIES.LOG <\/p>\n<p>#Author&#160;&#160;&#160; : Mike J     <br \/>#Date&#160;&#160;&#160; : 02\/24\/2009      <br \/>$version=&quot;V1.0&quot; <\/p>\n<p>$date=get-date     <br \/>$logfile=&quot;SHOW-PRUNESHADOWCOPIES.LOG.txt&quot; <\/p>\n<p>function GetDistinctDays([Microsoft.Internal.EnterpriseStorage.Dls.UI.ObjectModel.OMCommon.ProtectionGroup] $group,      <br \/>[Microsoft.Internal.EnterpriseStorage.Dls.UI.ObjectModel.OMCommon.Datasource] $ds)      <br \/>{&#160;&#160;&#160; <br \/>&#160;&#160;&#160; if($group.ProtectionType -eq [Microsoft.Internal.EnterpriseStorage.Dls.UI.ObjectModel.OMCommon.ProtectionType]::DiskToTape)      <br \/>&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; return 0      <br \/>&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160; $scheduleList = get-policyschedule -ProtectionGroup $group -ShortTerm      <br \/>&#160;&#160;&#160; if($ds -is [Microsoft.Internal.EnterpriseStorage.Dls.UI.ObjectModel.FileSystem.FsDataSource])      <br \/>&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; $jobType = [Microsoft.Internal.EnterpriseStorage.Dls.Intent.JobTypeType]::ShadowCopy      <br \/>&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160; else      <br \/>&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; $jobType = [Microsoft.Internal.EnterpriseStorage.Dls.Intent.JobTypeType]::FullReplicationForApplication      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; if($ds.ProtectionType -eq [Microsoft.Internal.EnterpriseStorage.Dls.Intent.ReplicaProtectionType]::ProtectFromDPM)      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return 2      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160; write-host&#160;&#160; &quot;Look for jobType $jobType&quot; <\/p>\n<p>&#160;&#160;&#160; foreach($schedule in $scheduleList)     <br \/>&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; write-host(&quot;schedule jobType {0}&quot; -f $schedule.JobType)      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; if($schedule.JobType -eq $jobType)      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return [Math]::Ceiling(($schedule.WeekDays.Length * $ds.RecoveryRangeinDays) \/ 7)      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160; } <\/p>\n<p>&#160;&#160;&#160; return 0     <br \/>} <\/p>\n<p>function IsShadowCopyExternal($id)     <br \/>{      <br \/>&#160;&#160;&#160; $result = $false; <\/p>\n<p>&#160;&#160;&#160; $ctx = New-Object -Typename Microsoft.Internal.EnterpriseStorage.Dls.DB.SqlContext      <br \/>&#160;&#160;&#160; $ctx.Open() <\/p>\n<p>&#160;&#160;&#160; $cmd = $ctx.CreateCommand()     <br \/>&#160;&#160;&#160; $cmd.CommandText = &quot;select COUNT(*) from tbl_RM_ShadowCopy where shadowcopyid = &#8216;$id&#8217;&quot;&#160;&#160; <br \/>&#160;&#160;&#160; write-host $cmd.CommandText      <br \/>&#160;&#160;&#160; $countObj = $cmd.ExecuteScalar()      <br \/>&#160;&#160;&#160; write-host $countObj      <br \/>&#160;&#160;&#160; if ($countObj -eq 0)      <br \/>&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; $result = $true      <br \/>&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160; $cmd.Dispose()      <br \/>&#160;&#160;&#160; $ctx.Close() <\/p>\n<p>&#160;&#160;&#160; return $result     <br \/>} <\/p>\n<p>function IsShadowCopyInUse($id)     <br \/>{      <br \/>&#160;&#160;&#160; $result = $true; <\/p>\n<p>&#160;&#160;&#160; $ctx = New-Object -Typename Microsoft.Internal.EnterpriseStorage.Dls.DB.SqlContext      <br \/>&#160;&#160;&#160; $ctx.Open() <\/p>\n<p>&#160;&#160;&#160; $cmd = $ctx.CreateCommand()     <br \/>&#160;&#160;&#160; $cmd.CommandText = &quot;select ArchiveTaskId, RecoveryJobId from tbl_RM_ShadowCopy where ShadowCopyId = &#8216;$id&#8217;&quot;&#160;&#160; <br \/>&#160;&#160;&#160; write-host $cmd.CommandText      <br \/>&#160;&#160;&#160; $reader = $cmd.ExecuteReader()      <br \/>&#160;&#160;&#160; while($reader.Read())      <br \/>&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; if ($reader.IsDBNull(0) -and $reader.IsDBNull(1))      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; $result = $false      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160; }       <br \/>&#160;&#160;&#160; $cmd.Dispose()      <br \/>&#160;&#160;&#160; $ctx.Close() <\/p>\n<p>&#160;&#160;&#160; return $result     <br \/>} <\/p>\n<p>&quot;**********************************&quot; &gt; $logfile     <br \/>&quot;Version $version&quot; &gt;&gt; $logfile      <br \/>get-date &gt;&gt; $logfile <\/p>\n<p>$dpmservername = &amp;&quot;hostname&quot; <\/p>\n<p>$dpmsrv = connect-dpmserver $dpmservername <\/p>\n<p>if (!$dpmsrv)     <br \/>{      <br \/>&#160;&#160;&#160; write-host &quot;Unable to connect to $dpmservername&quot;      <br \/>&#160;&#160;&#160; exit 1      <br \/>} <\/p>\n<p>write-host $dpmservername     <br \/>&quot;Selected DPM server = $DPMservername&quot; &gt;&gt; $logfile      <br \/>$pgList = get-protectiongroup $dpmservername      <br \/>if (!$pgList)      <br \/>{      <br \/>&#160;&#160;&#160; write-host&#160;&#160; &quot;No PGs found&quot;      <br \/>&#160;&#160;&#160; disconnect-dpmserver $dpmservername      <br \/>&#160;&#160;&#160; exit 2      <br \/>} <\/p>\n<p>write-host(&quot;Number of ProtectionGroups = {0}&quot; -f $pgList.Length)     <br \/>$replicaList = @{}      <br \/>$latestScDateList = @{} <\/p>\n<p>foreach($pg in $pgList)     <br \/>{      <br \/>&#160;&#160;&#160; $dslist = get-datasource $pg      <br \/>&#160;&#160;&#160; if ($dslist.length -gt 0)      <br \/>&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160; write-host(&quot;Number of datasources in this PG = {0}&quot; -f $dslist.length)      <br \/>&#160;&#160;&#160; (&quot;Number of datasources in this PG = {0}&quot; -f $dslist.length) &gt;&gt; $logfile      <br \/>&#160;&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160; Foreach ($ds in $dslist)      <br \/>&#160;&#160;&#160; {       <br \/>&#160;&#160;&#160;&#160;&#160;&#160; write-host(&quot;DS NAME=&#160; $ds&quot;)      <br \/>&#160;&#160;&#160;&#160;&#160;&#160; (&quot;DS NAME=&#160; $ds&quot;) &gt;&gt;$logfile      <br \/>&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160; foreach ($ds in $dslist)      <br \/>&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; $rplist = get-recoverypoint $ds | where { $_.DataLocation -eq &#8216;Disk&#8217; }      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; write-host(&quot;Number of recovery points for $ds {0}&quot; -f $rplist.length)      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; (&quot;Number of recovery points for $ds {0}&quot; -f $rplist.length) &gt;&gt;$logfile&#160; <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; $countDistinctDays = GetDistinctDays $pg $ds      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; write-host(&quot;Number of days with fulls = $countDistinctDays&quot;)      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; (&quot;Number of days with fulls = $countDistinctDays&quot;) &gt;&gt;$logfile      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; if($countDistinctDays -eq 0)      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; write-host&#160;&#160; &quot;D2T PG. No recovery points to delete&quot;      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;D2T PG. No recovery points to delete&quot; &gt;&gt;$logfile       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; continue;      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; $replicaList[$ds.ReplicaPath] = $ds.RecoveryRangeinDays      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; $latestScDateList[$ds.ReplicaPath] = new-object DateTime 0,0      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; $lastDayOfRetentionRange = ([DateTime]::UtcNow).AddDays($ds.RecoveryRangeinDays * -1);&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; write-host(&quot;Distinct days to count = {0}. LastDayOfRetentionRange = {1} &quot; -f $countDistinctDays, $lastDayOfRetentionRange)      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; (&quot;Distinct days to count = {0}. LastDayOfRetentionRange = {1} &quot; -f $countDistinctDays, $lastDayOfRetentionRange) &gt;&gt;$logfile      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; $distinctDays = 0;      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; $lastDistinctDay = (get-Date).Date      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; $numberOfRecoveryPointsDeleted = 0 <\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; if ($rplist)     <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; foreach ($rp in ($rplist | sort-object -property UtcRepresentedPointInTime -descending))      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if ($rp)      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if ($rp.UtcRepresentedPointInTime.Date -lt $lastDistinctDay)      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; $distinctDays += 1      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; $lastDistinctDay = $rp.UtcRepresentedPointInTime.Date      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; write-host(&quot; $ds&quot;)      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (&quot; $ds&quot;) &gt;&gt;$logfile      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; write-host(&quot;&#160; Recovery Point #$distinctdays RPtime={0}&quot; -f $rp.UtcRepresentedPointInTime)      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (&quot;&#160; Recovery Point #$distinctdays RPtime={0}&quot; -f $rp.UtcRepresentedPointInTime) &gt;&gt;$logfile       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (($distinctDays -gt $countDistinctDays) -and ($rp.UtcRepresentedPointInTime -lt $lastDayOfRetentionRange))      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; write-host (&quot;Recovery Point would be deleted ! &#8211; RPtime={0}&quot; -f $rp.UtcRepresentedPointInTime)&#160; -foregroundcolor red      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (&quot;Recovery Point would be deleted ! &#8211; RPtime={0} &lt;&lt;&lt;&lt;&lt;&lt;&lt;&quot; -f $rp.UtcRepresentedPointInTime) &gt;&gt;$logfile      <br \/>#remove-recoverypoint $rp -ForceDeletion -confirm:$true | out-null      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; $numberOfRecoveryPointsDeleted += 1      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; write-host &quot;&#160;&#160;&#160; Recovery point not expired yet&quot;      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;&#160;&#160;&#160; Recovery point not yet expired&quot; &gt;&gt;$logfile      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; write-host &quot;Got a NULL rp&quot;      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;Got a NULL rp&quot; &gt;&gt;$logfile       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;&#160;&#160; <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } <\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; write-host &quot;Number of RPs that would be deleted = $numberOfRecoveryPointsDeleted&quot;&#160;&#160; <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;Number of RPs that would be deleted = $numberOfRecoveryPointsDeleted&quot; &gt;&gt;$logfile&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160; }      <br \/>} <\/p>\n<p>disconnect-dpmserver $dpmservername     <br \/>write-host &quot;Exiting from script&quot; <\/p>\n<p>exit <\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Previously, I blogged about issues I was having where old recovery points were not being expired\/removed from my DPM servers.&#160; I had to open a ticket with Microsoft, and worked with them to determine the cause, and since then, they have released a fix. The fix that Microsoft developed is here: http:\/\/www.microsoft.com\/downloads\/details.aspx?FamilyID=aee949aa-d3e7-4b0f-b718-00b7c20f1257&amp;displayLang=en A few people&hellip; <a class=\"more-link\" href=\"https:\/\/blog.nukeitmike.com\/index.php\/2009\/08\/07\/follow-up-to-the-dpm-recovery-point-expiration-issues\/\">Continue reading <span class=\"screen-reader-text\">Follow up to the DPM recovery point expiration issues<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[6,17,33],"tags":[80,120,135,184],"class_list":["post-195","post","type-post","status-publish","format-standard","hentry","category-data-protection-manager","category-microsoft","category-system-center","tag-dpm","tag-microsoft","tag-powershell","tag-updates","entry"],"jetpack_featured_media_url":"","jetpack-related-posts":[],"jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pcW544-39","_links":{"self":[{"href":"https:\/\/blog.nukeitmike.com\/index.php\/wp-json\/wp\/v2\/posts\/195","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.nukeitmike.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.nukeitmike.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.nukeitmike.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.nukeitmike.com\/index.php\/wp-json\/wp\/v2\/comments?post=195"}],"version-history":[{"count":0,"href":"https:\/\/blog.nukeitmike.com\/index.php\/wp-json\/wp\/v2\/posts\/195\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.nukeitmike.com\/index.php\/wp-json\/wp\/v2\/media?parent=195"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.nukeitmike.com\/index.php\/wp-json\/wp\/v2\/categories?post=195"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.nukeitmike.com\/index.php\/wp-json\/wp\/v2\/tags?post=195"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}