Archive for the ‘Policy Based Management’ Category.

Expiring Databases and Policy-Based Management

Today on Twitter my friend Jes “Run Forrest Run” Schultz Borland (Blog | Twitter) asked the Community “How do you clean up your dev environments? Let DBs sit out there forever? Delete after X months? Other? This seemed like an interesting issue to tackle and me being the PBM freak that I am, immediately I had a light bulb moment for a policy. In this post I’ll show you a policy you can run against your databases (can work in dev or whatever environment suits you) and will tell you which databases are older than 30 days old. As an added bonus, I’ll also show you how to add a custom extended property to set a custom expiration date.

Continue reading ‘Expiring Databases and Policy-Based Management’ »

Make It Simple With Policy-Based Management

At work recently, I explained to a coworker the reasons and benefits of having databases in Simple mode in your development environment. Funnily enough, a few hours later, I see my friend Andie Letourneau (Blog | Twitter) posted a blog on how to adjust your recovery modes in development. While Andie’s homework assignment is to substitute it with a WHILE loop, I have MUCH simpler solution using Policy-Based Management!

First, let’s create the condition and policy. As always you can either use this T-SQL or you can simply download the XML policy and import it:

Download Policy Here

TSQL:

--Create Condition First
Declare @condition_id int
EXEC msdb.dbo.sp_syspolicy_add_condition @name=N'Simple Recovery Mode', @description=N'Ensures databases are set to SIMPLE recovery mode', @facet=N'Database', @expression=N'
  Bool
  EQ
  2

    Numeric
    RecoveryModel

    Numeric
    Enum
    Numeric
    2

      String
      System.String
      Microsoft.SqlServer.Management.Smo.RecoveryModel

      String
      System.String
      Simple

', @is_name_condition=0, @obj_name=N'', @condition_id=@condition_id OUTPUT
Select @condition_id

GO

--Create Policy
Declare @object_set_id int
EXEC msdb.dbo.sp_syspolicy_add_object_set @object_set_name=N'Simple Mode Check_ObjectSet', @facet=N'Database', @object_set_id=@object_set_id OUTPUT
Select @object_set_id

Declare @target_set_id int
EXEC msdb.dbo.sp_syspolicy_add_target_set @object_set_name=N'Simple Mode Check_ObjectSet', @type_skeleton=N'Server/Database', @type=N'DATABASE', @enabled=True, @target_set_id=@target_set_id OUTPUT
Select @target_set_id

EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database', @level_name=N'Database', @condition_name=N'', @target_set_level_id=0

GO

Declare @policy_id int
EXEC msdb.dbo.sp_syspolicy_add_policy @name=N'Simple Mode Check', @condition_name=N'Simple Recovery Mode', @policy_category=N'', @description=N'This policy ensures that the databases evaluated against are set to SIMPLE recovery mode.', @help_text=N'', @help_link=N'', @schedule_uid=N'00000000-0000-0000-0000-000000000000', @execution_mode=0, @is_enabled=False, @policy_id=@policy_id OUTPUT, @root_condition_name=N'', @object_set=N'Simple Mode Check_ObjectSet'
Select @policy_id

GO

Now that you’ve created your policy, you can either evaluate it directly on that server or we can leverage the Central Management Server feature to evaluate this policy against one or more servers in your environment! Since we’re looking at this from an enterprise-level standpoint, we’re going to go over the CMS way of doing this.

Once you’ve established your CMS, you’re going to want to register servers to it. You could register everything directly under the CMS but then it becomes one giant list and that’s not very nice. One method I like to implement in my CMS is to create new server groups for each environment (e.g. DEV, QA, PROD). Within each group, I also create additional groupings for each version of SQL Server (e.g. 2000, 2005, 2008). Once the groups/folders have been created I then register my servers in their appropriate spots.

The advantage of breaking groups up like this is that CMS allows you to query against multiple servers at once. For instance if you were to right-click the folder for DEV, which in my case contains two registered servers in groups beneath it, SSMS will connect to both instances so that you can query them at the same time. It is this mechanism that we’ll use with Policy-Based Management since that feature allows us to evaluate policies against multiple servers in the same way.

To evaluate this policy, right-click the DEV folder and select Evaluate Policies. For source, click on the ellipses button and select either the folder location of the XML file or select the SQL Server instance which you imported the policy to. Once you’ve selected the policy’s location, you’ll see the Evaluate Policies screen with a list. Tick the box for the Simple Mode Check and then click the Evaluate button.

Check that out, you just evaluated policies against all of the databases in DEV! The databases that are NOT in simple mode (per our condition check) fail the policy evaluation and show up with red X’s. To quickly switch those to simple mode simply check the boxes for those that failed the check, then click the Apply button. This will enforce the policy on those databases and switch them for you to Simple mode! Imagine doing this that quickly and easily against hundreds of databases!

If you’re wondering if you can automate this process, the answer is absolutely! Check out the great open-source project Enterprise Policy-Management Framework over at Codeplex. This project allows you not only automate this process and policy enforcement but it also offers some really nice reporting of all this as well!

UPDATE: After chatting with Andie it looks like I forgot to mention a few things. Namely that for those wondering if this works on down-level servers (2000, 2005, etc.) the answer is YES! So long as you have a SQL Server 2008 server acting as your CMS, you can evaluate (certain) policies against down-level servers. Given this confusion I’ll write up a post on how all this works and what the caveats are.

The other point to make is that CMS uses Windows authentication only. If you have multiple domains, and there is no trust established between the domains, then this solution won’t work. If you DO have multiple domains and trust established, so long as your credentials allow you to traverse domains and the proper security authorizations are in place on the target SQL Servers then it will work.

SQL Server Denali CTP3: Policy Based Management

Whether you know it or not, Policy-Based Management is an integral part of the new release of SQL Server “Denali”. Did you know that the HADR feature actually leverages PBM for checks? Yup, that’s right folks. If you’re an administrator and you’re NOT using Policy-Based Management yet, I highly recommend you pick up a book and check it out!

So what’s new in SQL Server “Denali” CTP3 for Policy-Based Management? I just got the shrink wrap off of it (I’m not quite the go-getter that Aaron Nelson is) but at a quick glance here’s the changes I see. These comparisons were made with listing of facets between SQL Server 2008 R2 and the new “Denali” CTP3 release.

 

We now have 84 facets (as opposed to 76 in 2008 R2). These are our new facets and their applicable target types!

Availability Database – Exposes properies of the Availability Database object
Applicable Target Types: AvailabilityDatabase
Availability Group – Exposes properies of the Availability Group object
Applicable Target Types: AvailabilityGroup
Availability Group State – Exposes properies of the Availability Group
Applicable Target Types: AvailabilityGroup
Availability Replica – Exposes properties of the Availability Replica object.
Applicable Target Types: AvailabilityReplica
Database Replica State – Exposes the properties of physical database replicas participating in an availability group.
Applicable Target Types: DatabaseReplicaState
Search Property List – Exposes properties of the Search Property List object
Applicable Target Types: SearchPropertyList
Sequence – Exposes properties of the sequence object.
Applicable Target Types: Sequence
Server Role – Exposes properties of the ServerRole object.
Applicable Target Types: ServerRole

 

Again, this still has that new install smell so I haven’t had time to mess around with it but I’ll soon be posting some new policies using these facets so you can get an idea of what you can do administratively using Policy-Based Management and these new facets.

Policy-Based Management and Local Password Policy

This post is based on an interesting question/situation that was posted over at ASKSSC.com today. The user asked how to create a policy condition that enforces local sql accounts to adhere to password expiration policies.

First off, to create the condition itself is relatively easy. Below I’ve provided the T-SQL code so that you can create the condition that way. I’ve also included a quick list on how to create it via SSMS GUI.

T-SQL method:

Declare @condition_id int
EXEC msdb.dbo.sp_syspolicy_add_condition
    @name=N'Password Policy Enforced', @description=N'', @facet=N'Login',
    @expression=N'<Operator>
  <TypeClass>Bool</TypeClass>
  <OpType>AND</OpType>
  <Count>2</Count>
  <Operator>
    <TypeClass>Bool</TypeClass>
    <OpType>EQ</OpType>
    <Count>2</Count>
    <Attribute>
      <TypeClass>Bool</TypeClass>
      <Name>PasswordExpirationEnabled</Name>
    </Attribute>
    <Function>
      <TypeClass>Bool</TypeClass>
      <FunctionType>True</FunctionType>
      <ReturnType>Bool</ReturnType>
      <Count>0</Count>
    </Function>
  </Operator>
  <Operator>
    <TypeClass>Bool</TypeClass>
    <OpType>EQ</OpType>
    <Count>2</Count>
    <Attribute>
      <TypeClass>Bool</TypeClass>
      <Name>PasswordPolicyEnforced</Name>
    </Attribute>
    <Function>
      <TypeClass>Bool</TypeClass>
      <FunctionType>True</FunctionType>
      <ReturnType>Bool</ReturnType>
      <Count>0</Count>
    </Function>
  </Operator>
</Operator>', @is_name_condition=0, @obj_name=N'',
@condition_id=@condition_id OUTPUT

Select @condition_id

GO

SSMS method:

  1. Under PBM node, right-click conditions folder and select New Condition
  2. Name your new condition something useful
  3. Select Login facet from drop-down menu
  4. Click on field box and select @PasswordExpirationEnabled from properties list
  5. Set the operator value to True
  6. Click on ‘Click here to add clause’ to add another clause to policy
  7. Click on field box and select @PasswordPolicyEnforced from properties list
  8. Set the operator value to True
  9. Click OK. You’ve now just created a new condition!

Now we’re left with another question: Where does this password policy come from? For details on that you can refer to the Books Online article about it (link). If your box is on a domain that has Active Directory policies regarding password expiration, when you select the box for ‘Enforce password policy’ as well as ‘Enforce password expiration’, these settings will come from that policy. Don’t have an Active Directory policy? No problem! If a policy isn’t provided from Active Directory, Windows then looks to its local security policies for these values.

image

To see the local values, click on your Start button, then type in ‘secpol.msc’ (don’t type type the single-quotes). This will open up the Local Security Policy MMC Snap-in. Expand the Account Policies folder and then click on the Password Policy folder. In the right side pane you will see the various password-related options you can set such as Maximum password age or password length.

image

While policy-based management can help you check whether or not the accounts have the option enabled to enforce the policy checks, Policy-based management itself has not bearing on the Local Security Policy settings. This is something you, as an administrator, will have to set and configure outside of SQL Server.

Find Table Heaps Using Policy-Based Management

This is just a quick post in regards to a conversation I just had via Twitter. If you don’t already use Twitter, the SQL Community has setup a great resource on there using the hashtag of #sqlhelp.

Today a conversation came up due to a forum question over at SQLServerCentral regarding applying policies to databases with tables that have heaps. If you’re not familiar with the term, a heap is a table that has no clustered index on it. This can be problematic from a performance stand point so it might benefit you to find a way to identify these potential problem children. Enter Policy-Based Management.

This is a simple policy that you can run against your servers and it will identify your tables that are heaps. Just to clarify this policy identifies if your table has a clustered index on it. If it doesn’t then it will fail policy check. I’ve provided two ways to get the policy.

Download policy by clicking here

OR (Updated 4/15/11 to include creation script for condition)

--CREATE CONDITION
Declare @condition_id intEXEC msdb.dbo.sp_syspolicy_add_condition @name=N'Find heaps', @description=N'', @facet=N'Table', @expression=N'<Operator>  <TypeClass>Bool</TypeClass>  <OpType>EQ</OpType>  <Count>2</Count>  <Attribute>    <TypeClass>Bool</TypeClass>    <Name>HasClusteredIndex</Name>  </Attribute>  <Function>    <TypeClass>Bool</TypeClass>    <FunctionType>True</FunctionType>    <ReturnType>Bool</ReturnType>    <Count>0</Count>  </Function></Operator>', @is_name_condition=0, @obj_name=N'', @condition_id=@condition_id OUTPUTSelect @condition_id
GO

--CREATE POLICY
Declare @object_set_id int
EXEC msdb.dbo.sp_syspolicy_add_object_set @object_set_name=N'Find Table Heaps_ObjectSet', @facet=N'Table', @object_set_id=@object_set_id OUTPUT
Select @object_set_id

Declare @target_set_id int
EXEC msdb.dbo.sp_syspolicy_add_target_set @object_set_name=N'Find Table Heaps_ObjectSet', @type_skeleton=N'Server/Database/Table', @type=N'TABLE', @enabled=True, @target_set_id=@target_set_id OUTPUT
Select @target_set_id

EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database/Table', @level_name=N'Table', @condition_name=N'', @target_set_level_id=0
EXEC msdb.dbo.sp_syspolicy_add_target_set_level @target_set_id=@target_set_id, @type_skeleton=N'Server/Database', @level_name=N'Database', @condition_name=N'', @target_set_level_id=0

GO

Declare @policy_id int
EXEC msdb.dbo.sp_syspolicy_add_policy @name=N'Find Table Heaps', @condition_name=N'Find heaps', @policy_category=N'', @description=N'Heaps are tables without clustered indexes. Read the link below to learn more about heaps.', @help_text=N'Fragmentation (part 4):what are heaps? by Paul Randal', @help_link=N'http://blogs.msdn.com/b/sqlserverstorageengine/archive/2006/09/19/761437.aspx', @schedule_uid=N'00000000-0000-0000-0000-000000000000', @execution_mode=0, @is_enabled=False, @policy_id=@policy_id OUTPUT, @root_condition_name=N'', @object_set=N'Find Table Heaps_ObjectSet'
Select @policy_id

GO