{"id":16211,"date":"2010-12-15T00:01:00","date_gmt":"2010-12-15T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/12\/15\/use-powershell-to-document-your-sql-database\/"},"modified":"2010-12-15T00:01:00","modified_gmt":"2010-12-15T00:01:00","slug":"use-powershell-to-document-your-sql-database","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-to-document-your-sql-database\/","title":{"rendered":"Use PowerShell to Document Your SQL Database"},"content":{"rendered":"<p>&nbsp;&nbsp;&nbsp;<\/p>\n<p><b>Summary:<\/b> Learn how to use Windows PowerShell to document your Microsoft SQL Server database<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><img decoding=\"async\" height=\"34\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" align=\"left\" alt=\"Hey, Scripting Guy! Question\" border=\"0\" title=\"Hey, Scripting Guy! Question\" \/><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>Hey, Scripting Guy! &nbsp;Is it possible to use Windows PowerShell to document my Microsoft SQL Server database? <\/p>\n<p>&#8212; CR<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><img decoding=\"async\" height=\"34\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" align=\"left\" alt=\"Hey, Scripting Guy! Answer\" border=\"0\" title=\"Hey, Scripting Guy! Answer\" \/><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/p>\n<p><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><span style=\"font-size: 10pt\"><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>Hello CR, Microsoft Scripting Guy Ed Wilson here. Welcome to day three of guest blogger week as it brings Rhys Campbell. <\/p>\n<p>&nbsp;<\/p>\n<p>Rhys Campbell is a London based SQL Server &amp; MySQL Database Administrator working for a statistics research company where he gets to put Windows PowerShell to many uses. Rhys blogs about SQL Server, MySQL, Windows PowerShell, SSIS and other stuff at the <a href=\"http:\/\/www.youdidwhatwithtsql.com\/\">you did what with SQL<\/a> webpage. <\/p>\n<p>&nbsp;<\/p>\n<h2>Using Windows PowerShell to generate database documentation<\/h2>\n<p>More often than not if database documentation exists, it is out of date or incomplete as it&rsquo;s at the bottom of every ones to-do list. I&rsquo;ve often advocated the use of extended properties to document databases.&nbsp; These comments can be useful for others to gain a better understanding of your database.&nbsp; You&rsquo;ve probably added these to the <b>Description<\/b> field present in the SSMS table designer. By default Microsoft calls these extended properties <b>MS_Description<\/b>. See the following figure:<\/p>\n<p class=\"Num-Caption\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0456.HSG-12-15-10-01.jpg\" border=\"0\" \/><\/p>\n<p class=\"Num-Caption\">&nbsp;<\/p>\n<p class=\"Num-Caption\">Unfortunately, these are not very useful when they just exist in the database. Using Windows PowerShell and SMO we can generate documentation by extracting this metadata from SQL Server databases and formatting it into something more useful.<\/p>\n<p>The script presented here will generate html documentation for all user databases on a SQL Server instance. The database doesn&rsquo;t have to have extended property comments but it will improve the documentation if they are present.&nbsp; The script will extract these comments, along with a few other details, for tables, columns, functions, views, stored procedures and triggers.<\/p>\n<p>First we need to load a couple of assembles so we are able to use SMO.<\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\"># Load needed assemblies<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">[System.Reflection.Assembly]::LoadWithPartialName(&#8220;Microsoft.SqlServer.SMO&#8221;) | <b>Out-Null<\/b>;<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">[System.Reflection.Assembly]::LoadWithPartialName(&#8220;Microsoft.SqlServer.SMOExtended&#8221;)| <b>Out-Null<\/b>;<\/span><\/p>\n<p><span style=\"font-family: courier new,courier\">&nbsp;<\/span><\/p>\n<p>This is followed by several functions that perform various tasks like writing html files, accessing the various database object types, reading extended properties and building lists of hyperlinks. There are comments above each function explaining their function. See the complete <a href=\"http:\/\/gallery.technet.microsoft.com\/scriptcenter\/en-us\/4187af0d-e82d-4615-b35d-a77aebcc7084\"><span style=\"color: #0000ff\">script at the Script Repository.<\/span><\/a> <\/p>\n<p>The next line set the directory where the documentation will be created. A folder called &lsquo;database_documentation&rsquo; will be created in your user profile directory. This is C:\\Users\\Rhys on my laptop.<\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\"># Root directory where the html documentation will be generated<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">$filePath = &#8220;$env:USERPROFILE\\database_documentation\\&#8221;;<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\"><b>New-Item<\/b> <i>-Path<\/i> $filePath <i>-ItemType<\/i> directory <i>-Force<\/i> | <b>Out-Null<\/b>;<\/span><\/p>\n<p><span style=\"font-family: courier new,courier\">&nbsp;<\/span><\/p>\n<p>Set the SQL Server instance you wish to document. Here I&rsquo;m documenting an installation of SQL Express 2008 on <b>localhost<\/b>.<\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\"># sql server that hosts the databases we wish to document<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">$sql_server = <b>New-Object<\/b> Microsoft.SqlServer.Management.Smo.Server localhost\\sqlexpress;<\/span><\/p>\n<p><span style=\"font-family: courier new,courier\">&nbsp;<\/span><\/p>\n<p>SMO doesn&rsquo;t return the <b>IsSystemObject<\/b> property by default so we have to ask for it first. This property is used to avoid cluttering up the documentation with system databases, views and stored procedures.<\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\"># IsSystemObject not returned by default so ask SMO for it<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">$sql_server.SetDefaultInitFields([Microsoft.SqlServer.Management.SMO.Table], &#8220;IsSystemObject&#8221;);<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">$sql_server.SetDefaultInitFields([Microsoft.SqlServer.Management.SMO.View], &#8220;IsSystemObject&#8221;);<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">$sql_server.SetDefaultInitFields([Microsoft.SqlServer.Management.SMO.StoredProcedure], &#8220;IsSystemObject&#8221;);<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">$sql_server.SetDefaultInitFields([Microsoft.SqlServer.Management.SMO.Trigger], &#8220;IsSystemObject&#8221;);<\/span><\/p>\n<p>&nbsp;<\/p>\n<p>A call to the <b>getDatabases<\/b> function will return all the user databases on the SQL Server instance.<\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\"># Get databases on our server<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">$databases = getDatabases $sql_server;<\/span><\/p>\n<p><span style=\"font-family: courier new,courier\">&nbsp;<\/span><\/p>\n<p>The <b>foreach<\/b> loop will cycle through each database generating documentation for each one. The functions defined earlier are used to document schemata, tables, views, stored procedures, function and triggers.<\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">foreach ($db in $databases)<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">{<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>Write-Host<\/b> &#8220;Started documenting &#8221; $db.Name;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Directory for each database to keep everything tidy<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>New-Item<\/b> <i>-Path<\/i> $($filePath + $db.Name) -ItemType directory -Force | <b>Out-Null<\/b>;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Make a page for the database<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $db_page = $filePath + $($db.Name) + &#8220;\\index.html&#8221;;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $body = &#8220;&lt;ul&gt;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li&gt;&lt;a href=&#8217;Schemata\/index.html&#8217;&gt;Schemata&lt;\/a&gt;&lt;\/li&gt;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li&gt;&lt;a href=&#8217;Tables\/index.html&#8217;&gt;Tables&lt;\/a&gt;&lt;\/li&gt;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li&gt;&lt;a href=&#8217;Views\/index.html&#8217;&gt;Views&lt;\/a&gt;&lt;\/li&gt;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li&gt;&lt;a href=&#8217;Stored Procedures\/index.html&#8217;&gt;Stored Procedures&lt;\/a&gt;&lt;\/li&gt;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li&gt;&lt;a href=&#8217;Functions\/index.html&#8217;&gt;Functions&lt;\/a&gt;&lt;\/li&gt;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li&gt;&lt;a href=&#8217;Triggers\/index.html&#8217;&gt;Triggers&lt;\/a&gt;&lt;\/li&gt;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/ul&gt;&#8221;;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeHtmlPage $db $db $body $db_page;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Get schemata for the current database<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $schemata = getDatabaseSchemata $sql_server $db;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createObjectTypePages &#8220;Schemata&#8221; $schemata $filePath $db;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>Write-Host<\/b> &#8220;Documented schemata&#8221;;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Get tables for the current database<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $tables = getDatabaseTables $sql_server $db;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createObjectTypePages &#8220;Tables&#8221; $tables $filePath $db;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>Write-Host<\/b> &#8220;Documented tables&#8221;;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Get views for the current database<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $views = getDatabaseViews $sql_server $db;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createObjectTypePages &#8220;Views&#8221; $views $filePath $db;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>Write-Host<\/b> &#8220;Documented views&#8221;;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Get procs for the current database<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $procs = getDatabaseStoredProcedures $sql_server $db;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createObjectTypePages &#8220;Stored Procedures&#8221; $procs $filePath $db;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>Write-Host<\/b> &#8220;Documented stored procedures&#8221;;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Get functions for the current database<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $functions = getDatabaseFunctions $sql_server $db;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createObjectTypePages &#8220;Functions&#8221; $functions $filePath $db;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>Write-Host<\/b> &#8220;Documented functions&#8221;;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Get triggers for the current database<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $triggers = getDatabaseTriggers $sql_server $db;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createObjectTypePages &#8220;Triggers&#8221; $triggers $filePath $db;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>Write-Host<\/b> &#8220;Documented triggers&#8221;;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>Write-Host<\/b> &#8220;Finished documenting &#8221; $db.Name;<\/span><\/p>\n<p class=\"CodeBlockScreened\" style=\"background: none transparent scroll repeat 0% 0%;margin-left: 0.5in\"><span style=\"font-family: courier new,courier\">}<\/span><\/p>\n<p>The full script can be found <a href=\"http:\/\/gallery.technet.microsoft.com\/scriptcenter\/en-us\/4187af0d-e82d-4615-b35d-a77aebcc7084\"><span style=\"color: #0000ff\">here at the Script Repository<\/span><\/a>. Save the Windows PowerShell code to a script called <b>ExtractDatabaseDocumentation.ps1 <\/b>and sign it. We can then execute the script against the SQL Server instance defined in <b>$sql_server. &nbsp;<\/b>The following figure shows running the script. <\/p>\n<p class=\"Num-Caption\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5661.HSG-12-15-10-02.jpg\" border=\"0\" \/>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>A folder of database documentation will be produced for each database. This will look similar to below.<\/p>\n<p>The Index page is shown here in the following figure:<\/p>\n<p class=\"Num-Caption\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0804.HSG-12-15-10-03.jpg\" border=\"0\" \/>&nbsp;<\/p>\n<p>The Table details page is seen here in this figure:<\/p>\n<p class=\"Num-Caption\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/8802.HSG-12-15-10-04.jpg\" border=\"0\" \/>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>I&rsquo;ve omitted a few cool things to cut down on the size of this script for the sake of brevity. SMO is very broad so there&rsquo;s plenty more you could include in this script if you wanted to.&nbsp; If there&rsquo;s something else you want to include in the documentation then a few minutes consulting the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms162169.aspx\"><span style=\"color: #0000ff\">SMO page on MSDN<\/span><\/a> should help you on your way.<\/p>\n<p>&nbsp;<\/p>\n<p>CR, that is all there is to using Windows PowerShell to generate documentation for your SQL Server database. Thanks Rhys for appearing today and sharing your expertise. Guest blogger week will continue tomorrow when our guest will be Shannon Ma. <\/p>\n<p>I invite you to follow me on <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingguystwitter\"><span style=\"color: #0000ff\">Twitter<\/span><\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\"><span style=\"color: #0000ff\">Facebook<\/span><\/a>. If you have any questions, send email to me at <a target=\"_blank\" href=\"mailto:scripter@microsoft.com\"><span style=\"color: #0000ff\">scripter@microsoft.com<\/span><\/a> or post them on the <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingforum\"><span style=\"color: #0000ff\">Official Scripting Guys Forum<\/span><\/a>. See you tomorrow. Until then, peace.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"margin-left: 0in\"><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp;&nbsp;&nbsp; Summary: Learn how to use Windows PowerShell to document your Microsoft SQL Server database &nbsp; Hey, Scripting Guy! &nbsp;Is it possible to use Windows PowerShell to document my Microsoft SQL Server database? &#8212; CR &nbsp; Hello CR, Microsoft Scripting Guy Ed Wilson here. Welcome to day three of guest blogger week as it brings [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[146,56,210,3,176,100],"class_list":["post-16211","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-databases","tag-guest-blogger","tag-rhys-campbell","tag-scripting-guy","tag-sql-server","tag-windows-powershell-ise"],"acf":[],"blog_post_summary":"<p>&nbsp;&nbsp;&nbsp; Summary: Learn how to use Windows PowerShell to document your Microsoft SQL Server database &nbsp; Hey, Scripting Guy! &nbsp;Is it possible to use Windows PowerShell to document my Microsoft SQL Server database? &#8212; CR &nbsp; Hello CR, Microsoft Scripting Guy Ed Wilson here. Welcome to day three of guest blogger week as it brings [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/16211","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=16211"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/16211\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=16211"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=16211"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=16211"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}