Deleting and Purging data from the SCOM Database


 

image

 

First, I have to begin with a disclaimer – Microsoft does not support customers manually editing the database, unless under the guidance of a Microsoft support engineer with a support case.

However, I have seen several blogs now “leaking” this guidance I send out or use from time to time…. so it is probably time to publish it as an example only.  I have always been hesitant to blog about any manual edits to the SCOM database, because all too many times, customers will jump to a conclusion, and start hacking away at their DB because of something they read on some website…. only to find they have corrupted their database, or made their original problem worse.  You should NEVER perform any activity like this unless you are experienced and aware of the possible consequences.  You should also ensure you take a full backup of the DB’s before ever attempting an edit like this.

Ok, warnings aside…..

There are times in a SCOM Management Groups life cycle, where objects can get orphaned.  Either from bugs in SCOM, or bad practices taken by discoveries, or SDK commands, or Product Connector solutions.

For instance, there is a bug in SCOM, when you delete a Management Server (rare, but happens if you are retiring an old OS and replacing with a new one).  When you delete the MS, more often than not – we will orphan that management server’s Health Service Watcher:

What can happen, is that when you view the OperationsManager > Management Server > Management Servers State view, you might see old Management Server Health Service Watcher objects here:

image

This doesn’t really cause a problem, but it is an annoyance.  It is just an example where a manual delete is required to clean it up.

 

Another common scenario, is when customers implement a management pack, that inserts data via the SDK.  If objects are inserted via the SDK, they must be removed via the SDK.  Sometimes those MP’s get decommissioned, and customers are left with these objects, wondering how to get them removed.

 

Probably the most common scenario – is Windows Computers showing up in the console, that don’t have an agent.  People tend to assume these are “orphans” but often times they are just discovered by some Topology discovery in a management pack, like AD, or SCCM.  AEM will also leave you with a lot of ghosts.  Sometimes these are caused by running a discovery to “extend” the Windows Computer class, but the discovery written has no logic to “undiscover” the computer when the agent is deleted.  It will still be associated to that discovery, even though the agent is long gone.

 

To inspect the database relationships to see if there is a still a discovery associated with a computer – you can run this query against the OperationsManager database.  Just change my computername on the first line to one you are inspecting:

DECLARE @name varchar(255) = '%ws2016.opsmgr.net%' SELECT BME.FullName, BME.DisplayName, BME.Path, dv.DisplayName AS 'DiscoveryDisplayName', dv.Name AS 'DiscoveryName' FROM typedmanagedentity TME JOIN BaseManagedEntity BME ON TME.BaseManagedEntityId = BME.BaseManagedEntityId JOIN DiscoverySourceToTypedManagedEntity DSTME ON TME.TypedManagedEntityID = DSTME.TypedManagedEntityID JOIN DiscoverySource DS ON DS.DiscoverySourceID = DSTME.DiscoverySourceID JOIN DiscoveryView dv ON DS.DiscoveryRuleID=dv.Id WHERE BME.Fullname like @name ORDER BY BME.FullName, DiscoveryDisplayName

 

If you have fully inspected this and determined the object is not related to any current discoveries – then you can attempt a manual deletion.

 

You will find lots of blogs talking about setting “IsDeleted = 1” in the BaseManagedEntity table, or even other tables.  This is WRONG.  You should never do this!!!

The better way to delete managed entities, is the below set of queries.

 

--Query 1 --First get the Base Managed Entity ID of the object you think is orphaned/bad/needstogo: -- DECLARE @name varchar(255) = '%computername%' -- SELECT BaseManagedEntityId, FullName, DisplayName, IsDeleted, Path, Name FROM BaseManagedEntity WHERE FullName like @name OR DisplayName like @name ORDER BY FullName

 

Query 1, will help you find the BaseManagedEntity ID of the object you are wanting to delete.  Take GREAT care here that you fully understand the object is correct that you want to forcibly remove, or you risk corrupting the SCOM object relationships.

This will give you the BaseManagedEntityId GUID – which we need for the next step:

image

 

In Query 2, we paste in that GUID for the orphaned object we are trying to delete.

--Query 2 --Next input that BaseManagedEntityID into the delete statement --This will delete specific typedmanagedentities more gracefully than setting IsDeleted=1 --change "00000000-0000-0000-0000-000000000000" to the ID of the invalid entity -- DECLARE @EntityId uniqueidentifier = '00000000-0000-0000-0000-000000000000' -- DECLARE @TimeGenerated datetime; SET @TimeGenerated = getutcdate(); BEGIN TRANSACTION EXEC dbo.p_TypedManagedEntityDelete @EntityId@TimeGenerated; COMMIT TRANSACTION

 

When you run this – it will delete the managed entity in a “graceful” method, that will delete any related objects in ManagedType tables – so you might see a lot more objects deleted in the SQL response than you expected.

 

In Query 3 – this is just a repeat of Query 1, but we run this to inspect the objects and see if their IsDeleted flag now = 1.

--Query 3 --Check to make sure the IsDeleted field of your BME now = 1 -- DECLARE @name varchar(255) = '%computername%' -- SELECT BaseManagedEntityId, FullName, DisplayName, IsDeleted, Path, Name FROM BaseManagedEntity WHERE FullName like @name OR DisplayName like @name ORDER BY FullName

 

In Query 4 – we can get an idea of how many objects currently are in a “Deleted” status, and ready to be purged from the database:

--Query 4 --Get an idea of how many BMEs are in scope to purge SELECT count(*) FROM BaseManagedEntity WHERE IsDeleted = 1

 

Lastly – in Query 5 – we are purging.  Purging is a normal cycle and part of SCOM grooming, where we will purge data from the SCOM database after 2-3 days of being marked deleted.  We do not delete these immediately, because that is an expensive operation and best reserved for when grooming runs at night.  Also, when you are troubleshooting an agent, you might not wish to delete all the data when you delete an agent from the management group.  This lets the discovered data remain, if you bring the agent back in within a day or two.

Purging on demand is only useful if you wish to remove the deleted data from SCOM immediately.  A common scenario where I use this – is when I need to take a server and install it as a Management Server or a Gateway server, but it was previously managed as an agent.  You don’t need to do all the manual SQL deletes in that scenario, but you do need to purge the DB so that when you install it as a Management Server or a GW, there are no issues during the installation.

--Query 5 --This query statement for SCOM 2012 will purge all IsDeleted=1 objects immediately --Normally this is a 2-3day wait before this would happen naturally --This only purges 10000 records.  If you have more it will require multiple runs --Purge IsDeleted=1 data from the SCOM 2012 DB: DECLARE @TimeGenerated DATETIME, @BatchSize INT, @RowCount INT SET @TimeGenerated = GETUTCDATE() SET @BatchSize = 10000 EXEC p_DiscoveryDataPurgingByRelationship @TimeGenerated@BatchSize@RowCount EXEC p_DiscoveryDataPurgingByTypedManagedEntity @TimeGenerated@BatchSize@RowCount EXEC p_DiscoveryDataPurgingByBaseManagedEntity @TimeGenerated@BatchSize@RowCount

 

 

Review:

Again – doing these DB edits are not supported by Microsoft.  I only publish this to keep people from using these queries (which have been published on other blogs now) without understanding the issues, the risks, or the proper way to leverage them.   And to get people to STOP forcing the IsDeleted = 1 property using a SQL update statement.

Here are all the Queries together for a quick copy/paste:

(These support SCOM 2012, 2016, and the semi-annual channel builds of SCOM)

--Query 1 --First get the Base Managed Entity ID of the object you think is orphaned/bad/needstogo: -- DECLARE @name varchar(255) = '%computername%' -- SELECT BaseManagedEntityId, FullName, DisplayName, IsDeleted, Path, Name FROM BaseManagedEntity WHERE FullName like @name OR DisplayName like @name ORDER BY FullName --Query 2 --Next input that BaseManagedEntityID into the delete statement --This will delete specific typedmanagedentities more gracefully than setting IsDeleted=1 --change "00000000-0000-0000-0000-000000000000" to the ID of the invalid entity -- DECLARE @EntityId uniqueidentifier = '00000000-0000-0000-0000-000000000000' -- DECLARE @TimeGenerated datetime; SET @TimeGenerated = getutcdate(); BEGIN TRANSACTION EXEC dbo.p_TypedManagedEntityDelete @EntityId@TimeGenerated; COMMIT TRANSACTION     --Query 3 --Check to make sure the IsDeleted field of your BME now = 1 -- DECLARE @name varchar(255) = '%computername%' -- SELECT BaseManagedEntityId, FullName, DisplayName, IsDeleted, Path, Name FROM BaseManagedEntity WHERE FullName like @name OR DisplayName like @name ORDER BY FullName     --Query 4 --Get an idea of how many BMEs are in scope to purge SELECT count(*) FROM BaseManagedEntity WHERE IsDeleted = 1     --Query 5 --This query statement for SCOM 2012 will purge all IsDeleted=1 objects immediately --Normally this is a 2-3day wait before this would happen naturally --This only purges 10000 records.  If you have more it will require multiple runs --Purge IsDeleted=1 data from the SCOM 2012 DB: DECLARE @TimeGenerated DATETIME, @BatchSize INT, @RowCount INT SET @TimeGenerated = GETUTCDATE() SET @BatchSize = 10000 EXEC p_DiscoveryDataPurgingByRelationship @TimeGenerated@BatchSize@RowCount EXEC p_DiscoveryDataPurgingByTypedManagedEntity @TimeGenerated@BatchSize@RowCount EXEC p_DiscoveryDataPurgingByBaseManagedEntity @TimeGenerated@BatchSize@RowCount 

Comments (2)

  1. M.Mathew says:

    Kevin, Thx for putting this together.!

Skip to main content