<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>SQL Server Policy-Based Management : SQL Server 2000</title><link>http://blogs.msdn.com/sqlpbm/archive/tags/SQL+Server+2000/default.aspx</link><description>Tags: SQL Server 2000</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Using PBM Against SQL2K and SQL2K5</title><link>http://blogs.msdn.com/sqlpbm/archive/2008/07/04/using-pbm-against-sql2k-and-sql2k5.aspx</link><pubDate>Fri, 04 Jul 2008 22:32:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8690816</guid><dc:creator>sqlpbm</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/sqlpbm/comments/8690816.aspx</comments><wfw:commentRss>http://blogs.msdn.com/sqlpbm/commentrss.aspx?PostID=8690816</wfw:commentRss><description>&lt;p&gt;We get this question a lot: can I use PBM against a SQL2K &amp;amp; SQL2K5 instances. The quick answer is yes but in a limited fashion. PBM is ultimately based on SMO (SQL Server Management Objects) and SMO supports SQL2K, SQL2K5, and SQL2K8. PBM relies on some changes to the DB engine which are not available in versions below SQL2K8, therefore, not all PBM functionality&amp;#160; is available in SQL2K and SQL2K5.&lt;/p&gt;  &lt;p&gt;Let's divide the PBM functionality into four key areas:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Authoring policies &lt;/li&gt;    &lt;li&gt;Storing policies on a server &lt;/li&gt;    &lt;li&gt;Automated policy evaluation &lt;/li&gt;    &lt;li&gt;Manual policy evaluation &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;u&gt;&lt;font size="3"&gt;Authoring Policies&lt;/font&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;There are two ways to author a policy: connected and disconnect. Connected policy authoring is only supported in SQL2K8. When authoring in connected mode (Object Explorer is connected to an instance) the policy is stored on the server. There is no way to alternatively save the policy to the file system (other than exporting it after it's created on the server). Disconnected authoring saves the policy to the file system (as an XML file). This functionality is only available in SQL2K8 Management Studio. Since it doesn't require a connection to a back-end server you don't need an instance of SQL2K8 available. Therefore, authoring policies is somewhat dependent upon SQL2K8 - you need the toolset but not a server.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;&lt;font size="3"&gt;Storing Policies On A Server&lt;/font&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;There are two ways to store a policy on a server: create it on the server and import a policy XML file to the server. Both of these are only available on SQL2K8 servers.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;&lt;font size="3"&gt;Automated Policy Evaluation&lt;/font&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;Policy automation is dependent upon enhancements to dependent features only available in SQL2K8 (SQCLR, SMO, Agent and DDL Eventing.) Therefore, automated policy evaluation (Check on Change - Prevent, Check on Change - Log, and Check on Schedule) is only available on SQL2K8 servers. In addition, the automation requires the policy to stored locally on the server which is only supported on SQL2K8.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;&lt;font size="3"&gt;Manual Policy Evaluation&lt;/font&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;Manually evaluating a policy is a client-side operation (simply meaning it doesn't run in the context of the DB Engine service) and therefore it requires SQL2K8 Management Studio (or at least the SQL2K8 management stack - PBM &amp;amp; SMO APIs). There are four ways to manually evaluate a policy:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;From Object Explorer in Management Studio &lt;/li&gt;    &lt;li&gt;From Registered Servers in Management Studio &lt;/li&gt;    &lt;li&gt;The PowerShell cmdlet Invoke-PolicyEvaluation &lt;/li&gt;    &lt;li&gt;From the PBM API &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Object Explorer (OE): Policy evaluation is supported from OE when connected to SQL2K5 and SQL2K8 servers (note: this may also be available when connected to a SQL2K server but I didn't have one available to me at the time of this writing to verify). You get the same Evaluation dialog in both cases. However, when connected to a SQL2K5 server there are no locally stored policies which means you need to select policies from file or from a SQL2K8 server.&lt;/p&gt;  &lt;p&gt;Registered Servers (RegSrvrs): Policy evaluation is supported from RegSrvrs for SQL2K, SQL2K5, and SQL2K8 servers. You can evaluate policies that are saved to file or stored on a SQL2K8 server. You can also evaluate policies against a group of servers. The server group can contain mixed versions.&lt;/p&gt;  &lt;p&gt;Invoke-PolicyEvaluation: This PowerShell cmdlet can be run against SQL2K, SQL2K5, and SQL2K8 servers. You just pass in the server name to the TargetServerName parameter. You can evaluate policies stored on a SQL2K8 server or on the file system. This &lt;a href="http://blogs.msdn.com/sqlpbm/archive/2008/06/14/running-against-sql-server-2005-and-sql-server-2000.aspx" target="_blank"&gt;blog post&lt;/a&gt; shows how to use the Agent PowerShell subsystem in SQL2K8 to create a job that runs a PowerShell script to evaluate policies against a group of servers. These servers can be SQL2K, SQL2K5 and SQL2K8 servers. &lt;/p&gt;  &lt;p&gt;PBM API: The PBM API is a public API and contains methods for evaluating policies. This is exactly what we use under the covers for our policy evaluation. You can create your own .Net application which calls this API. Similar to the PowerShell cmdlet you need to pass in a connection to the server to evaluate. This connection can be a SQL2K, SQL2K5, or SQL2K8 connection. The details for how to do this (the code you need to write) is beyond the scope of this posting but is a good topic for a future posting.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;&lt;font size="3"&gt;Summary&lt;/font&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;When we designed PBM we accounted for the fact that not all customers immediately upgrade their environment - you have to deal with mixed environments. We wanted to be sure PBM would add value to these mixed environments but we also need to give you a reason to upgrade :-). Therefore, we enable you to run policies against SQL2K and SQL2K5 just not with the same fidelity as SQL2K8.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8690816" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/sqlpbm/archive/tags/Policy/default.aspx">Policy</category><category domain="http://blogs.msdn.com/sqlpbm/archive/tags/PowerShell/default.aspx">PowerShell</category><category domain="http://blogs.msdn.com/sqlpbm/archive/tags/Management+Studio/default.aspx">Management Studio</category><category domain="http://blogs.msdn.com/sqlpbm/archive/tags/SQL+Server+Agent/default.aspx">SQL Server Agent</category><category domain="http://blogs.msdn.com/sqlpbm/archive/tags/SQL+Server+2000/default.aspx">SQL Server 2000</category><category domain="http://blogs.msdn.com/sqlpbm/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://blogs.msdn.com/sqlpbm/archive/tags/SQL+Server+2008/default.aspx">SQL Server 2008</category></item><item><title>Running Against SQL Server 2005 and SQL Server 2000</title><link>http://blogs.msdn.com/sqlpbm/archive/2008/06/14/running-against-sql-server-2005-and-sql-server-2000.aspx</link><pubDate>Sun, 15 Jun 2008 05:35:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8599049</guid><dc:creator>sqlpbm</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/sqlpbm/comments/8599049.aspx</comments><wfw:commentRss>http://blogs.msdn.com/sqlpbm/commentrss.aspx?PostID=8599049</wfw:commentRss><description>&lt;p&gt;@ TechEd SQL Server MVP Peter DeBetta and I presented a session where we created a PowerShell script for running a group of policies against a group of servers. The script was then automated using the PowerShell subsystem in SQL Server Agent. The result of each policy evaluation was loaded into a table for reporting purposes.&lt;/p&gt;  &lt;p&gt;Because PBM is built on top of SQL Server Management Objects (SMO) and SMO supports SQL Server 2000, SQL Server 2005, and SQL Server 2008, PBM will work against all of these versions.&lt;/p&gt;  &lt;p&gt;The script reads in a text file containing a list of the target servers (the servers each policy will be evaluated against). It connects to a primary server to grab the policies and then evaluates each policy in a particular category against each server.&lt;/p&gt;  &lt;p&gt;The script is intended to be a proof of concept and is not ready for a production environment. Some alterations that you would want to make include adding error handling and reading the servers from a Central Manageability Server or at the least a table in the primary server rather than from a file.&lt;/p&gt;  &lt;p&gt;Here's the script for creating the database and table to store the results of the policy evaluation:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff"&gt;CREATE DATABASE [PolicyResults]        &lt;br /&gt;GO &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;USE [PolicyResults]        &lt;br /&gt;GO &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;CREATE TABLE [dbo].[PolicyHistory](        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [EvalServer] [nvarchar](50) NULL,         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [EvalDateTime] [datetime] NULL,         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [EvalPolicy] [nvarchar](max) NULL,         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [EvalResults] [xml] NULL         &lt;br /&gt;) ON [PRIMARY] &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;GO &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;ALTER TABLE [dbo].[PolicyHistory] ADD&amp;#160; CONSTRAINT [DF_PolicyHistory_EvalDateTime]&amp;#160; DEFAULT (getdate()) FOR [EvalDateTime]        &lt;br /&gt;GO&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You might want to add a column to store the policy result or you can use an XQuery to grab it out of the EvalResults column. I'll show you the query below.&lt;/p&gt;  &lt;p&gt;Here's the PowerShell script. I cleaned up the version of the script that was presented - reorganizing it a little to make it easier to follow what's going on.&lt;/p&gt;  &lt;blockquote&gt;&lt;font color="#0000ff"&gt;#Evaluate Policies in a Particular Category against a Server list      &lt;br /&gt;#Uses the Invoke-PolicyEvaluation &amp;amp; Invoke-SqlCmd Cmdlets       &lt;br /&gt;&lt;/font&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;function InsertPolicyHistory($ServerVariable, $DBVariable, $EvalServer, $EvalPolicy, $EvalResults)        &lt;br /&gt;{         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; #Escape single quotes so we can insert         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $EvalResultsEscaped = $EvalResults -replace &amp;quot;'&amp;quot;, &amp;quot;''&amp;quot;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $EvalPolicyEscaped = $EvalPolicy -replace &amp;quot;'&amp;quot;, &amp;quot;''&amp;quot;         &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160; #Setup the insert statement        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $QueryText = &amp;quot;INSERT INTO PolicyHistory (EvalServer, EvalPolicy, EvalResults) VALUES(N'$EvalServer', '$EvalPolicyEscaped', N'$EvalResultsEscaped')&amp;quot;         &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160; #Run the insert statement using the Invoke-SqlCmd Cmdlet        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Invoke-Sqlcmd -ServerInstance $ServerVariable -Database $DBVariable -Query $QueryText         &lt;br /&gt;}         &lt;br /&gt;        &lt;br /&gt;#CONSTANTS         &lt;br /&gt;#Declare the Server\Instance &amp;amp; database to post the policy results         &lt;br /&gt;$HistoryServer = &amp;quot;myServer\myInstance&amp;quot;         &lt;br /&gt;$HistoryDatabase = &amp;quot;PolicyResults&amp;quot;         &lt;br /&gt;#Declare the server\instance for the Policy store         &lt;br /&gt;$PolicySourceServer = $HistoryServer         &lt;br /&gt;#Setup the file containing the list of servers         &lt;br /&gt;$ServersFile = &amp;quot;c:\Servers.txt&amp;quot;         &lt;br /&gt;#Setup the location to dump the policy evaluation result output         &lt;br /&gt;$PolicyDir = &amp;quot;c:\PolicyEvaluation\&amp;quot;         &lt;br /&gt;#Setup the policy filter - only policies in this category will be processed         &lt;br /&gt;$PolicyCategoryFilter = &amp;quot;Custom Automation&amp;quot;         &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;#Setup a connection to the policy store        &lt;br /&gt;$Conn = new-object Microsoft.SQlServer.Management.Sdk.Sfc.SqlStoreConnection(&amp;quot;server=$PolicySourceServer;Trusted_Connection=true&amp;quot;);         &lt;br /&gt;$PolStore = new-object Microsoft.SqlServer.Management.DMF.PolicyStore($Conn);         &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;#Read the servers file into a variable        &lt;br /&gt;$Servers = Get-Content $ServersFile         &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;#Clear out the directory where the evaluation results will go&amp;#160; &lt;br /&gt;del c:\PolicyEvaluation\*         &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;foreach ($TargetServer in $Servers)        &lt;br /&gt;{         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; foreach ($Policy in $PolStore.Policies)         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if ($Policy.PolicyCategory -eq $PolicyCategoryFilter)         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; #Clean-up any invalid file system characters         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $PolicyNameFriendly = (Encode-SqlName $Policy.Name)         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $TargetServerFriendly = (Encode-SqlName $TargetServer)         &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; #Setup the output file as Server_Policy.xml        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $OutputFile = $PolicyDir + (&amp;quot;{0}_{1}.xml&amp;quot; -f $TargetServerFriendly, $PolicyNameFriendly);&amp;#160; &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; #Evaluate the policy        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Invoke-PolicyEvaluation -Policy $policy -TargetServerName $TargetServer -OutputXML &amp;gt; $OutputFile;         &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; #Read in the policy evaluation results to load it into the result table        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $PolicyResult = Get-Content $OutputFile;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; #Insert the results to our result table         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; InsertPolicyHistory $HistoryServer $HistoryDatabase $TargetServer $Policy.Name $PolicyResult;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;}         &lt;br /&gt;#Clean-up the evaluation result files         &lt;br /&gt;del c:\PolicyEvaluation\*&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;After you run the script you can use SQLCMD or SSMS to query the result table. The query below will return all rows where the policy was violated. To get back all of the rows where the policy passed change &amp;quot;false&amp;quot; to &amp;quot;true&amp;quot;.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff"&gt;USE [PolicyResults]        &lt;br /&gt;GO         &lt;br /&gt;WITH XMLNAMESPACES ('&lt;/font&gt;&lt;a href="http://schemas.microsoft.com/sqlserver/DMF/2007/08'"&gt;&lt;font color="#0000ff"&gt;http://schemas.microsoft.com/sqlserver/DMF/2007/08'&lt;/font&gt;&lt;/a&gt;&lt;font color="#0000ff"&gt; AS Pol)        &lt;br /&gt;SELECT *         &lt;br /&gt;FROM dbo.policyhistory         &lt;br /&gt;WHERE EvaluationResults.exist('//Pol:EvalDetail/Pol:Result/text()[. = &amp;quot;false&amp;quot;]') = 1&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In closing, if you automate the script using SQL Server Agent it will run under the context of the SQL Server Agent job. This can either be the Agent service account or you can use a proxy account. Which ever path you choose you'll need to make sure the account has access to the servers.txt file, the location where the results will be written to, the server containing the policies, the server where you want to write the results and each of the servers listed in servers.txt.&lt;/p&gt;  &lt;p&gt;_____________&lt;/p&gt;  &lt;p&gt;&lt;font size="1"&gt;About the Author:      &lt;br /&gt;Dan Jones is a PM on the SQL Server Manageability team at Microsoft.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8599049" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/sqlpbm/archive/tags/PowerShell/default.aspx">PowerShell</category><category domain="http://blogs.msdn.com/sqlpbm/archive/tags/Sample/default.aspx">Sample</category><category domain="http://blogs.msdn.com/sqlpbm/archive/tags/SQL+Server+Agent/default.aspx">SQL Server Agent</category><category domain="http://blogs.msdn.com/sqlpbm/archive/tags/SQL+Server+2000/default.aspx">SQL Server 2000</category><category domain="http://blogs.msdn.com/sqlpbm/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category></item></channel></rss>