[{"categories":[],"content":"Ask an AI assistant how to restore a database with dbatools and you will usually get something that looks right. Then you run it and find out -RecoveryTime was never a parameter, or that the command it confidently recommended does not exist.\nThis server fixes that. Point your assistant at it and it searches the real dbatools documentation - 700-odd commands with their syntax, parameters and published examples, plus the articles on this site - and cites the page each answer came from, so you can check it.\nEndpoint: https://mcp.dbatools.io\nThere is no signup, no API key and no account. Add the URL and it works.\nIt exists because of Microsoft\u0026rsquo;s Learn MCP server, which does the same job for SQL Server itself and left an obvious gap where dbatools should have been. Install that one too - details below.\nAdd it to your client Claude Code Claude Desktop VS Code Cursor Codex Anything else Run this anywhere, then restart your session:\nCopy claude mcp add --transport http dbatools https://mcp.dbatools.io Add --scope user to make it available in every project rather than just this one. Check it registered with /mcp.\nClaude Desktop and claude.ai both take a remote server directly, no config file needed:\nOpen Settings \u0026rarr; Connectors.Choose Add custom connector.Name it dbatools and paste https://mcp.dbatools.io as the URL. Leave the OAuth fields empty. This server does not authenticate anyone.\nPut this in .vscode/mcp.json for one workspace, or in your user mcp.json for all of them:\nCopy { \u0026#34;servers\u0026#34;: { \u0026#34;dbatools\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;http\u0026#34;, \u0026#34;url\u0026#34;: \u0026#34;https://mcp.dbatools.io\u0026#34; } } } Copilot Chat picks it up on save. Open the tools picker in Agent mode to confirm the three dbatools_ tools are listed.\nAdd it to ~/.cursor/mcp.json, or .cursor/mcp.json inside a single project:\nCopy { \u0026#34;mcpServers\u0026#34;: { \u0026#34;dbatools\u0026#34;: { \u0026#34;url\u0026#34;: \u0026#34;https://mcp.dbatools.io\u0026#34; } } } Windsurf uses the same shape, in ~/.codeium/windsurf/mcp_config.json.\nCodex keeps its servers in ~/.codex/config.toml:\nCopy [mcp_servers.dbatools] url = \u0026#34;https://mcp.dbatools.io\u0026#34; Edit the file by hand. codex mcp add only understands servers it can launch as a local process, so there is no command-line form for a remote one.\nIt is an ordinary streamable HTTP MCP server, so any compliant client will talk to it. To check it from a terminal:\nCopy curl https://mcp.dbatools.io \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -H \u0026#34;Accept: application/json, text/event-stream\u0026#34; \\ -d \u0026#39;{ \u0026#34;jsonrpc\u0026#34;: \u0026#34;2.0\u0026#34;, \u0026#34;id\u0026#34;: 1, \u0026#34;method\u0026#34;: \u0026#34;tools/call\u0026#34;, \u0026#34;params\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;dbatools_docs_search\u0026#34;, \u0026#34;arguments\u0026#34;: { \u0026#34;query\u0026#34;: \u0026#34;restore to a point in time\u0026#34; } } }\u0026#39; There is no session to establish and no header to send. Requests are rate limited per IP, generously enough that you will only notice in a loop.\nOnce it is connected, ask your assistant to list its tools. You should see three names beginning with dbatools_.\nWhat to ask it You never have to name a tool. Ask the question you actually have and your assistant will reach for the server on its own:\nHow do I restore a database to a point in time with dbatools? What is the difference between -SqlCredential and -Credential? Show me a worked example of backing up to Azure blob storage. Which dbatools commands run on Linux? I need to copy logins between two instances without copying passwords. It is at its best on the questions models get wrong from memory: exact parameter names, which switches are mutually exclusive, and whether a command exists at all.\nThe three tools Tool What it returns dbatools_docs_search Up to 10 commands and articles, each with an excerpt and its dbatools.io URL dbatools_code_sample_search Up to 20 worked PowerShell examples, taken from the examples published with each command dbatools_docs_fetch One complete command page or article as markdown, by URL or by bare command name What it can\u0026rsquo;t do It reads documentation. That is the whole job.\nIt cannot connect to a SQL Server instance, cannot run a dbatools command, and holds no credentials of any kind - there is nowhere to put them and nothing that would use them. The search never leaves the process, because the documentation is compiled into the deployment artifact and searched in memory.\nAll three tools are declared read-only in the protocol, so most clients will let you auto-approve them and stop asking. That is the truthful description of the server, not a convenience setting.\nIf what you want is an MCP server that does run dbatools commands against your instances, that is dbatools-mcp-server - a separate project that runs locally on your own machine. You can install both at once; their tool names do not overlap.\nWhere it falls short It is a search engine over a pile of documentation, and it is worth knowing exactly how narrow that is before you rely on it.\nIt has no notion of meaning - it has a vocabulary. Queries and documents are both stemmed, so \u0026ldquo;migrate\u0026rdquo;, \u0026ldquo;migrating\u0026rdquo; and \u0026ldquo;migration\u0026rdquo; count as one word, and a curated list of about 120 phrases maps the words DBAs type onto the words the module uses. That is why \u0026ldquo;moving a database to another server\u0026rdquo; does reach the migration commands: because somebody wrote that mapping down, not because anything understood the question. A phrasing nobody anticipated falls back to plain word matching and can still come back empty. When it does, try again in the words the documentation itself would use.\nIt cannot tell reading from writing. Ask which port an instance is listening on and Set-DbaTcpPort may well rank above Get-DbaTcpPort, because nothing in the ranking distinguishes a command that reports something from one that changes it. Check the verb on anything you are about to run.\nIt only knows what is published on this site. Command help and articles. Not the GitHub issues, not the Slack channel, not the source code, and not the book. Plenty of the best dbatools knowledge lives in those and none of it is in here.\nIt is only as good as the docs are. Where a command\u0026rsquo;s help is thin or out of date, the answer is thin or out of date. Nothing in this server checks the documentation against the module\u0026rsquo;s actual behaviour.\nPlatform support is the clearest case. Every command carries the same Availability: Windows, Linux, macOS in its help - Get-DbaDiskSpace and Get-DbaFirewallRule included, though both lean on WMI or remoting and do not work on Linux. The real answer is in dbatools \u0026amp; SQL on Linux, which the server does return for that question: the pure-SQL commands work, the ones that reach into Windows do not, and the article puts the split at about three quarters. Trust the article, not the field.\nIt knows nothing about you. Not your SQL Server version, not which dbatools version you have installed, not your instances. Every answer is the general case.\nIt can be a day behind. The index rebuilds daily, so a command merged this morning may not be findable until tomorrow.\nResults are capped, too: ten documents per search, twenty code samples. That is a deliberate ceiling on how much of your context window one call can eat.\nWhat it costs your context The three tool definitions and the server\u0026rsquo;s instructions add up to roughly 640 tokens per session - about 0.3% of a 200K window, which is nothing. Clients that defer tool schemas until a tool is actually used bring that down to about 30 tokens for the three names.\nThe real cost is in results, not definitions. dbatools_docs_fetch returns a whole command page, and a page like Backup-DbaDatabase runs to thousands of tokens on its own. A ten-hit search with excerpts costs more than the tool definitions did for the entire session. If your context is tight, fetch deliberately rather than reflexively.\nWhat it records Tool calls are logged to Application Insights: the query text, how many results came back, the top hit, how long the search took, plus your user agent and IP address. The queries that come back empty get read most closely, because they are the fastest way to find out what the documentation is missing.\nSecret-shaped values are stripped before anything is stored - passwords and keys in a pasted connection string, long token-shaped strings, email addresses. That redaction is best effort rather than a guarantee, so treat the search box the way you would treat any other: do not paste a real connection string into it.\nNothing is sold or shared with anyone, and there is no account for it to be attached to.\nInstall Microsoft\u0026rsquo;s Learn server too If you only add one MCP server this week, make it Microsoft\u0026rsquo;s rather than this one.\nThe Microsoft Learn MCP server puts the whole of Microsoft Learn in front of your assistant: SQL Server itself, T-SQL, Azure SQL, PowerShell, Windows, the lot. It is free, hosted by Microsoft, and needs no sign-in. We use it constantly, and it is genuinely the reason this server exists - once you have watched an assistant stop guessing about SQL Server, the fact that it was still guessing about dbatools becomes impossible to ignore.\nclaude mcp add --transport http microsoft-learn https://learn.microsoft.com/api/mcp Or in VS Code, in .vscode/mcp.json:\n{ \u0026#34;servers\u0026#34;: { \u0026#34;microsoft-learn\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;http\u0026#34;, \u0026#34;url\u0026#34;: \u0026#34;https://learn.microsoft.com/api/mcp\u0026#34; } } } Claude Code and Copilot CLI users can install their plugin instead, which brings the server plus three skills that teach the assistant when to reach for it:\n/plugin marketplace add microsoftdocs/mcp /plugin install microsoft-docs@microsoft-docs-marketplace The two servers answer different halves of the same question. Learn tells you what SQL Server does and why; this one tells you which dbatools command does it and what the parameter is actually called. Run both. Their tool names do not collide, and the shape of this server - search, code samples, fetch - is copied from theirs on purpose, because it was the right design and there was no reason to invent a worse one.\nHow it stays current The index is rebuilt from three public sources every day at 09:00 UTC, and again on every deploy:\nSource Provides dbatools-index.json Syntax, parameters and examples, straight from the module commands.json Descriptions, categories and canonical URLs articles.json Blog posts and pages from this site Search is lexical BM25, with stemming, stop words and the synonym map sitting in front of it. There are no embeddings and no vector database. Storing vectors would be cheap, but embedding your query at request time would mean either a 25 MB model loaded in the cold-start path or an API round trip on every single call, and a documentation search does not need to cost that. The whole corpus fits in memory instead, so a query costs nothing and returns the same results every time.\n","date":"2026-07-30","summary":"Ask an AI assistant how to restore a database with dbatools and you will usually get something that looks right. Then you run it and find out -RecoveryTime was never a parameter, or that the command it confidently recommended does not exist.\nThis server fixes that. Point your assistant at it and it searches the real dbatools documentation - 700-odd commands with their syntax, parameters and published examples, plus the articles on this site - and cites the page each answer came from, so you can check it.","tags":[],"title":"dbatools MCP Server","type":"page","url":"https://dbatools.io/mcp/"},{"categories":[],"content":"This FAQ covers the technical questions that come up most often in the dbatools community. Start with the safe diagnostics below, then jump to the section that matches your symptom.\nExamples use sql01 as a placeholder. Replace it with your server, server\\instance, or server,port. Commands and defaults can change between dbatools releases, so confirm the syntax installed on your machine with Get-Help \u0026lt;Command\u0026gt; -Full.\nThis page was last verified against the stable dbatools v2.8.3 release, published July 11, 2026. Open issues and code merged only to the development branch are not presented as released behavior.\nStart here: collect a useful diagnostic snapshot Open a fresh PowerShell session and run:\n$PSVersionTable.PSVersion Get-Module dbatools -ListAvailable | Sort-Object Version -Descending | Select-Object Name, Version, Path Get-Module dbatools, dbatools.library | Select-Object Name, Version, Path Test-NetConnection sql01 -Port 1433 Test-DbaConnection -SqlInstance sql01 If a dbatools command fails, use Get-DbatoolsError to capture the complete error before closing the session:\nGet-DbatoolsError When asking for help, include the PowerShell version, dbatools version and path, SQL Server version, operating system, exact command, and redacted error. Never post passwords, tokens, full connection strings, or sensitive server names.\nInstallation and module loading How do I install or update dbatools? Follow the current installation guide. For a normal current-user installation from the PowerShell Gallery:\nInstall-Module dbatools -Scope CurrentUser To update an installation that came from the PowerShell Gallery:\nUpdate-Module dbatools If the machine cannot reach the Gallery, use the offline installation guide. Do not mix Gallery, manual ZIP, Chocolatey, and source-tree installations unless you intentionally manage which copy PowerShell imports.\nWhy does an upgrade report an Authenticode issuer or publisher mismatch? dbatools moved to Azure Trusted Signing in v2.5.5. When upgrading from v2.5.4 or earlier, PowerShellGet may reject the new signing chain. If you have verified that the package source is the official PowerShell Gallery, make the transition with:\nInstall-Module dbatools -Scope CurrentUser -Force -SkipPublisherCheck This is a one-time publisher transition, not a switch to use routinely for unknown modules or repositories. See Upgrading from older versions and the Azure Trusted Signing explanation for strict execution-policy environments.\nWhy is PowerShell loading an older dbatools version? Multiple versions or installation paths are usually involved. Compare everything PowerShell can see with what is loaded now:\nGet-Module dbatools -ListAvailable | Sort-Object Version -Descending | Select-Object Name, Version, Path Get-Module dbatools | Select-Object Name, Version, Path Then test the expected version in a fresh session:\nImport-Module dbatools -RequiredVersion 2.0.0 -Force Replace 2.0.0 with a version that is actually installed. Also inspect $env:PSModulePath; a scheduled task, SQL Agent job, service account, and interactive console can each have different module paths.\nWhy does the module fail to import or report an SMO/assembly error? First test in a fresh PowerShell process. Then record the loaded paths and retry the import with verbose output:\nGet-Module dbatools, dbatools.library -ListAvailable | Select-Object Name, Version, Path Import-Module dbatools -Force -Verbose $Error[0] | Format-List * -Force Common causes include a partial update, two dbatools copies on the module path, another module loading a conflicting SMO or identity-library version, or a long-running host retaining old assemblies. Reproduce the failure in a clean session before deleting or reinstalling anything.\nRemove-Module does not unload .NET assemblies that are already in the PowerShell process. If the message says an assembly with the same name is already loaded, close that PowerShell process and test again in a genuinely new one. Update dbatools and the conflicting module, test both import orders, and use separate PowerShell processes when their dependency versions remain incompatible. Do not copy DLLs between module directories as a fix.\nConnections, TLS, and credentials Could not connect to SqlInstance: what should I check? Work through the connection in layers:\nTarget — confirm the exact instance name. For a named instance, try server\\instance; for a fixed port, try server,port. Network — test DNS and the SQL port from the same machine and identity that runs dbatools. SQL Server — confirm the service is running, the expected protocol is enabled, and the listener or SQL Browser configuration matches the name being used. Authentication — verify the login type, credential, and database access. Encryption — only after the preceding checks, inspect the TLS/certificate error and connection settings. Resolve-DnsName sql01 Test-NetConnection sql01 -Port 1433 Test-DbaConnection -SqlInstance sql01 If SQL Server is not on port 1433, test its actual port. A successful ping does not prove that the SQL endpoint is reachable.\nWhy does SSMS connect when dbatools does not? Make the two tests truly equivalent. Compare:\nthe exact server name, instance, and port; Windows, SQL, or Entra authentication and the actual process identity; the initial database; encryption and certificate-trust options; whether SSMS is running on a different computer; and whether an alias is configured only for one client or architecture. SSMS connection options are not automatically inherited by PowerShell. Start by reproducing the SSMS target and authentication explicitly with Connect-DbaInstance.\nHow should I handle a certificate trust or TLS error? The preferred fix is a certificate whose subject matches the name you connect to and whose chain is trusted by the client. Check the server name, certificate expiration, issuing chain, SQL Server encryption configuration, and client clock.\nFor a controlled environment where trusting that server certificate is an intentional choice, the current command reference supports a per-connection override:\n$server = Connect-DbaInstance -SqlInstance sql01 -TrustServerCertificate Pass $server to subsequent dbatools commands so the exception stays scoped to that connection. Set-DbatoolsInsecureConnection changes broader defaults by trusting certificates and disabling required encryption; do not use it as a reflexive fix, especially on production or untrusted networks.\nIf the certificate is valid for a DNS name that differs from the connection target, v2.8.3 does not expose a dedicated -HostNameInCertificate parameter. Supply the expected certificate name through the documented connection-string extension instead:\n$splatConnection = @{ SqlInstance = \u0026#34;sql-listener\u0026#34; EncryptConnection = $true AppendConnectionString = \u0026#34;HostNameInCertificate=sql.contoso.com\u0026#34; } $server = Connect-DbaInstance @splatConnection This keeps certificate validation enabled. The value must match a name covered by the server certificate.\nCan I set global connection defaults and override them per server? Yes. dbatools exposes module-wide settings through Get-DbatoolsConfig and Set-DbatoolsConfig. Inspect the settings available in the installed version before changing them:\nGet-DbatoolsConfig -FullName \u0026#39;sql.connection.*\u0026#39; | Select-Object FullName, Value, Description A command-line parameter or an explicitly created connection is the clearest way to make a server-specific exception:\n$production = Connect-DbaInstance -SqlInstance prod-sql01 -EncryptConnection $development = Connect-DbaInstance -SqlInstance dev-sql01 -TrustServerCertificate Get-DbaDatabase -SqlInstance $production Get-DbaDatabase -SqlInstance $development Treat global settings as a baseline and per-server connections as deliberate overrides. If a global change must survive future PowerShell sessions, review Register-DbatoolsConfig and its scope options first. Security-sensitive defaults should be documented and centrally managed rather than silently changed in a personal profile.\nAs of v2.8.3, dbatools does not have a built-in named profile system for interactive, non-interactive, or per-server connection profiles. For repeatable per-server policy, keep the values in your approved configuration source and use a small wrapper that returns an explicit Connect-DbaInstance object.\nHow do I connect with Entra ID, MFA, or a managed identity? v2.8.3 added first-class -AuthenticationType support. For an interactive Entra ID login with MFA:\n$splatConnection = @{ SqlInstance = \u0026#34;sql01.database.windows.net\u0026#34; Database = \u0026#34;appdb\u0026#34; AuthenticationType = \u0026#34;ActiveDirectoryInteractive\u0026#34; } $server = Connect-DbaInstance @splatConnection For a system-assigned managed identity in a supported Azure host:\n$splatConnection = @{ SqlInstance = \u0026#34;sql01.database.windows.net\u0026#34; Database = \u0026#34;appdb\u0026#34; AuthenticationType = \u0026#34;ActiveDirectoryManagedIdentity\u0026#34; } $server = Connect-DbaInstance @splatConnection If your automation already obtains a database access token, pass either the string or SecureString token returned by current Az PowerShell versions:\n$token = (Get-AzAccessToken -ResourceUrl \u0026#34;https://database.windows.net/\u0026#34;).Token $splatConnection = @{ SqlInstance = \u0026#34;sql01.database.windows.net\u0026#34; Database = \u0026#34;appdb\u0026#34; AccessToken = $token } $server = Connect-DbaInstance @splatConnection Pass the resulting $server object to later dbatools commands. Other supported authentication values and their credential requirements are listed in Get-Help Connect-DbaInstance -Full.\nHow do I use a different credential safely? Use a PSCredential rather than embedding a password in a script:\n$credential = Get-Credential $server = Connect-DbaInstance -SqlInstance sql01 -SqlCredential $credential For unattended automation, use an approved secret store or managed identity where supported. Do not serialize plain-text passwords, write credentials to logs, or paste them into a support thread.\nWhy does Windows authentication fail only from a jump server or scheduled job? This often points to identity, delegation, or the Kerberos double hop rather than dbatools itself. Record the identity at every hop, determine whether the connection uses Kerberos or NTLM, and verify SPNs and delegation with your domain administrators. Test-DbaConnection includes authentication and connection details that help isolate the failing hop.\nThere is also an open, environment-specific PowerShell 7.5 report involving an \u0026ldquo;untrusted domain\u0026rdquo; error across segmented networks. It has not been reproduced as a general dbatools defect. If your case matches it, compare the same target under Windows PowerShell 5.1 and PowerShell 7.5, include the network topology and authentication scheme, and do not weaken authentication merely to suppress the message.\nFinding and running commands How do I find the right dbatools command? Search by task or tag, then read the installed help:\nFind-DbaCommand -Pattern \u0026#39;backup history\u0026#39; Find-DbaCommand -Tag Migration Get-Command -Module dbatools \u0026#39;*AgentJob*\u0026#39; Get-Help Backup-DbaDatabase -Examples Every command also has a short URL in the form https://dbatools.io/Command-Name, for example Backup-DbaDatabase.\nWhy does PowerShell say a parameter cannot be found? The example may target a different dbatools version, or another command with the same name may be taking precedence. Check the command source and the help installed with it:\nGet-Command Connect-DbaInstance | Select-Object Name, Source, Version Get-Help Connect-DbaInstance -Full Use the syntax from your installed version. If you need a newer parameter, update intentionally and test the affected automation before production use.\nWhy is Get-DbaDatabase very slow on SQL Server 2022 or later? Older dbatools releases asked SMO to initialize an ActiveConnections field that could make database enumeration take minutes on SQL Server 2022. The fix is included in v2.8.3. Update to a current stable release and retest in a new PowerShell process.\nIf the current release is still slow, report the SQL Server build, database count, login permissions, dbatools and dbatools.library versions, and timings for both Get-DbaDatabase and $server.Databases. That separates the resolved initialization problem from network, permissions, or a new SMO regression.\nWhy does a command show only a warning instead of throwing an exception? Many dbatools commands favor friendly warnings for interactive use. For automation, check whether that command supports -EnableException; it lets try/catch handle the underlying exception.\ntry { Invoke-DbaQuery -SqlInstance sql01 -Database master ` -Query \u0026#39;SELECT @@SERVERNAME AS ServerName\u0026#39; -EnableException } catch { $_ | Format-List * -Force } Do not assume every command exposes the same exception switch. Confirm with Get-Help.\nInvoke-DbaQuery How do I run a query and keep the results? Assign or pipe the returned objects:\n$rows = Invoke-DbaQuery -SqlInstance sql01 -Database master ` -Query \u0026#39;SELECT name, state_desc FROM sys.databases\u0026#39; $rows | Export-Csv -Path .\\databases.csv -NoTypeInformation If the query is in a file, use the command\u0026rsquo;s -File parameter. For values supplied at runtime, use -SqlParameter rather than building T-SQL by concatenating untrusted strings.\nWhy do I see no output? Check that the script returns a result set, that you did not discard it with Out-Null, and that the selected database is correct. Capture the result in a variable and inspect both its type and count:\n$result = Invoke-DbaQuery -SqlInstance sql01 -Database appdb -Query $query $result.GetType().FullName @($result).Count Messages printed by T-SQL are not the same as rows returned by SELECT.\nBackup and restore Why can I see a backup path but SQL Server cannot? Backup and restore file access normally happens under the SQL Server service account, not the user running PowerShell. Test the path from SQL Server\u0026rsquo;s perspective:\nTest-DbaPath -SqlInstance sql01 -Path \u0026#39;\\\\fileserver\\sqlbackups\u0026#39; For a UNC path, grant the SQL Server service identity the required share and NTFS permissions. A mapped drive visible in your interactive session may not exist for the service account.\nDoes dbatools support Azure Blob Storage and S3-compatible storage? Yes, in v2.8.3:\nBackup-DbaDatabase -StorageBaseUrl supports Azure Blob Storage and S3-compatible object storage. Native S3 backup requires SQL Server 2022 or later. Restore-DbaDatabase -Path accepts Azure and S3 URLs and can use -StorageCredential. Test-DbaLastBackup -Path can discover and test backups from local, UNC, Azure, or S3 locations accessible to the destination SQL Server. $splatBackup = @{ SqlInstance = \u0026#34;sql2022\u0026#34; Database = \u0026#34;AdventureWorks\u0026#34; StorageBaseUrl = \u0026#34;s3://mybucket.s3.us-west-2.amazonaws.com/backups\u0026#34; Type = \u0026#34;Full\u0026#34; } Backup-DbaDatabase @splatBackup Cloud URLs, SQL credentials for storage, and mapped filesystem drives are different mechanisms. Confirm that the SQL Server version supports the chosen provider and that the credential exists on the SQL Server performing the operation. Never put a SAS token or storage secret directly in a support post.\nHow do I investigate a restore failure without immediately restoring? Start by checking that SQL Server can reach the files and read their headers:\nTest-DbaPath -SqlInstance sql01 -Path \u0026#39;\\\\fileserver\\sqlbackups\\appdb.bak\u0026#39; Read-DbaBackupHeader -SqlInstance sql01 -Path \u0026#39;\\\\fileserver\\sqlbackups\\appdb.bak\u0026#39; Then verify the backup chain, target SQL Server version, destination file paths, free space, encryption keys or certificates, and exclusive-access requirements. Select-DbaBackupInformation can reduce discovered backup history to the chain required for a point in time.\nFor Azure SQL Managed Instance, an open v2.8.x issue tracks an XTP file already exists precheck that can block a restore even when native T-SQL succeeds. -WithReplace is not a general fix for Managed Instance. If the exact symptom applies, follow that issue and validate any native restore workaround in a non-production recovery test before automating it.\nWhat is the safest way to prove backups can be restored? A real restore test is stronger evidence than a successful backup job or header check. Test-DbaLastBackup restores the selected backups, runs DBCC CHECKDB, and drops its test databases by default.\nRun it against a dedicated non-production destination with adequate storage and permissions, limit the first run to one known database, and review Get-Help Test-DbaLastBackup -Full before scheduling it. The command creates and drops databases and can consume substantial I/O, CPU, time, and disk space.\nSQL Agent, tasks, and unattended automation Why does a script work interactively but fail in SQL Agent or Task Scheduler? The unattended process usually has a different identity and environment. Record these values in the job output:\nwhoami $PSVersionTable.PSVersion $env:PSModulePath Get-Module dbatools -ListAvailable | Select-Object Name, Version, Path Also check:\nwhether dbatools is installed for the service or proxy account; the job\u0026rsquo;s PowerShell executable and bitness; filesystem, share, SQL, and certificate permissions for that identity; the working directory and use of relative paths; non-interactive prompts or profile-dependent variables; and whether the job machine can resolve and reach the SQL endpoint. Use explicit paths, explicit connection settings, and a non-interactive credential source. Test under the same account and on the same machine as the job.\nSafe automation at scale How should I test a command before running it across many servers? Start with one non-production target and a narrow object selection. Read the command\u0026rsquo;s examples and side effects, and use -WhatIf only when that specific command documents support for it. Capture output per target so one failure is not lost in a long pipeline.\nFor repeated work, create reusable connections with Connect-DbaInstance and pass the returned objects to later commands. This keeps authentication and connection choices explicit and avoids reconnecting for every operation.\nHow do I check the SQL Server error log? If a dbatools command returns an error, use Get-DbatoolsError to capture the detailed error information:\nGet-DbatoolsError This shows the same information as $Error[0] | Select * but formatted for easier reading.\nStill stuck? Before asking for help, reduce the problem to the smallest reproducible command in a clean session. Include:\nexact dbatools, dbatools.library, and PowerShell versions and paths; operating system and SQL Server version/edition; the command and sanitized parameters; the full redacted error record; whether it fails interactively, unattended, or both; and which network, authentication, TLS, and path checks succeeded. Ask the community in #dbatools on SQL Community Slack or open a GitHub issue when you have a reproducible defect. Search existing issues first, and never attach secrets or private production data.\nThis FAQ is prioritized from recurring community questions and a review of current GitHub issues, merged pull requests, the v2.8.3 release, and the development branch as of July 14, 2026. The installed command help remains the source of truth for the version running in your environment.\n","date":"2026-07-14","summary":"This FAQ covers the technical questions that come up most often in the dbatools community. Start with the safe diagnostics below, then jump to the section that matches your symptom.\nExamples use sql01 as a placeholder. Replace it with your server, server\\instance, or server,port. Commands and defaults can change between dbatools releases, so confirm the syntax installed on your machine with Get-Help \u0026lt;Command\u0026gt; -Full.\nThis page was last verified against the stable dbatools v2.","tags":[],"title":"Technical FAQ \u0026 Troubleshooting","type":"page","url":"https://dbatools.io/troubleshooting/"},{"categories":["announcements"],"content":"This post is about a huge update to the CSV import (and now export!) capabilities in dbatools. If you\u0026rsquo;ve used Import-DbaCsv, you\u0026rsquo;ve been using the LumenWorks CSV library under the hood for years. It\u0026rsquo;s been rock solid and I\u0026rsquo;ve sung its praises many times. But LumenWorks was last updated 7-8 years ago, and .NET has come a long way since then.\nI\u0026rsquo;ve been using Claude Code for various projects and had a Max 20x account when Anthropic announced they\u0026rsquo;d be pretty much giving away Opus 4.5 for a week. Opus is known for its exceptional quality when it comes to software architecture so this is a PERFECT time to use its ultra big brain to rewrite the CSV library!\nThe backstory Way back in 2015, I was obsessed with CSV import speed. I wrote about testing three different methods and eventually settled on a multithreaded approach that could hit 260,000 rows per second. It was glorious! Except\u0026hellip; sometimes 4 rows out of millions would go missing. ¯\\(ツ)/¯\nUltimately, I gave in and admitted that it wasn\u0026rsquo;t all about speed but rather, reliability. So I switched to LumenWorks and accepted the performance hit in exchange for imports that actually worked.\nThat was nice and all but then we\u0026rsquo;d get requests and I couldn\u0026rsquo;t fulfill them because I don\u0026rsquo;t know C# and even if I did, Lumenworks never got updated anyway.\nEnter Claude Code I asked Claude to create a replacement for LumenWorks that takes advantage of modern .NET features. Here was my initial prompt:\nCreate a replacement for LumenWorks.Framework.IO.dll PLUS the additional functionality requested in dbatools issues on GitHub. This library was written over a decade ago. Considering the advances in .NET and SqlClient, please add a CSV reader of better quality (more functionality often seen in paid systems, faster) using recent .NET and Microsoft Data best practices.\nWhat came back was fast as 🔥 and used several patterns (apparently Span\u0026lt;T\u0026gt;, ArrayPool, along with proper async) that simply didn\u0026rsquo;t exist when LumenWorks was written. I\u0026rsquo;m a PowerShell developer so that doesn\u0026rsquo;t mean much to me other than I love the speed.\nThe results Using Claude to figure out benchmarking, I ran proper benchmarks comparing Dataplat.Dbatools.Csv against not just LumenWorks, but also the modern CSV libraries: Sep, Sylvan, and CsvHelper.\nBenchmark: 100,000 rows × 10 columns (.NET 8, AVX-512)\nHere\u0026rsquo;s the interesting thing: performance varies dramatically depending on how you access the data.\nSingle column read (typical SqlBulkCopy/IDataReader pattern):\nLibrary Time (ms) vs Dataplat Sep 18 ms 3.7x faster Sylvan 27 ms 2.5x faster Dataplat 67 ms baseline CsvHelper 76 ms 1.1x slower LumenWorks 395 ms 5.9x slower All columns read (full row processing):\nLibrary Time (ms) vs Dataplat Sep 30 ms 1.8x faster Sylvan 35 ms 1.6x faster Dataplat 55 ms baseline CsvHelper 97 ms 1.8x slower LumenWorks 102 ms 1.9x slower For the single-column pattern (which is how SqlBulkCopy typically reads data), Dataplat is ~6x faster than LumenWorks! For full row processing, we\u0026rsquo;re ~1.9x faster.\nWhere we stand in 2025 Being honest, if pure parsing speed is your only concern, Sep is faster. Sep can hit an insane 21 GB/s with AVX-512 SIMD. But our library isn\u0026rsquo;t trying to be Sep. We\u0026rsquo;re built for database import workflows where you need:\nIDataReader interface - Stream directly to SqlBulkCopy without intermediate allocations Built-in compression - Import .csv.gz files without extracting first Real-world data handling - Lenient parsing for messy enterprise exports Progress reporting - Know how far along your 10 million row import is dbatools integration - Works seamlessly with Import-DbaCsv The speed tradeoff I asked Claude to explain why we can\u0026rsquo;t match Sep/Sylvan, and it comes down to architecture. Sep uses Span\u0026lt;T\u0026gt; and only creates actual strings when you explicitly ask for them. But the IDataReader interface that SqlBulkCopy uses requires returning real objects from GetValue(). For string columns, that means allocating actual string instances—we can\u0026rsquo;t just hand back a span.\nCould we create a Sep-like API? Sure. But then you\u0026rsquo;d need to write your own IDataReader wrapper to use SqlBulkCopy, handle decompression yourself, implement progress reporting\u0026hellip; you get the idea. We optimized for the complete workflow, not the micro-benchmark.\nFor file.csv.gz → SqlBulkCopy → SQL Server workflows, Dataplat\u0026rsquo;s integrated pipeline is often comparable to combining Sep + manual decompression + manual IDataReader wrapping, while being simpler to use.\nWhy is it so much faster? For those of you who are into C#, the implementation uses:\nSIMD-accelerated field search via SearchValues\u0026lt;char\u0026gt; on .NET 8+ ArrayPool buffer management - eliminates per-read buffer allocations Span-based parsing using ReadOnlySpan\u0026lt;char\u0026gt; for zero-copy string slicing Hardware intrinsics - leverages AVX-512 when available I understood less than half of that when Claude explained it to me, but the benchmarks don\u0026rsquo;t lie.\nWhat\u0026rsquo;s new So many new features that I added to Import-DbaCsv, as requested by users of dbatools! Here are some highlights:\nMulti-character delimiters For weird exports where fields are separated by :: or || \u0026ndash; LumenWorks couldn\u0026rsquo;t handle those. Now we can:\nImport-DbaCsv -Path data.csv -SqlInstance sql01 -Database tempdb -Delimiter \u0026#34;::\u0026#34; -AutoCreateTable Built-in compression support Need to import a 2GB CSV but only have 500MB of disk space? Save it as .csv.gz and import it directly:\nImport-DbaCsv -Path huge-data.csv.gz -SqlInstance sql01 -Database staging -AutoCreateTable The decompression happens on-the-fly. No extracting to disk. Supports GZip, Deflate, Brotli (.NET 8+), and ZLib (.NET 8+).\nParallel processing For really large files, you can enable parallel parsing:\nImport-DbaCsv -Path massive.csv -SqlInstance sql01 -Database warehouse -Table BigData -Parallel This spreads the parsing work across your CPU cores. On my 8-core machine, it helped quite a bit with the 10M+ row files.\nLenient quote handling Real-world CSVs are messy. Embedded quotes that aren\u0026rsquo;t properly escaped, smart quotes from Word, you name it. The new -QuoteMode Lenient option handles these gracefully instead of throwing errors:\nImport-DbaCsv -Path messy-export.csv -SqlInstance sql01 -Database tempdb -QuoteMode Lenient -AutoCreateTable Static columns for metadata Ever wanted to add a \u0026ldquo;SourceFile\u0026rdquo; or \u0026ldquo;ImportDate\u0026rdquo; column to every row during import? Now you can:\n$metadata = @{ SourceFile = \u0026#34;sales_q4.csv\u0026#34;; ImportDate = (Get-Date); Region = \u0026#34;EMEA\u0026#34; } Import-DbaCsv -Path sales.csv -SqlInstance sql01 -Database sales -Table SalesData -StaticColumns $metadata Custom date parsing Importing data from Oracle with those fun dd-MMM-yyyy dates? No problem:\nImport-DbaCsv -Path oracle_export.csv -SqlInstance sql01 -Database tempdb -DateTimeFormats @(\u0026#34;dd-MMM-yyyy\u0026#34;) -AutoCreateTable Culture-aware parsing German CSV with comma as decimal separator? French dates? We got you:\nImport-DbaCsv -Path german_data.csv -SqlInstance sql01 -Database tempdb -Culture \u0026#34;de-DE\u0026#34; -AutoCreateTable Progress reporting (v1.1.0) For those big imports where you want to know what\u0026rsquo;s happening:\nvar options = new CsvReaderOptions { ProgressReportInterval = 10000, ProgressCallback = progress =\u0026gt; { Console.WriteLine($\u0026#34;Processed {progress.RecordsRead:N0} records ({progress.RowsPerSecond:N0}/sec)\u0026#34;); } }; Cancellation support (v1.1.0) Long-running import and need to stop it? CancellationToken support is built in:\nvar options = new CsvReaderOptions { CancellationToken = cancellationTokenSource.Token }; Schema inference (v1.1.10) Automatically detect optimal SQL Server column types from your CSV data! No more nvarchar(MAX) for everything:\nusing Dataplat.Dbatools.Csv.Reader; // Fast: Sample first 1000 rows (tiny risk if data changes after sample) var columns = CsvSchemaInference.InferSchemaFromSample(\u0026#34;data.csv\u0026#34;); // Safe: Scan entire file with progress (zero risk of type mismatches) var columns = CsvSchemaInference.InferSchema(\u0026#34;data.csv\u0026#34;, null, progress =\u0026gt; { Console.WriteLine($\u0026#34;Progress: {progress:P0}\u0026#34;); }); // Generate CREATE TABLE statement string sql = CsvSchemaInference.GenerateCreateTableStatement(columns, \u0026#34;MyTable\u0026#34;); // CREATE TABLE [dbo].[MyTable] ( // [Id] int NOT NULL, // [Name] nvarchar(100) NULL, // [Price] decimal(10,2) NOT NULL, // [Created] datetime2 NULL // ); Detected types include: uniqueidentifier, bit, int, bigint, decimal(p,s), datetime2, varchar(n), and nvarchar(n) (when Unicode is detected). The inference uses early-exit optimization—once a column fails a type check, it stops checking that type for remaining rows.\nA brand new command: Export-DbaCsv This one\u0026rsquo;s been requested for years (GitHub issue #8646). We finally have a proper Export-DbaCsv with compression support:\n# Export a query to compressed CSV Export-DbaCsv -SqlInstance sql01 -Database Northwind -Query \u0026#34;SELECT * FROM Orders\u0026#34; -Path orders.csv.gz -CompressionType GZip # Export a whole table Export-DbaCsv -SqlInstance sql01 -Database Sales -Table \u0026#34;dbo.Customers\u0026#34; -Path customers.csv # Pipe from other commands Invoke-DbaQuery -SqlInstance sql01 -Database master -Query \u0026#34;SELECT * FROM sys.databases\u0026#34; | Export-DbaCsv -Path databases.csv -DateTimeFormat \u0026#34;yyyy-MM-dd\u0026#34; The output tells you what happened:\nPath : C:\\exports\\orders.csv.gz RowsExported : 830000 FileSizeBytes : 12582912 FileSizeMB : 12.00 CompressionType : GZip Elapsed : 00:00:14.2341234 RowsPerSecond : 58327.1 Standalone NuGet package If you\u0026rsquo;re a .NET developer and want to use this outside of PowerShell, the CSV library is available as a standalone NuGet package. Check out the gorrrrgeous landing page for a quick overview of features and benchmarks.\ndotnet add package Dataplat.Dbatools.Csv Basic C# usage using Dataplat.Dbatools.Csv.Reader; // Simple file reading using var reader = new CsvDataReader(\u0026#34;data.csv\u0026#34;); while (reader.Read()) { var name = reader.GetString(0); var value = reader.GetInt32(1); Console.WriteLine($\u0026#34;{name}: {value}\u0026#34;); } Bulk loading to SQL Server using Dataplat.Dbatools.Csv.Reader; using Microsoft.Data.SqlClient; // Stream CSV directly to SQL Server with minimal memory using var reader = new CsvDataReader(\u0026#34;large-data.csv\u0026#34;); using var connection = new SqlConnection(connectionString); connection.Open(); using var bulkCopy = new SqlBulkCopy(connection) { DestinationTableName = \u0026#34;MyTable\u0026#34;, BatchSize = 10000 }; bulkCopy.WriteToServer(reader); Console.WriteLine($\u0026#34;Imported {reader.CurrentRecordIndex} rows\u0026#34;); Reading compressed files // Automatically detects compression from extension (.gz, .br, .deflate, .zlib) using var reader = new CsvDataReader(\u0026#34;data.csv.gz\u0026#34;); // Or specify explicitly with security limits var options = new CsvReaderOptions { CompressionType = CompressionType.GZip, MaxDecompressedSize = 100 * 1024 * 1024 // 100MB limit for security }; using var reader = new CsvDataReader(stream, options); Handling messy real-world data var options = new CsvReaderOptions { Delimiter = \u0026#34;;\u0026#34;, // Custom delimiter Culture = CultureInfo.GetCultureInfo(\u0026#34;de-DE\u0026#34;), // German number formats DuplicateHeaderBehavior = DuplicateHeaderBehavior.Rename, // Name, Name_2, Name_3 MismatchedFieldAction = MismatchedFieldAction.PadOrTruncate, QuoteMode = QuoteMode.Lenient, // Handle malformed quotes CollectParseErrors = true // Don\u0026#39;t throw, collect errors }; using var reader = new CsvDataReader(\u0026#34;messy-export.csv\u0026#34;, options); while (reader.Read()) { // Process valid records } // Review any errors foreach (var error in reader.ParseErrors) { Console.WriteLine($\u0026#34;Row {error.RowIndex}: {error.Message}\u0026#34;); } Full documentation is in the project README, and if you\u0026rsquo;re migrating from LumenWorks, there\u0026rsquo;s a complete migration guide.\nTry it out All of this is included in the latest version of dbatools:\nUpdate-Module dbatools, dbatools.library Or if you\u0026rsquo;re starting fresh:\nInstall-Module dbatools Let us know what you think! File issues on our GitHub repository if you run into any problems.\n- Chrissy\n","date":"2025-11-30","summary":"This post is about a huge update to the CSV import (and now export!) capabilities in dbatools. If you\u0026rsquo;ve used Import-DbaCsv, you\u0026rsquo;ve been using the LumenWorks CSV library under the hood for years. It\u0026rsquo;s been rock solid and I\u0026rsquo;ve sung its praises many times. But LumenWorks was last updated 7-8 years ago, and .NET has come a long way since then.\nI\u0026rsquo;ve been using Claude Code for various projects and had a Max 20x account when Anthropic announced they\u0026rsquo;d be pretty much giving away Opus 4.","tags":["csv","import","export","performance"],"title":"A New CSV Library: Built for SQL Server","type":"post","url":"https://dbatools.io/new-csv-library/"},{"categories":[],"content":"","date":"2025-10-26","summary":"","tags":[],"title":"Commands Browser","type":"page","url":"https://dbatools.io/commands/"},{"categories":["announcements"],"content":"TLDR: dbatools is moving to Azure Trusted Signing, which means Microsoft backs our reputation and dbatools won\u0026rsquo;t trigger as many antivirus false positives.\nUsers upgrading from older signed versions will need -SkipPublisherCheck only once during the initial transition. PowerShell users with strict ExecutionPolicies (AllSigned/RemoteSigned) will need to trust each new certificate after every update due to Azure Trusted Signing\u0026rsquo;s daily cert rotation (but you can use the automation script provided below).\nWhile Update-Module seems like the best route, Install-Module with its support for Force and SkipPublisherCheck can help automate updates, as Update-Module does not support these parameters.\n# For the initial upgrade from old cert to Azure Trusted Signing Install-Module dbatools -Force -SkipPublisherCheck # Or avoid the publisher check issue during install Install-PSResource dbatools Update-PSResource dbatools Users who have their execution policies set to AllSigned or RemoteSigned will face ongoing challenges with certificate trust. This is going to start on August 5, 2025 with version 2.5.5.\nThe reputation problem For years, dbatools has been plagued by antivirus false positives. Search our GitHub issues for \u0026ldquo;malicious\u0026rdquo; and you can see that Carbon Black, Windows Defender, FireEye, Avast have all, at some point in time, flagged our legitimate module as malware.\nThis issue affected other legitimate PowerShell modules, especially ones that are code-signed, which never made sense. We really seemed to have been penalized by AV for doing the right thing.\nHow I got here This whole journey started when I accidentally deleted my private key while rebuilding my Azure VM (and copy/pasting from AI, lol). When I contacted DigiCert about recovery, they informed me I\u0026rsquo;d need to go through their entire validation process again - another 2+ months of proving my identity. Hell no, not again. I was complaining to PowerShell genius Jordan Borean and he told me about Azure Trusted Signing.\nI was actually considering not even signing anymore but this is a way better option. dbatools get to stay signed and I can do it all without DigiCert headache.\nIntroducing Azure Trusted Signing Microsoft now offers Azure Trusted Signing (formerly Azure Code Signing) as a new way to sign software. The identity validation process is dramatically faster than traditional code signing:\nImmediate reputation - Microsoft\u0026rsquo;s backing means instant trust from Windows SmartScreen and antivirus software Identity-based trust - Reputation is tied to your verified identity, not a specific certificate Lightning-fast validation - My identity was approved in 30 minutes (compared to DigiCert\u0026rsquo;s 2+ months!) The catch? Azure Trusted Signing rotates certificates daily. For most software this is fine, but PowerShell\u0026rsquo;s execution policies were designed for certificates that last years, not days. So users with strict execution policies (AllSigned/RemoteSigned) will get prompted to trust the new certificate after every dbatools update.\nWe\u0026rsquo;re essentially trading months of waiting for DigiCert validation every 3 years for a minor inconvenience for some users with each update. The good news is that after the initial migration, installation won\u0026rsquo;t require -SkipPublisherCheck anymore since the subject and root CA remain constant.\nThis service has been used internally for all Microsoft\u0026rsquo;s products and close partners for years. It works well for executables and DLLs, though PowerShell support for daily certificate rotation is lacking, as we\u0026rsquo;ve discovered.\nMicrosoft ID Verified I\u0026rsquo;m particularly amazed that our certificate now displays Microsoft\u0026rsquo;s name. Check out this beauty:\n# Quick way to check the dbatools certificate details $moduleBase = (Get-Module dbatools -ListAvailable | Select-Object -First 1).ModuleBase $moduleManifest = Join-Path $moduleBase dbatools.psd1 (Get-AuthenticodeSignature -FilePath $moduleManifest).SignerCertificate | Format-List * [Subject] CN=dbatools, O=dbatools, L=Vienna, S=Virginia, C=US [Issuer] CN=Microsoft ID Verified CS AOC CA 02, O=Microsoft Corporation, C=US [Serial Number] 330004B7A6E29F81DCCBBF7F7F00000004B7A6 [Not Before] 8/5/2025 2:39:41 PM [Not After] 8/8/2025 2:39:41 PM [Thumbprint] 33C788A6A72BEEF315CF9C10FF093048A9608B72 TimeStamperCertificate: [Subject] CN=Microsoft Public RSA Time Stamping Authority, OU=nShield TSS ESN:7D00-05E0-D947, OU=Microsoft America Operations, O=Microsoft Corporation, L=Redmond, S=Washington, C=US [Issuer] CN=Microsoft Public RSA Timestamping CA 2020, O=Microsoft Corporation, C=US \u0026ldquo;Microsoft Corporation\u0026rdquo; in the issuer field gives instant credibility with enterprise security teams, including yours. If you have to get approval to use dbatools, let them know that it\u0026rsquo;s Microsoft ID Verified.\nYou can also view this directly in Windows Certificate Manager. After importing dbatools, you\u0026rsquo;ll find it in your Trusted Publishers store:\nPress Win+R and type certmgr.msc (or search for \u0026ldquo;Manage user certificates\u0026rdquo; in the Start menu) Navigate to Trusted Publishers \u0026gt; Certificates Look for the dbatools entries The certificate is valid for only 3 days (8/5/2025 to 8/8/2025 in this example), which is why automation becomes important for users with strict execution policies. You might see multiple dbatools certificates if you\u0026rsquo;ve been using the module for a while - the older DigiCert-signed versions alongside the new Microsoft-backed one.\nUnderstanding the two different issues Thanks to Jordan\u0026rsquo;s clarification, there are actually two separate issues at play here. The confusion comes from the fact that installing and importing modules are handled differently by PowerShell.\nExecutionPolicy only affects Import-Module, not Install-Module. You can install modules even with the most restrictive execution policy because Install-Module is just downloading and copying files. But when you try to import (use) the module, that\u0026rsquo;s when ExecutionPolicy kicks in and checks if the scripts are allowed to run. This is why you might successfully install dbatools but then get blocked when trying to use it.\n1. Installation time: The -SkipPublisherCheck issue This affects Install-Module (but not Update-Module which doesn\u0026rsquo;t support it) when upgrading from a module signed with one certificate to another with a different subject or root CA. PowerShellGet checks if:\nThe leaf certificate subject has changed (e.g., CN=dbatools,O=dbatools,\u0026hellip;) The root CA subject has changed When this happens, you\u0026rsquo;ll see an error like this:\nPackageManagement\\Install-Package : Authenticode issuer \u0026#39;CN=dbatools, O=dbatools, L=Vienna, S=Virginia, C=US\u0026#39; of the new module \u0026#39;dbatools\u0026#39; with version \u0026#39;2.5.5\u0026#39; from root certificate authority \u0026#39;CN=Microsoft Identity Verification Root Certificate Authority 2020, O=Microsoft Corporation, C=US\u0026#39; is not matching with the authenticode issuer \u0026#39;CN=dbatools, O=dbatools, L=Vienna, S=Virginia, C=US\u0026#39; of the previously-installed module \u0026#39;dbatools\u0026#39; with version \u0026#39;2.5.1\u0026#39; from root certificate authority \u0026#39;CN=DigiCert Global Root G3, OU=www.digicert.com, O=DigiCert Inc, C=US\u0026#39;. If you still want to install or update, use -SkipPublisherCheck parameter. Notice how it\u0026rsquo;s comparing the root certificate authorities - DigiCert Global Root G3 (old) vs Microsoft Identity Verification Root Certificate Authority 2020 (new). You might also see this same error for dbatools.library since it\u0026rsquo;s a dependency that\u0026rsquo;s also being re-signed.\nGood news: This only happens once! When you upgrade from the old DigiCert-signed dbatools to the new Azure Trusted Signing version, you\u0026rsquo;ll need -SkipPublisherCheck. But after that initial transition, you won\u0026rsquo;t need it again because Azure Trusted Signing keeps the same subject and root CA (valid until 2045).\nIs -SkipPublisherCheck safe? Yes, in this context. You\u0026rsquo;re still getting dbatools from the PowerShell Gallery (a trusted source) and the module is still signed.\n2. Runtime: The execution policy thumbprint issue This affects Import-Module when you have an execution policy enabled (AllSigned or RemoteSigned). PowerShell checks if the exact certificate thumbprint is in your TrustedPublisher store. Since Azure Trusted Signing rotates certificates daily, this means:\nEvery update brings a new certificate with a new thumbprint Users need to trust each new certificate manually This happens every time you update dbatools This is the issue tracked in PowerShell issue #21550 (please go upvote it!).\nUPDATE: Jordan already created a Pull Request to address this in future versions of PowerShell 7, please upvote this as well.\nWorkaround for the runtime issue For users with strict execution policies, Jordan helped me with a script that automates the trust process.\nfunction Import-Dbatools { # Check and trust the certificate if needed $moduleBase = (Get-Module dbatools -ListAvailable | Select-Object -First 1).ModuleBase $moduleManifest = Join-Path $moduleBase dbatools.psd1 $cert = (Get-AuthenticodeSignature -FilePath $moduleManifest).SignerCertificate if (-not (Test-Path -Path \u0026#34;Cert:\\CurrentUser\\TrustedPublisher\\$($cert.Thumbprint)\u0026#34;)) { Write-Host \u0026#34;Trusting new dbatools certificate...\u0026#34; -ForegroundColor Yellow $store = Get-Item Cert:\\CurrentUser\\TrustedPublisher $store.Open(\u0026#39;ReadWrite\u0026#39;) $store.Add($cert) $store.Close() } # Now import the module Import-Module dbatools } This function will automatically trust the certificate whenever you import dbatools, eliminating the manual trust prompt. Since Azure Trusted Signing rotates certificates daily, you\u0026rsquo;ll benefit from having this automation - it will seamlessly handle the new certificate after each update.\nThe long-term solution Jordan referenced would be for PowerShell itself to recognize Azure Trusted Signing certificates by their OID rather than requiring thumbprint matching, which would eliminate the need for this workaround entirely. But until then, this script provides a practical solution. Unfortunately that one will never be implemented in PS 5.1\nExecution policies vs. modern code signing According to Microsoft\u0026rsquo;s docs, execution policies are a safety feature, not a security system. Users can easily bypass a policy by typing the script contents at the command line. It\u0026rsquo;s like having a \u0026ldquo;Please Don\u0026rsquo;t Touch\u0026rdquo; sign instead of a locked door.\nThis becomes obvious when you look at how different platforms handle PowerShell. On non-Windows computers, the default execution policy is Unrestricted and cannot be changed. Linux and macOS users have been running PowerShell with zero restrictions from day one:\n# Trying to change the execution policy to strict on Linux PS /mnt/c/github\u0026gt; Set-ExecutionPolicy AllSigned Set-ExecutionPolicy: Operation is not supported on this platform. Many experienced Windows PowerShell users end up setting their policy to Bypass anyway. We start cautious with RemoteSigned, realize we\u0026rsquo;re constantly fighting it, and eventually just turn it off. Microsoft making Unrestricted the default for all non-Windows platforms shows they\u0026rsquo;ve recognized that strict execution policies create more hassle than value.\nThe real problem is that execution policies assumed certificates would last years, not days. They\u0026rsquo;re designed to prevent accidental script execution - not to handle cryptographic signatures that rotate every 24 hours. Azure Trusted Signing\u0026rsquo;s daily certificate rotation breaks this model completely.\nHere\u0026rsquo;s how different execution policies handle daily certificate rotation:\nExecutionPolicy Impact Workaround Restricted Can\u0026rsquo;t run scripts at all Change policy or use PowerShell 7 AllSigned Prompts to trust new publisher daily Manually trust cert or use Install-PSResource RemoteSigned Prompts to trust new publisher daily (for downloaded scripts) Manually trust cert or use Install-PSResource Unrestricted No impact None needed Bypass No impact None needed The irony is that dbatools is now more trusted than ever, backed by Microsoft\u0026rsquo;s own signing infrastructure, yet it\u0026rsquo;s harder to use for people with strict execution policies. That\u0026rsquo;s not a security improvement; it\u0026rsquo;s just added complexity.\nWhat about existing installations? Good news! All existing versions of dbatools (2.5.1 and earlier) will remain valid forever with their current signatures. There\u0026rsquo;s no grace period or forced migration - you can keep using older versions if needed. Version 2.5.5 onwards (starting today) will use Azure Trusted Signing.\nWhat this means for you For most users running PowerShell 7, this transition will eventually be seamless once PowerShell adds proper support. You\u0026rsquo;ll get:\nNo more false positive virus warnings Faster module updates without certificate delays due to Digicert\u0026rsquo;s identity process Better integration with enterprise security policies Continued assurance that dbatools code hasn\u0026rsquo;t been tampered with One potential bonus for users who check digital signatures: Azure Trusted Signing may offer faster module load times. Usually, certificate validation adds noticeable delays when loading modules, especially in environments with strict certificate checking. Since Azure Trusted Signing certificates come from Microsoft\u0026rsquo;s infrastructure, the validation process could be faster. I still need to test.\nWhat can you do? Upvote PowerShell issue #21550 - community engagement drives prioritization (add a thumbs up) Give Jordan\u0026rsquo;s Pull Request some support - again, community engagement drives prioritization (add a thumbs up) Consider using PSResourceGet - Install-PSResource bypasses the install/update issues entirely Update your documentation - add -SkipPublisherCheck to your initial upgrade scripts Create an Import-Dbatools function - automate certificate trust for your team Spread the word - help other dbatools users understand this change For a module downloaded over 90,000 times in just the past two weeks, reducing friction matters even if that means educating users about the differences between install-time and runtime certificate validation for a while.\n","date":"2025-08-05","summary":"TLDR: dbatools is moving to Azure Trusted Signing, which means Microsoft backs our reputation and dbatools won\u0026rsquo;t trigger as many antivirus false positives.\nUsers upgrading from older signed versions will need -SkipPublisherCheck only once during the initial transition. PowerShell users with strict ExecutionPolicies (AllSigned/RemoteSigned) will need to trust each new certificate after every update due to Azure Trusted Signing\u0026rsquo;s daily cert rotation (but you can use the automation script provided below).","tags":["security"],"title":"dbatools is moving to Azure Trusted Signing","type":"post","url":"https://dbatools.io/azure-trusted-signing/"},{"categories":[],"content":"","date":"2025-01-12","summary":"","tags":[],"title":"Bill of Health","type":"page","url":"https://dbatools.io/health/"},{"categories":[],"content":"","date":"2025-01-12","summary":"","tags":[],"title":"SQL Server Build Reference","type":"page","url":"https://dbatools.io/builds/"},{"categories":["announcements"],"content":"TLDR: This error is expected and the change is legitimate. To update, switch to Install-Module, then slap on the -SkipPublisherCheck and -Force parameters and continue your update.\nInstall-Module dbatools -Force -SkipPublisherCheck I\u0026rsquo;ve always been very proud that dbatools is Code Signed like a \u0026ldquo;real\u0026rdquo; application. These certs prove the identity of the creator and help prevent tampering. The certificates cost a bunch of money and are hard to obtain. You gotta send in tons of paperwork, including your passport and business papers. But again, the payoff is fantastic \u0026ndash; basically, it makes dbatools ready for the Enterprise and ready to deploy at organizations with strict security.\nThe new private key storage requirement for Code Signing certificates were implemented this year, making the signing process a whole lot harder. This change lead to us not publishing a new module for a little over three months.\nValidating the dbatools organization identity for a code signing certificate is always a pain, and it\u0026rsquo;s required to recur every 3 years. This year, though, I had to do that PLUS I also had to figure out this whole new signing process.\nAfter months of working with Jess Pomfret and weeks of working with Jordan Borean, WE FINALLY FIGURED IT OUT!! But unfortunately, the new requirements breaks the catalog check for Update-Module because all of the Certificate Authorities had to update their CA Servers.\nThis causes the following error (or something similar):\nPS\u0026gt; Update-Module dbatools PackageManagement\\Install-Package : Authenticode issuer \u0026lsquo;CN=dbatools, O=dbatools, L=Vienna, S=Virginia, C=US\u0026rsquo; of the new module \u0026lsquo;dbatools\u0026rsquo; with version \u0026lsquo;2.0.4\u0026rsquo; from root certificate authority \u0026lsquo;CN=DigiCert Global G3 Code Signing ECC SHA384 2021 CA1, O=\u0026ldquo;DigiCert, Inc.\u0026rdquo;, C=US\u0026rsquo; is not matching with the authenticode issuer \u0026lsquo;CN=dbatools, O=dbatools, L=Vienna, S=Virginia, C=US\u0026rsquo; of the previously-installed module \u0026lsquo;dbatools\u0026rsquo; with version \u0026lsquo;1.1.99\u0026rsquo; from root certificate authority \u0026lsquo;CN=DigiCert Assured ID Root CA, OU=www.digicert.com, O=DigiCert Inc, C=US\u0026rsquo;. If you still want to install or update, use -SkipPublisherCheck parameter.\nThis is expected and the change is legitimate. To update, switch to Install-Module, then slap on the -SkipPublisherCheck and -Force parameters and continue your update. As people update over time, this should become less and less of a support issue for us, I presume in 2-3 years.\nLikely in part due to these new requirements, Microsoft is coming up with a new version (sorta) of Update-Module that does not perform this check so stay tuned.\nAnd again, this change and the subsequent errors are expected.\n","date":"2023-09-21","summary":"TLDR: This error is expected and the change is legitimate. To update, switch to Install-Module, then slap on the -SkipPublisherCheck and -Force parameters and continue your update.\nInstall-Module dbatools -Force -SkipPublisherCheck I\u0026rsquo;ve always been very proud that dbatools is Code Signed like a \u0026ldquo;real\u0026rdquo; application. These certs prove the identity of the creator and help prevent tampering. The certificates cost a bunch of money and are hard to obtain. You gotta send in tons of paperwork, including your passport and business papers.","tags":["security","troubleshooting"],"title":"Update-Module dbatools Authenticode Issuer Error","type":"post","url":"https://dbatools.io/update-module-error/"},{"categories":["announcements"],"content":"If you work in an offline environment, you\u0026rsquo;re probably familiar with how painful it can be to install anything, including PowerShell modules like dbatools.\nIn the past, dbatools had no dependencies, so the installation process was somewhat straightforward — you could even download a zip from our GitHub repo. However, with the introduction of the new dbatools.library dependency, the installation process has become a smidge more complex. In this post, I\u0026rsquo;ll walk you through the steps to install dbatools (and with it, dbatools.library) in an offline environment.\nWhat is dbatools.library? The dbatools.library has the big DLL/library files and our specific C# types like dbasize. This module will rarely change, perhaps 3-4 times per year.\nIt\u0026rsquo;s about 43MB when you download it from the PowerShell Gallery and like 162MB on disk. dbatools.library contains the libraries for both Desktop (Windows) and Core (Windows Core, Linux and mac OS). In dbatools 2.0, dbatools.library is a required dependency, so it needs to be available before you can use dbatools.\nFortunately, when running the Save-Module command, it will automatically download all the dependencies of the module you specify.\nStep-by-Step Guide To download dbatools for offline use, you\u0026rsquo;ll need a machine that is connected to the Internet and can run the Save-Module command. Save-Module is included in PowerShell v4 and up. You can also download it separately from the PowerShell Gallery if you\u0026rsquo;re using an older version of PowerShell (just rename .nuget to .zip and extract the files).\nAs mentioned earlier, Save-Module will download both dbatools and dbatools.library and save them to a folder on your machine. You can then copy the folder to your offline machine and install dbatools and dbatools.library from there.\nHere are the steps to install dbatools and dbatools.library in an offline environment:\nSave-Module dbatools and dbatools.library to a folder on your machine that is connected to the Internet. Save-Module dbatools -Path C:\\temp\\offline Copy the folder to your offline machine (I tend to zip the folder and then copy it to the offline machine). Save the modules to a folder in your $env:PSModulePath folder. For example, if you\u0026rsquo;re using PowerShell 5.1, you can save the modules to the C:\\Users\\username\\Documents\\WindowsPowerShell\\Modules folder. If you\u0026rsquo;re using PowerShell 7, you can save the modules to the C:\\Users\\username\\Documents\\PowerShell\\Modules folder. Don\u0026rsquo;t know where your $env:PSModulePath folder is? Run the following command:\n# Windows $env:PSModulePath -split \u0026#39;;\u0026#39; # Linux $env:PSModulePath -split \u0026#39;:\u0026#39; Pick any of those and place both dbatools and dbatools.library in the folder. This is what $env:PSModulePath looks like on my machine:\nC:\\Users\\cl\\Documents\\WindowsPowerShell\\Modules C:\\Program Files\\WindowsPowerShell\\Modules C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules Placing it in my home directory (C:\\Users\\cl\\Documents\\WindowsPowerShell\\Modules) will give only me access to the module. If I wanted to make dbatools available to all users, including the SQL Server user account, I\u0026rsquo;d have to place the modules in the path that contains Program Files.\nNote: If you really want to load it from a directory that is not in your $env:PSModulePath, that is possible too, but you\u0026rsquo;ll need to explicitly import both modules. For example, if you want to load dbatools from the C:\\temp\\offline folder, you can run the following command:\nImport-Module C:\\temp\\offline\\dbatools.library Import-Module C:\\temp\\offline\\dbatools And there we have it, you can now use dbatools 2.0 in an offline environment.\nPS. Most of this blog post was written with GitHub Copilot.\n","date":"2023-04-05","summary":"If you work in an offline environment, you\u0026rsquo;re probably familiar with how painful it can be to install anything, including PowerShell modules like dbatools.\nIn the past, dbatools had no dependencies, so the installation process was somewhat straightforward — you could even download a zip from our GitHub repo. However, with the introduction of the new dbatools.library dependency, the installation process has become a smidge more complex. In this post, I\u0026rsquo;ll walk you through the steps to install dbatools (and with it, dbatools.","tags":["installation"],"title":"Offline Installation of dbatools 2.0 with the dbatools.library Dependency","type":"post","url":"https://dbatools.io/offline-install/"},{"categories":[],"content":"If you work in an offline environment, you\u0026rsquo;re probably familiar with how painful it can be to install anything, including PowerShell modules like dbatools.\nIn the past, dbatools had no dependencies, so the installation process was somewhat straightforward — you could even download a zip from our GitHub repo. However, with the introduction of the new dbatools.library dependency, the installation process has become a smidge more complex. In this post, I\u0026rsquo;ll walk you through the steps to install dbatools (and with it, dbatools.library) in an offline environment.\nWhat is dbatools.library? The dbatools.library has the big DLL/library files and our specific C# types like dbasize. This module will rarely change, perhaps 3-4 times per year.\nIt\u0026rsquo;s about 43MB when you download it from the PowerShell Gallery and like 162MB on disk. dbatools.library contains the libraries for both Desktop (Windows) and Core (Windows Core, Linux and mac OS). In dbatools 2.0, dbatools.library is a required dependency, so it needs to be available before you can use dbatools.\nFortunately, when running the Save-Module command, it will automatically download all the dependencies of the module you specify.\nStep-by-Step Guide To download dbatools for offline use, you\u0026rsquo;ll need a machine that is connected to the Internet and can run the Save-Module command. Save-Module is included in PowerShell v4 and up. You can also download it separately from the PowerShell Gallery if you\u0026rsquo;re using an older version of PowerShell (just rename .nuget to .zip and extract the files).\nAs mentioned earlier, Save-Module will download both dbatools and dbatools.library and save them to a folder on your machine. You can then copy the folder to your offline machine and install dbatools and dbatools.library from there.\nHere are the steps to install dbatools and dbatools.library in an offline environment:\nSave-Module dbatools and dbatools.library to a folder on your machine that is connected to the Internet. Save-Module dbatools -Path C:\\temp\\offline Copy the folder to your offline machine (I tend to zip the folder and then copy it to the offline machine). Save the modules to a folder in your $env:PSModulePath folder. For example, if you\u0026rsquo;re using PowerShell 5.1, you can save the modules to the C:\\Users\\username\\Documents\\WindowsPowerShell\\Modules folder. If you\u0026rsquo;re using PowerShell 7, you can save the modules to the C:\\Users\\username\\Documents\\PowerShell\\Modules folder. Don\u0026rsquo;t know where your $env:PSModulePath folder is? Run the following command:\n# Windows $env:PSModulePath -split \u0026#39;;\u0026#39; # Linux $env:PSModulePath -split \u0026#39;:\u0026#39; Pick any of those and place both dbatools and dbatools.library in the folder. This is what $env:PSModulePath looks like on my machine:\nC:\\Users\\cl\\Documents\\WindowsPowerShell\\Modules C:\\Program Files\\WindowsPowerShell\\Modules C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules Placing it in my home directory (C:\\Users\\cl\\Documents\\WindowsPowerShell\\Modules) will give only me access to the module. If I wanted to make dbatools available to all users, including the SQL Server user account, I\u0026rsquo;d have to place the modules in the path that contains Program Files.\nNote: If you really want to load it from a directory that is not in your $env:PSModulePath, that is possible too, but you\u0026rsquo;ll need to explicitly import both modules. For example, if you want to load dbatools from the C:\\temp\\offline folder, you can run the following command:\nImport-Module C:\\temp\\offline\\dbatools.library Import-Module C:\\temp\\offline\\dbatools And there we have it, you can now use dbatools 2.0 (now available!) in an offline environment.\nPS. Most of this blog post was written with GitHub Copilot 🤩\n","date":"2023-04-05","summary":"If you work in an offline environment, you\u0026rsquo;re probably familiar with how painful it can be to install anything, including PowerShell modules like dbatools.\nIn the past, dbatools had no dependencies, so the installation process was somewhat straightforward — you could even download a zip from our GitHub repo. However, with the introduction of the new dbatools.library dependency, the installation process has become a smidge more complex. In this post, I\u0026rsquo;ll walk you through the steps to install dbatools (and with it, dbatools.","tags":[],"title":"Offline Installation of dbatools 2.0 with the dbatools.library Dependency","type":"post","url":"https://dbatools.io/offline/"},{"categories":["announcements"],"content":"So much is new and different! If you\u0026rsquo;d like to try it while you read this blog post, you can currently install dbatools 2.0 by executing the following command:\nInstall-Module dbatools Requirements dbatools still works on PowerShell v3 an v4! Thanks to Microsoft for making that possible with SMO.\nPowerShell v5.1 is still supported, of course. That\u0026rsquo;s what I use and develop on. But when it comes to PowerShell v7, we did up the requirements to 7.2 and above and 6.0 is no longer supported. That\u0026rsquo;s because we changed underlying our dotnet version to dotnet 6 and that\u0026rsquo;s only supported in PowerShell v7.2 and above.\ndbatools is now two modules (but you still just install it using Install-Module dbatools) dbatools is now divided into two modules. This helps reduce the amount of space we require on your hard drive, especially if you update often.\ndbatools The dbatools has the PowerShell code. Depending on the team\u0026rsquo;s productivity, this can change and require an update multiple times per day. Usually, though, we do about weekly releases.\nIf you\u0026rsquo;re used to looking at our code, you\u0026rsquo;ll see that allcommands.ps1 is no longer there. That combined file was often pretty big and people were tempted to modify it. Now, it\u0026rsquo;s a compressed file called dbatools.dat that\u0026rsquo;s 1/5th the size. This file is automatically expanded and imported when dbatools is loaded. If you end up having any issues with your anti-virus, please file an issue immediately so that we can take a look. I may have to revert this change (AV\u0026rsquo;s sometimes hate compression), but so far, it\u0026rsquo;s worked well for me.\nYou can find the GitHub repository for dbatools in our organizational repository, dataplat/dbatools.\ndbatools.library The dbatools.library has the big DLL/library files and our specific C# types like dbasize. This module will rarely change, perhaps 3-4 times per year. This module, which you can use for your own projects if you\u0026rsquo;re a developer, supplies the following libraries:\nSQL Management Objects (SMO) - these are the DLLs that power dbatools and SQL Server Management Studio SqlClient - this provides Microsoft.Data.SqlClient which replaces System.Data.SqlClient DacFx - this is for sqlpackage and publishing, etc Microsoft.SqlServer.XEvent.XELite - This is a new library that helps us manage Extended Events Bogus - this framework helps us with our Data Generation and Masking commands XESmartTarget - This is another framework that helps us with SQL Server Extended Events It\u0026rsquo;s about 43MB when you download it from the PowerShell Gallery and like 162MB on disk. dbatools.library contains the libraries for both Desktop (Windows) and Core (Windows Core, Linux and mac OS).\nYou can find the GitHub repository for dbatools.library in our organizational repository, dataplat/dbatools.library.\nConnection defaults are now more secure Remember when the whole web went from HTTP to HTTPS? This is sorta the same, but for SQL Server connections. These new defaults, which were modified by Microsoft\u0026rsquo;s underlying libraries, may prevent you from being able to connect until you make some changes.\nYou can read more on my blog post, \u0026ldquo;New Encryption and Certificate Defaults in Microsoft\u0026rsquo;s SQL Server Connection Provider\u0026rdquo;.\nThat message will appear until a later version or until you configure the message to no longer appear.\nSet-DbatoolsConfig -Name Import.EncryptionMessageCheck -Value $false -PassThru | Register-DbatoolsConfig We now support fewer ways to install dbatools Dependency management is hard, so we\u0026rsquo;ve removed install.ps1. The easiest way, really, is to use a modern version of Windows that is connected to the Internet, then using Install-Module or Save-Module. dbatools still works on older versions of PowerShell, all the way back to v3 but you\u0026rsquo;ll just have to get the files in a different way now.\nThe upside is that this move will save millions of terabytes of storage all around the world AND! The way we setup the library just makes it so much more reliable. It\u0026rsquo;s hard to explain because I don\u0026rsquo;t know enough about DLL management, but all I know is that this works so much better.\nDevelopment and debugging now requires cloning dbatools from the GitHub repository Previously, we invested a lot of time attempting to strike a balance between debugging capabilities and fast imports. This required us to include even more code in the module and having that code there confused some non-dev end-users who wanted to make changes to a command because they didn\u0026rsquo;t understand how we import the module.\nAllll that whole run-on sentence to say, if you\u0026rsquo;d like to debug, you will need to clone our our repository to grab the code, as the PowerShell Gallery version no longer supports debugging.\nThe folder structure changed slightly When I was a younger scripter, I\u0026rsquo;d see words like \u0026ldquo;public\u0026rdquo; and \u0026ldquo;private\u0026rdquo; and thought it so confusing. If it\u0026rsquo;s so private, why can I see it? Then I realized they were like helper commands that end-users don\u0026rsquo;t need. So it made more sense to me to have a folder called functions where I saved all my exported/public functions. Then I\u0026rsquo;d create a folder called internal for my internal/private commands.\nI thought this naming scheme would help others understand it the way that I did, and perhaps it was useful. But then one day I woke up and thought functions/internal was ugly and public/private was pretty. So I renamed them and our core team seemed happy with the change. Now it feels all grown up.\nSqlCollaborative is now DataPlat Man, that was hard to spell. We\u0026rsquo;ve renamed our GitHub Organization and we changed all internal references to s-q-l-c-o-l-l-a-b-o-r-a-t-i-v-e. Even our C# class namespace has changed.\nA bunch of other stuff For more details on what else has changed, please check out our merged Pull Requests since October 22, 2022 to see.\nAnd again, if you\u0026rsquo;d like to try dbatools 2.0, run the following code:\nInstall-Module dbatools Let us know how it works for you!\n","date":"2023-03-05","summary":"So much is new and different! If you\u0026rsquo;d like to try it while you read this blog post, you can currently install dbatools 2.0 by executing the following command:\nInstall-Module dbatools Requirements dbatools still works on PowerShell v3 an v4! Thanks to Microsoft for making that possible with SMO.\nPowerShell v5.1 is still supported, of course. That\u0026rsquo;s what I use and develop on. But when it comes to PowerShell v7, we did up the requirements to 7.","tags":["release"],"title":"What's new and different in dbatools 2.0","type":"post","url":"https://dbatools.io/dbatools-2-0/"},{"categories":["announcements"],"content":"This post is about Import-DbaCsv, a command within the dbatools PowerShell module for SQL Server.\nI\u0026rsquo;ve been writing about CSV imports using PowerShell for a pretty long time and in VBScript for even longer. Initially, my primary concerns were ease-of-use and speed. Over time, I realized that what mattered most was:\nEase-of-use Reliability Data quality management I learned a ton about performance from my speed experiments but in the end, I threw most of that out in favor of a higher quality and mildly slower solution using a .NET compiled library called LumenWorks.Framework.IO.\nThe best part about using LumenWorks instead of rolling my own solution is that it handles imperfect data very well. My solutions were fast but had no error handling and only the cleanest of CSVs would work. Clean CSVs are ideal but not always found in real-world data sets.\nEase-of-use Ease and enjoyment is extremely important when designing and using a tool because if something is a headache to use, you\u0026rsquo;ll probably start avoiding it. Like me with the Import and Export Wizard. I haven\u0026rsquo;t used it in over a decade, because nearly every time I tried, this happened:\nUghhh just figure it out and let me import my data! Initial versions of Import-DbaCsv only accepted perfect data too, though, so I get it ¯\\(ツ)/¯.\nNow, Import-DbaCsv just figures everything out and lets you import your data, whether it\u0026rsquo;s perfect or not. When it comes to ease-of-use, it really can\u0026rsquo;t get any easier than this to import a whole directory full of varied CSVs:\nGet-ChildItem C:\\temp\\csv | Import-DbaCsv -SqlInstance sql01 -Database tempdb -AutoCreateTable This will get a list of all CSV files in C:\\temp\\csv, then import them to the tempdb database on sql01, using the basename of the file as the table name. If the table doesn\u0026rsquo;t already exist, it\u0026rsquo;ll auto-create it using nvarchar(MAX), which is inefficient/slow but guaranteed to be big enough.\nOnce the data has been imported, you can massage this data however you like within SQL Server, which is much more suited for data manipulation than PowerShell due to the focus and power of T-SQL.\nAs suggested by Import-DbaCsv\u0026rsquo;s verbose messages, if you\u0026rsquo;re looking for the fastest import possible, you should pre-create the table with appropriate datatypes. But if you just want the data in SQL Server with no fuss, -AutoCreateTable will do.\nPre-creating tables to increase performance Here\u0026rsquo;s the DDL of a sample table which was automatically created to accommodate a CSV import.\nCREATE TABLE allcountries ( GeoNameId nvarchar(max) NULL, Name nvarchar(max) NULL, AsciiName nvarchar(max) NULL, AlternateNames nvarchar(max) NULL, Latitude nvarchar(max) NULL, Longitude nvarchar(max) NULL, FeatureClass nvarchar(max) NULL, FeatureCode nvarchar(max) NULL, CountryCode nvarchar(max) NULL, Cc2 nvarchar(max) NULL, Admin1Code nvarchar(max) NULL, Admin2Code nvarchar(max) NULL, Admin3Code nvarchar(max) NULL, Admin4Code nvarchar(max) NULL, Population nvarchar(max) NULL, Elevation nvarchar(max) NULL, Dem nvarchar(max) NULL, Timezone nvarchar(max) NULL, ModificationDate nvarchar(max) NULL ) This resulted in an import of 4.4 million rows in 2 minutes and 4 seconds, or 35446 rows per second.\nComputerName : workstation InstanceName : MSSQLSERVER SqlInstance : workstation Database : tempdb Table : allcountries Schema : dbo RowsCopied : 4400000 Elapsed : 00:02:04 RowsPerSecond : 35446.7 Path : C:\\Archive\\csv\\allcountries.csv Acceptable enough, especially for a wide table. The import can be sped up by creating more accurate data types, however. After optimizing the datatypes for the data that will actually be in the table, the DDL looks like this:\nCREATE TABLE allcountries ( GeoNameId int PRIMARY KEY, Name nvarchar(200), AsciiName nvarchar(200), AlternateNames nvarchar(max), Latitude float, Longitude float, FeatureClass char(1), FeatureCode varchar(10), CountryCode char(2), Cc2 varchar(255), Admin1Code varchar(20), Admin2Code varchar(80), Admin3Code varchar(20), Admin4Code varchar(20), Population bigint, Elevation varchar(255), Dem int, Timezone varchar(40), ModificationDate smalldatetime, ) This resulted in an import of 4.4 million rows in about 59 seconds, or 74754 rows per second. This doubles the performance!\nComputerName : workstation InstanceName : MSSQLSERVER SqlInstance : workstation Database : tempdb Table : allcountries Schema : dbo RowsCopied : 4400000 Elapsed : 58.86 s RowsPerSecond : 74754.9 Path : C:\\Archive\\csv\\allcountries.csv If you did just stuff your data into the database, you can use INSERT\u0026hellip;SELECT to import the data into the properly structured table. In my case, it took 32 seconds to insert 4.4 million rows from the import table to the optimized table.\nReliability The most important part of importing data is that the data remains the same. But I found that some data could disappear if multithreading was used. Multithreading got me up to 260,000 rows per second for some data sets, but sometimes like 4 rows out of millions would be missing. Not good enough, it needs to be perfect.\nI\u0026rsquo;ve seen this behavior in other PowerShell runspace/multithreading projects (C# can deliver perfection but PS and multithreading is complicated), so by default, I removed runspaces which reduced the import speed by half. That was hard to let go of, but opened me up to using a third-party solution like LumenWorks.\nData quality management As I mentioned earlier, real-world CSVs are filled with imperfect data. For example, let\u0026rsquo;s say that you have a CSV and it uses quotes when a comma is present in the actual data.\n101152, Skies of Ores Sunblock, \u0026#34;This 30 SPF sunblock is light, scent-free and safe for all skin types.\u0026#34; This has to be handled within the importer, because if the data is imported as-is, the quotes will be included in the database and that\u0026rsquo;s not what we want.\nHandling this data introduced nanosecond slowdowns so my initial projects didn\u0026rsquo;t support it because I was obsessed with speed. As it turns out, though, most CSVs contain these types of exceptions, so most people couldn\u0026rsquo;t even use initial versions of Import-DbaCsv (then called Import-CsvToSql) to import their data.\nWhen I let go of my dreams of achieving speeds that matched bcp (a program compiled in c, which is known for its blazing speeds even moreso than other compiled languages), I ended up with a smarter tool that works for most people and most datasets.\nMy favorite things It\u0026rsquo;s near impossible to quickly (milliseconds) determine how many rows are going to be uploaded within in a large file. Because of this, I couldn\u0026rsquo;t add a progress bar for the rows left to upload, but I could show how many rows were imported and the elapsed time, updated every 50,000 rows.\nI also like the output, which includes things I\u0026rsquo;m always curious about.\nComputerName : workstation InstanceName : MSSQLSERVER SqlInstance : workstation Database : tempdb Table : AirlineDemoSmall Schema : dbo RowsCopied : 600000 Elapsed : 4.99 s RowsPerSecond : 120168.2 Path : C:\\temp\\csv\\AirlineDemoSmall.csv I appreciate that Import-DbaCsv just makes it so easy to import a bunch of CSVs, especially when I\u0026rsquo;m using it for my own projects. Yeah, the newly created tables are inefficient but the data is there and I can just use that table structure to create a new table and go about my day.\nMy most favorite thing, though, is feeling confident that Lumenworks will properly import user data, even at the expense of speed.\n","date":"2022-05-24","summary":"This post is about Import-DbaCsv, a command within the dbatools PowerShell module for SQL Server.\nI\u0026rsquo;ve been writing about CSV imports using PowerShell for a pretty long time and in VBScript for even longer. Initially, my primary concerns were ease-of-use and speed. Over time, I realized that what mattered most was:\nEase-of-use Reliability Data quality management I learned a ton about performance from my speed experiments but in the end, I threw most of that out in favor of a higher quality and mildly slower solution using a .","tags":["csv","import"],"title":"Import-DbaCsv Design Considerations","type":"post","url":"https://dbatools.io/import-csv-design/"},{"categories":["announcements"],"content":"SQL Client Aliases allow you to connect to a SQL Server instance using another name. This is especially useful during migrations. Want your servers to connect to the new SQL Server without modifying connection strings within your application? Or what if you could use easy-to-remember names for your docker containers? SQL Client Aliases can help.\nFor the longest time, I managed these aliases using cliconfg for 64-bit applications (C:\\Windows\\System32\\cliconfg.exe) or cliconfg for 32-bit applications (C:\\Windows\\SysWOW64\\cliconfg.exe).\nWhen I\u0026rsquo;d remember and if it was available, I\u0026rsquo;d also manage SQL Client Aliases using SQL Server Configuration Manager, which surfaces aliases for both 32-bit applications and 64-bit applications in a single pane. Here\u0026rsquo;s a screenshot of both SQL Server Configuration Manager and cliconfg. Note they both show the same aliases, confirming that you can manage aliases using whichever you prefer.\nSQL Native Client provides cliconfg.exe but I think it\u0026rsquo;s also built into Windows. I\u0026rsquo;ve yet to find an OS that doesn\u0026rsquo;t have cliconfg on it - and I tried all the way back to Windows 2003! So if SQL Client Aliases seem useful to you, you\u0026rsquo;re in luck.\nWhile you can manage SQL Client Aliases using the GUI, I prefer using dbatools which helps me avoid logging into multiple servers at once, and creates both the 32-bit and 64-bit aliases at once.\nUsing dbatools I find SQL Client Aliases most useful for facilitating easy migrations and using them is even recommended as a best practice in the SharePoint world.\nFirst, I check all of my servers to see which aliases are currently setup.\nGet-DbaClientAlias -ComputerName web01, web02, web03 Then, I\u0026rsquo;ll either remove old ones using something like this, which allows me to select the aliases I want to remove.\nGet-DbaClientAlias -ComputerName web01, web02, web03 | Out-GridView -Passthru | Remove-DbaClientAlias Then I create my aliases as required. Note that the aliases and server names can be formatted in a number of ways. Both named instances and specifying a port numbers is supported.\nNew-DbaClientAlias -ComputerName web01, web02, web03 -ServerName sql02 -Alias sql01 New-DbaClientAlias -ComputerName web01, web02, web03 -ServerName sql02\\sqlexpress19 -Alias sql01\\sqlexpress14 New-DbaClientAlias -ComputerName web01, web02, web03 -ServerName \u0026#39;sql02,2383\u0026#39; -Alias \u0026#39;sql01,2383\u0026#39; By default, connections are created as TCP/IP. Want to use named pipes? That\u0026rsquo;s also possible.\nNew-DbaClientAlias -ServerName sqlcluster\\sharepoint -Alias sp -Protocol NamedPipes If you\u0026rsquo;re familiar with named pipe aliases, you may remember that it creates a funky string. Don\u0026rsquo;t worry, we take care of that for you. Just pass the ServerName and Alias as you would with TCP/IP and we\u0026rsquo;ll build the named pipe string for you.\nNow that I\u0026rsquo;ve created all of my required aliases, let\u0026rsquo;s take a look at them using Get-DbaClientAlias and Out-GridView. Note that when I don\u0026rsquo;t specify -ComputerName, the command executes against my local machine, in this case, WORKSTATIONX.\nTry It Out Test this out yourself - create a new alias, then use dbatools, Azure Data Studio or SSMS to connect to the new server using the old name. In the example below, I\u0026rsquo;ve migrated sql2014 to sql2016 then will use the sql2014 alias to connect.\nAutomating your migrations just got even easier! For more information, check out our built-in help using Get-Help Get-DbaClientAlias -Detailed.\nChrissy ","date":"2020-01-10","summary":"SQL Client Aliases allow you to connect to a SQL Server instance using another name. This is especially useful during migrations. Want your servers to connect to the new SQL Server without modifying connection strings within your application? Or what if you could use easy-to-remember names for your docker containers? SQL Client Aliases can help.\nFor the longest time, I managed these aliases using cliconfg for 64-bit applications (C:\\Windows\\System32\\cliconfg.exe) or cliconfg for 32-bit applications (C:\\Windows\\SysWOW64\\cliconfg.","tags":[],"title":"Working with SQL Client Aliases","type":"post","url":"https://dbatools.io/aliases/"},{"categories":["announcements"],"content":"Within dbatools, you may notice file sizes are pretty and human-readable.\nThat was some C# based magic created by Microsoft PFE and creator of PSFramework, Fred Weinmann. In the background, SQL Server often gives us different types of numbers to represent file sizes. Sometimes it\u0026rsquo;s bytes, sometimes it\u0026rsquo;s megabytes. We wanted to standardize the sizing in dbatools, and thus the dbasize type was born.\nUsage This size type is cool because it looks beautiful, showing KB, MB, GB, TB and PB. But it\u0026rsquo;s also packed with usable data behind-the-scenes. This can be seen when you expand the property, either by using .ColumnName or Select -ExpandProperty ColumnName.\nThis means that you don\u0026rsquo;t have to parse the results to get the bits and bytes - it\u0026rsquo;s all there in the background. Here\u0026rsquo;s the code used in the above screenshot:\n# Evaluate UsedSpace details Get-DbaDbSpace -SqlInstance sql2017 -Database master | Select -First 1 | Select -ExpandProperty UsedSpace When using this type in practice, your code will likely look something like this:\n# Use the type with Where-Object Get-DbaDbSpace -SqlInstance sql2017 | Where-Object { $_.UsedSpace.Megabyte -gt 10 } # Write it to file using foreach Set-Content -Path C:\\temp\\mb.csv -Value \u0026#39;Name,UsedMB\u0026#39; foreach ($file in (Get-DbaDbSpace -SqlInstance sql2017 -Database master)) { $name = $file.Database $usedmb = $file.UsedSpace.Megabyte Add-Content -Path C:\\temp\\mb.csv -Value \u0026#34;$name,$usedmb\u0026#34; } # Write it to CSV using calculated properties Get-DbaDbSpace -SqlInstance sql2017 -Database master | Select-Object -Property Database, @{ Name = \u0026#39;UsedMB\u0026#39;; Expression = { $_.UsedSpace.Megabyte } } | Export-Csv -Path C:\\temp\\mb.csv -NoTypeInformation Configuration You can also configure the output. Want more than 2 numbers after the decimal points? Can do! Don\u0026rsquo;t want the human-readable display by default? It can be disabled using Set-dbatoolsConfig 👍\n# Get the two properties you\u0026#39;ll be working with Get-dbatoolsConfig formatting.size.* | Out-GridView This ultimately shows details for formatting.size.digits and formatting.size.style.\nformatting.size.digits This setting controls how many digits are displayed after the decimal. By default, two digits are shown. Let\u0026rsquo;s change that to four.\n# Change value to 4 Set-dbatoolsConfig -FullName formatting.size.digits -Value 4 | Register-dbatoolsConfig Piping to Register-dbatoolsConfig persists the value across sessions. Otherwise, your digits would revert back to two when you create a new session.\nNow you can see that there are 4 digits after the decimal! Cool. I didn\u0026rsquo;t even realize this before writing this blog post 😄\nformatting.size.style By default, we use the \u0026ldquo;Dynamic\u0026rdquo; styling size. This basically means that we\u0026rsquo;ll show file sizes similar to way Explorer does: the biggest size is used. So if something is 2.5 megabytes, it won\u0026rsquo;t use B or KB, but 2.5 MB.\nNow let\u0026rsquo;s disable styling altogether and show values in bytes, but only for the current session.\n# Removing formatting, show in bytes Set-dbatoolsConfig -FullName formatting.size.style -Value plain Note in the screenshot above that UsedSpace is now an unformatted number.\nPrefer that everything be displayed in terabytes by default? We support that too.\n# Set default value to terabyte Set-dbatoolsConfig -FullName formatting.size.style -Value Tb Here are all the options available:\nDynamic Plain Byte B Kilobyte KB Megabyte MB Gigabyte GB Terabyte TB If you\u0026rsquo;re wondering how I got that, I researched how to show an enum in PowerShell, found this article on Microsoft Learn then executed:\n# Use .NET to enumerate the available values of SizeStyle [System.Enum]::GetNames([Sqlcollaborative.dbatools.Utility.SizeStyle]) Hope that helps with number formatting in dbatools! And thanks to Fred for such a beautiful, standardized way to show numbers 😊\n- Chrissy\n","date":"2019-09-12","summary":"Within dbatools, you may notice file sizes are pretty and human-readable.\nThat was some C# based magic created by Microsoft PFE and creator of PSFramework, Fred Weinmann. In the background, SQL Server often gives us different types of numbers to represent file sizes. Sometimes it\u0026rsquo;s bytes, sometimes it\u0026rsquo;s megabytes. We wanted to standardize the sizing in dbatools, and thus the dbasize type was born.\nUsage This size type is cool because it looks beautiful, showing KB, MB, GB, TB and PB.","tags":[],"title":"Working with File Sizes in dbatools","type":"post","url":"https://dbatools.io/size/"},{"categories":["announcements"],"content":"After nearly 10 months of work, early access to Learn dbatools in a Month of Lunches is now available from our favorite publisher, Manning Publications!\nFor years, people have asked if any dbatools books are available and the answer now can finally be yes, mostly 😊. Learn dbatools in a Month of Lunches, written by me and Rob Sewell (the DBA with the beard), is now available for purchase, even as we\u0026rsquo;re still writing it. And as of today, you can even use the code bldbatools50 to get a whopping 50% off (valid forever).\nRight now, the first few chapters are available, and we\u0026rsquo;re going to release a new chapter at least once a month. Here\u0026rsquo;s our current Table of Contents.\nWhat is MEAP? Manning\u0026rsquo;s Early Access Program was introduced in 2003, because the publisher \u0026ldquo;found it frustrating that while authors were working on later chapters, the earlier ones sat gathering dust, of no use to anyone.\u0026rdquo;\nAccording to the website, MEAP offers several benefits over the traditional \u0026ldquo;wait to read\u0026rdquo; model.\nGet started now. You can read early versions of the chapters before the book is finished. Regular updates. We\u0026rsquo;ll let you know when updates are available. Get finished books faster. MEAP customers are the first to get final eBooks and pbooks. What I appreciate as an author is that this allows early-adopters to become part of the writing process and can help make the book even better. As Manning puts it:\nThe content you get is not finished and will evolve, sometimes dramatically, before it is good enough for us to publish. But you get the chapter drafts when you need the information. And, you get a chance to let the author know what you think, which can really help both them and us make a better book.\nOccasionally, Manning will decide not to publish a book that\u0026rsquo;s become available in MEAP. Fear not! If they cancel your MEAP, you can exchange it for another book or get a refund.\nThanks 💓 For those 300+ of you who have already purchased our book, Rob and I very much appreciate your support and hope that you find the book super useful 🚀\nAlso, shoutout to Mike Shepard and Cláudio Silva for the technical edits and to the anonymous community editors who took the time to review our book before it went to MEAP!\n- Chrissy\n","date":"2019-09-04","summary":"After nearly 10 months of work, early access to Learn dbatools in a Month of Lunches is now available from our favorite publisher, Manning Publications!\nFor years, people have asked if any dbatools books are available and the answer now can finally be yes, mostly 😊. Learn dbatools in a Month of Lunches, written by me and Rob Sewell (the DBA with the beard), is now available for purchase, even as we\u0026rsquo;re still writing it.","tags":["book","dbatoolsMoL","MonthOfLunches"],"title":"Learn dbatools in a Month of Lunches","type":"post","url":"https://dbatools.io/meap/"},{"categories":["announcements"],"content":"Some dbatools functionality that has not been talked about much on the blog are our internal configuration options. This functionality was added back in October 2017. Kind of like how in ADS or SSMS, you can go to File -\u0026gt; Preferences -\u0026gt; Settings or Edit -\u0026gt; Preferences to edit advanced preferences and options, you can do something similar in dbatools!\nSince dbatools is command-line based, you can view/modify your current options using our various config commands.\nGet-dbatoolsConfig Get-dbatoolsConfigValue Set-dbatoolsConfig Reset-dbatoolsConfig Import-dbatoolsConfig Export-dbatoolsConfig Register-dbatoolsConfig Unregister-dbatoolsConfig We offer the ability to configure various options such as connection timeouts, datetime formatting and default export paths. All-in-all, we offer nearly 100 configuration options to help customize and enhance your dbatools experience.\nExploring Our Options To see a list of all of the options offered, open a PowerShell console and type Get-dbatoolsConfig.\nIn the image above, you can find some of the configuration options that you can set and will be widely used by dbatools.\nThese settings are scoped at the session-level. This means that if you use dbatools module within SQL Agent jobs and you have a different account to run it, you will need to set the options for the user/credential running your SQL Agent jobs. You can do this by logging into the server as that user and editing the options. You can also run PowerShell as that user by right-clicking the PowerShell logo in the taskbar, then pressing Shift + right-click over the PowerShell logo. There, you will be offered the option to run as a different user.\nBecause there are nearly 100 configuration options, you can take advantage of Out-Gridview to easily view and sort them.\nYou can then filter out the results in a easier manner.\n\u0026ldquo;I Saw That Settings Are Grouped by Modules. Which Modules Are Available?\u0026rdquo; If you run the following command, you will find all the distinct modules we have:\nGet-dbatoolsConfig | Select-Object -Property Module -Unique As you can see there are a good amount of different modules.\nGet-dbatoolsConfig vs. Get-dbatoolsConfigValue You may have noticed two similarly named commands: Get-dbatoolsConfig and Get-dbatoolsConfigValue. Let\u0026rsquo;s take a look at the differences.\nGet-dbatoolsConfig - A Rich Object This command returns not only the value for a setting but also the module where it belongs and a useful description about it. You can specify the -FullName (preferable because it is unique) or only the -Name (same as -FullName but without the prefix which is the module name).\n-FullName example:\nGet-dbatoolsConfig -FullName sql.connection.timeout -Name example:\nGet-dbatoolsConfig -Name connection.timeout We also provide a validation script to a configuration. If you want to know how we validate it, you can see the Validation property, as example if you run:\nGet-dbatoolsConfig -FullName formatting.size.digits | Select-Object * You will get:\nGet-dbatoolsConfigValue - Is What You Are Thinking but We Have Interesting Options If you just want to get the configured value as a string, you should use the Get-dbatoolsConfigValue command. This command is widely used internally within the dbatools module.\nYou may find that we also use the -FallBack, as stated on documentation \u0026ldquo;A fallback value to use, if no value was registered to a specific configuration element. This basically is a default value that only applies on a \u0026ldquo;per call\u0026rdquo; basis, rather than a system-wide default.\u0026rdquo;\nAlso if we don\u0026rsquo;t want to get a null result we can specify the -NotNull parameter \u0026ldquo;…the function will throw an error if no value was found at all.\u0026rdquo;\nSet a New Configuration Value To update a value you need to use the Set-dbatoolsConfig command. Unfortunately, you will not find documentation for this command on our docs page. This is a known issue and it happens because that command is a cmdlet so the help is in the dbatools library itself.\nFor this particular case, you can and should rely on the Get-Help command.\nGet-Help -Name Set-dbatoolsConfig -Full The easier way to update a value is provide the -FullName and -Value parameters. Example:\nSet-dbatoolsConfig -FullName formatting.size.digits -Value 3 Note that changes made by Set-dbatoolsConfig only persists for the current session. To permanently persist your changes, use Register-dbatoolsConfig. This command will be covered next.\nLet\u0026rsquo;s See Other Examples Want to clean the logs more frequently? Or keep them longer than the default of 7 days? Let\u0026rsquo;s change to 8 days by setting the Logging.MaxLogFileAge configuration.\nSet-dbatoolsConfig -FullName Logging.MaxLogFileAge -Value (New-TimeSpan -Days 8) Want to Format Dates and Times Differently? Take a look at the formatting section and find a couple of configurations to set the format as you would like.\nIf you want to change from dd MMM yyyy format to yyyy MM dd you can run the following command:\nSet-dbatoolsConfig -FullName formatting.date -Value \u0026#39;yyyy MM dd\u0026#39; What About SQL Connection Timeout? 15 seconds (the default) is not enough? Change it using the sql.connection.timeout configuration.\nSet-dbatoolsConfig -FullName Logging.MaxLogFileAge -Value 30 Do You Use dbatools with Azure? There are a couple of configs that you can set in the Azure section. Take a look at them:\nGet-dbatoolsConfig -Module azure Note that only a few of our commands have been tested to work with Azure. Better support for Azure is a long-term goal.\nPermanently Persist Changes As mentioned previously, when you use the Set command, it is set only for your current session. To make the change permanent, use Register-dbatoolsConfig.\nGet-dbatoolsConfig | Register-dbatoolsConfig This will write all configuration values, by default, in the registry. Like all of our config commands, this works on Windows, Linux and macOS.\nReset Configured Value to Its Default To reset all of your configured values to dbatools default, run the following:\nReset-dbatoolsConfig -FullName sql.connection.timeout This will set the configuration value back to 15. To reset all of your dbatools options to default, run the following:\nGet-dbatoolsConfig | Reset-dbatoolsConfig What\u0026rsquo;s New? Since last dbatools version 1.0.32, new PowerShell Remoting configurations are available. You can read more about it on Claudio Silva\u0026rsquo;s blog to learn more.\nJust Remember… Next time you catch yourself thinking about changing some default behaviour remember to take a look into these configurations. If you found something that is not available for your use case, talk with us on Slack or just open a feature request explaining your needs and we will try to guide/help you.\nThanks for reading! Cláudio 🇵🇹\n","date":"2019-08-20","summary":"Some dbatools functionality that has not been talked about much on the blog are our internal configuration options. This functionality was added back in October 2017. Kind of like how in ADS or SSMS, you can go to File -\u0026gt; Preferences -\u0026gt; Settings or Edit -\u0026gt; Preferences to edit advanced preferences and options, you can do something similar in dbatools!\nSince dbatools is command-line based, you can view/modify your current options using our various config commands.","tags":["dbatools Configs","dbatools Settings","defaults"],"title":"dbatools Advanced Configuration","type":"post","url":"https://dbatools.io/configuration/"},{"categories":["announcements"],"content":"\nToday\u0026rsquo;s article is part of T-SQL Tuesday. T-SQL Tuesday is the brainchild of Adam Machanic. It is a blog party on the second Tuesday of each month and everyone is welcome to participate.\nThis month\u0026rsquo;s T-SQL Tuesday is hosted by Tracy Boggiano (blog), is all about Linux.\ndbatools and Linux As a long-time Linux user and open-source advocate, I was beyond excited when PowerShell and SQL Server came to Linux.\nA few of the decisions I made about dbatools were actually inspired by Linux. For instance, when dbatools was initially released, it was GNU GPL licensed, which is the same license as the Linux kernel (we\u0026rsquo;ve since re-licensed under the more permissive MIT). In addition, dbatools\u0026rsquo; all-lower-case naming convention was also inspired by Linux, as most commands executed within Linux are in lower-case and a number of projects use the lower-case naming convention as well.\ndbatools on Linux Thanks to Microsoft\u0026rsquo;s PowerShell and SQL Server teams, dbatools runs on Linux and Mac OS!\nAs covered in our book which\u0026rsquo;ll be released next year, dbatools in a Month of Lunches, 75% of commands in dbatools are supported by Linux and Mac OS.\nCommands that are pure-SQL Server, like Get-DbaDatabase or New-DbaLogin, work on Linux and Mac OS. Others that rely on WMI or remoting, like Get-DbaDiskSpace or Enable-DbaAgHadr, do not currently work on Linux.\nIf you\u0026rsquo;re curious, our docs site will tell you if a command is supported by Linux and Mac OS.\nAnd, of course, you can also ask on Linux itself. After installing dbatools, run Get-Command -Module dbatools to see all of the commands that are available.\nSQL on Linux dbatools also supports SQL on Linux. If it works on SQL Server Management Studio, it\u0026rsquo;ll work with dbatools as we\u0026rsquo;re built on the same libraries. Also because SQL on Linux is pretty much the same everything as SQL on Windows.\nInterested in learning more? Check out the #1 rated SQL Server on Linux book, Pro SQL Server on Linux by Microsoft\u0026rsquo;s Bob Ward. This book was actually edited by our friend Anthony Nocentino and it\u0026rsquo;s rumored that Anthony will contribute some sweet Linux-centric commands to dbatools when the Year of the Linux Desktop arrives, so we\u0026rsquo;re looking forward to that 😊\nKidding aside, dbatools supports Linux and Mac OS in a number of ways. Not only can you run dbatools FROM Linux, you can also connect TO SQL on Linux. We even have fantastic Registered Server support that eases authentication.\nTo Linux / macOS Connecting to SQL Server (Windows or Linux) from Linux or Mac OS is generally done with using an alternative -SqlCredential. So let\u0026rsquo;s say you follow Microsoft\u0026rsquo;s guide to setting up SQL on Linux or if you use dbatools\u0026rsquo; Docker guide, you\u0026rsquo;ll likely need to authenticate with the sa or sqladmin account. Execute the following command.\nGet-DbaDatabase -SqlInstance sqlonlinux -SqlCredential sa You\u0026rsquo;ll then be prompted for your password, and voilà! Don\u0026rsquo;t want to type your password every time? You can reuse it by assigning the credential to a variable.\n$cred = Get-Credential sa Get-DbaDatabase -SqlInstance sqlonlinux -SqlCredential $cred You can also export your credentials to disk using Export-CliXml. The password will be encrypted and only the same user/computer can decrypt.\nGet-Credential sa | Export-CliXml -Path C:\\temp\\creds.xml $cred = Import-CliXml -Path C:\\temp\\creds.xml Get-DbaDatabase -SqlInstance sqlonlinux -SqlCredential $cred Prefer using the Windows Credential Store instead? Check out the PowerShell module, BetterCredentials.\nTo Linux / macOS Using Registered Servers You can also use Local Registered Servers! This functionality was added in dbatools 1.0\nConnect-DbaInstance -SqlInstance sqlonlinux -SqlCredential sa | Add-DbaRegServer -Name \u0026#34;SQL Server on Linux\u0026#34; From there, you can see it in SQL Server Management Studio\u0026rsquo;s Local Server Groups.\nAnd the detailed pane\nOhhh! What! Now you can do this without worrying about authentication:\nGet-DbaRegServer -ServerName sqlonlinux | Get-DbaDatabase From dbatools on macOS to SQL Server on Windows Something that I had super fun doing was joining my Mac Mini to my homelab then authenticating flawlessly with my domain-joined, Windows-based SQL Server. Didn\u0026rsquo;t even need the -SqlCredential because Integrated Authentication worked 👍\nIf you cannot join your Linux or Mac OS workstation to a Windows domain, you can still use -SqlCredential. This parameter not only supports SQL Logins, but Windows logins as well. So you could connect to a Windows-based SQL Server using an Active Directory account such as ad\\sqladmin.\nGot any questions, hit up #dbatools on the SQL Server Community Slack at aka.ms/sqlslack and one of our friendly community members will be there to assist.\n- Chrissy 🐈\n","date":"2019-07-09","summary":"Today\u0026rsquo;s article is part of T-SQL Tuesday. T-SQL Tuesday is the brainchild of Adam Machanic. It is a blog party on the second Tuesday of each month and everyone is welcome to participate.\nThis month\u0026rsquo;s T-SQL Tuesday is hosted by Tracy Boggiano (blog), is all about Linux.\ndbatools and Linux As a long-time Linux user and open-source advocate, I was beyond excited when PowerShell and SQL Server came to Linux.","tags":["linux"],"title":"dbatools \u0026 SQL on Linux","type":"post","url":"https://dbatools.io/linux/"},{"categories":["announcements"],"content":"Hi, I am Gareth N - a SQL Server DBA in the UK. I have started to blog over at ifexists.blog - today I want to share some information around how dbatools can cache connection information, and how to reset it.\ndbatools is smart. It can do things in the background when you\u0026rsquo;re using the commands, like cache connections and also cache the results of those connections. This can help speed things up as it will re-use the existing object.\nBut what if something changed since it cached the connection? Let\u0026rsquo;s see how we can edit the existing connections if necessary.\nMy Scenario I was updating some dev instances using what has to be one of my favorite commands, Update-DbaInstance. Here\u0026rsquo;s what my command looked like:\nUpdate-DbaInstance -ComputerName devbox1.domain.local -Restart -Path \u0026#34;\\fileshare\\sql updates\u0026#34; -Credential ad\\gareth For anyone new to dbatools, let\u0026rsquo;s briefly talk about what this is doing for us based on this example.\nPrompt us for ad\\gareth\u0026rsquo;s password Find all SQL Server instances on devbox1 Search fileshare \u0026ldquo;\\fileshare\\sql updates\u0026rdquo; for updates relevant to any instances we found If a Windows restart is required before installing patches, then restart Prompt the user to install patches for any instances that were found and need updating Finally, it will restart the computer after patching Works like a charm! For more details and examples, you can check out the Update-DbaInstance help page.\nBack on Topic I came to update one instance, and my credentials were not working, I received an Access Denied message in PowerShell. I did what was necessary to get my permissions added on the windows server, confident I was good to go I tried again, but still no luck. This time the error was slightly different, \u0026ldquo;Windows authentication was used, but is known to not work!\u0026rdquo;. Hmmm, not sure what this means? I went off to the dbatools slack channel for advice and got the answer I needed.\ndbatools was showing me this message because I recently tried to access this server and it knows I didn\u0026rsquo;t have permission, it remembered and wasn\u0026rsquo;t going to waste time trying again. But now I do have permission, so I do actually need it to forget and try again, to do that we use Set-DbaCmConnection.\nSet-DbaCmConnection -ComputerName devbox1.domain.local -ResetCredential -ResetConnectionStatus -DisableBadCredentialCache This will give us a fresh start with this server and cause dbatools to try and authenticate again, resulting in a good connection object. Also using the -DisableBadCredentialCache flag we can stop it from caching bad credentials while we debug our access issues.\nCheck out the Set-DbaCmConnection help page for further information.\n- Gareth 🇬🇧\n","date":"2019-06-25","summary":"Hi, I am Gareth N - a SQL Server DBA in the UK. I have started to blog over at ifexists.blog - today I want to share some information around how dbatools can cache connection information, and how to reset it.\ndbatools is smart. It can do things in the background when you\u0026rsquo;re using the commands, like cache connections and also cache the results of those connections. This can help speed things up as it will re-use the existing object.","tags":["authentication","caching","connections","set-dbacmconnection"],"title":"Using Set-DbaCmConnection to Reset Credentials and Cached Connection Status","type":"post","url":"https://dbatools.io/reset-credentials-cached-connection/"},{"categories":[],"content":"If dbatools has ever saved you time, either through our migration commands or easing SQL Server automation in general, please consider sponsoring one or more of us for a couple bucks a month.\nSponsoring one or more of our developers through GitHub\u0026rsquo;s new Developer Sponsorship Program will help dbatools continue to live on, which ultimately means an easier, funner time at work for you as you relax while dbatools does all of the heavy-lifting.\nThe great thing about GitHub Sponsorships is that it doesn\u0026rsquo;t take much to make a huge difference if enough people sponsor our work. So three or five bucks can really mean a lot.\nClicking on the picture above will bring you to our GitHub page. You can click on any developer to read more about them. Chrissy\u0026rsquo;s will look a lil like this page because this page was based off of her profile 😄\nFor the first year, GitHub will match sponsorship funds! So giving to us now is like giving double. Sponsorship lasts only as long as you wish and you can cancel anytime, no questions asked. Thank you for the time you did sponsor us 💖\nThanks to Data Masterminds Big ol\u0026rsquo; shout out to our friends and team members at Data Masterminds in the Netherlands.\nThey\u0026rsquo;ve always been so supportive, from buying stickers and merch for our fans to paying our huge Appveyor $2495/year bill to ensure all of our tests run within a reasonable amount of time. Thank you all so very much 💘\nEelco Drost William Durkin ","date":"2019-06-24","summary":"If dbatools has ever saved you time, either through our migration commands or easing SQL Server automation in general, please consider sponsoring one or more of us for a couple bucks a month.\nSponsoring one or more of our developers through GitHub\u0026rsquo;s new Developer Sponsorship Program will help dbatools continue to live on, which ultimately means an easier, funner time at work for you as you relax while dbatools does all of the heavy-lifting.","tags":[],"title":"Sponsorship","type":"page","url":"https://dbatools.io/sponsors/"},{"categories":[],"content":"If dbatools has ever saved you time, either through our migration commands or easing SQL Server automation in general, please consider sponsoring one or more of us for a couple bucks a month.\nSponsoring one or more of our developers through GitHub\u0026rsquo;s new Developer Sponsorship Program will help dbatools continue to live on, which ultimately means an easier, funner time at work for you as you relax while dbatools does all of the heavy-lifting.\nThe great thing about GitHub Sponsorships is that it doesn\u0026rsquo;t take much to make a huge difference if enough people sponsor our work. So three or five bucks can really mean a lot.\nClicking on the picture above will bring you to our GitHub page. You can click on any developer to read more about them. Chrissy\u0026rsquo;s will look a lil like this page because this page was based off of her profile 😊\nFor the first year, GitHub will match sponsorship funds! So giving to us now is like giving double. Sponsorship lasts only as long as you wish and you can cancel anytime, no questions asked. Thank you for the time you did sponsor us ❤\nThanks to Data Masterminds Big ol\u0026rsquo; shout out to our friends and team members at Data Masterminds in the Netherlands.\nThey\u0026rsquo;ve always been so supportive, from buying stickers and merch for our fans to paying our huge Appveyor $2495/year bill to ensure all of our tests run within a reasonable amount of time. Thank you all so very much ❤\nEelco Drost William Durkin Eelco Drost William Durkin ","date":"2019-06-24","summary":"If dbatools has ever saved you time, either through our migration commands or easing SQL Server automation in general, please consider sponsoring one or more of us for a couple bucks a month.\nSponsoring one or more of our developers through GitHub\u0026rsquo;s new Developer Sponsorship Program will help dbatools continue to live on, which ultimately means an easier, funner time at work for you as you relax while dbatools does all of the heavy-lifting.","tags":[],"title":"Sponsorship","type":"page","url":"https://dbatools.io/sponsorship/"},{"categories":["announcements"],"content":"We are so super excited to announce that after 5 long years, dbatools 1.0 is publicly available!\nOur team had some lofty goals and met a vast majority of them 🏅. In the end, my personal goal for dbatools 1.0 was to have a tool that is not only useful and fun to use but trusted and stable as well. Mission accomplished: over the years, hundreds of thousands of people have used dbatools and dbatools is even recommended by Microsoft.\nBefore we get started with what\u0026rsquo;s new, let\u0026rsquo;s take a look at some history.\nHistorical Milestones dbatools began in July of 2014 when I was tasked with migrating a SQL Server instance that supported SharePoint. No way did I want to do that by hand! Since then, the module has grown into a full-fledged data platform solution.\n07/2014 - Started 07/2014 - Published to GitHub \u0026amp; ScriptCenter 06/2016 - First major contributors 01/2017 - Road to 1.0 began 03/2018 - Switch from GPL to MIT 05/2019 - Added MFA Support 06/2019 - Over 160 contributors and 550 commands Thanks so much to every single person who has volunteered any time to dbatools. You\u0026rsquo;ve helped change the SQL Server landscape.\nImprovements We\u0026rsquo;ve made a ton of enhancements that we haven\u0026rsquo;t had time to share even over the past six months. Here are a few.\nAvailability Groups Availability Group support has been solidified and is looking good and New-DbaAvailabilityGroup is better than ever. Try out the changes and let us know how you like them.\nGet-Help New-DbaAvailabilityGroup -Examples Authentication Support We now also support all the different ways to login to SQL Server! So basically this:\nWant to try it for yourself? Here are a few examples.\n# AAD Integrated Auth Connect-DbaInstance -SqlInstance psdbatools.database.windows.net -Database dbatools # AAD Username and Pass Connect-DbaInstance -SqlInstance psdbatools.database.windows.net -SqlCredential username@acme.onmicrosoft.com -Database dbatools # Managed Identity in Azure VM w/ older versions of .NET Connect-DbaInstance -SqlInstance psdbatools.database.windows.net -Database abc -SqlCredential appid -Tenant tenantguidorname # Managed Identity in Azure VM w/ newer versions of .NET (way faster!) Connect-DbaInstance -SqlInstance psdbatools.database.windows.net -Database abc -AuthenticationType \u0026#39;AD Universal with MFA Support\u0026#39; You can also find a couple more within the MFA Pull Request on GitHub and by using Get-Help Connect-DbaInstance -Examples.\nRegistered Servers This is probably my favorite! We now support Local Server Groups and Azure Data Studio groups. Supporting Local Server Groups means that it\u0026rsquo;s now a whole lot easier to manage servers that don\u0026rsquo;t use Windows Authentication.\nHere\u0026rsquo;s how you can add a local docker instance.\n# First add it with your credentials Connect-DbaInstance -SqlInstance \u0026#39;dockersql1,14333\u0026#39; -SqlCredential sqladmin | Add-DbaRegServer -Name mydocker # Then just use it for all of your other commands. Get-DbaRegisteredServer -Name mydocker | Get-DbaDatabase Totally dreamy 😋\nCSV Import-DbaCsv is now far more reliable. While the previous implementation was faster, it didn\u0026rsquo;t work a lot of the time. The new command should suit your needs well.\nGet-ChildItem C:\\allmycsvs | Import-DbaCsv -SqlInstance sql2017 -Database tempdb -AutoCreateTable Future \u0026amp; Backwards Compatible In the past couple months, we\u0026rsquo;ve started focusing a bit more on Azure: both Azure SQL Database and Managed Instances. In particular, we now support migrations to Azure Managed Instances! We\u0026rsquo;ve also added a couple more commands to PowerShell Core., in particular, the Masking and Data Generation commands. Over 75% of our commands run on mac OS and Linux!\nStill, we support PowerShell 3 and Windows 7 and SQL Server 2000 when we can. Our final testing routines included ensuring support for:\nWindows 7 SQL Server 2000-2019 User imports vs Developer imports mac OS / Linux x86 and x64 Strict (AllSigned) Execution Policy New Commands We\u0026rsquo;ve also added a bunch of new commands, mostly revolving around Roles, PII, Masking, Data Generation and even ADS notebooks!\nWant to see the full list? Check out our freshly updated Command Index page 🙏.\nConfiguration Enhancements A few configuration enhancements have been made and a blog post for our configuration system is long overdue. But one of the most useful, I think, is that you can now control the client name. This is the name that shows up in logs, in Profiler and in Xevents.\n# Set it Set-dbatoolsConfig -FullName sql.connection.clientname -Value \u0026#34;my custom module built on top of dbatools\u0026#34; -Register # Double check it Get-dbatoolsConfig -FullName sql.connection.clientname | Select Value, Description The -Register parameter is basically a shortcut for piping to Register-dbatoolsConfig. This writes the value to the registry, otherwise, it\u0026rsquo;ll be effective only for your current session.\nAnother configuration enhancement helps with standardization. Now, all export commands will default to Documents\\dbatoolsExport. You can change it by issuing the following commands.\n# Set it Set-dbatoolsConfig -FullName path.dbatoolsexport -Value \u0026#34;C:\\temp\\exports\u0026#34; -Register # Double check it Get-dbatoolsConfig -FullName path.dbatoolsexport | Select Value, Description Help Is Separated Something new that I like because it\u0026rsquo;s \u0026ldquo;proper\u0026rdquo; PowerShell: we\u0026rsquo;re now publishing our module with Help separated into its own file. We\u0026rsquo;re using a super cool module called HelpOut. HelpOut was created for dbatools by a former member of the PowerShell team, James Brundage.\nHelpOut allows our developers to keep writing Help within the functions themselves, then separates the Help into dbatools-help.xml and the commands into allcommands.ps1, which helps with faster loading. Here\u0026rsquo;s how we do it:\nInstall-Maml -FunctionRoot functions, internal\\functions -Module dbatools -Compact -NoVersion It\u0026rsquo;s as simple as that! This does all of the heavy lifting: making the maml file and placing it in the proper location, and parsing the functions for allcommands.ps1!\nHelp will continue to be published to docs.dbatools.io and updated with each release. You can read more about HelpOut on GitHub.\nBreaking Changes We\u0026rsquo;ve got a number of breaking changes included in 1.0.\nBefore diving into this section, I want to emphasize that we have a command to handle a large majority of the renames! Invoke-DbatoolsRenameHelper will parse your scripts and replace script names and some parameters for you.\nCommand Renames Renames in the past 30 days were mostly changing Instance to Server. But we also made some command names more accurate:\nTest-DbaDbVirtualLogFile -\u0026gt; Measure-DbaDbVirtualLogFile Uninstall-DbaWatchUpdate -\u0026gt; Uninstall-dbatoolsWatchUpdate Watch-DbaUpdate -\u0026gt; Watch-dbatoolsUpdate\nCommand Removal Export-DbaAvailabilityGroup has been removed entirely. The same functionality can now be found using Get-DbaAvailabiltyGroup | Export-DbaScript.\nAlias Removals All but 5 command aliases have been removed. Here are the ones that are still around:\nGet-DbaRegisteredServer -\u0026gt; Get-DbaRegServer Attach-DbaDatabase -\u0026gt; Mount-DbaDatabsae Detach-DbaDatabase - Dismount-DbaDatabase Start-SqlMigration -\u0026gt; Start-DbaMigration Write-DbaDataTable -\u0026gt; Write-DbaDbTableData\nI kept Start-SqlMigration because that\u0026rsquo;s where it all started, and the rest are easier to remember.\nAlso, all ServerInstance and SqlServer aliases have been removed. You must now use SqlInstance. For a full list of what Invoke-dbatoolsRenameHelper renames/replaces, check out the source code.\nParameter Standardization Most of the commands now follow the following practices we\u0026rsquo;ve observed in Microsoft\u0026rsquo;s PowerShell modules.\nPiped input is -InputObject and not DatabaseCollection or LoginCollection, etc. Directory (and some file) paths are now -Path and not BackupLocation or FileLocation When a distinction is required, file paths are now -FilePath, and not RemoteFile or BackupFileName If both file and directory path needs to be distinguished, Path is used for directory and FilePath for file locations Parameter Removal -SyncOnly is no longer an option in Copy-DbaLogin. Please use Sync-DbaLoginPermission instead.\n-CheckForSql is no longer an option in Get-DbaDiskSpace. Perhaps the functionality can be made into a new command which can be piped into Get-DbaDiskSpace but the implementation we had was 👎.\nFor a full list of breaking changes, you can browse our gorgeous changelog, maintained by Andy Levy.\nBook Party! In case you did not hear the news, Rob Sewell and I, are currently in the process of writing dbatools in a Months of Lunches! We\u0026rsquo;ve really excited and hope to have a MEAP (Manning Early Access Program) available sometime in July. We will keep everyone updated here and on our blogs.\nThe above is what the editor looks like - a lot like markdown!\nIf you\u0026rsquo;d like to see what the writing process is like, I did a livestream a couple of months back while writing Chapter 6, which is about Find-DbaInstance. Sorry about the music being a bit loud, that has been fixed in future streams which can be found at youtube.com/dbatools.\nSponsorship Since Microsoft acquired GitHub, they\u0026rsquo;ve been rolling out some really incredible features. One such feature is Developer Sponsorships, which allows you to sponsor developers with cash subscriptions. It\u0026rsquo;s sorta like Patreon where you can pay monthly sponsorships with different tiers. If you or your company has benefitted from dbatools, consider sponsoring one or more of our developers.\nCurrently, GitHub has approved four of our team members to be sponsored including me, Shawn Melton, Stuart Moore and Sander Stad.\nWe\u0026rsquo;ve invited other dbatools developers to sign up as well 🙏\nOh, and for the first year, GitHub will match sponsorship funds! So giving to us now is like giving double.\nBig Ol\u0026rsquo; Thanks I\u0026rsquo;d like to give an extra special thanks to the contributors who helped get dbatools across the finish line these past couple months: Simone Bizzotto, Joshua Corrick, Patrick Flynn, Sander Stad, Cláudio Silva, Shawn Melton, Garry Bargsley, Andy Levy, George Palacios, Friedrich Weinmann, Jess Pomfret, Gareth N, Ben Miller, Shawn Tunney, Stuart Moore, Mike Petrak, Bob Pusateri, Brian Scholer, John G \u0026ldquo;Shoe\u0026rdquo; Hohengarten, Kirill Kravtsov, James Brundage, Hüseyin Demir, Gianluca Sartori and Rob Sewell.\nWithout you all, 1.0 would be delayed for another 5 years.\nBlog Party! Want to know more about dbatools? Check out some of these posts ☺\ndbatools 1.0 - the tools to break down the barriers - Shane O\u0026rsquo;Neill\ndbatools 1.0 is here and why you should care - Ben Miller\ndbatools 1.0 and beyond - Joshua Corrick\ndbatools 1.0 - Dusty R\nYour DBA Toolbox Just Got a Refresh - dbatools v1.0 is Officially Available!!! - Garry Bargsley\ndbatools v1.0? It\u0026rsquo;s available - Check it out!\nupdating sql server instances using dbatools 1.0 - Gareth N\nLivestreaming We\u0026rsquo;re premiering dbatools 1.0 at DataGrillen in Lingen, Germany today and will be livestreaming on Twitch.\nThank you, everyone, for your support along the way. We all hope you enjoy dbatools 1.0\n💌, Chrissy\n","date":"2019-06-18","summary":"We are so super excited to announce that after 5 long years, dbatools 1.0 is publicly available!\nOur team had some lofty goals and met a vast majority of them 🏅. In the end, my personal goal for dbatools 1.0 was to have a tool that is not only useful and fun to use but trusted and stable as well. Mission accomplished: over the years, hundreds of thousands of people have used dbatools and dbatools is even recommended by Microsoft.","tags":["party"],"title":"dbatools 1.0 Has Arrived","type":"post","url":"https://dbatools.io/dbatools10/"},{"categories":["announcements"],"content":"Recently, a colleague asked me to assist with the migration of some older, customized application databases to a SQL Server 2017 instance. Most of the migrations I perform are rather vanilla, but this one was a bit more involved.\nSetup Imagine this scenario:\nSource (APPSQL1) Dedicated SQL Server 2008 R2 failover clustered instance with a non-default collation (SQL_Latin1_General_CP1_CI_AI) Custom .NET application with an intense database containing a non-default collation (also SQL_Latin1_General_CP1_CI_AI), multiple CLR assemblies, and thousands of tables, views, stored procedures, functions Nearly 30 SQL Agent jobs, many of which had to be disabled over the years due to compatibility issues and scope changes Out-of-support for both Microsoft and the application vendor Destination (APPSQL2) Shared server SQL Server 2017 Default collation (SQL_Latin1_General_CP1_CI_AS) There was even a linked server in the mix, but our biggest concerns revolved around the changing collation and the Agent jobs, which were known to be brittle.\nThe destination test server was an existing shared server, which mirrored the scenario that would play out in production. And while the databases only needed to exist on the new server for a limited period of time, these migrated databases were going to be the most important databases on the entire instance. This meant that the SQL Server configs were going to have to cater to this app\u0026rsquo;s needs. One exception was the collation, as the accent sensitivity was determined not to be a big deal and the vendor agreed.\nInteresting requirements, no doubt!\nPrep Fortunately, my colleague kept a login inventory, and we used this to determine that there would be 5 servers with connection strings that\u0026rsquo;d have to be updated with the new server name. Generally, I try to see if creating SQL client aliases is a suitable solution and this was no exception. Creating SQL aliases satisfies my curiosity and can let us know early on if the migration was a success.\nThis blog post refers to options added in 1.0.34. If you\u0026rsquo;d like to follow along, please ensure you\u0026rsquo;ve updated to the latest version of dbatools.\nSo let\u0026rsquo;s take a look at the prep work.\n# Ensure PowerShell remoting is available (Test-DbaConnection would also work) Invoke-Command -ComputerName server1, server2, server3, server4, server5 -ScriptBlock { $env:computername } # See current aliases to ensure no overlap Get-DbaClientAlias -ComputerName server1, server2, server3, server4, server5 # Export / Document all instance objects from source SQL Server Export-DbaInstance -SqlInstance APPSQL1, APPSQL2 # Ensure no jobs are currently running Get-DbaRunningJob -SqlInstance APPSQL1 # Perform final log backup Start-DbaAgentJob -SqlInstance APPSQL1 -Job \u0026#34;DatabaseBackup - USER_DATABASES - LOG\u0026#34; Since the old server was going to be turned off entirely, I thought it\u0026rsquo;d be a good idea to export all of the objects (logins, jobs, etc) so that the DBA could see the state they were in at the time of migration. While we were at it, we threw in the destination server as well.\nOnce the final log backup was made, it was time to perform the migration!\nMigration Because the destination server was a shared server, it wasn\u0026rsquo;t a likely candidate for Start-DbaMigration as this command is intended for instance-to-instance migrations. In general, when I migrate to shared servers, I\u0026rsquo;ll run each individual Copy-Dba command for things like databases, logins and jobs.\nIn this case, however, I recommended Start-DbaMigration since the application was high-priority and I wanted the migration to be as thorough as possible. I knew that the SQL Server configuration values would change, but because they were exported when we ran Export-DbaInstance, we could easily reference old settings.\nI did decide to exclude a few things that could needlessly pollute the new server like user objects in the system databases (Copy-DbaSysDbUserObject) and I also excluded the Agent Server Properties, because the destination server properties (like fail-safe operator) were already set.\n# Start Migration - view results in a pretty grid, and assign the results to a variable so that it can be easily referenced later Start-DbaMigration -Source APPSQL1 -Destination APPSQL2 -UseLastBackup -SetSourceReadOnly -Exclude SysDbUserObjects, AgentServerProperties, PolicyManagement, ResourceGovernor, DataCollector | Select-Object * -OutVariable migration | Out-GridView # Create new alias New-DbaClientAlias -ComputerName server1, server2, server3, server4, server5 -ServerName APPSQL2 -Alias APPSQL1 # Prep post migration potential failure/fallback # Set-DbaDbState -SqlInstance APPSQL11 -AllDatabases -ReadWrite -Force # Get-DbaClientAlias -ComputerName server1, server2, server3, server4, server5 | Where AliasName -eq APPSQL11 | Remove-DbaClientAlias Post-Migration So the migration went decently well. While we didn\u0026rsquo;t have to use the fallback commands, we did have to investigate a couple failures.\nFailed Job Migration A couple jobs didn\u0026rsquo;t migrate because they were rejected by the new server. Seems that scripted export code referenced \u0026ldquo;server=\u0026rdquo;, which was invalid because it contained the name of the old server.\n# Find jobs causing issues Get-DbaAgentJobStep -SqlInstance APPSQL1 | Where Command -match \u0026#34;@server=N\u0026#39;APPSQL1\u0026#39;\u0026#34; # Nope that didn\u0026#39;t work. Oh, wait, I need the export code, not the command code. $jobs = $migration | Where-Object { $psitem.Type -eq \u0026#34;Agent Job\u0026#34; -and $psitem.Status -eq \u0026#34;Failed\u0026#34; } | Select -ExpandProperty Name Get-DbaAgentJob -SqlInstance APPSQL1 -Job $jobs | Export-DbaScript -Passthru -Outvariable tsql | clip The above code resulted in the T-SQL CREATE scripts being added to the clipboard. We then pasted that code into SSMS, performed a find/replace for @server=N\u0026rsquo;APPSQL1\u0026rsquo; with @server=N\u0026rsquo;APPSQL2\u0026rsquo; then executed the T-SQL. Boom, it worked. Jobs were created and scheduled. I also updated dbatools to avoid this failure in the future.\nWhile I used SSMS to perform the find/replace, this could have been done in PowerShell as well.\n$tsql = $tsql -Replace \u0026#34;@server=N\u0026#39;APPSQL1\u0026#39;\u0026#34;,\u0026#34;@server=N\u0026#39;APPSQL2\u0026#39;\u0026#34; Invoke-DbaQuery -SqlInstance APPSQL2 -Query $tsql Now we needed to run each of the newly created jobs to see if they work, as it make me feel more confident in the migration\u0026rsquo;s success. After evaluating each job\u0026rsquo;s purpose, we determined it would be okay to run every job outside of their scheduled execution times.\n# Start newly created jobs that are enabled (the lazy way), wait for them to finish Get-DbaAgentJob -SqlInstance APPSQL2 | Where CreateDate -gt (Get-Date).AddMinutes(-60) | Where Enabled | Start-DbaAgentJob -Wait # Ugh, looks like we have some failed executions. Were any of these jobs failing prior to migration? Get-DbaAgentJob -SqlInstance APPSQL1 | Where LastRunOutcome -ne \u0026#34;Succeeded\u0026#34; | Where Enabled | select Name Nooo, all the failed jobs ran successfully on the APPSQL1! Now we\u0026rsquo;d have to dig into the code to see what code is failing and how it can be fixed. I imagined the failures were due to collation issues and I was right. Good ol\u0026rsquo; Cannot resolve the collation conflict between….\nMaybe we can update the collation in the databases? I recall years ago someone asked for this functionality in dbatools but thoroughly changing the collation of an existing database is so complicated as it requires changing the collation of so many objects including tables and indexes.\nLet\u0026rsquo;s try changing the database collation anyway, just to see if it\u0026rsquo;s possible and if it helps. This was mostly to satisfy my curiosity.\n# first we have to kill the connections then attempt a collation change in SSMS Get-DbaProcess -SqlInstance APPSQL1 -Database appdb | Stop-DbaProcess Nope. Our attempted collation change using SSMS didn\u0026rsquo;t even work because there were some dependent features in a couple of the databases. So now we had to find and edit the impacted views.\n# Omg most of the database objects are encrypted 😵, don\u0026#39;t we have a command for that? Get-Command -Module dbatools *crypt* # Yesss, Invoke-DbaDbDecryptObject. Thanks Sander! Get-Help -Examples Invoke-DbaDbDecryptObject # Run it Invoke-DbaDbDecryptObject -SqlInstance APPSQL2 -Database appdb -Name vwImportantView # Oh darn, DAC is not enabled and Invoke-DbaDbDecryptObject needs DAC Set-DbaSpConfigure -SqlInstance APPSQL2 -ConfigName RemoteDacConnectionsEnabled -Value 1 # Run again Invoke-DbaDbDecryptObject -SqlInstance APPSQL2 -Database appdb -Name $names # Turn DAC back off Set-DbaSpConfigure -SqlInstance APPSQL2 -ConfigName RemoteDacConnectionsEnabled -Value 0 We decrypted the views then added COLLATE DATABASE_DEFAULT to some queries, altered the views and voila! We were set. After the jobs ran successfully, we handed the migration off to the application team.\nSSPI Failures The application team immediately handed it right back to us 😅. Seems they encountered some \u0026ldquo;Cannot Generate SSPI Context\u0026rdquo; failures. Wait, what? The SPNs are set, right?\n# Double-checking all of the SPNs are set Test-DbaSpn -ComputerName APPSQL2 # Looks great! So is it just the app or can we make any kerberos connections using PowerShell? # Maybe this is because they are using a SQL Client alias? Test-DbaConnectionAuthScheme -SqlInstance APPSQL2 Oh, no: our dbatools connection was also using NTLM. So we checked to see if there were some stale DNS records. Nope. Cleaned out the Kerberos tickets. Works? Still no. Triple checked with Microsoft\u0026rsquo;s tools and really, Kerberos should be working.\nTurns out it was an issue with a setting in Windows (didn\u0026rsquo;t record which, oops), and after that was adjusted, Kerberos worked!\nNow for the Application After confirming that Kerberos was totally working, I removed the newly created SQL Client aliases and they updated all of the connection strings. Still there were problems. The error message was written in en-gb (\u0026ldquo;initalised\u0026rdquo;) so I figured it was an application error. If this was an error coming from SQL Server or IIS, it would have been written in en-us.\nWe figured that if the error is referencing database initialization, there must be some config table that has the name of the server. What a nightmare. Now we have to search through the databases, guessing at the potential name for this configuration object.\n# I bet it\u0026#39;s one of those configuration tables. Get-DbaDbTable -SqlInstance APPSQL2 -Database appdb | Where Name -match config # No good candidates. Let\u0026#39;s look thru the stored procedures. Find-DbaStoredProcedure -SqlInstance APPSQL2 -Database appdb -Pattern config # Oops, forgot they were all encrypted. That didn\u0026#39;t return anything. # Search views, stored procedures and triggers then save the candidates\u0026#39; names to a variable so they can be passed to Invoke-DbaDbDecryptObject Get-DbaDbModule -SqlInstance APPSQL2 -Database appdb -Type View, StoredProcedure, Trigger | Out-GridView -Passthru | Select-Object -ExpandProperty Name -OutVariable names Invoke-DbaDbDecryptObject -SqlInstance APPSQL2 -Database appdb -Name $names Oh, la la! We found a candidate, updated the values and we were back in action! The migration was successful and the test results were accepted. With this knowledge, they were able to quickly perform a the production migration.\nOut of Curiosity What was your most challenging migration with dbatools like? How often do you have to modify jobs and database objects like stored procedures/views?\nChrissy 🚀 ","date":"2019-05-26","summary":"Recently, a colleague asked me to assist with the migration of some older, customized application databases to a SQL Server 2017 instance. Most of the migrations I perform are rather vanilla, but this one was a bit more involved.\nSetup Imagine this scenario:\nSource (APPSQL1) Dedicated SQL Server 2008 R2 failover clustered instance with a non-default collation (SQL_Latin1_General_CP1_CI_AI) Custom .NET application with an intense database containing a non-default collation (also SQL_Latin1_General_CP1_CI_AI), multiple CLR assemblies, and thousands of tables, views, stored procedures, functions Nearly 30 SQL Agent jobs, many of which had to be disabled over the years due to compatibility issues and scope changes Out-of-support for both Microsoft and the application vendor Destination (APPSQL2) Shared server SQL Server 2017 Default collation (SQL_Latin1_General_CP1_CI_AS) There was even a linked server in the mix, but our biggest concerns revolved around the changing collation and the Agent jobs, which were known to be brittle.","tags":[],"title":"Migrating Super Old App Databases","type":"post","url":"https://dbatools.io/oldapp/"},{"categories":["announcements"],"content":"Today marks the 30 day countdown to dbatools 1.0, which we will be debuting at Data Grillen in Lingen, Germany! These next 30 days are important and I\u0026rsquo;m writing to ask for your help.\nIntegration Tests We could still use a hand getting in those last few Integration tests. If you\u0026rsquo;re interested in adding a couple tests, I did a quick lil livestream on Twitch about writing integration tests for dbatools that could be useful to you.\nI don\u0026rsquo;t think I\u0026rsquo;ve had the time to share, but dbatools team members livestream at dbatools.io/live and videos are published on our youtube channel, youtube.com/dbatools. More on that later.\nBugs and Various Issues We\u0026rsquo;ve got about 30 issues left to resolve which you can see and follow on our GitHub Projects page. If you\u0026rsquo;ve ever been interested in helping, now is the perfect time as we only have 30 more days left to reach our goal.\nIf you\u0026rsquo;re a current or past dbatools developer, we\u0026rsquo;d love any help we can get. Just hit up the GitHub Projects page to see what issues are left to resolve. If someone is already assigned, please reach out to them on Slack in the #dbatools-dev channel and see if they can use your help.\nPrerelease Branch For anyone submitting Pull Requests, please submit to the temporary default: prerelease\nOh, and if you ❤ dbatools, please give it a ⭐ on GitHub if you haven\u0026rsquo;t already. Stars make our day.\n-Chrissy\n","date":"2019-05-20","summary":"Today marks the 30 day countdown to dbatools 1.0, which we will be debuting at Data Grillen in Lingen, Germany! These next 30 days are important and I\u0026rsquo;m writing to ask for your help.\nIntegration Tests We could still use a hand getting in those last few Integration tests. If you\u0026rsquo;re interested in adding a couple tests, I did a quick lil livestream on Twitch about writing integration tests for dbatools that could be useful to you.","tags":[],"title":"30 Day Countdown to 1.0 Starts Today!","type":"post","url":"https://dbatools.io/30-day-countdown-to-1-0-starts-today/"},{"categories":["announcements"],"content":"I am Andreas Schubert and I am working as a Principal Consultant and Database Reliability Engineer for SQL Server \u0026amp; Azure for multiple national and international companies. My focus is on implementing and operating complex 24/7 SQL environments with tens and hundreds of servers and multi-terabyte databases.\nWelcome to a quick post that should help you operate your SQL Server environment more consistently and reduce manual, repetitive work.\nThe Problem When you are running SQL Server Availability Groups, one of the most cumbersome tasks is to ensure that all logins are synchronised between all replicas. While not exactly rocket science, it is something that quickly means a lot of work if you are managing more than one or two Availability Groups.\nWouldn\u0026rsquo;t it be nice to have a script that is flexible enough to\nbe called by only specifying the Availability Group Listener detect all replicas and their roles automatically connect to the primary, read all SQL logins and apply them to EVERY secondary automatically? Well, dbatools to the rescue again.\nThe Solution With dbatools, such a routine takes only a few lines of code.\nThe below script connects to the Availability Group Listener, queries it to get the current primary replica, as well as every secondary replica and then synchronizes all logins to each secondary.\nIn the template code, no changes are actually written due to the -WhatIf switch, so that you can safely test it to see what changes would be committed.\n\u0026lt;# Script : SyncLoginsToReplica.ps1 Author : Andreas Schubert (https://www.linkedin.com/in/schubertandreas) Purpose: Sync logins between all replicas in an Availability Group automatically. -------------------------------------------------------------------------------------------- The script will connect to the listener name of the Availability Group and read all replica instances to determine the current primary replica and all secondaries. It will then connect directly to the current primary, query all Logins and create them on each secondary. Attention: The script is provided so that no action is actually executed against the secondaries (switch -WhatIf). Change that line according to your logic, you might want to exclude other logins or decide to not drop any existing ones. -------------------------------------------------------------------------------------------- Usage: Save the script in your file system, change the name of the AG Listener (AGListenerName in this template) and schedule it to run at your prefered schedule. I usually sync logins once per hour, although on more volatile environments it may run as often as every minute #\u0026gt; # define the AG name $AvailabilityGroupName = \u0026#39;AGListenerName\u0026#39; # internal variables $ClientName = \u0026#39;AG Login Sync helper\u0026#39; $primaryInstance = $null $secondaryInstances = @{} try { # connect to the AG listener, get the name of the primary and all secondaries $replicas = Get-DbaAgReplica -SqlInstance $AvailabilityGroupName $primaryInstance = $replicas | Where-Object Role -eq Primary | Select-Object -ExpandProperty name $secondaryInstances = $replicas | Where-Object Role -ne Primary | Select-Object -ExpandProperty name # create a connection object to the primary $primaryInstanceConnection = Connect-DbaInstance $primaryInstance -ClientName $ClientName # loop through each secondary replica and sync the logins $secondaryInstances | ForEach-Object { $secondaryInstanceConnection = Connect-DbaInstance $_ -ClientName $ClientName Copy-DbaLogin -Source $primaryInstanceConnection -Destination $secondaryInstanceConnection -ExcludeSystemLogins -WhatIf } } catch { $msg = $_.Exception.Message Write-Error \u0026#34;Error while syncing logins for Availability Group \u0026#39;$($AvailabilityGroupName): $msg\u0026#39;\u0026#34; } To make tools reusable, you could easily turn this script into a function by adding the 2 variables as parameters. Then you could call it from any other script like\nSyncLoginsToReplica.ps1 -AvailabilityGroupName YourAGListenerName -ClientName \u0026#34;Client\u0026#34; For simplicity, I created this as a standalone script though.\nI hope you find this post useful. For questions and remarks please feel free to message me!\n","date":"2019-05-20","summary":"I am Andreas Schubert and I am working as a Principal Consultant and Database Reliability Engineer for SQL Server \u0026amp; Azure for multiple national and international companies. My focus is on implementing and operating complex 24/7 SQL environments with tens and hundreds of servers and multi-terabyte databases.\nWelcome to a quick post that should help you operate your SQL Server environment more consistently and reduce manual, repetitive work.\nThe Problem When you are running SQL Server Availability Groups, one of the most cumbersome tasks is to ensure that all logins are synchronised between all replicas.","tags":[],"title":"Keeping Availability Group Logins in Sync Automatically","type":"post","url":"https://dbatools.io/keeping-availability-group-logins-in-sync-automatically/"},{"categories":["announcements"],"content":"The Situation Hey all, I am Andreas Schubert and I am working as a Principal Consultant and Database Reliability Engineer for SQL Server \u0026amp; Azure for multiple national and international companies. My focus is on implementing and operating complex 24/7 SQL environments with tens and hundreds of servers and multi-terrabyte databases.\nWith the multitude of environments that I am operating, it\u0026rsquo;s impossible to remember every server, every database or the multiple different ways they are interacting with each other. Therefore, one of the first things I do when taking over a consulting engagement is mapping out all those different bits of information.\nSince the environments usually change pretty fast, my goal is to automate this process as much as possible.\nIn this series of posts, I will try to show you how I am implementing this. Of course, your requirements or implementations may differ, but hopefully this blog post can give you some ideas about your tasks too.\nEnter dbatools Before dbatools existed, I had to rely on either the various monitoring solutions that my customers are using or on scripts created by myself. There are a lot of really great 3rd party tools out there that do an awesome job. Unfortunately, they all differ in how they are used or what information they report back. I needed something that is easy to implement, with as few dependencies as possible and works across all SQL Server versions. That\u0026rsquo;s when I started using dbatools.\nI immediately felt in love with how flexible it is. And boy, did its functionality grow fast!\nToday, there are tons of commands available that cover almost all, of the various, areas SQL Server has to offer.\nThe Task Before I dive into specific SQL Servers for in-depth analysis, I want to see some sort of inventory. The minimum information I would like to collect is:\nWhat server is SQL running on? What edition and patch level does it have? How many cores and RAM is it equipped with? How many databases are on the SQL, what size are they and what\u0026rsquo;s the biggest one? Is the SQL part of an Availability Group? If yes, what\u0026rsquo;s the name of the AG, what role does the SQL have right now and what\u0026rsquo;s the underlying cluster object name? On top of that, I find that SQL Instances usually get a \u0026ldquo;pet name\u0026rdquo; alias. This means, when people within the company are talking about the SQL Server, they don\u0026rsquo;t call it by it\u0026rsquo;s machine name, but rather something like \u0026ldquo;the production database\u0026rdquo; or \u0026ldquo;the cluster\u0026rdquo;. Technically not correct, but that\u0026rsquo;s how it is happening. Due to that, my overview should also contain that alias to make it easier for me until I remember all the mappings. Whoever has built an inventory script in the past knows that collecting the above information requires quite a few scripts. On top of that, the underlying DMVs have been changed between SQL versions, so you need to account for that. Microsoft has made that much easier with providing SMO (SQL Server Management Objects), a set of libraries that abstract away the complexity of collecting that information. Thankfully, Microsoft also enabled the dbatools team to include SMO in their framework. My example solution relies solely on dbatools (which works - not only but also - with SMO).\nOK, enough talk, let\u0026rsquo;s jump straight into the code.\nThe Solution Right at the beginning of any of my scripts, I am defining the root of the script itself. I do this because I re-use a lot of functions.\nSince we want to collect the information for more than one SQL Server instance, we will first build a list of SQL Servers. We could query the list of instances from a central management server, but for the purpose of this post - and portability- we will keep it simple. We will also assume the account executing this script will have sufficient permissions on each SQL Server instance and that it can connect via Windows Authentication. I generally prefer Windows Authentication over SQL Server authentication due to security concerns, but that is a completely separate topic.\nThe names of the Servers will be coming from a simple text file in our example. Just do me a favour and do NOT put your server list into an unsecured network location - again, we need to keep security in mind.\nNext, we need to load this file into our PowerShell session. For the sake of simplicity, I am loading it explicitely into my script. Normally, I have a variable populated with the servers in my profile, so I don\u0026rsquo;t have to do this each time.\n$script:root = \u0026#39;D:\\AdminScripts\u0026#39; $ProductionServers = Get-Content (Join-Path $script:root -ChildPath \u0026#39;Production.txt\u0026#39;) Similar to the actual server list, I am using a text file \u0026ldquo;AliasList.txt\u0026rdquo; to store the alias information i mentioned above:\nIt\u0026rsquo;s the same system: the name of the server or instance, followed by the alias name. Both values are separated by a semicolon. Loading and storing the alias information in a hash table is a simple one-liner in PowerShell:\n$AliasList = Get-Content (Join-Path $script:root -ChildPath \u0026#39;AliasList.txt\u0026#39;) | Select @{Name= \u0026#34;Instance\u0026#34;;Expression={$_.ToString().Split(\u0026#39;;\u0026#39;)[0]}},@{Name= \u0026#34;Alias\u0026#34;;Expression={$_.ToString().Split(\u0026#39;;\u0026#39;)[1]}} Since I usually exclude system databases from my reports, I am defining a separate list of them as well for easier reuse:\n$systemDBs = \u0026#34;master\u0026#34;,\u0026#34;model\u0026#34;,\u0026#34;msdb\u0026#34;,\u0026#34;tempdb\u0026#34;, \u0026#34;ReportServer\u0026#34;,\u0026#34;ReportServerTempDB\u0026#34; At this point, we have all the preliminaries completed: A list of SQL Servers to query, a list of system databases that we will exclude and a list of alias information. Let\u0026rsquo;s hit the servers and put the resulting data into a variable. I\u0026rsquo;ll first show the complete code block, then we will talk about what it does.\n$rawData = $ProductionServers | Connect-DbaInstance | Sort-Object Computername | Select-Object ComputerName, # map the SQL version @{Name=\u0026#34;SQL Version\u0026#34;;Expression={ if ($_.VersionMajor -eq \u0026#34;11\u0026#34;) {\u0026#34;SQL 2012\u0026#34;} elseif ($_.VersionMajor -eq \u0026#34;12\u0026#34;) {\u0026#34;SQL 2014\u0026#34;} elseif ($_.VersionMajor -eq \u0026#34;13\u0026#34;) {\u0026#34;SQL 2016\u0026#34;} elseif ($_.VersionMajor -eq \u0026#34;14\u0026#34;) {\u0026#34;SQL 2017\u0026#34;} elseif ($_.VersionMajor -eq \u0026#34;15\u0026#34;) {\u0026#34;SQL 2019\u0026#34;} elseif ($_.VersionMajor -lt \u0026#34;11\u0026#34;) {\u0026#34;SQL 2008R2 or older\u0026#34;} else {\u0026#34;unknown\u0026#34;}}}, ProductLevel, Edition, # RAM @{Name= \u0026#34;Memory (GB)\u0026#34;;Expression={[math]::Round(($_.PhysicalMemory) / 1024)}}, Processors, InstanceName, # total count of user dbs @{Name= \u0026#34;User DBs\u0026#34;;Expression={($_.Databases | where {$_.Name -notin $systemDBs} | Measure).Count}}, # total db size for all user dbs @{Name= \u0026#34;Total DB Size (GB)\u0026#34;;Expression={[math]::Round(($_.Databases | where {$_.Name -notin $systemDBs} | Select size | Measure -Property Size -sum | Select sum).sum / 1024)}}, # biggest DB (name, Size(GB) @{Name= \u0026#34;Biggest DB (GB)\u0026#34;;Expression={\u0026#34;$($_.Databases | where {$_.Name -notin $systemDBs} | Sort Size -Descending | Select -ExpandProperty Name -First 1) ($([math]::Round(($_.Databases | where {$_.Name -notin $systemDBs} | Sort Size -Descending | Select -ExpandProperty Size -First 1)/1024)) GB)\u0026#34;}}, # add the name of the Availability Group (if any) @{Name= \u0026#34;AG (s)\u0026#34;;Expression={$_ | Select -ExpandProperty AvailabilityGroups | Select -ExpandProperty AvailabilityGroupListeners}}, # add the current role of the server in the Availability Group (if any) @{Name= \u0026#34;Role (s)\u0026#34;;Expression={$_ | Select -ExpandProperty AvailabilityGroups | Select -ExpandProperty LocalReplicaRole}}, ClusterName | Sort ComputerName While this code may look complex, from a PowerShell point of view it\u0026rsquo;s really pretty simple. First, we take the list of our Productionservers and pipe it to Connect-DbaInstance cmdlet. Connect-DbaInstance is the result of dbatools calling the SMO functionality, returning a complete SMO object of the SQL Server connected to.\nTechnically, the part with $rawData = $ProductionServers | Connect-DbaInstance already gives us all the information we need for our report. But since we don\u0026rsquo;t want to return all the possible SMO properties and objects (that would result in a very long operation), we pipe the results of this directly to a Sort, followed by returning the actual information we are interested in:\n$rawData = $ProductionServers | Connect-DbaInstance | Sort Computername | Select ComputerName, First we extract the Computername. On the next two lines, we map the SQL Server major version number to a clear-text string:\n# map the SQL version @{Name=\u0026#34;SQL Version\u0026#34;;Expression={ if ($_.VersionMajor -eq \u0026#34;11\u0026#34;) {\u0026#34;SQL 2012\u0026#34;} elseif ($_.VersionMajor -eq \u0026#34;12\u0026#34;) {\u0026#34;SQL 2014\u0026#34;} elseif ($_.VersionMajor -eq \u0026#34;13\u0026#34;) {\u0026#34;SQL 2016\u0026#34;} elseif ($_.VersionMajor -eq \u0026#34;14\u0026#34;) {\u0026#34;SQL 2017\u0026#34;} elseif ($_.VersionMajor -eq \u0026#34;15\u0026#34;) {\u0026#34;SQL 2019\u0026#34;} elseif ($_.VersionMajor -lt \u0026#34;11\u0026#34;) {\u0026#34;SQL 2008R2 or older\u0026#34;} else {\u0026#34;unknown\u0026#34;}}}, Right on, we extract the product level (e.g. RTM, SP1, …) and the Edition of the SQL Server (Standard, Enterprise…), followed by the available machine memory. Since this is returned in MB, we format and round it so that we get a nice number in GB (e.g. 12, 48 or 128).\nThen we include the number of logical processors and the name of the instance - in case we have a named instance.\nThe number and size of user databases is a bit more complex. We need to query the \u0026ldquo;Databases\u0026rdquo; collection of the SMO Server object, filter out the system databases, get the size property of each object in the collection and measure it (count for the number and SUM for the combined size of the databases). Of course, we want those numbers to be nicely formatted and rounded to the full GB, so we add the formatting as well:\n# total count of user dbs @{Name= \u0026#34;User DBs\u0026#34;;Expression={($_.Databases | Where {$_.Name -notin $systemDBs} | Measure).Count}}, # total db size for all user dbs @{Name= \u0026#34;Total DB Size (GB)\u0026#34;;Expression={[math]::Round(($_.Databases | Where {$_.Name -notin $systemDBs} | Select size | Measure -Property Size -sum | Select sum).sum / 1024)}}, To get the size of the biggest / largest database on the server, we use the same technique, only that we sort the database object list by size in descending order and take only the first object:\n# biggest DB (name, Size(GB) @{Name= \u0026#34;Biggest DB (GB)\u0026#34;;Expression={\u0026#34;$($_.Databases | Where {$_.Name -notin $systemDBs} | Sort Size -Descending | Select -ExpandProperty Name -First 1) ($([math]::Round(($_.Databases | Where {$_.Name -notin $systemDBs} | Sort Size -Descending | Select -ExpandProperty Size -First 1)/1024)) GB)\u0026#34;}}, The PowerShell pipeline can be really awesome!\nNow let\u0026rsquo;s add the information about the Availability Group Listener to our list. The AG information is another sub-object of the SMO collection which we first have to extract to get to the information below.\n# add the name of the Availability Group (if any) @{Name= \u0026#34;AG (s)\u0026#34;;Expression={$_ | Select -ExpandProperty AvailabilityGroups | Select -ExpandProperty AvailabilityGroupListeners}}, And exactly the same way for the role of the current replica as well as the cluster object name:\n# add the current role of the server in the Availability Group (if any) @{Name= \u0026#34;Role (s)\u0026#34;;Expression={$_ | Select -ExpandProperty AvailabilityGroups | Select -ExpandProperty LocalReplicaRole}}, ClusterName | Sort ComputerName That\u0026rsquo;s a whole lot of information retrieved by just one call to a PowerShell method. How awesome is that? Most of our script is logic around formatting and extracting information from sub-properties and objects.\nAnd finally, we add the Alias to our result, matching them by computername:\n# add the alias to the rawdata $rawData | % { $v = $_.ComputerName if (\u0026#39;\u0026#39; -ne $_.InstanceName){$v +=\u0026#34;\\$($_.InstanceName)\u0026#34;} $alias = $AliasList | Where {$_.Instance -eq $v } | Select -ExpandProperty Alias -First 1 $_ | Add-Member -MemberType NoteProperty -Name AliasName -Value $alias } The last step is to convert our object to HTML and add some css styling to it. Then we can either send it via eMail or store the generated html as a file for future reference.\n$css = Get-Content (Join-Path $script:root -ChildPath \u0026#39;css.txt\u0026#39;) $html = $rawData | ConvertTo-Html -Fragment -PreContent \u0026#34;$($css)\u0026lt;h2\u0026gt;Instance KPI Summary\u0026lt;/h2\u0026gt;\u0026#34; -PostContent \u0026#34;This summary has been generated with the help of the awesome PowerShell module dbatools!\u0026#34; | Out-File (Join-Path $script:root -ChildPath \u0026#39;result.html\u0026#39;) The result is a nicely formatted html report:\nThis was only a very basic example of what you can do with PSTools, PowerShell and a bit of magic piping. I hope you found this useful.\nFor questions and remarks please feel free to message me at any time!\nYou can find the complete script in my GitHub repo.\n","date":"2019-04-25","summary":"The Situation Hey all, I am Andreas Schubert and I am working as a Principal Consultant and Database Reliability Engineer for SQL Server \u0026amp; Azure for multiple national and international companies. My focus is on implementing and operating complex 24/7 SQL environments with tens and hundreds of servers and multi-terrabyte databases.\nWith the multitude of environments that I am operating, it\u0026rsquo;s impossible to remember every server, every database or the multiple different ways they are interacting with each other.","tags":[],"title":"Building an Inventory View of SQL Servers with dbatools","type":"post","url":"https://dbatools.io/building-an-inventory/"},{"categories":["announcements"],"content":"Recently, dbatools contributor Jess Pomfret teamed up with Bert Wager for a super cool video about dbatools.\nCheck it out!\nThey also wrote accompanying blog posts too! Jess wrote a post titled dbatools with Bert where she talks more in-depth about Backing up your databases and changing your recovery model. Bert penned a post titled Automating Database Maintenance with Jess Pomfret and dbatools 😄👍\nHow incredibly cool! Thank you Jess and Bert for the awesome and fun video 🍕\n","date":"2019-02-05","summary":"Recently, dbatools contributor Jess Pomfret teamed up with Bert Wager for a super cool video about dbatools.\nCheck it out!\nThey also wrote accompanying blog posts too! Jess wrote a post titled dbatools with Bert where she talks more in-depth about Backing up your databases and changing your recovery model. Bert penned a post titled Automating Database Maintenance with Jess Pomfret and dbatools 😄👍\nHow incredibly cool! Thank you Jess and Bert for the awesome and fun video 🍕","tags":[],"title":"dbatools Featured on SQL With Bert","type":"post","url":"https://dbatools.io/sqlbert/"},{"categories":["announcements"],"content":"This post originally appeared in two parts on my personal blog at flxsql.com and has been reposted here by request.\nA bit over a year ago, I blogged about my experience migrating a test SQL Server instance from a VM to a physical machine with a little help from my friends. That migration went well and the instance has been running trouble-free ever since. But it\u0026rsquo;s small potatoes. A modest instance, it\u0026rsquo;s only about 5% the size of production. With SQL Server 2008R2\u0026rsquo;s EOL looming, it was time to migrate production to SQL Server 2016. It\u0026rsquo;s a pretty beefy setup:\n2-node Failover Clustered Instance 16 cores 768GB RAM 4 TB of storage Over 8000 databases The Challenge How do you move eight thousand databases in a reasonable amount of time?\nI spent about an hour and a half one morning hashing ideas out w/ folks in the dbatools Slack channel, plus several conversations in the office and with our hosting provider.\nStart-DbaMigration? I love that function but it\u0026rsquo;s single-threaded and we just don\u0026rsquo;t have time to backup \u0026amp; restore that many databases that way. Backup \u0026amp; restore? Multi-threaded, our daily full backups take over 3 hours to run. Double that to do a backup \u0026amp; restore. Detach \u0026amp; reattach? We\u0026rsquo;ll need either double the storage and eat the time copying the data, or risk the time required to restore from backup if we have to revert. Log shipping, mirroring, replication? Again, double the storage, and we have so many databases that it\u0026rsquo;s just not feasible. In-place upgrade? Not supported by our hosting provider, and there\u0026rsquo;s not much of a safety net. Ultimately the team settled on a variation of the detach \u0026amp; reattach.\nInstall SQL Server 2016 on new physical servers with \u0026ldquo;dummy\u0026rdquo; drives (so that paths could be set during install) Shut down SQL Server 2008R2 Take a SAN snapshot Move the LUN to the new server Attach the databases This is the fastest way for us to move the data, and the snapshot provides a way back if we have to revert. We have backups as well, but those are the reserve parachute - the snapshot is the primary. This process is easiest if the paths for the data and log files remain the same. But that didn\u0026rsquo;t happen here. On the old instance, both data and logs were dumped in the same directory. The new instance has separate data and log directories. And it\u0026rsquo;s a new drive letter to boot.\nOK, so how do you attach eight thousand databases and relocate their files in a reasonable amount of time?\nIt\u0026rsquo;s dbatools to the rescue, with Mount-DbaDatabase being the star of the show. Not only does it attach databases for you, you can use it to relocate and rename the files as well. But that\u0026rsquo;s really one of the last steps. We have setup to do first.\nPreparation Basics Once the servers were turned over to us, the DBA basics had to get set up. I configured a few trace flags for the instance with Set-DbaStartupParameter -Traceflags 3226,4199,7412,460.\nTrace Flag Purpose 460 Enable detailed String or Binary Data would be truncated error message in a future Cumulative Update 3226 Suppress successful backup messages in the error log 4199 Enable query optimizer fixes in CUs and hotfixes 7412 Enable lightweight execution statistics profiling Since publishing the original post, I\u0026rsquo;ve received a couple questions about the use of TF4199. With the database-scoped option QUERY_OPTIMIZER_HOTFIXES this isn\u0026rsquo;t absolutely necessary to get post-RTM hotfixes for the optimizer. Pedro Lopes (blog) recommended in his Summit 2018 to enable it globally, and he confirmed that in an email exchange with Andy Galbraith (blog) that Andy wrote up on his blog. Pam Lahoud wrote about the topic in a recent post as well.\nI did use Start-DbaMigration but excluded Databases, Logins, AgentServer, ExtendedEvents (the last because we don\u0026rsquo;t use XE on the old instance anyway; this avoided any warnings or errors related to it). Excluding databases makes sense given what I wrote above, but why logins and Agent jobs?\nThe source instance is several years old and has built up a lot of cruft; this migration was a good chance to clear that out. All disabled logins and jobs were scripted out and saved, and only the active items migrated. But that also meant I couldn\u0026rsquo;t use Copy-DbaAgentServer because it doesn\u0026rsquo;t filter jobs out; a few extra steps were necessary. For reasons I don\u0026rsquo;t understand, Start-DbaMigration copied our database mail and Linked Server setups faithfully, with one exception - the passwords.\nWe were able to fix that up easily enough but I found it strange that of all things, the passwords weren\u0026rsquo;t copied properly. Especially since I\u0026rsquo;ve done this successfully with dbatools in the past.\nMoving Logins Although I only wanted to migrate the currently-active logins, I wanted the ability to re-create any disabled logins just in case, so I needed to extract the create scripts for them. I achieved this via Get-DbaLogin, Export-DbaLogin, and Copy-DbaLogin:\nMoving Agent Jobs I had the same need for Agent jobs, and achieved it similarly. However, because I excluded the AgentServer from Start-DbaMigration, I had to peek into that function to find out all the other things it copies before copying the jobs. I also wanted to leave the jobs disabled on the new server so they didn\u0026rsquo;t run before we were ready to test \u0026amp; monitor them in a more controlled way.\nMaintenance \u0026amp; Monitoring When that was complete, we updated the community tools that are installed in system databases\nBrent Ozar\u0026rsquo;s First Responder Kit - Install-DbaFirstResponderKit-database master -force Adam Machanic\u0026rsquo;s sp_whoisactive - Install-DbaWhoIsActive-database master Ola Hallengren\u0026rsquo;s Maintenance Solution - Install-DbaMaintenanceSolution-database master By default, this function doesn\u0026rsquo;t install Agent jobs, which is fine here. I already copied the Agent jobs over, but I wanted the latest \u0026amp; greatest versions of the backup and index maintenance stored procedures that they call. We use MinionWare\u0026rsquo;s Minion CheckDB but didn\u0026rsquo;t need do a separate installation or migration. With the exception of the Agent jobs, everything is self-contained in a single database. The Agent jobs were copied above, and the database came over with all the others.\nReady to Go With the above complete, there wasn\u0026rsquo;t much left to do aside from doing some small-scale testing of the database attachment process and validating system operations (database mail, backups, CheckDB, etc.).\nFinal Prep We completed our nightly backups as usual on Friday night, so when I arrived Saturday I kicked off a final differential backup to catch any overnight changes. We\u0026rsquo;ve multi-threaded Ola\u0026rsquo;s backup script by creating multiple jobs and I started them all at once with (of course) PowerShell.\nGet-DbaAgentJob -SqlInstance $OldInstance | Where-Object {$_.name -like \u0026#39;user database backups - diff*\u0026#39;} | ForEach-Object {$_.Start()} I estimated that the diff backups would take about 90 minutes based on a couple test runs; they took 100 minutes (not too shabby!). While that ran, I re-exported the Agent jobs just to be sure I had everything captured there. I also copied a few databases to another 2008R2 instance in case they were needed for debugging purposes. The very last step was to extract a listing of all our databases and the full paths to the physical data and log files, then split them into ten files.\nThe method I used to attach the databases wasn\u0026rsquo;t scalable to running it for all eight thousand databases at once and this let me control the batch sizes easily.\nThe resulting CSV file gave me each database file, the type of file (data or log), and the database name itself.\ndatabase_id name FileType physical_name 7 MyDatabase ROWS S:\\Very\\Long\\Path\\MyDatabase.mdf 7 MyDatabase LOG S:\\Very\\Long\\Path\\MyDatabase_1.ldf Time to Move With all of our pre-migration work complete, we shut down the SQL Server 2008R2 instance. Then we turned things over to the folks in the datacenter to detach the storage LUN, take the snapshot, and attach the LUN to the new instance. When their work was complete, they passed the baton back to me to move the files around and attach the databases.\nAttaching the Databases Before reading this section, the author referenced posts on PowerShell multithreading with PoshRSJob and thread-safe logging with PSFramework, which provide background for how the database attachment process was done.\nI created my own function as a wrapper for Mount-DbaDatabase from dbatools, adding the extra features I needed (or thought I needed):\nLogging Multi-threading Logically renaming the files Setting the database owner appropriately Rebuilding indexes Upgrading the CompatibilityLevel In practice, I only used the first four in the initial attachment of the databases for the upgrade. Example execution:\nGet-MountProgress is a variation on one of the functions in my multithreading post above, which let me keep tabs on the progress as the function ran. I ran the above code ten (well, eleven) times, once for each \u0026ldquo;batch\u0026rdquo; of 10% of the databases. The first group ran great! Only about 6 minutes to attach the databases. The next batch was 10 minutes. Then 16. And then, and then, and then…\nFrom the timestamps on the log files, you can see that each batch took progressively longer and longer. It was agonizing once we got past the 5th group. I have observed that SMO\u0026rsquo;s enumeration when connecting to a database instance can be lengthy with large numbers of databases on the instance, which would correlate to what I observed; the more databases I have, the longer it takes. But I can\u0026rsquo;t completely attribute the slowdown to this.\nPartway through, we shifted gears a bit and I ran a special group of databases which hadn\u0026rsquo;t yet been attached but the QA team needed for their testing. This let them get rolling on their test plans without waiting longer.\nMemory consumption for powershell.exe was very high as well, and kept growing with each batch. After the 3rd batch, I decided I needed to exit PowerShell after each one and restart it just to keep that from getting out of hand. I\u0026rsquo;m not sure what happened there; maybe a runspace memory leak?\nI had estimated attaching the databases would take about one hour. It took over six and a half. There was no one more upset over this than me. On the up side, the logs showed nothing but success.\nValidation Once we realized that attaching the databases was going to run longer than expected, our developers and QA team pivoted to testing what they could with the databases we had attached early on. In hindsight, I should have asked them which databases they needed for their test plans and attached those right away, so that they could test while ther remainder of the databases were running. But, great news! They didn\u0026rsquo;t find any issues that could be directly attributed to how we did the migration of the data.\nI re-ran my earlier PowerShell to fetch the databases and their files from sys.databases against the new instance and compared to the original; everything matched! Confirmation that all of the databases were attached.\nFinal Steps We missed the estimated time for our go/no-go decision by five minutes. With the number of moving parts, databases in play, unexpected delays, and amount of testing we had to do, that\u0026rsquo;s pretty good! My colleague and I had some additional work we needed to take care of after the team declared the migration a success. Agent jobs needed to be enabled, overnight job startups monitored, things like that. We called it a day after about 14 hours in the office.\nThe next day, we had some more tasks to complete. Per a blog post by Erin Stellato (blog) back in May, because we upgraded from 2008R2 to 2016, an index rebuild was advisable for all our nonclustered indexes. I did this via Red Gate Multi Script and some dynamic SQL instead of PowerShell this time, looping through all the NC indexes in each database and running ALTER INDEX REBUILD.\nAftermath Our first few days post-upgrade didn\u0026rsquo;t go well. CPU usage and response times were terrible and after checking over everything for days on end, we finally tracked it back to a piece of code that was still looking for the old SQL Server 2008R2 instance. Once that was fixed, everything came back to normal.\nA few days post-migration, we did have one problem caused by a change in SQL Server 2016. It seems that SQL Server got a little stricter about doing subtraction of integers from time types (instead of using dateadd()). Correcting it was pretty easy as it was limited to a couple stored procedures which are used in a limited capacity.\nLessons Learned It\u0026rsquo;s not a good project without some solid lessons learned! What could we have done to make migration day easier?\nWork out which databases need to be available for performing post-upgrade checks and attach those first Work in smaller batches (not sure how much this would have helped) Have a test environment that\u0026rsquo;s as close as possible to production in all aspects Conclusion I suppose you\u0026rsquo;re expecting me to say something profound here. The most surprising thing to me about this migration is that there were no major surprises. Aside from one portion taking longer than anticipated and those two small pieces of code, everything went to plan. All in all, our migration is a success and after working out a few glitches in the week or two after, things have been running well. We\u0026rsquo;re on a modern release now, and looking forward to taking advantage of the new features available to us now.\n- Andy Levy, flxsql.com\n","date":"2019-01-17","summary":"This post originally appeared in two parts on my personal blog at flxsql.com and has been reposted here by request.\nA bit over a year ago, I blogged about my experience migrating a test SQL Server instance from a VM to a physical machine with a little help from my friends. That migration went well and the instance has been running trouble-free ever since. But it\u0026rsquo;s small potatoes. A modest instance, it\u0026rsquo;s only about 5% the size of production.","tags":[],"title":"A Monumental Migration to SQL Server 2016","type":"post","url":"https://dbatools.io/xlmigration/"},{"categories":[],"content":"Here\u0026rsquo;s a quick tutorial on creating your first pull request.\nFork the project, clone your fork, and configure the remotes: # Clone your fork of the repo into the current directory git clone https://github.com/\u0026lt;your-username\u0026gt;/dbatools.git # Navigate to the newly cloned directory cd dbatools # Assign the original repo to a remote called \u0026#34;upstream\u0026#34; git remote add upstream https://github.com/dataplat/dbatools.git If you cloned a while ago, get the latest changes from upstream: git checkout development git pull upstream development Create a new topic branch (off the main project development branch) to contain your feature, change, or fix: git checkout -b \u0026lt;topic-branch-name\u0026gt; Commit your changes in logical chunks. For any Git project, some good rules for commit messages are the first line is commit summary, 50 characters or less, followed by an empty line followed by an explanation of the commit, wrapped to 72 characters. See a note about git commit messages for more.\nThe first line of a commit message becomes the title of a pull request on GitHub, like the subject line of an email. Including the key info in the first line will help us respond faster to your pull.\nPush your topic branch up to your fork: git push origin \u0026lt;topic-branch-name\u0026gt; Open a Pull Request with a clear title and description.\nDone!\nTutorial used from: pointcloudlibrary\n","date":"2019-01-16","summary":"Here\u0026rsquo;s a quick tutorial on creating your first pull request.\nFork the project, clone your fork, and configure the remotes: # Clone your fork of the repo into the current directory git clone https://github.com/\u0026lt;your-username\u0026gt;/dbatools.git # Navigate to the newly cloned directory cd dbatools # Assign the original repo to a remote called \u0026#34;upstream\u0026#34; git remote add upstream https://github.com/dataplat/dbatools.git If you cloned a while ago, get the latest changes from upstream: git checkout development git pull upstream development Create a new topic branch (off the main project development branch) to contain your feature, change, or fix: git checkout -b \u0026lt;topic-branch-name\u0026gt; Commit your changes in logical chunks.","tags":[],"title":"Your First Pull Request","type":"page","url":"https://dbatools.io/github/"},{"categories":["announcements"],"content":"In this age of many companies adopting the ideas of either DevOps or SRE (Site Reliability Engineer) roles, there is constant need for automation. Mundane tasks like collecting metrics, alerts, server and database asset info into a central database on which you can do reporting is now a common task that many DBAs or system admins are performing.\nIn SQL Server world, we are fortunate to have a vibrant community of PowerShell enthusiasts that have open sourced dbatools - a community driven PowerShell module to automate database development and administration.\nThis begs a question..\nWhy Do We Need Automation? We need automation to get rid of repetitive tasks that we have to perform on a daily basis. It is often said:\nIf you have to repeat it, better automate it.\nThis makes sense as the room for common errors is alleviated when the same steps you are taking are automated. Also, with ever increasing data needs, the infrastructure footprint is ever increasing. To meet this ever increasing demand, the only way for a team to scale is to adopt automation.\nFor example, being a SQL Server DBA, you might have been involved in server migration projects wherein you are tasked to migrate from older version of SQL server (SQL server 2008, SQL server 2008R2) to a more modern \u0026amp; supported version (SQL server 2014, 2016, 2017, etc.).\nIn the stone age (before dbatools), we as DBA\u0026rsquo;s spent countless hours scripting pre-migration tasks like logins, SQL Agent jobs, linked servers, system database custom objects, resource governor settings, certificates, etc. Even doing all this effort, often we miss few critical things due to non-standard process. dbatools takes care of the entire migration including pre-migration steps and migrating all or few databases from one instance to another along with error handling and logging. This is awesome, isn\u0026rsquo;t it?\nOnce good thing about dbatools is that it has lots of commands to get all kinds of information that you want to gather. The commands name have the prefix Get-Dba*. Another beauty is the ability to pipe the output of the commands and write to SQL tables using Write-DbaDataTable command.\nIn a large organization where you have hundreds of servers to manage and you often face a situation where you want to query all your SQL server estate. For example, checking total RAM and the max memory setting or you want to get version and service pack info for your entire SQL Server estate. Doing these tasks single threaded against a ton of servers is often painful because it takes lot of time!\nMultithreading to the Rescue What Is Multithreading and How Does PowerShell Offer Multithreading? In simple terms, multithreading is the ability to run multiple threads on same or separate processors at the same time resulting in parallel execution.\nPowerShell provides many ways to allow multi-threading in your scripts. Let\u0026rsquo;s explore the most common ways:\nBackground jobs: A powerful way of allowing commands to run in the background and then retrieve the results later thereby freeing up the terminal and allowing the users to continue their work without interruption. Whenever a new job is started using Start-Job, it ends up spawning a new powershell.exe process which you can easily see using windows task manager or just running Get-Process command. This means that the more background jobs you run, the more powershell.exe processes are created which is a resource hog! Also, there is no ability to throttle the jobs (i.e. all jobs are started and executed at the same time). There is limited ability to manage multiple threads and have them share variables as well.\nPowerShell Runspaces: A powerful and flexible way of leveraging .NET\u0026rsquo;s system.management.automation.runspaces namespace that exposes variety of classes designed to create, manipulate and orchestrate a pool of PowerShell processes. In simple terms, think of Runspaces as containers where everything is contained or stored and ran in an asynchronous fashion.\nHow to Efficiently Leverage PowerShell Runspaces With High Performance and Less Overhead? Boe Prox has open sourced his awesome PoshRSJob module that provides an alternative to native PowerShell jobs with greater performance and less overhead to run commands in the background, freeing up the console and allowing throttling on the jobs.\nWe can use this module to leverage multi-threading in dbatools as well. The PoshRSJob module is well-documented, so in this blog post, I will just get into the details of how to leverage PoshRSJob module with dbatools.\nAs of writing this blog post, there are total of 514 functions in 0.9.722 version of dbatools out of which 192 are for fetching data (Get-Dba*) from your SQL server instances. How did I get those? Easy enough:\n# How many functions are there in dbatools? Get-Command -Module dbatools -Type Function | Measure-Object # How many functions are there in dbatools that fetch data from SQL Server instances? Get-Command -Module dbatools -Verb Get | Where CommandType -eq Function | Measure-Object Now let\u0026rsquo;s say you are tasked to get all the databases that are part of a given Availability Group. There are two ways to approach this: the traditional (sequential) way and multithreading.\nThe Traditional Sequential Way # Get the list of servers. You can read directly from a text file or you can connect to your central database to get the list using tsql. $servers = Get-Content D:\\DBA\\serverList.txt # store credential in a variable which will be used for SQL authentication to your sql servers $cred = Get-Credential -UserName sqladmin -Message \u0026#34;Enter your sqladmin Password\u0026#34; # use foreach to loop through the collection and get the desired data foreach ($server in $servers) { # here you can use any dbatools commands (Get-Dba*) Get-DbaAgDatabase -SqlInstance $server -SqlCredential $cred } Using PoshRSJob Module to Leverage Runspaces \u0026amp; Multithreading # Get the list of servers. You can read directly from a text file or you can connect to your central database to get the list using tsql. $servers = Get-Content D:\\DBA\\serverList.txt # store credential in a variable which will be used for SQL authentication to your SQL Servers $cred = Get-Credential -UserName sqladmin -Message \u0026#34;Enter your sqladmin Password\u0026#34; # PoshRSJob has throttle parameter. I usually keep it to the number of processors installed on the server $throttle = $env:NUMBER_OF_PROCESSORS # Multithread! See below for a breakdown Start-RSJob -InputObject $servers -Throttle $throttle -ModulesToImport dbatools -ScriptBlock { Param($server) Get-DbaAgDatabase -SqlInstance $server -SqlCredential $Using:cred } # Get-RSJob will display all jobs that are currently available to include completed and currently running jobs. # Receive-RSJob Gets the results of the Windows PowerShell runspace jobs in the current session. Also you can use -OutVariable variableName e.g. -OutVariable Results and then do $Results to get all the output Get-RSJob | Where-Object {$_.State -like \u0026#34;Completed\u0026#34; -and $_.HasMoreData -like \u0026#34;False\u0026#34; -and $_.HasErrors -like \u0026#34;False\u0026#34;} | Receive-RSJob # cleanup only the jobs that are completed, does not have more data and no errors Get-RSJob | Where-Object {$_.State -like \u0026#34;Completed\u0026#34; -and $_.HasMoreData -like \u0026#34;False\u0026#34; -and $_.HasErrors -like \u0026#34;False\u0026#34;} | Remove-RSJob Breakdown -InputObject $servers\nHere we are passing the collection item - $servers as an input object that will take that object and use it as the first parameter in the script block as long as you add a Param() block in it.\nParam($server)\nThis is added so that the -InputObject collection can be used as the first parameter\n-ModulesToImport dbatools\nHere you can use any dbatools commands as all the commands are imported as part of the module import\n-SqlCredential $Using:cred\nThis is pretty cool way of passing a local variable to the script block i.e. you can use variables from parent PS Process into PSJob\u0026rsquo;s scriptblock\nOn a side note, if you want to get the results or output of Start-RSJob into a variable, you can do it using $results = Get-RSJob | Receive-RSJob or Get-RSJob | Receive-RSJob -OutVariable Results (now you can use $Results same like former example) and then you can work with the result set as usual, and even write the entire result set to a database using Write-DbaDataTable.\nResults Below test shows the performance difference between Sequential Execution vs Multithreaded execution using PoshRSJob:\nTotal Servers in the serverList.txt: 134 Total No. of logical CPUs: 16 dbatools command Sequential Execution PoshRSJob PercentGain Get-DbaAgDatabase TotalSeconds: 123.13 TotalSeconds: 30.75 300.42 % Note: When running using Start-Job, the CPU is pegged to 100% (since it spawns individual powershell.exe processes and does not have native throttling option) and it uses almost all the available RAM than the PoshRSJob. The execution time for Start-Job is more than double and exhaust CPU and available RAM on the machine.\nReferences:\nBackground jobs Multi Threaded PowerShell Cookbook PoshRSJob Thanks for reading ! ~ Kin Shah\nGet in touch at therockstardba.github.io or dba.se\n","date":"2019-01-04","summary":"In this age of many companies adopting the ideas of either DevOps or SRE (Site Reliability Engineer) roles, there is constant need for automation. Mundane tasks like collecting metrics, alerts, server and database asset info into a central database on which you can do reporting is now a common task that many DBAs or system admins are performing.\nIn SQL Server world, we are fortunate to have a vibrant community of PowerShell enthusiasts that have open sourced dbatools - a community driven PowerShell module to automate database development and administration.","tags":[],"title":"Multithreading Commands","type":"post","url":"https://dbatools.io/multithread/"},{"categories":["announcements"],"content":"Splatting in PowerShell makes code easier to read. Instead of typing a bunch of parameters allllll across the screen, you can use an easy-to-read hashtable or array. Argument splatting was introduced in PowerShell v3 and works with all PowerShell commands, not just dbatools.\nNote: I\u0026rsquo;ve only used splatting with hashtables, as they allow me to be explicit about which parameters I\u0026rsquo;m passing. It appears that arrays would employ positional parameters, which is less wordy but leaves room for error.\nExample 1 In the example below, sql2008 will be migrated to sql2017 using the backup restore method.\n# Ultimately, this (which scrolls offscreen): Start-DbaMigration -Source sql2008 -Destination sql2017 -BackupRestore -SharedPath \\\\nas\\sql\\migration -Force | Select * | Out-GridView # becomes this: $splat = @{ Source = \u0026#34;sql2008\u0026#34; Destination = \u0026#34;sql2017\u0026#34; BackupRestore = $true SharedPath = \u0026#34;\\\\nas\\sql\\migration\u0026#34; Exclude = \u0026#34;AgentServer\u0026#34;,\u0026#34;Audits\u0026#34;,\u0026#34;BackupDevices\u0026#34; } Start-DbaMigration @splat -Force | Select * | Out-GridView Note that the dollar sign in the variable name $splat becomes an at sign, @splat when executing the command. Also, not every parameter has to belong to the splat. As you can see, -Force is specified separately.\nAlso, the use of quotes is slightly different. While quotes are sometimes optional (string variables without special characters) when executing a command the traditional way, quotes around string values are required in a hashtable.\nExample 2 The first example was a short intro and the next ones are a bit longer. Imagine the following splat used with one of our larger commands, Invoke-DbaDbLogShipping.\n$params = @{ Source = \u0026#34;localhost\\sql2016\u0026#34; Destination = \u0026#34;localhost\\sql2017\u0026#34; Database = \u0026#34;shipped\u0026#34; BackupNetworkPath= \u0026#34;\\\\localhost\\backups\u0026#34; PrimaryMonitorServer = \u0026#34;localhost\\sql2017\u0026#34; SecondaryMonitorServer = \u0026#34;localhost\\sql2017\u0026#34; BackupScheduleFrequencyType = \u0026#34;Daily\u0026#34; BackupScheduleFrequencyInterval = 1 CompressBackup = $true CopyScheduleFrequencyType = \u0026#34;Daily\u0026#34; CopyScheduleFrequencyInterval = 1 GenerateFullBackup = $true Force = $true } Invoke-DbaDbLogShipping @params You can see above that switches such as -Force or -CompressBackup when used in a splat will use the following syntax Force = $true.\nExample 3 Here\u0026rsquo;s another example we use in our Extended Events presentation.\n$params = @{ SmtpServer = \u0026#34;localhost\u0026#34; To = \u0026#34;sqldba@ad.local\u0026#34; Sender = \u0026#34;reports@ad.local\u0026#34; Subject = \u0026#34;Deadlock Captured\u0026#34; Body = \u0026#34;Caught a deadlock\u0026#34; Event = \u0026#34;xml_deadlock_report\u0026#34; Attachment = \u0026#34;xml_report\u0026#34; AttachmentFileName = \u0026#34;report.xdl\u0026#34; } $emailresponse = New-DbaXESmartEmail @params Start-DbaXESmartTarget -SqlInstance sever01\\sql2017 -Session \u0026#34;Deadlock Graphs\u0026#34; -Responder $emailresponse Example 4 And finally, an example that will be included in the High Availability blog post when it finally comes out.\n$cred = Get-Credential sqladmin $params = @{ Primary = \u0026#34;sql1\u0026#34; PrimarySqlCredential = $cred Secondary = \u0026#34;sql2\u0026#34;, \u0026#34;sql3\u0026#34; SecondarySqlCredential = $cred Name = \u0026#34;test-ag\u0026#34; Database = \u0026#34;pubs\u0026#34; ClusterType = \u0026#34;None\u0026#34; SeedingMode = \u0026#34;Automatic\u0026#34; FailoverMode = \u0026#34;Manual\u0026#34; Confirm = $false } New-DbaAvailabilityGroup @params VS Code In his blog post Easily Splatting PowerShell with VS Code, Rob Sewell shows how VS Code can easily create splats, as explained in his instructions and video below. First, run:\nImport-Module -Name EditorServicesCommandSuite Import-EditorCommand -Module EditorServicesCommandSuite then:\nWrite the command, leave the cursor on a parameter, hit F1 - Choose PowerShell : Show Additional Commands (or use a keyboard shortcut) type splat press enter. Done 😊\nRob also noted to be careful where your cursor is. He usually puts it in the command, as sometimes it goes screwy if the cursor is at the end of the line.\nHave Fun If you use commands with a number of parameters or even want to reuse parameter sets, splatting is an ideal solution.\n- Chrissy\n","date":"2019-01-03","summary":"Splatting in PowerShell makes code easier to read. Instead of typing a bunch of parameters allllll across the screen, you can use an easy-to-read hashtable or array. Argument splatting was introduced in PowerShell v3 and works with all PowerShell commands, not just dbatools.\nNote: I\u0026rsquo;ve only used splatting with hashtables, as they allow me to be explicit about which parameters I\u0026rsquo;m passing. It appears that arrays would employ positional parameters, which is less wordy but leaves room for error.","tags":[],"title":"PowerShell Splatting","type":"post","url":"https://dbatools.io/splat/"},{"categories":["announcements"],"content":"Data compression is not a new feature in SQL Server. In fact it has been around since SQL Server 2008, so why does it matter now? Before SQL Server 2016 SP1 this feature was only available in Enterprise edition. Now that it\u0026rsquo;s in Standard edition data compression can be an option for far more people.\ndbatools has three functions available to help you work with data compression, and in true dbatools style it makes it easy and fast to compress your databases.\nGet-DbaDbCompression This one is pretty straightforward, it shows you your current compression levels across one or more SQL Servers. You can either view all objects or narrow it down to a specific database, as shown below.\nGet-DbaDbCompression -SqlInstance Server1 -Database AdventureWorks2017 | Select-Object Database, Schema, TableName, IndexName, IndexType, Partition, DataCompression PowerShell Database : AdventureWorks2017 Schema : dbo TableName : AWBuildVersion IndexName : PK_AWBuildVersion_SystemInformationID IndexType : ClusteredIndex Partition : 1 DataCompression : None Database : AdventureWorks2017 Schema : dbo TableName : DatabaseLog IndexName : IndexType : Heap Partition : 1 DataCompression : Page Database : AdventureWorks2017 Schema : dbo TableName : DatabaseLog IndexName : PK_DatabaseLog_DatabaseLogID IndexType : NonClusteredIndex Partition : 1 DataCompression : None Database : AdventureWorks2017 Schema : dbo TableName : ErrorLog IndexName : PK_ErrorLog_ErrorLogID IndexType : ClusteredIndex Partition : 1 DataCompression : None Database : AdventureWorks2017 Schema : HumanResources TableName : Department IndexName : AK_Department_Name IndexType : NonClusteredIndex Partition : 1 DataCompression : None Database : AdventureWorks2017 Schema : HumanResources TableName : Department IndexName : PK_Department_DepartmentID IndexType : ClusteredIndex Partition : 1 DataCompression : Page Database : AdventureWorks2017 Schema : HumanResources TableName : Employee IndexName : AK_Employee_LoginID IndexType : NonClusteredIndex Partition : 1 DataCompression : Page Database : AdventureWorks2017 Schema : HumanResources TableName : Employee IndexName : AK_Employee_NationalIDNumber IndexType : NonClusteredIndex Partition : 1 DataCompression : None Database : AdventureWorks2017 Schema : HumanResources TableName : Employee IndexName : IX_Employee_OrganizationLevel_OrganizationNode IndexType : NonClusteredIndex Partition : 1 DataCompression : None Test-DbaDbCompression Now this is where the magic happens. This function takes the leg work out of deciding whether compression is a good fit for your database. When you look to implement data compression you have two options (as far as rowstore compression goes), row or page compression. Page compression gives you superior space savings but it comes with more CPU overhead.\nInefficient Data Types and Repeated Data When you start to analyze your database to make this decision you first need to look at your table structures. Do you have a lot of fixed length datatypes that aren\u0026rsquo;t being fully utilized? Think bigint storing the number 1 or char(1000) storing \u0026lsquo;Jess\u0026rsquo; - then row compression could be a good fit. Do you have a lot of repeating data, like State or Gender columns? Then page compression could do wonders for you.\nWorkload and I/O Secondly, and perhaps more importantly, is your workload. As previously mentioned there is a CPU overhead associated with querying compressed data, so if you are doing a lot of seeks and/or updates the benefits might be outweighed by the costs. On the other hand if you do a lot of scans one of the benefits of data compression, more data stored per page, will greatly reduce your I/O costs and improve your performance overall.\nThis is a lot to think about for each object in each of your databases. Worry not friends! The SQL Server Tiger Team created a script (available on their github) that will analyze both your table structures and your workload. This makes up the logic within Test-DbaDbCompression.\nCompression in Action You can see below I\u0026rsquo;ve analyzed the entire AdventureWorks2017 database and saved the results to a variable. This makes it easy to work through the output, looking at certain objects/indexes of interest.\n$results = Test-DbaDbCompression -SqlInstance Server1 -Database AdventureWorks2017 $results | Where-Object TableName -eq \u0026#39;SalesOrderDetail\u0026#39; | Select-Object TableName, IndexName, IndexId, PercentScan, PercentUpdate, RowEstimatePercentOriginal, PageEstimatePercentOriginal, CompressionTypeRecommendation, SizeCurrent, SizeRequested, PercentCompression | Format-Table PowerShell TableName IndexName IndexId PercentScan PercentUpdate RowEstimatePercentOriginal PageEstimatePercentOriginal CompressionTypeRecommendation --------- --------- ------- ----------- ------------- -------------------------- --------------------------- ----------------------------- SalesOrderDetail PK_SalesOrderDetail_SalesOrderDetailID 1 100 0 70 48 PAGE SalesOrderDetail AK_SalesOrderDetail_rowguid 2 0 0 109 109 NO_GAIN SalesOrderDetail IX_SalesOrderDetail_ProductID 3 0 0 77 68 PAGE This database is actually running in a container on my laptop so there isn\u0026rsquo;t much activity, but when you use this command the PercentScan and PercentUpdate will be determined by your workload so the longer your instance has been up the more accurate these will be.\nI\u0026rsquo;ve selected to look at the SalesOrderDetail table in the above example. You can see the function suggests we apply page compression to our primary key (IndexId of 1) and one of our Nonclustered indexes (IndexId of 3).\nSet-DbaDbCompression The final compression function is used to apply compression to our objects. You can choose to apply row or page compression to your entire database, which could be useful to save space in your development or test environments.\nSet-DbaDbCompression -SqlInstance Server1 -Database AdventureWorks2017 -CompressionType Page More useful however is to once again use the Tiger Team script to apply the recommended compression to your objects.\nRunning the following one line will first analyze your database using the same logic we discussed above, and then apply the suggested levels to each index and table within your database.\nSet-DbaDbCompression -SqlInstance Server1 -Database AdventureWorks2017 -CompressionType Recommended Additional Options There are also some other options available to control this behavior. You can use the -PercentCompression parameter so objects will only be compressed if the calculated savings are greater than the specified percentage. You also can control the amount of time this command runs for. If you set -MaxRunTime to 60 it will finish the current compression command and then stop.\nSet-DbaDbCompression -SqlInstance Server1 -Database AdventureWorks2017 -CompressionType Recommended -PercentCompression 25 -MaxRunTime 60 Conclusion One final idea I\u0026rsquo;ll leave you with- earlier I ran Test-DbaDbCompression and saved the output to a variable. I did this because I like to be able to see what the suggestions are and can also save this output for a later date if needed. Once I\u0026rsquo;m happy and ready to run Set-DbaDbCompression I don\u0026rsquo;t want to wait for the analysis to happen again. I can instead pass in the output I saved using the -InputObject and Set-DbaDbCompression will work through those suggestions applying the recommended compression levels immediately.\nSet-DbaDbCompression -SqlInstance Server1 -InputObject $results Data compression can be a powerful tool in your DBA toolbelt for saving space and performance tuning. You can apply this with minimal effort and no application code changes. I\u0026rsquo;d recommend playing with the Test-DbaDbCompression function and see if you can\u0026rsquo;t squeeze out some easy gains.\nCheers,\nJess\n","date":"2019-01-02","summary":"Data compression is not a new feature in SQL Server. In fact it has been around since SQL Server 2008, so why does it matter now? Before SQL Server 2016 SP1 this feature was only available in Enterprise edition. Now that it\u0026rsquo;s in Standard edition data compression can be an option for far more people.\ndbatools has three functions available to help you work with data compression, and in true dbatools style it makes it easy and fast to compress your databases.","tags":[],"title":"Managing Data Compression with dbatools","type":"post","url":"https://dbatools.io/compression/"},{"categories":["announcements"],"content":"We recently released a VS Code extension that lets you highlight terms and search dbatools.io, Microsoft Docs, Google, StackOverflow, DuckDuckGo, Technet or Thwack right from your code! It\u0026rsquo;s called search from code and you can find it in the Extension Marketplace.\nOptions and Settings By default, only Google, docs and dbatools are enabled but you can configure whichever providers you\u0026rsquo;d like in VS Code Settings.\nAt first, I was just messing around to see what it took to create a VS Code extension, but then I realized that I was actually using it and decided to share. If you use VS Code, give it a shot and let me know if you\u0026rsquo;d like any features or additional search providers!\n- Chrissy\nP.S. Can\u0026rsquo;t see the gif? Watch the video on YouTube.\n","date":"2018-11-28","summary":"We recently released a VS Code extension that lets you highlight terms and search dbatools.io, Microsoft Docs, Google, StackOverflow, DuckDuckGo, Technet or Thwack right from your code! It\u0026rsquo;s called search from code and you can find it in the Extension Marketplace.\nOptions and Settings By default, only Google, docs and dbatools are enabled but you can configure whichever providers you\u0026rsquo;d like in VS Code Settings.\nAt first, I was just messing around to see what it took to create a VS Code extension, but then I realized that I was actually using it and decided to share.","tags":["party"],"title":"dbatools Extension for Visual Studio Code","type":"post","url":"https://dbatools.io/dbatools-extension-for-visual-studio-code/"},{"categories":["announcements"],"content":"We\u0026rsquo;ve made even more progress in the past week! Here are some highlights of 0.9.520.\nNon-Breaking Changes Aliases have been added for the changes, so these are not breaking changes:\nMismatched Copy commands have been renamed to match their corresponding Get command names (ie. Copy-DbaCentralManagementServer is now Copy-DbaCmsRegServer). Most parameters named Password have been changed to SecurePassword. They\u0026rsquo;ve always been a SecureString data type but this makes that clear. The parameters ExcludeAllSystemDb and ExcludeAllUserDb have been changed to ExcludeSystem and ExcludeUser, respectively. Reset-DbaAdmin Reset-DbaAdmin actually has output now! This was a big oversight for an otherwise incredibly useful and cool command.\nI also added a -SqlCredential parameter to make passing secure passwords easier while still staying secure.\nConnect-DbaInstance The Credential parameter in Connect-DbaInstance has been changed to SqlCredential and an alias to Credential has been added. Also, we fixed trusted domain support in both our internal and external Connect commands. So if you\u0026rsquo;ve ever had a problem with that before, it should work now.\nBreaking Changes Aliases have not been created for commands using these parameters so these are breaking changes.\nParameters and output columns containing MB have been changed to the parameter or column name without MB. For instance SizeMB -\u0026gt; Size. Corresponding documentation and examples have been updated as well. Parameters such as NoSystemLogins have been changed to ExcludeSystemLogins. The basic rule I followed when determining what would change was keep No for Verbs and Exclude for nouns: NoVerb, ExcludeNoun. Invoke-DbatoolsRenameHelper has been updated to handle the No to Exclude changes, so don\u0026rsquo;t forget you can auto-update your scripts. Running it is as simple as:\nGet-ChildItem *.ps1 -Recurse | Invoke-dbatoolsRenameHelper\nNote that it does not work for the breaking changes released below (they are massive) or any of the Exclude parameters in Start-DbaMigration since the change wouldn\u0026rsquo;t be a one-to-one and I\u0026rsquo;m not good with regex.\nGet-DbaProductKey This command had been rewritten pretty much from the ground up. It no longer requires remote registry access, just SQLWMI and PowerShell Remoting. It also accepts servers from CMS natively instead of relying on the terribly named -CmsServer parameter. To find out more, check out Get-DbaProductKey\nInvoke-DbaDbShrink Invoke-DbaDbShrink now has better column names.\nImport-DbaCsv I\u0026rsquo;m so happy to announce that Import-DbaCsvToSql has been renamed to Import-DbaCsv and is now usable and reliable for most CSVs. The original command was ultra fast, but it came at the price of reliability. I found myself never using a fast command because it so rarely handled my imperfect data. That\u0026rsquo;s been fixed and the command is still pretty darn fast.\nWriting more in-depth about this command is on my todo list, but I love that you can pipe in a bunch of CSVs from a directory and smash them into a database. Everything is done within a transaction, too, so if the import fails, the transaction is rolled back and no changes persist.\nNo More Breaking Changes for a While K that should do it for breaking changes, at least until we\u0026rsquo;re closer to 1.0.\nWe\u0026rsquo;re trying our best to ensure you don\u0026rsquo;t get too frustrated while we make necessary changes, and we thank you for your patience.\nBig Ol\u0026rsquo; Bug Bash 🐛 The bug bash is going incredibly well! We\u0026rsquo;re now down from 90+ open bugs to just 25 minor bugs 😊 Huge thanks to everyone who has helped bring our count down to such a manageable number.\n- Chrissy\n","date":"2018-11-22","summary":"We\u0026rsquo;ve made even more progress in the past week! Here are some highlights of 0.9.520.\nNon-Breaking Changes Aliases have been added for the changes, so these are not breaking changes:\nMismatched Copy commands have been renamed to match their corresponding Get command names (ie. Copy-DbaCentralManagementServer is now Copy-DbaCmsRegServer). Most parameters named Password have been changed to SecurePassword. They\u0026rsquo;ve always been a SecureString data type but this makes that clear. The parameters ExcludeAllSystemDb and ExcludeAllUserDb have been changed to ExcludeSystem and ExcludeUser, respectively.","tags":["party"],"title":"More 1.0 Progress","type":"post","url":"https://dbatools.io/more-1-0-progress/"},{"categories":["announcements"],"content":"Before I go into the breaking changes introduced in 0.9.518, I wanted to highlight Invoke-dbatoolsRenameHelper which is an awesome command that will help you with a vast majority of our renames. Using it is as simple as:\nGet-ChildItem *.ps1 -Recurse | Invoke-dbatoolsRenameHelper\nThis command even takes care of a couple parameter renames like NetworkShare and UseLastBackups.\nBreaking Changes It\u0026rsquo;s been a busy couple days! Here\u0026rsquo;s a list of our breaking changes\nInvoke-Sqlcmd2 has been removed and replaced with a warning to use Invoke-DbaQuery The NetworkShare parameter has been renamed to SharedPath UseLastBackups has been renamed to UseLastBackup Most NoXyz in Start-DbaMigration has been renamed to ExcludeXyz New Commands Recently, we\u0026rsquo;ve also added a bunch of new WSFC, Mirroring and AG commands (like Sync-DbaAvailabilityGroup!) that I\u0026rsquo;ll write about more in-depth about later. If you\u0026rsquo;d like to test the commands now and give us feedback, check out the Availability Groups section of the Commands Index.\nWe also have other new commands including\nInstall-DbaSqlWatch Uninstall-DbaSqlWatch Get-DbaMemoryCondition Remove-DbaDbBackupRestoreHistory New-DbaDatabase New-DbaDatabase allows you to create databases easily. It even allows you to create multiple databases on multiple servers at once!\nAlso, a teammate suggested we highlight that Install-DbaSqlWatch, which installs sqlwatch is different from Install-DbatoolsWatchUpdate (which watches for updates to dbatools - note: this command was renamed from Install-DbaWatchUpdate in dbatools 1.0).\nOther Updates We also added Azure support to Copy-DbaDbTableData. Oh, and, we added -AutoCreateTable which creates the destination table based off of the definition of the source table. Have you ever used this command? It\u0026rsquo;s an insanely fast streaming bulk-copy between two tables.\nNote that it took 11ms to create the destination table on a remote server and insert 2155 rows 🙌\nThank you all for your patience while we make these huge strides. We\u0026rsquo;ll be in touch soon.\nChrissy\n","date":"2018-11-16","summary":"Before I go into the breaking changes introduced in 0.9.518, I wanted to highlight Invoke-dbatoolsRenameHelper which is an awesome command that will help you with a vast majority of our renames. Using it is as simple as:\nGet-ChildItem *.ps1 -Recurse | Invoke-dbatoolsRenameHelper\nThis command even takes care of a couple parameter renames like NetworkShare and UseLastBackups.\nBreaking Changes It\u0026rsquo;s been a busy couple days! Here\u0026rsquo;s a list of our breaking changes","tags":[],"title":"Breaking Changes Update","type":"post","url":"https://dbatools.io/breaking-changes-update/"},{"categories":["announcements"],"content":"Thanks to several of our team members, we\u0026rsquo;re now progressing quickly towards dbatools 1.0! 🙌\nThe progress is so encouraging, I believe 1.0 is around the corner. Because of this, I wanted to let you all know that tomorrow, we\u0026rsquo;ll start introducing breaking changes.\nOutput Changes Things like output and parameter names will change. For example, the output for the command Get-DbaPrivilege will be updated. Currently, it looks like this:\nPrivilege being repeated in the column names seems unnecessary, so it\u0026rsquo;ll soon have shortened column names:\nLogonAsBatch InstantFileInitialization LockPagesInMemory Tomorrow I\u0026rsquo;ll be updating the max memory series:\nGet-DbaMaxMemory Set-DbaMaxMemory Test-DbaMaxMemory This update includes updated output and parameter names. Basically, I removed the \u0026ldquo;MB\u0026rdquo; and updated the docs to let people know that the output and params are measured in megabytes.\nParameter Name Changes Sometime in the next month, I\u0026rsquo;ll also be updating Start-DbaMigration to more closely match the parameters of Export-DbaInstance. Parameters like NoDatabases and NoLogins will be replaced by -Exclude Databases, Logins.\nSo the functionality won\u0026rsquo;t necessarily change, but if you have scheduled tasks or scripts that perform migrations, you will need to update your parameters once you update dbatools once these changes are made.\nI\u0026rsquo;ll be sending regular updates via email, but no more than once per day. For more frequent updates, you can follow the dbatools project on GitHub or visit dbatools.io.\n- Chrissy\n","date":"2018-11-14","summary":"Thanks to several of our team members, we\u0026rsquo;re now progressing quickly towards dbatools 1.0! 🙌\nThe progress is so encouraging, I believe 1.0 is around the corner. Because of this, I wanted to let you all know that tomorrow, we\u0026rsquo;ll start introducing breaking changes.\nOutput Changes Things like output and parameter names will change. For example, the output for the command Get-DbaPrivilege will be updated. Currently, it looks like this:","tags":[],"title":"dbatools 1.0 Progress!","type":"post","url":"https://dbatools.io/dbatools-1-0-progress/"},{"categories":["announcements"],"content":"During the month of October 2018 DigitalOcean is again running Hacktoberfest to support open source projects. They are offering a limited edition T-Shirt for any person making five pull requests to any public repo on GitHub.\nTo get a shirt, you must make five pull requests (PRs) between October 1-31 in any timezone. PRs can be to any public repo on GitHub, not just the ones highlighted. The PR must contain commits you made yourself. This year, the first 50,000 of you can earn a T-shirt (compared with 30,000 in 2017).\nFull details can be found here.\ndbatools As part of dbatools participation in this event we are encouraging contributors to assist \u0026ldquo;the road towards 1.0\u0026rdquo; by improving the examples available in the comment-based help, which power the new docs site at docs.dbatools.io.\nThe activity is available to anyone who wants to help and does not require any expertise in PowerShell. Any of the following actions are desirable:\nFix typos in examples Fix obvious errors in examples Add examples to illustrate use of all possible parameters Add examples to illustrate use of pipeline support Add examples to illustrate combining multiple dbatools commands. Add examples that illustrate use of dbatools commands in new or interesting ways. We are a looking for a max of 6-8 examples per command.\nNot Sure How to Commit? If you\u0026rsquo;d like to participate but aren\u0026rsquo;t familiar with GitHub, cloning and repos, we\u0026rsquo;ve got good news! You can update our help files using the web interface at GitHub.com. Here\u0026rsquo;s how:\nFirst, create an account. GitHub is free and you do not need to pay to participate. Then head over to the dbatools repository using the shortlink dbatools.io/git.\nAfter creating your GitHub account don\u0026rsquo;t forget to register at hacktoberfest if you want your contributions to be recorded and to qualify for a T-Shirt.\nFind the Command You Want to Edit In this case, we\u0026rsquo;ll add an example to Get-DbaClientAlias. We can do this by clicking on the functions directory.\nNext, click on the Get-DbaClientAlias function.\nThen the edit button.\nAdd an Example If you haven\u0026rsquo;t forked our repo before, you\u0026rsquo;ll get a notice that GitHub has done all the work for you.\nProceed to adding the example by scrolling down to find the list of examples.\nCopy/paste/modify.\nIf you are unsure of how to write or format examples you can look at some existing examples. eg\nInvoke-DbaDbLogShipping Restore-DbaDatabase Then proceed to saving your changes by filling out the form at the bottom. Click the green \u0026ldquo;Propose file changes\u0026rdquo;. Congrats! You\u0026rsquo;ve made your first commit.\nCreate the Pull Request You will now be prompted to create a Pull Request. Click the button that says \u0026ldquo;Create pull request\u0026rdquo;.\nThings are filled out for you already.\nModify as necessary and click \u0026ldquo;Create Pull Request\u0026rdquo;.\nCelebrate After a review is complete and the changes are approved, your request will be merged 👍\nAnd now they will show up on docs.dbatools.io\nIf you\u0026rsquo;d like more examples, check out Möltz Jensen\u0026rsquo;s last two pull requests where he added some useful examples.\nRemember You Will Need Five Pull Requests Before End of October for a T-Shirt! ","date":"2018-10-09","summary":"During the month of October 2018 DigitalOcean is again running Hacktoberfest to support open source projects. They are offering a limited edition T-Shirt for any person making five pull requests to any public repo on GitHub.\nTo get a shirt, you must make five pull requests (PRs) between October 1-31 in any timezone. PRs can be to any public repo on GitHub, not just the ones highlighted. The PR must contain commits you made yourself.","tags":[],"title":"Hacktoberfest - dbatools Edition","type":"post","url":"https://dbatools.io/hacktoberfest/"},{"categories":["announcements"],"content":"Just a quick note that we\u0026rsquo;ve made more changes to align with 1.0, now available in version 0.9.453.\nRenamed Log Shipping Get-DbaDbLogShipError Invoke-DbaDbLogShipping Invoke-DbaDbLogShipRecovery Test-DbaDbLogShipStatus\nRegistered Servers (Central Management Server) Add-DbaRegServer Add-DbaRegServerGroup Get-DbaRegServer Get-DbaRegServerGroup Get-DbaRegServerStore Import-DbaRegServer Move-DbaRegServer Move-DbaRegServerGroup Remove-DbaRegServer Remove-DbaRegServerGroup\nAnd don\u0026rsquo;t forget, you can use Invoke-DbatoolsRenameHelper to rename commands in your scripts.\nGet-ChildItem .\\scripts | Invoke-DbatoolsRenameHelper New I\u0026rsquo;ll write about these more soon, but until then, enjoy this piping hot batch of new HA commands.\nWindows Server Failover Clustering Get-DbaWsfcAvailableDisk Get-DbaWsfcCluster Get-DbaWsfcDisk Get-DbaWsfcNetwork Get-DbaWsfcNetworkInterface Get-DbaWsfcNode Get-DbaWsfcResource Get-DbaWsfcResourceType Get-DbaWsfcRole Get-DbaWsfcSharedVolume\n- Chrissy\n","date":"2018-10-03","summary":"Just a quick note that we\u0026rsquo;ve made more changes to align with 1.0, now available in version 0.9.453.\nRenamed Log Shipping Get-DbaDbLogShipError Invoke-DbaDbLogShipping Invoke-DbaDbLogShipRecovery Test-DbaDbLogShipStatus\nRegistered Servers (Central Management Server) Add-DbaRegServer Add-DbaRegServerGroup Get-DbaRegServer Get-DbaRegServerGroup Get-DbaRegServerStore Import-DbaRegServer Move-DbaRegServer Move-DbaRegServerGroup Remove-DbaRegServer Remove-DbaRegServerGroup\nAnd don\u0026rsquo;t forget, you can use Invoke-DbatoolsRenameHelper to rename commands in your scripts.\nGet-ChildItem .\\scripts | Invoke-DbatoolsRenameHelper New I\u0026rsquo;ll write about these more soon, but until then, enjoy this piping hot batch of new HA commands.","tags":[],"title":"More Updates","type":"post","url":"https://dbatools.io/more-updates/"},{"categories":["announcements"],"content":"Now that you\u0026rsquo;ve convinced your security team that PowerShell improves your security posture, it\u0026rsquo;s time to learn PowerShell if you haven\u0026rsquo;t already.\nMonth of Lunches Learn PowerShell in a Month of Lunches Hands down, the one book most people recommend for learning PowerShell is Learn Windows PowerShell in a Month of Lunches by Don Jones and Jeffrey Hicks. You can buy the 3rd edition from Amazon or directly from Manning.\nThis book even comes with its own YouTube series, featuring author Don Jones.\nThere\u0026rsquo;s also a website called More lunches but it hasn\u0026rsquo;t been updated since 2014 while the most recent version of Learn Windows PowerShell in a Month of Lunches was released in 2016.\nLearn dbatools in a Month of Lunches Want to learn about dbatools, specifically? Chrissy and Rob are currently writing Learn dbatools in a Month of Lunches and it is available via Manning\u0026rsquo;s Early Access Program!\nOne reviewer said the following about our book 💓:\nThis book makes PowerShell approachable for SQL professionals, and SQL administration approachable for proficient PowerShell users.\nOther books Once you\u0026rsquo;re comfortable with PowerShell, check out the PowerShell Cookbook by PowerShell Team member Lee Holmes and Windows PowerShell in Action by PowerShell Team member Bruce Payette and MVP Richard Siddaway.\nThe PowerShell Cookbook provides \u0026ldquo;recipes\u0026rdquo; of solutions, but I like that it\u0026rsquo;s also useful for learning best practices. Lee\u0026rsquo;s code is great to learn from! PowerShell in Action tells an amazing story and discusses the \u0026ldquo;Why\u0026rdquo; in-depth.\nYou can also check out The PowerShell Conference Book:\nThis book is designed to be like a conference in a book where each chapter is written by a different author who is a subject matter expert on the topic covered in their chapter. Each chapter is also independent of the others so you can read one chapter, ten chapters, or all of them. You can start with the first chapter, the last one, or somewhere in-between and not miss out on anything related to that particular topic. This book is written for the intermediate to advanced audience. Prior experience with PowerShell is highly recommended.\nAll (100%) of the royalties from this book are donated to the OnRamp scholarship program. More information about the OnRamp track at the PowerShell + DevOps Global Summit and their scholarship program can be found on the PowerShell.org website.\nCode Editor Just skip everything else and use Microsoft VS Code with the PowerShell extensions.\nThe ISE is no longer being developed and Microsoft officially says:\nThe PowerShell ISE has been the official editor for PowerShell throughout most of the history of Windows PowerShell. Now with the advent of the cross-platform PowerShell Core, we need a new official editor that\u0026rsquo;s available across all supported OS platforms and versions. Visual Studio Code is now that editor and the majority of our effort will be focused there.\nHowever, the PowerShell ISE will remain in Windows supporting Windows PowerShell with no plans to remove it. We will consider investing effort there in the future if there is a high demand for it, but for now we think that we will be able to provide the best possible experience to the PowerShell community through Visual Studio Code.\nNearly everyone I know uses VS Code and new cool extensions are added or enhanced every day in the Extension Gallery. There are so many cool extensions like gitlens which allows you to see who wrote a specific line of code:\nYou can also share your screen with colleagues using Visual Studio Live Share.\nYou may notice that I still use the ISE for demos, but that\u0026rsquo;s because it has a ▶ button and the ISE is very stable. Last time I tried to use Code for a demo it bombed out and the last thing I want to worry about during a presentation is my IDE crashing.\nSo for now, I\u0026rsquo;m using ISE for demos. I\u0026rsquo;ve heard the newer versions of Code are more stable, so now I\u0026rsquo;ve just gotta make the time to give it another shot.\nVideos Microsoft Learn Microsoft Learn (formerly Microsoft Virtual Academy) has PowerShell training videos including Getting Started with PowerShell 3.0: Don\u0026rsquo;t fear the shell and Advanced Tools \u0026amp; Scripting with PowerShell 3.0: Get Started.\nNote that this is for PowerShell 3 but it\u0026rsquo;s still relevant as dbatools is designed to work with PowerShell 3 and above.\nConference Playlists You can also watch videos from the PowerShell + DevOps Global Summit 2018 as well as PSConf EU 2018.\nPSKoans The goal of the PowerShell koans is to teach you PowerShell by presenting you with a set of questions. Each kōan (each question) is represented by a failing Pester test. Your goal is to make those tests pass by filling out the correct answer, or writing the correct code. The koans start very simple to get you familiar with the basic concepts and progress towards more difficult. Teaching you multiple beginner, intermediate and advanced aspects of PowerShell in the process.\nPSPowerHour And, of course, the regularly scheduled PSPowerHour which is \u0026ldquo;like a virtual PowerShell User Group, with a lightning-demo format, and room for non-PowerShell-specific content.\u0026rdquo; Eight community members give a demo each PowerHour.\nPSAtlas PSAtlas (formerly PWSHSchool) is all about gaining/sharing experiences. Join in to learn about PowerShell interactively, by using PowerShell!\nDocs Microsoft Docs is updated regularly, easy-to-read, and useful.\nLive Chat SQL Server Slack In #powershellhelp and #dbatools PowerShell Slack Every channel, but #sqlserver is bridged to the SQL Community #powershellhelp channel 👍 Reddit /r/PowerShell Live Chat Forums PowerShell.org Forums Reddit Spiceworks PowerShell Forum dbatools For dbatools specifically, we have a number of posts that can help navigate our module on our blog. Here\u0026rsquo;s a sampling:\ngetting started walk-thru: installing modules from the powershell gallery offline installs of dbatools real-world tde database migrations building a dedicated backup test server creating a history timeline simplifying snapshots managing a central management server stuck on older versions of sql server? check out our trace commands. three ways to track user logins minimal-downtime migrations using invoke-dbalogshipping a new command to find all of your instances simplifying extended events management with dbatools simplifying disaster recovery with dbatools Hope that helps those of you looking to get started. If you have any suggestions for this list, please let me know.\n- Chrissy\n","date":"2018-10-01","summary":"Now that you\u0026rsquo;ve convinced your security team that PowerShell improves your security posture, it\u0026rsquo;s time to learn PowerShell if you haven\u0026rsquo;t already.\nMonth of Lunches Learn PowerShell in a Month of Lunches Hands down, the one book most people recommend for learning PowerShell is Learn Windows PowerShell in a Month of Lunches by Don Jones and Jeffrey Hicks. You can buy the 3rd edition from Amazon or directly from Manning.","tags":[],"title":"Getting Started With PowerShell","type":"post","url":"https://dbatools.io/start/"},{"categories":["announcements"],"content":"Last year, during our PASS Summit and SQL Bits precons, we highlighted the reasons that PowerShell is even more secure than GUI administration.\nI even created a cute lil logo for it 😊\nRecently, our team had a discussion about security in #dbatools-dev and I realized I should probably highlight why PowerShell and dbatools are ideal for every organization, including security-minded organizations.\nIf you\u0026rsquo;re questioned about PowerShell or dbatools, here are some handy facts to help prove we can help make your administration more, not less, secure.\nPowerShell So how is using PowerShell more secure than GUI administration? This shocking video from a few years back can help explain. In it, Microsoft Security MVP Marcus Murray highlights just how easy it is to steal a token and impersonate an admin who is logged in via the GUI.\nJPG -\u0026gt; IIS -\u0026gt; cmd/.NET -\u0026gt; file system -\u0026gt; SQL Server -\u0026gt; token theft from GUI -\u0026gt; domain controller -\u0026gt; ☠️\nRemote PowerShell sessions do not create tokens, and consequently do not subject us to the threat of token theft and privilege escalation.\nRemote PowerShell, You Say? I remember when I heard the term PowerShell Remoting and saw some book chapters on it, I was like \u0026ldquo;aw man, another thing I gotta learn?\u0026rdquo; but it\u0026rsquo;s actually pretty straight forward.\nWindows PowerShell supports remote computing by using various technologies, including WMI, SQL WMI, RPC, SSH \u0026amp; WS-Management. Some commands require no remote configuration, including:\nRestart-Computer Test-Connection Get-HotFix Get-Process Get-Service Get-WinEvent Remoting Remoting refers to commands that use WS-Management. And it\u0026rsquo;s Microsoft\u0026rsquo;s recommended method of managing Windows. Why?\nBy default, it only allows connections from members of the Administrators group It uses single port: 5985 or 5986 Regardless of the transport protocol used (HTTP or HTTPS), PowerShell Remoting always encrypts all communication after initial authentication with a per-session AES-256 symmetric key Initial authentication is NTLM, Kerberos and Certificates so no credentials are ever exposed The PowerShell team\u0026rsquo;s mantra is Secure by Design and you can see it in action with this remoting implementation.\nSecure by Design The PowerShell team is very serious about security and their lead security architect, Lee Holmes, is well-respected in the InfoSec community. He and Jeffrey Snover even did a keynote at DerbyCon where they talked about PowerShell security in-depth.\nYet we\u0026rsquo;ll sometimes see things like this:\nSo why do anti-virus (AV) companies highlight the obvious fact that suspicious files uploaded to a suspicious-file-checker will probably be suspicious?\nLee Holmes addresses this very issue in the keynote:\nAV, they love to talk about ransomware attacks that use PowerShell, and the reason they do this is because they literally can\u0026rsquo;t keep up with the plain old stuff like exes. But they also do this because we as a community encourage it. We blog it, we tweet about it, we talk about it. And the next thing you hear is that there\u0026rsquo;s a PowerShell problem. They don\u0026rsquo;t seem to ask how to solve their C++ problem or their darn x64 problem.\nHe then went on to say\nWhen security researchers leverage PowerShell, it is always in a post-compromise context. They have compromised a machine through some other avenue (phishing, SQL injection, etc.), and ultimately have the choice of any number of tools on the system. They were able to accomplish their goals before PowerShell, and will be able to accomplish their goals without PowerShell.\nPretty convincing argument there, Lee! Thank you 🎉\nLooking for more? Check out PowerShell, Remoting, and Security by Microsoft MVP Don Jones.\nHackers Avoid PowerShell Christopher Glyer once mentioned that a red teamer at DerbyCon said they try to stay as far away from PowerShell as they can while discussing the SharPersist tool release. This should make Lee Holmes proud, as it demonstrates that PowerShell\u0026rsquo;s security features and logging capabilities make it less attractive to attackers.\ndbatools dbatools is an open source project so all of our coding and discussions happen out in the open. Whether it be on GitHub or Slack. We even created a channel called #dbatools-github just to watch GitHub spam, which includes all Pull Requests, Issues and commits to master \u0026amp; development.\nOpen source is generally considered more secure, but as the SQLShack article \u0026ldquo;SQL Server security considerations with open source tools\u0026rdquo; highlights, there are some concerns to address.\nCode Signed What data pro doesn\u0026rsquo;t love integrity? #DBCCCHECK4EVER\nThanks to a donation from dbatools contributors, Data Masterminds, dbatools is legit, code-signed, Enterprise software.\nCode signing requires a code signing certificate. Obtaining a globally recognized code signing certificate isn\u0026rsquo;t easy and took me about a month. A ton of paperwork \u0026amp; multiple proofs of identity were required, but I did it because I wanted dbatools to be as professional as possible.\nUpdate 2025: dbatools has migrated to Azure Trusted Signing, Microsoft\u0026rsquo;s modern code signing solution. This provides faster identity validation, immediate reputation with Windows SmartScreen and antivirus software, and helps reduce false positives that have occasionally affected dbatools. The transition began with version 2.5.5.\nWhat are code signing certs? Code signing certificates are used by software developers to digitally sign apps, drivers, and software programs as a way for end-users to verify that the code they receive has not been altered or compromised by a third party. They include your signature, your company\u0026rsquo;s name, and if desired, a timestamp.\nOur signatures do include a timestamp, and I personally sign every release that goes into the PowerShell Gallery and chocolately. Rob Sewell and I are the only two people with access to the certificate. And while Rob can also potentially sign dbatools, he uses the certificate solely to sign our sister project, dbachecks.\nLimited Permissions to Merge Going back to that article on SQLShack.com: they talk about diffusion of responsibility. Basically, the human impulse to say \u0026ldquo;another developer is looking, so I don\u0026rsquo;t have to.\u0026rdquo;\nOnly six of us can merge code into the dbatools master branch, and only six of us ever have. How did we determine this number? We executed the following command and threw the results into Excel:\ngit log --graph --abbrev-commit --decorate --first-parent master --merges --pretty=format:%h-%aN Five of the six people (Me, Shawn, Fred, Rob, Simone and Stuart) who can currently merge code intro dev/master are current/former MVPs or Microsoft employees. Our primary C# library developer, Friedrich Weinmann, is a former MVP and current Security PFE at Microsoft. Friedrich approves all C# code. The other dbatools code is mostly approved by me and fellow MVPs Shawn Melton and Stuart Moore.\nWe are all known by Microsoft and have visible community profiles. You\u0026rsquo;ll notice that I\u0026rsquo;m the primary merger, but if you watch our repo, you\u0026rsquo;ll also notice Shawn spends a good deal of time evaluating and testing code, even after I\u0026rsquo;ve merged it and after it\u0026rsquo;s been tested by appveyor \u0026amp; Pester.\nManageable Code Base dbatools also has a decently manageable code base. Here are some stats about our code, courtesy of Simone who used cloc to produce this pretty chart.\nNote that over 35% of our PowerShell code is comments or comment-based help 😊\nYou Can Compile dbatools.dll Yourself Our dbatools C# library code can be found in our GitHub repo, AND! You can even set it to compile each time you import dbatools using the $dbatools_alwaysbuildlibrary variable instead of relying on our included dll.\n$dbatools_alwaysbuildlibrary = $true Import-Module dbatools The module itself handles the compile so that\u0026rsquo;s all you have to do.\nNote that $dbatools_alwaysbuildlibrary is not supported by our PowerShell Gallery or chocolatey releases. If you need to compile the DLL, you\u0026rsquo;ll need to either clone our repo or download the zip directly from GitHub.\nExternal Libraries and Programs Our external libraries and programs come primarily from Microsoft. But like SQL Server Management Studio, we also use community DLLs.\nOur XESmartTarget support comes from Data Platform MVP \u0026amp; Formula 1 DBA Gianluca Sartori and nuget.\nWe also obtained permission to include bcp.exe and sqlcmd.exe, and that came directly from my own installation of SQL Server Management Studio.\nWhile it\u0026rsquo;d be foolish to make a guaranteed promise that our library is 💵, we do try our best and no malware has ever been detected in my repo root or in our PowerShell Gallery and chocolatey packages.\nWe\u0026rsquo;re on Chocolatey Thanks to Paul Broadwith, dbatools is now available in the chocolatey repository, and chocolatey takes package integrity very seriously.\nEvery version of every package submitted must pass through a rigorous moderation review process before they become publicly available (includes checks for quality, consistency, installation, and validations against VirusTotal).\nYou can find out more about this review process at chocolatey.org.\nWe\u0026rsquo;re in the Microsoft PowerShell Gallery You can also find us on the PowerShell Gallery which performs antivirus scanning on all uploaded modules.\nAccording to Microsoft, all modules have to meet a minimum quality standard, which includes being free of malware and viruses.\nWe\u0026rsquo;re Used by Microsoft Amazingly enough, Microsoft also uses dbatools (and 1999 me is totally tripping out). So while Microsoft does not officially endorse us, they appear to trust that we\u0026rsquo;re a project with integrity.\nDavid Peter Hansen, SQL Server PFE, has written about the tools he uses, and dbatools is all up in the mix 😎 Another PFE and former Data Platform MVP, Ryan J. Adams, has suggested using dbatools to sync logins for Availability Groups.\nAnd I just noticed he even made a video about dbatools!\nAlso, SQL PFE Patrick Keisler has written about SQL Server DBA morning health checks which doesn\u0026rsquo;t use dbatools directly, but does use some of the shared code base that I wrote.\nWord has it, we\u0026rsquo;re also used in the banking industry, the airline industry, the super fancy speedcar industry, the insurance industry, the medical industry and more.\nLow-Hanging Fruit There\u0026rsquo;s also some low-hanging fruit that we address, like using ScriptAnalyzer to ensure we follow security best practices. We also update our website\u0026rsquo;s backend regularly and each of our sites use HTTPS.\nResources Microsoft itself has written extensively about PowerShell security.\nWho\u0026rsquo;s Afraid of PowerShell Security? Who\u0026rsquo;s afraid of PowerShell security? by former Microsoft PFE Ashley McGlone was an instant classic because it was effective and succinct. This article made so many great points, including:\nThe improvements in WMF 5.0 (or WMF 4.0 with KB3000850) make PowerShell the worst tool of choice for a hacker when you enable script block logging and system-wide transcription. Hackers will leave fingerprints everywhere, unlike popular CMD utilities. For this reason, PowerShell should be the only tool you allow for remote administration. These features allow you to answer the classic questions who, what, when, where, and how for activities on your servers.\nPowerShell Security at Enterprise Customers PowerShell Security at Enterprise Customers by former Microsoft PFE David das Neves is another highly referenced article. I consider this the definitive, in-depth article about PowerShell security.\nThis post is practically a book, and even making an outline would be too long. If you need to know anything about PowerShell security, this post is a great reference. Bravo, David!\nA Comparison of Shell and Scripting Language Security A Comparison of Shell and Scripting Language Security by PowerShell\u0026rsquo;s Security Architect Lee Holmes is another ace.\nMy favorite part was this easy-to-understand visual bit that shows why PowerShell is mega-secure 💪\nI hope this addresses everything your security department needs. If not, post a comment or email me at clemaire@gmail.com and we\u0026rsquo;ll see what we can do.\n- Chrissy\n","date":"2018-09-26","summary":"Last year, during our PASS Summit and SQL Bits precons, we highlighted the reasons that PowerShell is even more secure than GUI administration.\nI even created a cute lil logo for it 😊\nRecently, our team had a discussion about security in #dbatools-dev and I realized I should probably highlight why PowerShell and dbatools are ideal for every organization, including security-minded organizations.\nIf you\u0026rsquo;re questioned about PowerShell or dbatools, here are some handy facts to help prove we can help make your administration more, not less, secure.","tags":["security"],"title":"Talking to Your Security Team About PowerShell and dbatools","type":"post","url":"https://dbatools.io/secure/"},{"categories":[],"content":"A while back, I added some new features to our migration commands but I forgot to blog about them. Then, I used one of the new features for a fast and successful migration, got so pumped and had to share.\nMultiple Destinations Now, you can migrate from one server to many. This applies to both Start-DbaMigration and all of the Copy-Dba* commands, including Copy-DbaDatabase and Copy-DbaLogin.\nAs you may be able to see in the title bar of this Out-GridView, I am migrating from workstation, which is a SQL Server 2008 instance, to localhost\\sql2016 and localhost\\sql2017. My entire command is as follows:\nStart-DbaMigration -Source workstation -Destination localhost\\sql2016, localhost\\sql2017 -BackupRestore -UseLastBackup | Out-GridView If you examine the results, you\u0026rsquo;ll see it migrated sp_configure, then moved on to credentials - first for localhost\\sql2016 then localhost\\sql2017. And continued on from there, migrating central management server, database mail, server triggers and databases.\nIt migrates a bunch of other things too, of course. Haven\u0026rsquo;t seen or performed a migration before? Check out this 50-second video of a migration.\n-UseLastBackup This one is awesome. Now, you can use your existing backups to perform a migration! Such a huge time saver. Imagine the following scenario:\nDear DBA, Your mission, should you choose to accept it, is to migrate the SQL Server instance for a small SharePoint farm. You\u0026rsquo;ll work with the SharePoint team and will have four hours to accomplish your portion of the migration. All combined, the databases are about 250 GB in size. Good luck, colleague!\nA four hour outage window seems reasonable to me! Here is one way I could accomplish this task:\nUpdate the SQL Client Alias for the SharePoint Servers Shut down the SharePoint servers Execute my scheduled log backup job one final time Perform the migration using -UseLastBackup switch Boot up the SharePoint Servers Check that the sites work Party 🎉 I\u0026rsquo;ve actually done this a number of times, and even made a video about it a couple years ago.\nThe outdated output is drastically different from today\u0026rsquo;s output but the overall approach still applies. Note that back then, -UseLastBackup did not yet exist so in the video, it performs a backup and restore, not just a restore. I should make a new video.. one day!\nSo basically, this is the code I\u0026rsquo;d execute to migrate from spcluster to newcluster:\n# first, modify the alias then shut down the SharePoint servers $spservers = \u0026#34;spweb1\u0026#34;, \u0026#34;spweb2\u0026#34;, \u0026#34;spapp1\u0026#34;, \u0026#34;spapp2\u0026#34; Remove-DbaClientAlias -ComputerName $spservers -Alias spsql1 New-DbaClientAlias -ComputerName $spservers -ServerName newcluster -Alias spsql1 Stop-Computer -ComputerName $spservers # Once each of the servers were shut down, I\u0026#39;d begin my SQL Server migration. Start-DbaMigration -Source spcluster -Destination newcluster -BackupRestore -UseLastBackup | Out-GridView # Mission accomplished 🙅‍♀️🙅‍♂️ This would migrate all of my SQL Logins, with their passwords \u0026amp; SIDs, etc, jobs, linked servers, all that, then it\u0026rsquo;d build my last full, diff and log backups chain, and perform the restore to newcluster! Down. To. My. Last. Log. So awesome 😁👍\nThanks so much for that functionality Stuart, Oleg and Simone!\nWhat About VLDBs? For very large database migrations, we currently offer log shipping. Sander Stad made some cool enhancements to Invoke-DbaDbLogShipping and Invoke-DbaDbLogShipRecovery recently, too.\n# Also supports multiple destinations! # Oh, and has a ton of params, so use a PowerShell splat $params = @{ Source = \u0026#39;sql2008\u0026#39; Destination = \u0026#39;sql2016\u0026#39;, \u0026#39;sql2017\u0026#39; Database = \u0026#39;shipped\u0026#39; BackupNetworkPath= \u0026#39;\\\\backups\\sql\u0026#39; PrimaryMonitorServer = \u0026#39;sql2012\u0026#39; SecondaryMonitorServer = \u0026#39;sql2012\u0026#39; BackupScheduleFrequencyType = \u0026#39;Daily\u0026#39; BackupScheduleFrequencyInterval = 1 CompressBackup = $true CopyScheduleFrequencyType = \u0026#39;Daily\u0026#39; CopyScheduleFrequencyInterval = 1 GenerateFullBackup = $true Force = $true } # pass the splat Invoke-DbaDbLogShipping @params # And now, failover to secondary Invoke-DbaDbLogShipRecovery -SqlInstance localhost\\sql2017 -Database shipped Other migration options such as Classic Mirroring and Availability Groups are still on the agenda.\nHappy migrating!\n- Chrissy\n","date":"2018-09-24","summary":"A while back, I added some new features to our migration commands but I forgot to blog about them. Then, I used one of the new features for a fast and successful migration, got so pumped and had to share.\nMultiple Destinations Now, you can migrate from one server to many. This applies to both Start-DbaMigration and all of the Copy-Dba* commands, including Copy-DbaDatabase and Copy-DbaLogin.\nAs you may be able to see in the title bar of this Out-GridView, I am migrating from workstation, which is a SQL Server 2008 instance, to localhost\\sql2016 and localhost\\sql2017.","tags":["migration","party"],"title":"SQL Server Migration Enhancements","type":"post","url":"https://dbatools.io/migration-enhancements/"},{"categories":["announcements"],"content":"Over the weekend, I presented a session in Glasgow called doomsday prepping with dbatools at SQLGLA, a community event hosted by Craig Porteous, sql_bob and Louise Paterson.\nIt was a lot of fun, even though the audience put no effort into winning the MRE give away\nNow I\u0026rsquo;ve got some ready-to-eat beef tacos when the zombie apocalypse hits!\nDown to Business When we talk about Disaster Recovery or DR, it\u0026rsquo;s often coupled with the term High Availability or HA. Here are some definitions from my graduate course on HADR.\nHigh Availability Deals with minor outages, and failover solutions are automated The goal is to restore full system functionality in a short time Disaster Recovery Deals with major outages such as natural and man-made disasters Focuses on manual processes and procedures to restore systems back to their original state Characterized by a phased approach to restoring the primary site In the context of SQL Server, HA would be Availability Groups (AG), Failover Clustering (FCI), Log Shipping and more. I won\u0026rsquo;t be addressing High Availability in this post, however.\nDisaster Recovery Why There are a number of articles discussing the importance of disaster recovery. Here are the three I list in my presentation:\nCertain federal regulations require development of DR plans Business partners and customers often demand proof of disaster recovery plans Supporting ongoing availability of IT services for business continuity While I can\u0026rsquo;t find the original reference to cite, I once read in my HADR class that Cleveland State University did a study about the importance of DR, and they found that:\nA company that experiences a computer outage lasting more than 10 days will never fully recover financially. Within five years, 50% of those companies will be out of business.\nThat\u0026rsquo;s insane! And a very solid reason to have a well-tested DR plan.\nWho There was once a story on Reddit about someone who accidentally dropped the production database on their first day on the job and was fired by the CTO.\nCompanies like Amazon correctly recognize that such disasters are a team effort and disaster recovery is the responsibility of the entire organization.\nHere\u0026rsquo;s how you can do your part.\nSQL Server Disaster Recovery Tracy Boggiano has an awesome, in-depth presentation about DR titled Disaster Recovery: Where to Begin that I recommend checking out. It was the primary source for my own research.\nDatabases When it comes to SQL Server and Disaster Recovery, Microsoft offers a number of options.\nBackup/Restore Replication Log Shipping Mirroring Multi-site Failover Clustering Availability Groups Tracy\u0026rsquo;s slide deck didn\u0026rsquo;t mention it, but Bacpacs and Dacpacs are a potential option as well.\nScenarios the faster you want to get data back, the more you will pay\nNeed a quick DR solution? Use Ola Hallengren\u0026rsquo;s free and open source SQL Server Maintenance Solution to schedule your backups, then use robocopy to mirror those backups to a secondary data center or the cloud.\nYou can reliability recover your data this way but it won\u0026rsquo;t be immediate.\nIf you need to recover your data far faster, you can use Distributed Availability Groups. This method is faster but far more costly, because you\u0026rsquo;d potentially need:\nAnother data center More SQL Server licenses More Windows licenses More resources \u0026amp; storage More support staff Everything Else Microsoft rightly places a lot of emphasis on database DR, but what about everything else? Things like:\nLogins SQL Agent Extended Events Linked Servers Credentials Audit sp_configure Central Management Server Database Mail System Triggers Endpoints Custom errors Replication Availability Groups How do you DR these? You can backup the required databases for some things - like msdb restores everything in Agent. Or, if it\u0026rsquo;s available, you can right-click hundreds of objects, one-by-one, and export them.\nIntroducing Simplified Disaster Recovery dbatools can help ease your DR, all in one convenient command. No, not good ol\u0026rsquo; Export-DbaScript which is essentially the command line equivalent of the screenshot above.\nNow, dbatools offers a whole new command, written specifically for the DR presentation: Export-DbaInstance\nExport-DbaInstance is a wrapper for over 50 export commands. This is similar to Start-DbaMigration which is a wrapper for a bunch of copy commands.\nThe databases export is an export of all the restore commands from the last log backup. So full, diff and logs.\nRESTORE DATABASE [anotherdb] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\anotherdb\\FULL\\WORKSTATION$SQL2016_anotherdb_FULL_20180914_002533.bak\u0026#39; WITH FILE = 1, MOVE N\u0026#39;anotherdb\u0026#39; TO N\u0026#39;M:\\DATA\\anotherdb.mdf\u0026#39;, MOVE N\u0026#39;anotherdb_log\u0026#39; TO N\u0026#39;M:\\DATA\\anotherdb_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, REPLACE, STATS = 10 RESTORE DATABASE [anotherdb] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\anotherdb\\DIFF\\WORKSTATION$SQL2016_anotherdb_DIFF_20180914_002539.bak\u0026#39; WITH FILE = 1, MOVE N\u0026#39;anotherdb\u0026#39; TO N\u0026#39;M:\\DATA\\anotherdb.mdf\u0026#39;, MOVE N\u0026#39;anotherdb_log\u0026#39; TO N\u0026#39;M:\\DATA\\anotherdb_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, REPLACE, STATS = 10 RESTORE LOG [anotherdb] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\anotherdb\\LOG\\WORKSTATION$SQL2016_anotherdb_LOG_20180914_002545.trn\u0026#39; WITH FILE = 1, MOVE N\u0026#39;anotherdb\u0026#39; TO N\u0026#39;M:\\DATA\\anotherdb.mdf\u0026#39;, MOVE N\u0026#39;anotherdb_log\u0026#39; TO N\u0026#39;M:\\DATA\\anotherdb_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, STATS = 10 RESTORE LOG [anotherdb] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\anotherdb\\LOG\\WORKSTATION$SQL2016_anotherdb_LOG_20180914_002551.trn\u0026#39; WITH FILE = 1, MOVE N\u0026#39;anotherdb\u0026#39; TO N\u0026#39;M:\\DATA\\anotherdb.mdf\u0026#39;, MOVE N\u0026#39;anotherdb_log\u0026#39; TO N\u0026#39;M:\\DATA\\anotherdb_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, STATS = 10 RESTORE LOG [anotherdb] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\anotherdb\\LOG\\WORKSTATION$SQL2016_anotherdb_LOG_20180914_002557.trn\u0026#39; WITH FILE = 1, MOVE N\u0026#39;anotherdb\u0026#39; TO N\u0026#39;M:\\DATA\\anotherdb.mdf\u0026#39;, MOVE N\u0026#39;anotherdb_log\u0026#39; TO N\u0026#39;M:\\DATA\\anotherdb_log.ldf\u0026#39;, NOUNLOAD, STATS = 10 RESTORE DATABASE [db1] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\db1\\FULL\\WORKSTATION$SQL2016_db1_FULL_20180914_002533.bak\u0026#39; WITH FILE = 1, MOVE N\u0026#39;db1\u0026#39; TO N\u0026#39;M:\\DATA\\db1.mdf\u0026#39;, MOVE N\u0026#39;db1_log\u0026#39; TO N\u0026#39;M:\\DATA\\db1_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, REPLACE, STATS = 10 RESTORE DATABASE [db1] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\db1\\DIFF\\WORKSTATION$SQL2016_db1_DIFF_20180914_002540.bak\u0026#39; WITH FILE = 1, MOVE N\u0026#39;db1\u0026#39; TO N\u0026#39;M:\\DATA\\db1.mdf\u0026#39;, MOVE N\u0026#39;db1_log\u0026#39; TO N\u0026#39;M:\\DATA\\db1_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, REPLACE, STATS = 10 RESTORE LOG [db1] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\db1\\LOG\\WORKSTATION$SQL2016_db1_LOG_20180914_002545.trn\u0026#39; WITH FILE = 1, MOVE N\u0026#39;db1\u0026#39; TO N\u0026#39;M:\\DATA\\db1.mdf\u0026#39;, MOVE N\u0026#39;db1_log\u0026#39; TO N\u0026#39;M:\\DATA\\db1_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, STATS = 10 RESTORE LOG [db1] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\db1\\LOG\\WORKSTATION$SQL2016_db1_LOG_20180914_002552.trn\u0026#39; WITH FILE = 1, MOVE N\u0026#39;db1\u0026#39; TO N\u0026#39;M:\\DATA\\db1.mdf\u0026#39;, MOVE N\u0026#39;db1_log\u0026#39; TO N\u0026#39;M:\\DATA\\db1_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, STATS = 10 RESTORE LOG [db1] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\db1\\LOG\\WORKSTATION$SQL2016_db1_LOG_20180914_002557.trn\u0026#39; WITH FILE = 1, MOVE N\u0026#39;db1\u0026#39; TO N\u0026#39;M:\\DATA\\db1.mdf\u0026#39;, MOVE N\u0026#39;db1_log\u0026#39; TO N\u0026#39;M:\\DATA\\db1_log.ldf\u0026#39;, NOUNLOAD, STATS = 10 RESTORE DATABASE [dbwithsprocs] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\dbwithsprocs\\FULL\\WORKSTATION$SQL2016_dbwithsprocs_FULL_20180914_002534.bak\u0026#39; WITH FILE = 1, MOVE N\u0026#39;dbwithsprocs\u0026#39; TO N\u0026#39;M:\\DATA\\dbwithsprocs.mdf\u0026#39;, MOVE N\u0026#39;dbwithsprocs_log\u0026#39; TO N\u0026#39;M:\\DATA\\dbwithsprocs_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, REPLACE, STATS = 10 RESTORE DATABASE [dbwithsprocs] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\dbwithsprocs\\DIFF\\WORKSTATION$SQL2016_dbwithsprocs_DIFF_20180914_002540.bak\u0026#39; WITH FILE = 1, MOVE N\u0026#39;dbwithsprocs\u0026#39; TO N\u0026#39;M:\\DATA\\dbwithsprocs.mdf\u0026#39;, MOVE N\u0026#39;dbwithsprocs_log\u0026#39; TO N\u0026#39;M:\\DATA\\dbwithsprocs_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, REPLACE, STATS = 10 RESTORE LOG [dbwithsprocs] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\dbwithsprocs\\LOG\\WORKSTATION$SQL2016_dbwithsprocs_LOG_20180914_002545.trn\u0026#39; WITH FILE = 1, MOVE N\u0026#39;dbwithsprocs\u0026#39; TO N\u0026#39;M:\\DATA\\dbwithsprocs.mdf\u0026#39;, MOVE N\u0026#39;dbwithsprocs_log\u0026#39; TO N\u0026#39;M:\\DATA\\dbwithsprocs_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, STATS = 10 RESTORE LOG [dbwithsprocs] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\dbwithsprocs\\LOG\\WORKSTATION$SQL2016_dbwithsprocs_LOG_20180914_002552.trn\u0026#39; WITH FILE = 1, MOVE N\u0026#39;dbwithsprocs\u0026#39; TO N\u0026#39;M:\\DATA\\dbwithsprocs.mdf\u0026#39;, MOVE N\u0026#39;dbwithsprocs_log\u0026#39; TO N\u0026#39;M:\\DATA\\dbwithsprocs_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, STATS = 10 RESTORE LOG [dbwithsprocs] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\dbwithsprocs\\LOG\\WORKSTATION$SQL2016_dbwithsprocs_LOG_20180914_002557.trn\u0026#39; WITH FILE = 1, MOVE N\u0026#39;dbwithsprocs\u0026#39; TO N\u0026#39;M:\\DATA\\dbwithsprocs.mdf\u0026#39;, MOVE N\u0026#39;dbwithsprocs_log\u0026#39; TO N\u0026#39;M:\\DATA\\dbwithsprocs_log.ldf\u0026#39;, NOUNLOAD, STATS = 10 RESTORE DATABASE [distribution] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\distribution\\FULL\\WORKSTATION$SQL2016_distribution_FULL_20180914_002534.bak\u0026#39; WITH FILE = 1, MOVE N\u0026#39;distribution\u0026#39; TO N\u0026#39;M:\\DATA\\distribution.MDF\u0026#39;, MOVE N\u0026#39;distribution_log\u0026#39; TO N\u0026#39;M:\\DATA\\distribution.LDF\u0026#39;, NORECOVERY, NOUNLOAD, REPLACE, STATS = 10 RESTORE DATABASE [distribution] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\distribution\\DIFF\\WORKSTATION$SQL2016_distribution_DIFF_20180914_002540.bak\u0026#39; WITH FILE = 1, MOVE N\u0026#39;distribution\u0026#39; TO N\u0026#39;M:\\DATA\\distribution.MDF\u0026#39;, MOVE N\u0026#39;distribution_log\u0026#39; TO N\u0026#39;M:\\DATA\\distribution.LDF\u0026#39;, NOUNLOAD, REPLACE, STATS = 10 RESTORE DATABASE [master] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\master\\FULL\\WORKSTATION$SQL2016_master_FULL_20180914_002533.bak\u0026#39; WITH FILE = 1, MOVE N\u0026#39;master\u0026#39; TO N\u0026#39;M:\\DATA\\master.mdf\u0026#39;, MOVE N\u0026#39;mastlog\u0026#39; TO N\u0026#39;M:\\DATA\\mastlog.ldf\u0026#39;, NOUNLOAD, REPLACE, STATS = 10 RESTORE DATABASE [model] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\model\\FULL\\WORKSTATION$SQL2016_model_FULL_20180914_002533.bak\u0026#39; WITH FILE = 1, MOVE N\u0026#39;modeldev\u0026#39; TO N\u0026#39;M:\\DATA\\model.mdf\u0026#39;, MOVE N\u0026#39;modellog\u0026#39; TO N\u0026#39;M:\\DATA\\modellog.ldf\u0026#39;, NOUNLOAD, REPLACE, STATS = 10 RESTORE DATABASE [msdb] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\msdb\\FULL\\WORKSTATION$SQL2016_msdb_FULL_20180914_002534.bak\u0026#39; WITH FILE = 1, MOVE N\u0026#39;MSDBData\u0026#39; TO N\u0026#39;M:\\DATA\\MSDBData.mdf\u0026#39;, MOVE N\u0026#39;MSDBLog\u0026#39; TO N\u0026#39;M:\\DATA\\MSDBLog.ldf\u0026#39;, NOUNLOAD, REPLACE, STATS = 10 RESTORE DATABASE [shipped] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\shipped\\FULL\\WORKSTATION$SQL2016_shipped_FULL_20180914_002534.bak\u0026#39; WITH FILE = 1, MOVE N\u0026#39;shipped\u0026#39; TO N\u0026#39;M:\\DATA\\shipped.mdf\u0026#39;, MOVE N\u0026#39;shipped_log\u0026#39; TO N\u0026#39;M:\\DATA\\shipped_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, REPLACE, STATS = 10 RESTORE DATABASE [shipped] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\shipped\\DIFF\\WORKSTATION$SQL2016_shipped_DIFF_20180914_002540.bak\u0026#39; WITH FILE = 1, MOVE N\u0026#39;shipped\u0026#39; TO N\u0026#39;M:\\DATA\\shipped.mdf\u0026#39;, MOVE N\u0026#39;shipped_log\u0026#39; TO N\u0026#39;M:\\DATA\\shipped_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, REPLACE, STATS = 10 RESTORE LOG [shipped] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\shipped\\LOG\\WORKSTATION$SQL2016_shipped_LOG_20180914_002545.trn\u0026#39; WITH FILE = 1, MOVE N\u0026#39;shipped\u0026#39; TO N\u0026#39;M:\\DATA\\shipped.mdf\u0026#39;, MOVE N\u0026#39;shipped_log\u0026#39; TO N\u0026#39;M:\\DATA\\shipped_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, STATS = 10 RESTORE LOG [shipped] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\shipped\\LOG\\WORKSTATION$SQL2016_shipped_LOG_20180914_002552.trn\u0026#39; WITH FILE = 1, MOVE N\u0026#39;shipped\u0026#39; TO N\u0026#39;M:\\DATA\\shipped.mdf\u0026#39;, MOVE N\u0026#39;shipped_log\u0026#39; TO N\u0026#39;M:\\DATA\\shipped_log.ldf\u0026#39;, NORECOVERY, NOUNLOAD, STATS = 10 RESTORE LOG [shipped] FROM DISK = N\u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\\shipped\\LOG\\WORKSTATION$SQL2016_shipped_LOG_20180914_002557.trn\u0026#39; WITH FILE = 1, MOVE N\u0026#39;shipped\u0026#39; TO N\u0026#39;M:\\DATA\\shipped.mdf\u0026#39;, MOVE N\u0026#39;shipped_log\u0026#39; TO N\u0026#39;M:\\DATA\\shipped_log.ldf\u0026#39;, NOUNLOAD, STATS = 10 Looking good!\nAnd Now for a Demo Here is a slightly modified version of the demo I gave in Glasgow, commented for your enjoyment.\n# Check out our export/backup commands Get-Command -Name Export-DbaScript -Module dbatools -Type Function Get-Command -Name *export* -Module dbatools -Type Function Get-Command -Name *backup* -Module dbatools -Type Function Get-Command -Name *dbadac* -Module dbatools -Type Function # Let\u0026#39;s examine the commands a little more. First up! Export-DbaScript # Start with something simple Get-DbaAgentJob -SqlInstance workstation\\sql2016 | Select -First 1 | Export-DbaScript # Now let\u0026#39;s look inside Get-DbaAgentJob -SqlInstance workstation\\sql2016 | Select -First 1 | Export-DbaScript | Invoke-Item # Raw output and add a batch separator Get-DbaAgentJob -SqlInstance workstation\\sql2016 | Export-DbaScript -Passthru -BatchSeparator GO # Get crazy #Set Scripting Options $options = New-DbaScriptingOption $options.ScriptSchema = $true $options.IncludeDatabaseContext = $true $options.IncludeHeaders = $false $Options.NoCommandTerminator = $false $Options.ScriptBatchTerminator = $true $Options.AnsiFile = $true # The next command will use SQL authentication # first, pipe the password to clipboard as an example \u0026#39;Zjady7$$$fxzy(\u0026amp;*($1\u0026#39; | clip Get-DbaDbMailProfile -SqlInstance workstation\\sql2016 -SqlCredential sqladmin | Export-DbaScript -Path C:\\temp\\export.sql -ScriptingOptionsObject $options -NoPrefix | Invoke-Item # Now for a few special commands that SMO didn\u0026#39;t quite do justice to Export-DbaSpConfigure -SqlInstance workstation\\sql2016 -Path C:\\temp\\sp_configure.sql # Warning, this will write clear-text passwords to disk Export-DbaLinkedServer -SqlInstance workstation\\sql2016 -Path C:\\temp\\linkedserver.sql | Invoke-Item # This will write hashed passwords to disk Export-DbaLogin -SqlInstance workstation\\sql2016 -Path C:\\temp\\logins.sql | Invoke-Item # Other specials, relative to the server itself Backup-DbaDbMasterKey -SqlInstance workstation\\sql2016 Backup-DbaDbMasterKey -SqlInstance workstation\\sql2016 -Path \\\\localhost\\backups # What if you just want to script out your restore? Invoke Backup-DbaDatabase or your Maintenance Solution job # Let\u0026#39;s create a FULL, DIFF, LOG, LOG, LOG Start-DbaAgentJob -SqlInstance localhost\\sql2016 -Job \u0026#39;DatabaseBackup - SYSTEM_DATABASES - FULL\u0026#39;,\u0026#39;DatabaseBackup - USER_DATABASES - FULL\u0026#39; Get-DbaRunningJob -SqlInstance localhost\\sql2016 Start-DbaAgentJob -SqlInstance localhost\\sql2016 -Job \u0026#39;DatabaseBackup - USER_DATABASES - DIFF\u0026#39; Get-DbaRunningJob -SqlInstance localhost\\sql2016 Start-DbaAgentJob -SqlInstance localhost\\sql2016 -Job \u0026#39;DatabaseBackup - USER_DATABASES - LOG\u0026#39; Get-DbaRunningJob -SqlInstance localhost\\sql2016 Start-DbaAgentJob -SqlInstance localhost\\sql2016 -Job \u0026#39;DatabaseBackup - USER_DATABASES - LOG\u0026#39; Get-DbaRunningJob -SqlInstance localhost\\sql2016 Start-DbaAgentJob -SqlInstance localhost\\sql2016 -Job \u0026#39;DatabaseBackup - USER_DATABASES - LOG\u0026#39; Get-DbaRunningJob -SqlInstance localhost\\sql2016 # Now export the restores to disk Get-ChildItem -Directory \u0026#39;\\\\localhost\\backups\\WORKSTATION$SQL2016\u0026#39; | Restore-DbaDatabase -SqlInstance localhost\\sql2017 -OutputScriptOnly -WithReplace | Out-File -Filepath c:\\temp\\restore.sql Invoke-Item c:\\temp\\restore.sql # Speaking of Ola, use his backup script? We can restore an *ENTIRE INSTANCE* with just one line Get-ChildItem -Directory \\\\workstation\\backups\\sql2012 | Restore-DbaDatabase -SqlInstance localhost\\sql2017 -WithReplace # Log shipping, what\u0026#39;s up - dbatools.io/logshipping # Also supports multiple destinations! $params = @{ Source = \u0026#39;localhost\\sql2016\u0026#39; Destination = \u0026#39;localhost\\sql2017\u0026#39; Database = \u0026#39;shipped\u0026#39; BackupNetworkPath= \u0026#39;\\\\localhost\\backups\u0026#39; PrimaryMonitorServer = \u0026#39;localhost\\sql2017\u0026#39; SecondaryMonitorServer = \u0026#39;localhost\\sql2017\u0026#39; BackupScheduleFrequencyType = \u0026#39;Daily\u0026#39; BackupScheduleFrequencyInterval = 1 CompressBackup = $true CopyScheduleFrequencyType = \u0026#39;Daily\u0026#39; CopyScheduleFrequencyInterval = 1 GenerateFullBackup = $true Force = $true } Invoke-DbaDbLogShipping @params # And now, failover to secondary Invoke-DbaDbLogShipRecovery -SqlInstance localhost\\sql2017 -Database shipped # Introducing Export-DbaInstance # Written for #SQLGLA! # Get Pester and drop code at sqlps.io/doomsday # Check that everything exists prior to export Invoke-Pester C:\\github\\community-presentations\\chrissy-lemaire\\doomsday.Tests.ps1 # Do it all at once Export-DbaInstance -SqlInstance workstation\\sql2016 -Path \\\\workstation\\backups\\DR Invoke-Item \\\\workstation\\backups\\DR # It ain\u0026#39;t a DR plan without testing Test-DbaLastBackup -SqlInstance workstation\\sql2016 # Now let\u0026#39;s test the output scripts. # This will also kill SSMS so that I\u0026#39;m forced to refresh, and open it back up . C:\\github\\community-presentations\\chrissy-lemaire\\doomsday-dropeverything.ps1 # Check that everything has been dropped Invoke-Pester C:\\github\\community-presentations\\chrissy-lemaire\\doomsday.Tests.ps1 # Prep Stop-DbaService -ComputerName localhost -InstanceName sql2016 -Type Agent Get-DbaProcess -SqlInstance localhost\\sql2016 -Database msdb | Stop-DbaProcess # Perform restores and restart SQL Agent $files = Get-ChildItem -Path \\\\workstation\\backups\\DR -Exclude *agent* | Sort-Object LastWriteTime $files | ForEach-Object { Write-Output \u0026#34;Running $psitem\u0026#34; Invoke-DbaQuery -File $PSItem -SqlInstance workstation\\sql2016 -ErrorAction Ignore -Verbose } Start-DbaService -ComputerName localhost -InstanceName sql2016 -Type Agent # Check if everything is back Invoke-Pester C:\\github\\community-presentations\\chrissy-lemaire\\doomsday.Tests.ps1 Excellent! How gorgeous is that Pester test? Well, the output is hard to read, sorry. But the results are magic\nAnd a YouTube Link! I also had a blast presenting this session virtually for the Portland PowerShell User Group if you\u0026rsquo;d like to see a recorded demo.\nSo check out Export-DbaInstance, let me know what you think\nIf you\u0026rsquo;ve got some suggestions, let me know or create a pull request on GitHub with your enhancements.\nThanks for reading,\nChrissy ","date":"2018-09-20","summary":"Over the weekend, I presented a session in Glasgow called doomsday prepping with dbatools at SQLGLA, a community event hosted by Craig Porteous, sql_bob and Louise Paterson.\nIt was a lot of fun, even though the audience put no effort into winning the MRE give away\nNow I\u0026rsquo;ve got some ready-to-eat beef tacos when the zombie apocalypse hits!\nDown to Business When we talk about Disaster Recovery or DR, it\u0026rsquo;s often coupled with the term High Availability or HA.","tags":[],"title":"Simplifying Disaster Recovery With dbatools","type":"post","url":"https://dbatools.io/dr/"},{"categories":["announcements"],"content":"We\u0026rsquo;ve been busy the past few days and have huge updates to share.\nNew Docs Site First, our new beta docs site is now up at dbatools.io/commands! Please check it out and let us know what you think.\nThis new docs site is auto-generated by our command help! Auto-generated docs were required because we\u0026rsquo;re adding so many new commands and updating so often, keeping our website up-to-date was just too time-consuming. Shoutout to Simone Bizzotto for his mad regex, JavaScript and PowerShell skills that made this possible 🏆!\nYou\u0026rsquo;ll notice that videos and screenshots are now absent. We\u0026rsquo;re considering ways to reincorporate media. If you have any requests, suggestions or problems with the site, please fill out an issue on the docs repo on GitHub.\nSpeaking of GitHub, our docs are hosted on GitHub Pages. If you\u0026rsquo;re wondering how we colocated two subdomains within the same GitHub Organization, we followed this helpful StackOverflow post.\nUpdated Command Index Cláudio Silva also updated our commands page this week 🎉 He added all 433 dbatools commands and also added a category index. Check it out!\nUpdated Documentation Special thanks to Aaron Nelson and Andy Levy for updating our docs by fixing typos, providing clarification and adding examples. Your contributions help not only readers of Get-Help, but our website as well 👍\nIf anyone else is interested in helping with docs or anything else, we\u0026rsquo;re looking for help! Join us on Slack in #dbatools for more info.\ndbatools Update Over the weekend, we released a quickfix in 0.9.412 that was totally busted, our apologies. Please update to the latest version, v0.9.418.\n- Chrissy\n","date":"2018-09-11","summary":"We\u0026rsquo;ve been busy the past few days and have huge updates to share.\nNew Docs Site First, our new beta docs site is now up at dbatools.io/commands! Please check it out and let us know what you think.\nThis new docs site is auto-generated by our command help! Auto-generated docs were required because we\u0026rsquo;re adding so many new commands and updating so often, keeping our website up-to-date was just too time-consuming.","tags":[],"title":"New Docs Site and Updated Command Index","type":"post","url":"https://dbatools.io/new-docs-site/"},{"categories":["announcements"],"content":"Marching onward to dbatools 1.0, a ton of commands have been renamed to align with our now mature naming scheme. These changes were made in today\u0026rsquo;s release, version 0.9.410 aka regularlegs, now available on GitHub and the PowerShell Gallery.\nHere\u0026rsquo;s the general idea:\nDbaDatabase has mostly been renamed to DbaDb with a couple exceptions DbaSql has been changed to just Dba, no exceptions. Considering Microsoft reserved the Sql prefix and we can\u0026rsquo;t use it, think of Dba as \u0026ldquo;Sql\u0026rdquo;. DbaConfig has been renamed to dbatoolsConfig TempDbConfiguration has been renamed to TempdbConfig All Configuration commands are Config except SpConfigure DbaDacpac has been renamed to DbaDacPackage. Dac is the prefix for our data-tier application commands. DbaDbQueryStoreOptions has been renamed to DbaDbQueryStoreOption If you use the old name, it\u0026rsquo;ll still work but will show a warning that the command name has been changed and its alias will be removed in 1.0. Oh, also, Get-DbaTrigger has been removed and Get-DbaInstanceTrigger and Get-DbaDbTrigger have been added in its place. Unfortunately, there was no appropriate alias, so it was removed without an alias.\nRenaming If you\u0026rsquo;d like help renaming dbatools scripts within your command, use the newly created function Invoke-dbatoolsRenameHelper, available in regularlegs. The screenshot below shows is what it looked like when I ran the this:\nGet-ChildItem -Recurse C:\\temp\\community-presentations\\*.ps1 | Invoke-dbatoolsRenameHelper | Out-GridView Thanks, PowerShell! 😊\nOther Updates There are other cool updates with this release. In preparation for my doomsday prepping with dbatools presentation at SQLGLA, I created a new command, Export-DbaInstance, which I\u0026rsquo;ll write more about in a future post.\nIn order for Export-DbaInstance to work well, I had to create a number of underlying commands, some of which may be of interest to you.\nGet-DbaDbMail Get-DbaDbMailAccount Get-DbaDbMailProfile Get-DbaDbMailConfig Get-DbaDbMailServer Export-DbaCredential Export-DbaLinkedServer Get-DbaResourceGovernor Get-DbaRgResourcePool Get-DbaRgWorkloadGroup Get-DbaRgClassifierFunction Get-DbaPbmCategory Get-DbaPbmCategorySubscription Get-DbaPbmCondition Get-DbaPbmObjectSet Get-DbaPbmPolicy Get-DbaPbmStore New Website Documentation Coming Soon We\u0026rsquo;ll soon be moving our documentation to a system that automatically generates docs from markdown! Expect to see that by next week. It\u0026rsquo;ll be a great relief once released because keeping the website manually updated with all these changes is a near impossible task.\nThe command index will remain and be updated manually since it requires some categorization. That page also needs updating; I should have that done by Monday.\ndbachecks Recall that using old command names will show big ol yellow warnings and dbachecks uses a number of the renamed commands. So, dbachecks will be updated today, too, a couple hours after this email is sent out ✓\n- Chrissy\n","date":"2018-09-07","summary":"Marching onward to dbatools 1.0, a ton of commands have been renamed to align with our now mature naming scheme. These changes were made in today\u0026rsquo;s release, version 0.9.410 aka regularlegs, now available on GitHub and the PowerShell Gallery.\nHere\u0026rsquo;s the general idea:\nDbaDatabase has mostly been renamed to DbaDb with a couple exceptions DbaSql has been changed to just Dba, no exceptions. Considering Microsoft reserved the Sql prefix and we can\u0026rsquo;t use it, think of Dba as \u0026ldquo;Sql\u0026rdquo;.","tags":[],"title":"New Release with Significant but Non-Breaking Changes","type":"post","url":"https://dbatools.io/regularlegs/"},{"categories":["announcements"],"content":"Last night\u0026rsquo;s #PSPowerHour made me realize I should highlight a few awesome projects I\u0026rsquo;ve come across recently.\nPSDatabaseClone PSDatabaseClone was created by Sander Stad.\nPSDatabaseClone is a PowerShell module for creating SQL Server database images and clones. It enables administrator to supply environments with database copies that are a fraction of the original size.\nIt is well-documented and open-source.\ndbops dbops was created by Kirill Kravtsov.\ndbops is a Powershell module that provides Continuous Integration/Continuous Deployment capabilities for SQL database deployments.\nIt is based on DbUp, which is DbUp is an open source .NET library that helps you to deploy changes to SQL Server databases. dbops currently supports both SQL Server and Oracle.\nsqlwatch sqlwatch was created by Marcin Gminski.\nThe aim of this this project is to provide a free, repository backed, SQL Server Monitoring.\nThe project is open-source and the developers are active in the #sqlwatch channel of the SQL Server Community Slack.\nPowerUpSQL PowerUpSQL was created by Scott Sutherland.\nPowerUpSQL includes functions that support SQL Server discovery, weak configuration auditing, privilege escalation on scale, and post exploitation actions such as OS command execution.\nThe project is open-source and was recently featured at Black Hat USA.\ndbachecks If you\u0026rsquo;re new to dbatools and not familiar with our other projects, dbachecks was created by the dbatools team and is now primarily maintained by Rob Sewell.\ndbachecks is a framework created by and for SQL Server pros who need to validate their environments using crowd-sourced checklists.\nThe project is open-source and totally beautiful.\nIf you\u0026rsquo;re wondering what happened to dbareports, Rob handed it off to Jason Squires who is currently in the middle of a rewrite.\nYour Module Here If I\u0026rsquo;ve missed your module or project, let me know in the comments and I\u0026rsquo;ll happily add it to this post!\nMissed #PSPowerHour? Last night, was the second live stream of #PSPowerHour! Check it.\nTitle Name Cloning SQL Server Databases using PowerShell Sander Stad Getters and Setters for Classes with Custom Attributes Ryan Bartram Using PwSH to gather information from silos Teresa Clark PowerShell and RegExp to convert code Cláudio Silva Getting Started with Visual Studio Code Shawn Melton Deploying SQL code using Powershell Kirill Kravtsov PSKoans Joel Sallow Chrissy ","date":"2018-08-31","summary":"Last night\u0026rsquo;s #PSPowerHour made me realize I should highlight a few awesome projects I\u0026rsquo;ve come across recently.\nPSDatabaseClone PSDatabaseClone was created by Sander Stad.\nPSDatabaseClone is a PowerShell module for creating SQL Server database images and clones. It enables administrator to supply environments with database copies that are a fraction of the original size.\nIt is well-documented and open-source.\ndbops dbops was created by Kirill Kravtsov.\ndbops is a Powershell module that provides Continuous Integration/Continuous Deployment capabilities for SQL database deployments.","tags":["party"],"title":"A Few Other Community Tools","type":"post","url":"https://dbatools.io/community-tools/"},{"categories":["announcements"],"content":"Hey all! Kirill Kravtsov, here. I\u0026rsquo;m a SQL Server DBA that is passionate about automation and PowerShell. I\u0026rsquo;m also a major contributor to dbatools and creator of the dbops module, which provides continuous database deployments at any scale.\nThis week, I wrote an article on my blog and Chrissy asked me to mirror it on dbatools, so here we go.\nIntroduction Many SQL Server DBAs know that there is a very convenient way of delivering a full copy of the database structure to a different SQL Server: it\u0026rsquo;s called dacpac, or a Data-tier Application package. You can extract the database any time using SQL Server Management Studio context menu: Tasks -\u0026gt; Extract Data-tier Application, which would guide you through the extraction options and output a compressed package file that would contain all necessary schema definitions, as well as table data. This package can be further on deployed on a completely different server using a Deploy Data-tier Application context menu item.\nWhat people do not widely know, however, is how much fine-tuning a simple deployment might require, and how difficult it is sometimes to force the deployment operation to behave in a certain way. Good thing is, now we have a convenient way of automating this process using dacpac-related functions from the dbatools module:\nExport-DbaDacPackage Publish-DbaDacPackage New-DbaDacProfile This article would explain how to:\nExtract dacpac from a database Choose whether you want to include data or not Deploy the dacpac package on any version of SQL Server higher than 2008 SP2 Exclude object types from the deployment process Generate deployment scripts Create a Jenkins job that will take care of this whole process for you Extracting DacPac Package Let\u0026rsquo;s use this simple script to extract dacpac from an existing database:\nParam ( $Server, $Database, $Path, [switch]$IncludeData ) # Prepare extraction properties string $exportProperties = \u0026#34;/p:IgnorePermissions=True /p:IgnoreUserLoginMappings=True\u0026#34; # Ignore permissions definition if ($IncludeData) { $exportProperties += \u0026#34; /p:ExtractAllTableData=True\u0026#34; #Extract data } Export-DbaDacPackage -SqlInstance $Server -Database $Database -Path C:\\temp -ExtendedProperties $exportProperties Export properties here are defined to control the extract process:\nIgnore database permissions, as there is rarely a need to add permissions into the mix Define an option to include data into the package Export-DbaDacPackage function will take care of the extraction process and will return all details about the extraction, including the Path property that would direct us to the extracted file:\nPowerShell Database Elapsed Path -------- ------- ---- DBAdmin 23.25 s C:\\temp\\DBAdmin.dacpac You can check all other available properties (which are basically command line parameters) in a corresponding article: https://learn.microsoft.com/sql/tools/sqlpackage/sqlpackage-publish\nDeploying DacPac Package There is one important note about dacpac deployment: it requires a so called Publish Profile for the deployment. Publish profile is an xml file that contains deployment parameters that you want to enable during the deployment. You can create such profile by using one of the following options:\nRun New-DbaDacProfile, specifying the connection parameters. The resulting file will enable you to run the deployment, but it is highly recommended that you modify it according to your needs From Visual Studio SSDT project, select Build -\u0026gt; Publish. It would open a dialog, that allows you to load, save and modify the Publish profile. Make sure to take a look at the Advanced Publish Settings dialog, as it provides access to dozens of configuration items that you might want to review Manually, using documentation from Publish parameters section of the same article The parameters that we\u0026rsquo;re going to use during deployment are as follows:\nAllowIncompatiblePlatform - would enable me to deploy to an earlier version of SQL Server. CreateNewDatabase - will re-create the database every time ExcludeObjectTypes - semicolon-separated list of objects that will be excluded from the deployment. ExcludeLogins and ExcludeUsers - somehow, these two ended up being independent parameters, not included in the previously mentioned ExcludeObjectTypes. Excludes logins and/or users from the deployment. IgnorePermissions - ignores object permissions during the deployment. DropObjectsNotInSource - boolean value, which is True by default, that controls whether existing objects in the database are going to be dropped if they are not present in the package. This is a very important parameter if you are planning to deploy dacpac to a non-empty database. IgnoreRoleMembership - ignores role membership This is an example of the Publish profile file that we\u0026rsquo;re going to use in this exercise:\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; ?\u0026gt; \u0026lt;Project ToolsVersion=\u0026#34;14.0\u0026#34; xmlns=\u0026#34;http://schemas.microsoft.com/developer/msbuild/2003\u0026#34;\u0026gt; \u0026lt;PropertyGroup\u0026gt; \u0026lt;TargetConnectionString\u0026gt;\u0026lt;/TargetConnectionString\u0026gt; \u0026lt;ProfileVersionNumber\u0026gt;1\u0026lt;/ProfileVersionNumber\u0026gt; \u0026lt;AllowIncompatiblePlatform\u0026gt;True\u0026lt;/AllowIncompatiblePlatform\u0026gt; \u0026lt;CreateNewDatabase\u0026gt;False\u0026lt;/CreateNewDatabase\u0026gt; \u0026lt;ExcludeObjectTypes\u0026gt;Permissions;RoleMembership\u0026lt;/ExcludeObjectTypes\u0026gt; \u0026lt;ExcludeLogins\u0026gt;True\u0026lt;/ExcludeLogins\u0026gt; \u0026lt;IgnorePermissions\u0026gt;True\u0026lt;/IgnorePermissions\u0026gt; \u0026lt;DropObjectsNotInSource\u0026gt;False\u0026lt;/DropObjectsNotInSource\u0026gt; \u0026lt;IgnoreUserSettingsObjects\u0026gt;True\u0026lt;/IgnoreUserSettingsObjects\u0026gt; \u0026lt;IgnoreLoginSids\u0026gt;True\u0026lt;/IgnoreLoginSids\u0026gt; \u0026lt;IgnoreRoleMembership\u0026gt;True\u0026lt;/IgnoreRoleMembership\u0026gt; \u0026lt;/PropertyGroup\u0026gt; \u0026lt;/Project\u0026gt; Once we have a Publish profile ready we can start the deployment by using Publish-DbaDacPackage function, specifying:\nSqlInstance - target server Database - target database Path - path to the dacpac package PublishXml - path to the publish profile PowerShell PS C:\\\u003e Publish-DbaDacPackage -SqlInstance MSSQLSERVER -Database DBAdmin_copy -Path 'C:\\temp\\DBAdmin.dacpac' -PublishXml (Get-Item .\\etc\\publish.xml) ComputerName : MSSQLSERVER InstanceName : MSSQLSERVER SqlInstance : MSSQLSERVER Database : DBAdmin_copy Dacpac : C:\\temp\\DBAdmin.dacpac PublishXml : .\\etc\\publish.xml Result : Initializing deployment (Start) Initializing deployment (Complete) Analyzing deployment plan (Start) Analyzing deployment plan (Complete) Reporting and scripting deployment plan (Start) Updating database (Complete) Creating DBAdmin_copy... Creating [SECONDARY]... Creating [dbo].[BackupVerificationHistory]... Creating [dbo].[CommandLog]... Creating [dbo].[CommandLogID]... Creating [dbo].[CommandLogSummary]... Creating [dbo].[DatabaseSelect]... Creating [dbo].[BackupVerification]... Creating [dbo].[CommandExecute]... Creating [dbo].[CommandExecuteID]... Creating [dbo].[DatabaseIntegrityCheck]... Creating [dbo].[IndexOptimize]... Creating [dbo].[InsertCommandLogSummary]... Creating [dbo].[Isp_WhoIsActive]... Creating [dbo].[OutputFile]... Altering [dbo].[Connection]... Altering [dbo].[PublicRead]... DeployOptions : @{AdditionalDeploymentContributorArguments=; AllowDropBlockingAssemblies=False;...} SqlCmdVariableValues : {} Other parameters of Publish-DbaDacPackage that you might find useful:\nGenerateDeploymentScript - will generate a deployment script prior to deployment ScriptOnly - will not perform the deployment, generating a deployment script instead Full Script This script below would extract the dacpac from an existing database and deploy it to a different server using the publish.xml file we created above. Feel free to modify it to your own liking!\n[Cmdletbinding()] Param ( $SourceServer, $TargetServer = $SourceServer, $SourceDatabaseName, $TargetDatabaseName, $Path, $PublishXml = \u0026#39;.\\publish.xml\u0026#39;, [switch]$IncludeData ) #Stop on any error by default $ErrorActionPreference = \u0026#39;Stop\u0026#39; # Construct export parameters $exportProperties = \u0026#34;/p:IgnorePermissions=True /p:IgnoreUserLoginMappings=True\u0026#34; if ($IncludeData) { $exportProperties += \u0026#34; /p:ExtractAllTableData=True\u0026#34; } #Export database to path Write-Verbose \u0026#34;Starting the export from $SourceServer.$SourceDatabaseName to $Path\u0026#34; $exportFile = Export-DbaDacPackage -SqlInstance $SourceServer -Database $SourceDatabaseName -Path $Path -ExtendedProperties $exportProperties -EnableException Write-Verbose \u0026#34;Export completed`: $exportFile\u0026#34; #publish dacpac with defined publish xml file Write-Verbose \u0026#34;Starting the publication from $($exportFile.Path) to $TargetServer.$TargetDatabaseName\u0026#34; $xml = (Get-Item $PublishXml).FullName Publish-DbaDacPackage -SqlInstance $TargetServer -Database $TargetDatabaseName -PublishXml $xml -Path $exportFile.Path -EnableException #remove dacpac file if (Test-Path $exportFile.Path) { Write-Verbose \u0026#34;Removing dacpac file $($exportFile.Path)\u0026#34; Remove-Item $exportFile.Path } Creating a Jenkins Job In order to create an interface and a scheduler at the same time, I would definitely recommend to make this scenario available on your Jenkins instance, similar to how it is described in a SQL Server Jenkins Lab series: Refresh database \u0026amp; keep permissions - SQL Server Jenkins labs (Part 2).\nConclusion Dacpac packages are a convenient way of copying a full database when other methods are unavailable for whatever reason. It has some learning curve associated with it, but it can be a great help when used in an automated manner.\nIt is also a perfect workaround for database copying, when a source server has a higher SQL Server version than the target server: this will work even between 2017 and 2008, if all the objects are compatible with the target database version.\nIt also work pretty well as an alternative for a snapshot replication, being much less restrictive in its approach.\n- Kirill Blog: nvarscar.wordpress.com\n","date":"2018-08-29","summary":"Hey all! Kirill Kravtsov, here. I\u0026rsquo;m a SQL Server DBA that is passionate about automation and PowerShell. I\u0026rsquo;m also a major contributor to dbatools and creator of the dbops module, which provides continuous database deployments at any scale.\nThis week, I wrote an article on my blog and Chrissy asked me to mirror it on dbatools, so here we go.\nIntroduction Many SQL Server DBAs know that there is a very convenient way of delivering a full copy of the database structure to a different SQL Server: it\u0026rsquo;s called dacpac, or a Data-tier Application package.","tags":[],"title":"Using DacPac Functions to Clone SQL Server Databases","type":"post","url":"https://dbatools.io/clone/"},{"categories":["announcements"],"content":"Last night was the premiere of #PSPowerHour! It featured great speakers and a lot of dbatools content.\nWhat is PSPowerHour? Created by Michael T Lombardi and Warren F, PSPowerHour is \u0026ldquo;like a virtual User Group, with a lightning-demo format, and room for non-PowerShell-specific content. Eight community members will give a demo each PowerHour.\u0026rdquo;\nSessions are proposed and organized on GitHub, which is really cool. Both new and seasoned speakers are invited to propose topics 🙌\nAgenda Title Name Default Parameter Values Chrissy LeMaire The dime tour: PowerShell + Excel = Better Together Doug Finke Setting Trace Flags as Startup Parameters with dbatools Andrew Wickham Applying SQL Server Data Compression with dbatools Jess Pomfret Better, Safer SQL Queries from PowerShell Andy Levy Easy Desktop Notifications with BurntToast Josh King Raspberry Pi with PowerShell and IoT module Daniel Silva Everyone did such a great job, I love this livestream! As you can see above, the hour was opened up with my session about Default Parameter Values, which I wrote about earlier. Then Doug Fink talked about his really amazing module, ImportExcel.\nNext, dbatools contributor Andrew Wickman talked about setting SQL Server trace flags using PowerShell. This session also features containers! After Andrew\u0026rsquo;s session, dbatools contributor Jess Pomfret talked about her awesome compression commands which make it really easy to enable compression within SQL Server.\nFinally for dbatools content, major contributor Andy Levy talks discusses safely (and properly!) querying SQL Server using Invoke-DbaSqlQuery.\nAfter that Josh King talked about his very impressive and beautiful module BurntToast. And the hour is wrapped up by Daniel Silva who has a fantastic demo where he controls a Raspberry Pi with PowerShell ❤\nNext Meeting The next PSPowerHour will happen on August 30. The meeting\u0026rsquo;s agenda is already posted and features sessions about ChatOps, VS Code, SQL Server, getters \u0026amp; setters, PSKoans, PowerShell 6.0 and converting code using PowerShell.\nBe sure to check it out!\n- Chrissy\n","date":"2018-08-22","summary":"Last night was the premiere of #PSPowerHour! It featured great speakers and a lot of dbatools content.\nWhat is PSPowerHour? Created by Michael T Lombardi and Warren F, PSPowerHour is \u0026ldquo;like a virtual User Group, with a lightning-demo format, and room for non-PowerShell-specific content. Eight community members will give a demo each PowerHour.\u0026rdquo;\nSessions are proposed and organized on GitHub, which is really cool. Both new and seasoned speakers are invited to propose topics 🙌","tags":["party","pspowerhour"],"title":"PSPowerHour YouTube Livestream","type":"post","url":"https://dbatools.io/pspowerhour/"},{"categories":["announcements"],"content":"Hey all, my name is Marcin and this is my first post and my first contribution to the dbatools. I hope you find it useful.\nIntroduction Part of a successful administration and management of any database is to know what happens over a period of time, when scheduled jobs and backups run and whether they are successful or not.\nThe common difficulty is getting this information out of SQL Server and then - the most difficult part - understanding what it means. In case of scheduled jobs, we want to make sure that there are no clashing and those heavy workloads such as ETL, backups, integrity checks and index maintenance run in isolation as much as possible.\nBefore dbatools, getting the information out of SQL Server was often a tedious task that often involved relatively complex T-SQL script, spreadsheet and some copying and pasting. Thanks to all the hard work of the dbatools team this is a history. A simple command can retrieve all the information we want and now with the new ConvertTo-DbaTimeline, it can be easily plotted on a graphical timeline!\nConcept The concept of a timeline is very simple and based on a Gantt chart used in project management and time schedule:\nA Gantt chart is a type of bar chart that illustrates a project schedule, named after its inventor, Henry Gantt (1861-1919), who designed such a chart around the years 1910-1915 https://en.wikipedia.org/wiki/Gantt_chart\nThe idea is to show a graphical representation of an item or items of interest (task, job, meeting duration) with the start and end dates on a common timeline:\nA timeline is a chart that depicts how a set of resources are used over time. If you\u0026rsquo;re managing a software project and want to illustrate who is doing what and when, or if you\u0026rsquo;re organizing a conference and need to schedule meeting rooms, a timeline is often a reasonable visualization choice. One popular type of timeline is the Gantt chart. https://developers.google.com/chart/interactive/docs/gallery/timeline\nExecution Currently, the output from the following commands is supported:\nGet-DbaAgentJobHistory Get-DbaDbBackupHistory You will run the above commands as you would normally do but pipe the output to ConvertTo-DbaTimeline, the same way as you would with any other ConverTo-* PowerShell function. The output is a string that most of the time you will save as file using the Out-File command in order to open it in a browser.\nExamples Get-DbaAgentJobHistory #To generate the timeline for agent job history and save as html file: Get-DbaAgentJobHistory -SqlInstance sql-1 -StartDate \u0026#39;2018-08-18 00:00\u0026#39; -EndDate \u0026#39;2018-08-19 23:59\u0026#39; -ExcludeJobSteps | ConvertTo-DbaTimeline | Out-File C:\\temp\\DbaAgentJobHistory.html -Encoding ASCII Note the -Encoding ASCII - this is required for correct JavaScript and HTML formatting.\nColours are applied automatically based on the job status:\nSucceeded (green: #36b300) Failed (red: #ff3d3d) Retry (yellow: #ffff00) Canceled (grey: #c2c2c2) In Progress (cyan: #00ccff) Get-DbaDbBackupHistory #Backup history timeline: Get-DbaDbBackupHistory -SqlInstance sql-1 -Since \u0026#39;2018-08-18 00:00\u0026#39; | ConvertTo-DbaTimeline | Out-File C:\\temp\\Get-DbaDbBackupHistory.html -Encoding ascii Each backup type has its own colour. This time, however, they are not pre-configured but are set automatically by the Google\u0026rsquo;s framework so could be random.\nWe can also run it for multiple servers at once AND THIS IS GREAT as it allows to produce a comprehensive overview of the entire estate which can help to assess the impact on the network, storage or virtual cluster. And without passing the Out-File command it will simply output an HTML as a string:\nGet-DbaDbBackupHistory -SqlInstance sql2017, sql2016 -Since \u0026#39;2018-08-13 00:00\u0026#39; | ConvertTo-DbaTimeline Which can be assigned to a variable or used to compose an email as in the example below:\n$messageParameters = @{ Subject = \u0026#34;Backup history for sql2017 and sql2016\u0026#34; Body = Get-DbaDbBackupHistory -SqlInstance sql2017, sql2016 -Since \u0026#39;2018-08-13 00:00\u0026#39; | ConvertTo-DbaTimeline From = \u0026#34;dba@ad.local\u0026#34; To = \u0026#34;dba@ad.local\u0026#34; SmtpServer = \u0026#34;smtp.ad.local\u0026#34; } Send-MailMessage @messageParameters -BodyAsHtml The Mechanics We are using Google Charts Framework to generate the graph in the ConvertTo-DbaTimeline. The framework is JavaScript based, very easy to use and fast. The rendering happens on the client PC and no data is ever sent to Google or anywhere.\nYou can read more about the Google Chart Framework:\nhttps://developers.google.com/chart/\nAnd specifically about the Timeline object:\nhttps://developers.google.com/chart/interactive/docs/gallery/timeline\nThe creation of the HTML file is not much different to how dynamic websites work. If we look at Google\u0026rsquo;s generic example below, the part containing JavaScript Array data rows is generated dynamically from the pipe input. The rest of the code apart from few parameters is static. Once the input is transposed it is being returned as a string. That\u0026rsquo;s it. It is very simple yet powerful.\ngoogle.charts.load(\u0026#34;current\u0026#34;, {packages:[\u0026#34;timeline\u0026#34;]}); google.charts.setOnLoadCallback(drawChart); function drawChart() { var container = document.getElementById(\u0026#39;example3.1\u0026#39;); var chart = new google.visualization.Timeline(container); var dataTable = new google.visualization.DataTable(); dataTable.addColumn({ type: \u0026#39;string\u0026#39;, id: \u0026#39;Position\u0026#39; }); dataTable.addColumn({ type: \u0026#39;string\u0026#39;, id: \u0026#39;Name\u0026#39; }); dataTable.addColumn({ type: \u0026#39;date\u0026#39;, id: \u0026#39;Start\u0026#39; }); dataTable.addColumn({ type: \u0026#39;date\u0026#39;, id: \u0026#39;End\u0026#39; }); dataTable.addRows([ [ \u0026#39;President\u0026#39;, \u0026#39;George Washington\u0026#39;, new Date(1789, 3, 30), new Date(1797, 2, 4) ], [ \u0026#39;President\u0026#39;, \u0026#39;John Adams\u0026#39;, new Date(1797, 2, 4), new Date(1801, 2, 4) ], [ \u0026#39;President\u0026#39;, \u0026#39;Thomas Jefferson\u0026#39;, new Date(1801, 2, 4), new Date(1809, 2, 4) ], [ \u0026#39;Vice President\u0026#39;, \u0026#39;John Adams\u0026#39;, new Date(1789, 3, 21), new Date(1797, 2, 4)], [ \u0026#39;Vice President\u0026#39;, \u0026#39;Thomas Jefferson\u0026#39;, new Date(1797, 2, 4), new Date(1801, 2, 4)], [ \u0026#39;Vice President\u0026#39;, \u0026#39;Aaron Burr\u0026#39;, new Date(1801, 2, 4), new Date(1805, 2, 4)], [ \u0026#39;Vice President\u0026#39;, \u0026#39;George Clinton\u0026#39;, new Date(1805, 2, 4), new Date(1812, 3, 20)], [ \u0026#39;Secretary of State\u0026#39;, \u0026#39;John Jay\u0026#39;, new Date(1789, 8, 25), new Date(1790, 2, 22)], [ \u0026#39;Secretary of State\u0026#39;, \u0026#39;Thomas Jefferson\u0026#39;, new Date(1790, 2, 22), new Date(1793, 11, 31)], [ \u0026#39;Secretary of State\u0026#39;, \u0026#39;Edmund Randolph\u0026#39;, new Date(1794, 0, 2), new Date(1795, 7, 20)], [ \u0026#39;Secretary of State\u0026#39;, \u0026#39;Timothy Pickering\u0026#39;, new Date(1795, 7, 20), new Date(1800, 4, 12)], [ \u0026#39;Secretary of State\u0026#39;, \u0026#39;Charles Lee\u0026#39;, new Date(1800, 4, 13), new Date(1800, 5, 5)], [ \u0026#39;Secretary of State\u0026#39;, \u0026#39;John Marshall\u0026#39;, new Date(1800, 5, 13), new Date(1801, 2, 4)], [ \u0026#39;Secretary of State\u0026#39;, \u0026#39;Levi Lincoln\u0026#39;, new Date(1801, 2, 5), new Date(1801, 4, 1)], [ \u0026#39;Secretary of State\u0026#39;, \u0026#39;James Madison\u0026#39;, new Date(1801, 4, 2), new Date(1809, 2, 3)] ]); chart.draw(dataTable); } Final Note Although it\u0026rsquo;s a Google framework, this works great on any browser not only on Google Chrome. As per the Google Docs: Charts are rendered using HTML5/SVG technology to provide cross-browser compatibility (including VML for older IE versions).\nHowever, one last thing to keep in mind is that it does require access to the internet in order to access Google Charts and Bootstrap frameworks. As these are based on JavaScript, it is best to run on a client PC and not on Windows Server.\nMy Experience as a Contributor Although I have been using dbatools for quite some time now this was my first contribution to the project. I never really looked how it all works behind scenes but oh boy it is impressive. Chrissy has done a fantastic job designing the dbatools framework. All the internal functions are there, as a developer I did not have to worry about how to write a message or raise an error.\nChrissy is also a great mentor, she reviewed my code and tweaked it a bit where required with the full explanation of what she did and why, which made perfect sense. I probably learned more PowerShell in those couple of days working with Chrissy than in my whole career. Thank you!\n","date":"2018-08-21","summary":"Hey all, my name is Marcin and this is my first post and my first contribution to the dbatools. I hope you find it useful.\nIntroduction Part of a successful administration and management of any database is to know what happens over a period of time, when scheduled jobs and backups run and whether they are successful or not.\nThe common difficulty is getting this information out of SQL Server and then - the most difficult part - understanding what it means.","tags":[],"title":"Creating a History Timeline","type":"post","url":"https://dbatools.io/timeline/"},{"categories":["announcements"],"content":"When connecting to a SQL Server instance with alternative credentials, it can be tedious to repeat the SQL credential over and over.\nThe great news is that this repetition is not required, as it can be handled instead by $PSDefaultParameterValues\nIntro to $PSDefaultParameterValues $PSDefaultParameterValues is a hashtable available in PowerShell that can set defaults for any command that you run. In it\u0026rsquo;s simplest form, setting a default parameter value can look like this:\n$PSDefaultParameterValues[\u0026#39;Get-DbaDatabase:Verbose\u0026#39;] = $true According to Microsoft, $PSDefaultParameterValues:\nLet you specify custom default values for any command Commands use the custom default value unless you specify another value Useful when you must specify the same value nearly every time After running the above code, Get-DbaDatabase will show verbose output every time it\u0026rsquo;s executed, without me having to specify -Verbose. If I need to override that verbose flag for some reason, I can simply add -Verbose:$false to my Get-DbaDatabase command.\nUsage Here\u0026rsquo;s what I\u0026rsquo;ve used $PSDefaultParameterValues for:\nSqlCredential for SQL Authentication in docker ErrorAction Stop in Agent Jobs to ensure failures fail Confirm:$false in Agent Jobs to avoid prompting Verbose in Agent Jobs to see command output in the logs EnableException in dbachecks to ensure Pester tests fail SqlCredential for any alternative credential needs, actually Invoke-WebRequest Proxy and ProxyUseDefaultCredentials You could even set a default SQL Server and get results from Get-DbaDatabase.\nIf you have configured a good amount of default parameters and want to see all of your default parameter values, you just need to run $PSDefaultParameterValues .\nOh, and it\u0026rsquo;s no big deal if a command does not support the parameter, the parameter and its value just won\u0026rsquo;t be passed. And also, like most things that support defaults, you can override the defaults, as mentioned previously.\nSyntax \u0026amp; Real-World Examples Michael Sorens awesome article on simple-talk goes in-depth about syntax, but here are some basics.\n# EnableException for all dbatools commands using wildcards, overwrite previous $PSDefaultParameterValues $PSDefaultParameterValues = @{ \u0026#39;*-Dba*:EnableException\u0026#39; = $true } # Turn off confirmation prompts for all commands (useful in automation/scheduled jobs), add to existing $PSDefaultParameterValues $PSDefaultParameterValues[\u0026#39;*:Confirm\u0026#39;] = $false # Use a saved credential for all commands, add to existing PSDefaultParameterValues $sqlcredential = Import-CliXml -Path \u0026#34;$home\\Documents\\sqlcred.xml\u0026#34; $wincredential = Import-CliXml -Path \u0026#34;$home\\Documents\\wincred.xml\u0026#34; $PSDefaultParameterValues += @{ \u0026#39;*-Dba*:SqlCredential\u0026#39; = $sqlcredential \u0026#39;*:Credential\u0026#39; = $wincredential } # Conditional default params, thanks Boe! $PSDefaultParameterValues = @{ \u0026#34;Format-Table:AutoSize\u0026#34; = { if ($host.Name -eq \u0026#34;ConsoleHost\u0026#34;) { $true } } } In the real-world, I primarily use Default Parameter Values when running Scheduled Tasks/Agent Jobs. I like to see verbose output in my logs, so I enable that. I also make sure there are no confirmation prompts; that got me once as I waited over 24 hours for a job to complete (\u0026ldquo;daaang this code is slow\u0026rdquo;) 😄\nDisabling $PSDefaultParameterValues Your default parameter values can be temporarily disabled by adding the following key:\n$PSDefaultParameterValues[\u0026#34;Disabled\u0026#34;] = $true And you can reenable it by setting Disabled to $false or by removing the Disabled key.\n$PSDefaultParameterValues.Remove(\u0026#39;Disabled\u0026#39;) Persistence Setting $PSDefaultParameterValues at the command-line only lasts during that session, meaning if you close your console, it will be reset. So, if you want the default values to persist, you\u0026rsquo;ll have to add it to your profile (basically: notepad $profile, paste, save).\nScopes Are Dope In dbachecks, we set $PSDefaultParameterValues to EnableException across the board. This allows our Pester tests to fail when a failure occurs.\nWhat\u0026rsquo;s interesting is that setting the value within the module does not impact the end-user, so even after you import dbachecks, your $PSDefaultParameterValues will not be modified.\nResources There are some great resources that go more in-depth about Parameters Default Values. Here are just a few:\nMicrosoft: About Parameters Default Values Scripting Guys: Use PowerShell Default Parameter Values to Simplify Scripts Boe Prox: Using PSDefaultParameterValues in PowerShell Michael Sorens: PowerShell Time Saver: Automatic Defaults - Chrissy\n","date":"2018-08-15","summary":"When connecting to a SQL Server instance with alternative credentials, it can be tedious to repeat the SQL credential over and over.\nThe great news is that this repetition is not required, as it can be handled instead by $PSDefaultParameterValues\nIntro to $PSDefaultParameterValues $PSDefaultParameterValues is a hashtable available in PowerShell that can set defaults for any command that you run. In it\u0026rsquo;s simplest form, setting a default parameter value can look like this:","tags":[],"title":"Default Parameter Values","type":"post","url":"https://dbatools.io/defaults/"},{"categories":["announcements"],"content":"SQL Server\u0026rsquo;s Central Management Server (CMS), first introduced in SQL Server 2008, \u0026ldquo;stores a list of instances of SQL Server that is organized into one or more central management server groups\u0026rdquo;.\nIt\u0026rsquo;s a super useful feature that not all DBAs know about. Since CMS data is stored in msdb and accessible via SMO, you can access it from SQL Server Management Studio or PowerShell modules like dbatools.\nCentral Management Server\u0026rsquo;s essential functionality includes:\nActions that are taken by using a central management server group act on all servers in the server group. This includes connecting to servers by using Object Explorer and executing Transact-SQL statements and Policy-Based Management policies on multiple servers at the same time.\nI mostly use it as a visual repository of my SQL Servers. Prior to using dbatools and Invoke-DbaQuery, however, I did use CMS to easily execute code against a number of different servers.\nServer Grouping The screenshot above is a sample representation of how SQL Servers can be divided into groups. I generally organize by department, but organizing by version is also useful when performing migrations. I\u0026rsquo;ve done that as well.\nAnd because a SQL Server can be listed multiple times within different groups, my buddy Brandon created an automated system that divided by both Application and assigned DBA. Too cool! In this example from sqlmatters.com, their servers are divided up by environment.\nBut wait. The screenshot also shows Registered Servers. What are those?\nRegistered Servers vs Central Management Servers The article Registered Servers vs Central Management Servers lays out the differences in a straightforward manner.\nRegistered Servers Connection data is stored locally in an XML file (passwords are encrypted) in the user path. Because it is a local file with encrypted data, Registered Servers are local and only work for the user that created them. Can be used with SQL Server Authentication or Windows Authentication. Can be used for the database engine, SSAS, SSIS and SSRS. Central Management Servers Connection data is stored in a central SQL Server (in the msdb database), and can be used by other users. Can be used with Windows Authentication only. Can be used for the database engine only. I work primarily in environments where Windows Authentication works for all of my servers, so I haven\u0026rsquo;t used Registered Servers in years. I also appreciate that my list of servers within CMS is backed up each day because it\u0026rsquo;s stored in msdb. And, it\u0026rsquo;s easily accessible through both SQL Server Management Studio and PowerShell.\ndbatools Commands We have a number of commands to help manage CMS! We even updated our command names after this blog post came out.\nGet-DbaRegServer Gets list of SQL Server objects stored in SQL Server Central Management Server.\n# Here\u0026#39;s how you get a list of all servers stored on the CMS instance on sql2008. # Note that this list is pipable to all dbatools commands Get-DbaRegServer -SqlInstance sql2008 # Pipe all the results to another dbatools command Get-DbaRegServer -SqlInstance sql2008 | Get-DbaLastBackup # Get all registered servers in the group \u0026#34;Production\u0026#34; Get-DbaRegServer -SqlInstance sql2008 -Group Production # Get all registered servers in the subgroup \u0026#34;HR\u0026#34; within \u0026#34;Production\u0026#34; Get-DbaRegServer -SqlInstance sql2008 -Group Production\\HR Add-DbaRegServer Adds registered servers to SQL Server Central Management Server.\n# To create a registered server on sql2008\u0026#39;s CMS which points to the SQL Server, sql01. # When scrolling in CMS, the name \u0026#34;sql01\u0026#34; will be visible. Add-DbaRegServer -SqlInstance sql2008 -ServerName sql01 # To create a registered server on sql2008\u0026#39;s CMS which points to the SQL Server, sql01. # When scrolling in CMS, \u0026#34;The 2008 Clustered Instance\u0026#34; will be visible. Add-DbaRegServer -SqlInstance sql2008 -ServerName sql01 -Name \u0026#34;The 2008 Clustered Instance\u0026#34; -Description \u0026#34;HR\u0026#39;s Dedicated SharePoint instance\u0026#34; # To create a registered server on sql2008\u0026#39;s CMS which points to the SQL Server, sql01. # When scrolling in CMS, the name \u0026#34;sql01\u0026#34; will be visible within the Seattle group which is in the hr group. Add-DbaRegServer -SqlInstance sql2008 -ServerName sql01 -Group hr\\Seattle Add-DbaRegServerGroup Adds registered server groups to SQL Server Central Management Server.\n# To create a registered server group called HR, in the root of sql2012\u0026#39;s CMS Add-DbaRegServerGroup -SqlInstance sql2012 -Name HR # To create a registered server group on sql2012 and sql2014 called subfolder within the HR group Add-DbaRegServerGroup -SqlInstance sql2012, sql2014 -Name subfolder -Group HR # To create a registered server group on sql2012 and sql2014 called subfolder within the HR group of each server Get-DbaRegServerGroup -SqlInstance sql2012, sql2014 -Group HR | Add-DbaRegServerGroup -Name subfolder Export-DbaRegServer Exports Central Management Server registered servers and registered server groups to file.\n# To export all Registered Server and Registered Server Groups on sql2008 to an automatically generated file name in the current directory Export-DbaRegServer -SqlInstance sql2008 # To export all Registered Server and Registered Server Groups with the Seattle group within the HR group on sql2008 to C:\\temp\\Seattle.xml Export-DbaRegServer -SqlInstance sql2008 -Group hr\\Seattle -Path C:\\temp\\Seattle.xml # To export all registered servers on sql2008 and sql2012. Warning - each one will have its own individual file. Consider piping groups. Get-DbaRegServer -SqlInstance sql2008, sql2012 | Export-DbaRegServer # To export all registered servers on sql2008 and sql2012, organized by group. Get-DbaRegServerGroup -SqlInstance sql2008, sql2012 | Export-DbaRegServer Get-DbaRegServerGroup Gets list of Server Groups objects stored in SQL Server Central Management Server.\n# This is more of a helper command that will return a RegisteredServerGroup object Get-DbaRegServerGroup -SqlInstance sql2008 -Group Production\\HR Get-DbaRegServerStore Gets list of Server Groups objects stored in SQL Server Central Management Server.\n# This is more of a helper command that will return a RegisteredServerStore object Get-DbaRegServerStore -SqlInstance sql2008 Import-DbaRegServer Gets list of Server Groups objects stored in SQL Server Central Management Server.\n# To import C:\\temp\\corp-regservers.xml to the CMS on sql2012 Import-DbaRegServer -SqlInstance sql2012 -Path C:\\temp\\corp-regservers.xml # To import C:\\temp\\Seattle.xml to Seattle subgroup within the hr group on sql2008 Import-DbaRegServer -SqlInstance sql2008 -Group hr\\Seattle -Path C:\\temp\\Seattle.xml # To import all registered servers from sql2008 and sql2012 to sql2017 Get-DbaRegServer -SqlInstance sql2008, sql2012 | Import-DbaRegServer -SqlInstance sql2017 # To import all registered servers from the hr\\Seattle group on sql2008 to the Seattle group on sql2017 Get-DbaRegServerGroup -SqlInstance sql2008 -Group hr\\Seattle | Import-DbaRegServer -SqlInstance sql2017 -Group Seattle Move-DbaRegServer Moves registered server groups around SQL Server Central Management Server. This could be useful during migrations.\n# To move the registered server on sql2012 titled \u0026#39;Web SQL Cluster\u0026#39; to the Prod group within the HR group Move-DbaRegServer -SqlInstance sql2012 -Name \u0026#39;Web SQL Cluster\u0026#39; -NewGroup HR\\Prod Move-DbaRegServerGroup Removes registered servers found in SQL Server Central Management Server.\n# To move the Development group within HR to the Prod group within AD Move-DbaRegServerGroup -SqlInstance sql2012 -Group HR\\Development -NewGroup AD\\Prod Remove-DbaRegServer Removes registered servers found in SQL Server Central Management Server.\n# To remove all servers from the HR and Accounting groups on sql2012 Remove-DbaRegServer -SqlInstance sql2012 -Group HR, Accounting # To remove all servers from the HR and sub-group Development from the CMS on sql2012. Remove-DbaRegServer -SqlInstance sql2012 -Group HR\\Development # To remove all registered servers on sql2012 and turns off all prompting Remove-DbaRegServer -SqlInstance sql2012 -Confirm:$false Remove-DbaRegServerGroup Removes registered server groups found in SQL Server Central Management Server.\n# To remove the HR and Accounting groups on sql2012 Remove-DbaRegServerGroup -SqlInstance sql2012 -Group HR, Accounting # To remove the Development subgroup within the HR group on sql2012 and turns off all prompting Remove-DbaRegServerGroup -SqlInstance sql2012 -Group HR\\Development -Confirm:$false ⭐⭐⭐⭐⭐ Would Use Again CMS is a longtime favorite of mine and I\u0026rsquo;d like to give a shoutout to Bryan Hamby for helping make dbatools commands compatible with Central Management Server.\nIn case you missed it in the sea of code above, you can pipe a collection of servers right from CMS. Here\u0026rsquo;s how you\u0026rsquo;d find all running agent jobs in your estate, if you stored all of your SQL Servers in the CMS on sql2008.\nGet-DbaRegServer -SqlInstance sql2008 | Get-DbaRunningJob Too cool!\nHappy piping,\nChrissy Edit: Someone asked what server should be designated as the Central Management Server. A few people on the SQL Server Community Slack said they have a dedicated instance, as do I.\nI have a management server where I perform all of my work. If you\u0026rsquo;re interested in a dedicated instance but don\u0026rsquo;t have a license, it works on SQL Server Express Edition 👍\n","date":"2018-07-11","summary":"SQL Server\u0026rsquo;s Central Management Server (CMS), first introduced in SQL Server 2008, \u0026ldquo;stores a list of instances of SQL Server that is organized into one or more central management server groups\u0026rdquo;.\nIt\u0026rsquo;s a super useful feature that not all DBAs know about. Since CMS data is stored in msdb and accessible via SMO, you can access it from SQL Server Management Studio or PowerShell modules like dbatools.\nCentral Management Server\u0026rsquo;s essential functionality includes:","tags":["cms"],"title":"Managing Central Management Server","type":"post","url":"https://dbatools.io/cms/"},{"categories":["announcements"],"content":"I remember the first time I saw database snapshots, I was so excited. Then I right-clicked in SSMS and..\nNo way to easily create a snapshot. So then I researched how to create one using T-SQL and I had to know the exact path. UGH.\nCREATE DATABASE db1_snapshot_preupgrade ON (NAME = N\u0026#39;db1_snapshot_preupgrade_datafile\u0026#39;, FILENAME = N\u0026#39;M:\\MSSQL14.MSSQLSERVER\\MSSQL\\DATA\\db1_snapshot_preupgrade.ss\u0026#39;) AS SNAPSHOT OF db1 Intro to Snapshots Basically, database snapshots are similar to VM snapshots but for databases. If you update an application and its database, you can take a snapshot and if the upgrade goes poorly, you can super quickly restore the snapshot and even a multi-TB database can be restored in no time. Here\u0026rsquo;s a more technical definition from Microsoft.\nA database snapshot is a read-only, static view of a SQL Server database (the source database). The database snapshot is transactionally consistent with the source database as of the moment of the snapshot\u0026rsquo;s creation. A database snapshot always resides on the same server instance as its source database. As the source database is updated, the database snapshot is updated. Therefore, the longer a database snapshot exists, the more likely it is to use up its available disk space.\nI\u0026rsquo;ve never done this but my BFF and DBA Brandon swears by it. He noted that up until SQL Server 2016 SP1, snapshots were solely available in Enterprise Edition. With SQL Server 2016 SP1 and up, they are available in every edition, even Express!\nBenefits Benefits, as listed on Microsoft\u0026rsquo;s Snapshot page on docs are listed as follows:\nSnapshots can be used for reporting purposes Maintaining historical data for report generation Using a mirror database that you are maintaining for availability purposes to offload reporting Safeguarding data against administrative error Safeguarding data against user error Managing a test database That last example is pretty cool and relatable. In a testing environment, snapshots can be useful when repeatedly running a test for the database to contain identical data at the start of each round of testing.\nOne thing Microsoft didn\u0026rsquo;t emphasize as a bullet-point is how useful snapshots can be when upgrading an application. As mentioned above the upgrade goes poorly, it\u0026rsquo;s fast and easy to revert.\nSnapshot Commands One of our awesome devs, Simone Bizzoto, created a series of snapshot commands which make them way easier to work with. Like most other dbatools commands, these commands are flexible but require as little information as possible by default.\nSuper important note: these commands were recently renamed to align with our 1.0 convention. Please update to the latest version (0.9.359) or none of this will work as expected.\nNew-DbaDbSnapshot To create a new snapshot, you no longer need to know the path of the snapshot location (though we do support custom paths). You don\u0026rsquo;t even need to specify a name! But you can, of course.\n# Here\u0026#39;s how you create a snapshot for the HR and Accounting databases on server \u0026#34;sql2017\u0026#34; New-DbaDbSnapshot -SqlInstance sql2017 -Database HR, Accounting # Want it to be created in a specific path? New-DbaDbSnapshot -SqlInstance sql2017 -Database HR, Accounting -Path S:\\snaps # Want to create snapshots on a bunch of different servers? # You can pass -SqlInstance $servers or you can pipe from Out-GridView in PS v5.1 and below! $servers | Get-DbaDatabase | Out-GridView -PassThru | New-DbaDbSnapshot \u0026lt;iframe width=\u0026quot;560\u0026quot; height=\u0026quot;315\u0026quot; src=\u0026quot;https://www.youtube.com/embed/MEFFfEVsQPs\u0026quot; frameborder=\u0026quot;0\u0026quot; allow=\u0026quot;autoplay; encrypted-media\u0026quot; allowfullscreen\u0026gt;\u0026lt;/iframe\u0026gt;\n# To specify the name of the resulting snapshot, you can use the -Name parameter New-DbaDbSnapshot -SqlInstance sql017 -Database HR -Name MyCustomSnapNameforHRdb # If you\u0026#39;d like to create a snapshot for a few databases, but not use the default names, # you can use placeholders. As an example, the command below creates the following will # create two snapshots: one named new_HR_snap and new_Accounting_snap. New-DbaDbSnapshot -SqlInstance sqlserver2014a -Database HR, Accounting -NameSuffix \u0026#39;new_{0}_snap\u0026#39; Get-DbaDbSnapshot Now that you have a couple new snapshots, let\u0026rsquo;s take a look at them.\n# Find snapshots by specifying their base database Get-DbaDbSnapshot -SqlInstance sql2017 -Database HR, Accounting # Or you can even pass in a few servers. Get-DbaDbSnapshot -SqlInstance sql2017, sql2016, sql2014 -Database db1, db2, db3 # Or get a snapshot with a specific name Get-DbaDbSnapshot -SqlInstance sql2017 -Snapshot HR_snap_20161201 # Want to see every snapshot across your entire estate? Just pipe in your server inventory, # whether it be a string array, from AD or from Central Management Server Get-DbaRegisteredServer -SqlInstance SQLCMS | Get-DbaDbSnapshot PowerShell [05:07:28][00:00:00] C:\\github\\dbatools\u003e Get-DbaRegisteredServer -SqlInstance sql2008 | Get-DbaDbSnapshot ComputerName : SQL2014 InstanceName : MSSQLSERVER SqlInstance : SQL2014 Name : AdventureWorks2014_20180625_045302 SnapshotOf : AdventureWorks2014 CreateDate : 6/25/2018 4:53:04 PM DiskUsage : 3.38 MB ComputerName : SQL2014 InstanceName : MSSQLSERVER SqlInstance : SQL2014 Name : db1_20180625_045302 SnapshotOf : db1 CreateDate : 6/25/2018 4:53:04 PM DiskUsage : 384.00 KB ComputerName : SQL2014 InstanceName : MSSQLSERVER SqlInstance : SQL2014 Name : distribution_20180625_045302 SnapshotOf : distribution CreateDate : 6/25/2018 4:53:05 PM DiskUsage : 384.00 KB ComputerName : SQL2014 InstanceName : MSSQLSERVER SqlInstance : SQL2014 Name : msdb_20180625_045302 SnapshotOf : msdb CreateDate : 6/25/2018 4:53:03 PM DiskUsage : 1.69 MB Restore-DbaDbSnapshot Something very important to note about snapshot restores: according to Microsoft, restoring/reverting a snapshot does not work in an offline or corrupted database. Ultimately, this means that snapshots are not a replacement for a solid backup/restore plan.\nIf you\u0026rsquo;re wondering how long a snapshot will take to restore, the answer is \u0026ldquo;it depends.\u0026rdquo; If you have very few page changes, it\u0026rsquo;ll be very fast even on a multi-TB database. If you had GBs of changes since you took the snapshot, it\u0026rsquo;ll take longer.\n# To restore the HR database using the latest snapshot available. # By default, a prompt will appear to confirm the restore. Restore-DbaDbSnapshot -SqlInstance sql2017 -Database HR # To restore the HR_snap_20161201 snapshot and kill any active connections in the base database (HR) Restore-DbaDbSnapshot -SqlInstance sql2017 -Snapshot HR_snap_20161201 -Force # To select from a list of snapshots on sql2016, then restore them. Get-DbaDbSnapshot -SqlInstance sql2016 | Out-GridView -Passthru | Restore-DbaDbSnapshot Remove-DbaDbSnapshot When you\u0026rsquo;re finished with a snapshot, you should remove it. Why? All changes to your database will take up hdd space both in the database and the snapshot. This means you could potentially run out of disk space and if you do, your snapshots will become invalid.\n# To remove database snapshots named HR_snap_20161201 and HR_snap_20161101 Remove-DbaDbSnapshot -SqlInstance sql2014 -Snapshot HR_snap_20161201, HR_snap_20161101 # To remove all database snapshots for HR and Accounting Remove-DbaDbSnapshot -SqlInstance sql2014 -Database HR, Accounting # To select from a list of snapshots on sql2016, then remove them using a pipe Get-DbaDbSnapshot -SqlInstance sql2014 | Out-GridView -Passthru | Remove-DbaDbSnapshot # To remove all snapshots in all databases on sql2014 and confirm for each Remove-DbaDbSnapshot -SqlInstance sql2014 -AllSnapshots -Confirm Note that these commands will not remove your base database! Also, if you try to pass in a regular database object, the command will tell you it\u0026rsquo;s a real database and skip the drop 👍\nSnapshots Are 🔥 Hopefully, there will be a greater adoption of SQL Server snapshots both because their use has been simplified with PowerShell and because Microsoft has made this feature available in all editions of SQL Server 2016 SP1 and above.\nRemember, though, that while snapshots are super useful, they are not a replacement for a solid backup/restore strategy.\n- Chrissy\n","date":"2018-06-25","summary":"I remember the first time I saw database snapshots, I was so excited. Then I right-clicked in SSMS and..\nNo way to easily create a snapshot. So then I researched how to create one using T-SQL and I had to know the exact path. UGH.\nCREATE DATABASE db1_snapshot_preupgrade ON (NAME = N\u0026#39;db1_snapshot_preupgrade_datafile\u0026#39;, FILENAME = N\u0026#39;M:\\MSSQL14.MSSQLSERVER\\MSSQL\\DATA\\db1_snapshot_preupgrade.ss\u0026#39;) AS SNAPSHOT OF db1 Intro to Snapshots Basically, database snapshots are similar to VM snapshots but for databases.","tags":[],"title":"Simplifying Snapshots","type":"post","url":"https://dbatools.io/snapshots/"},{"categories":["announcements"],"content":"For those of you still using PowerShell ISE, I know the news about Microsoft no longer actively developing the ISE was sad. The good news is that it\u0026rsquo;s been replaced by something WAY cooler: VS Code.\nVS Code is free, open-source and a joy to use. If you\u0026rsquo;d like to make the move, or if you just want to see how PowerShell Pros use VS Code, Rob Sewell will be presenting an hour long web session today for 24 Hours of PASS Summit Preview at June 12, 2018 at 20:00 GMT.\nI use Google to help me convert and it seems that 20:00 GMT is 3:00 PM New Orleans/Central, 22:00 Brussels/Paris and 01:30 Wednesday in New Delhi. But please check using Google or this converter to be sure.\nSession Details Title: Writing PowerShell with VS Code Time: June 12, 2018 at 20:00 GMT Level: 100 Abstract: We should be using VS Code to write our PowerShell code. In this presentation I will show you how to set up VS Code, which extensions I use, and some of the features that make writing PowerShell easy using VS Code.\nRob is a fantastic trainer with a super cool English accent and VS Code is the future.\n- Chrissy\n","date":"2018-06-12","summary":"For those of you still using PowerShell ISE, I know the news about Microsoft no longer actively developing the ISE was sad. The good news is that it\u0026rsquo;s been replaced by something WAY cooler: VS Code.\nVS Code is free, open-source and a joy to use. If you\u0026rsquo;d like to make the move, or if you just want to see how PowerShell Pros use VS Code, Rob Sewell will be presenting an hour long web session today for 24 Hours of PASS Summit Preview at June 12, 2018 at 20:00 GMT.","tags":[],"title":"Today on 24HOP: Writing PowerShell with VS Code","type":"post","url":"https://dbatools.io/rob24hop/"},{"categories":["announcements"],"content":"If you\u0026rsquo;re still using super old versions of SQL Server and don\u0026rsquo;t have access to awesome XEvents, we\u0026rsquo;ve got some commands to help simplify trace management.\nBefore I Begin Just a quick note, if you use newer versions of SQL Server and haven\u0026rsquo;t seen the XEvents Profiler in SSMS 17, it\u0026rsquo;s awesome! In my experience, it\u0026rsquo;s much faster than using Profiler and just as useful.\nSadly, however, it\u0026rsquo;s only available for SQL Server version 2012 and up.\nOn to Traces Traces are less exciting than Extended Events, but PowerShell makes them kinda fun to work with (at least for me). As with most of our commands, multiple servers are supported.\nCheck out the list of traces across my lab. This information was gathered in 324ms!\nNote that SQL Server 2000 is not in the result set, as SQL 2000 does not support sys.traces 🤩\nGet-DbaTrace The above screenshot contains the results of Get-DbaTrace. This basically returns the results of select * from sys.traces. Here\u0026rsquo;s some sample usage:\n# Get all traces on sql2017 Get-DbaTrace -SqlInstance sql2017 # Get the default trace on sql2016 Get-DbaTrace -SqlInstance sql2016 -Default # Get the traces with ID 2 on both sql2016 and sql2017 Get-DbaTrace -SqlInstance sql2016, sql2017 -Id 2 PowerShell PS C:\\github\\dbatools\u003e Get-DbaTrace -SqlInstance sql2017 ComputerName : SQL2017 InstanceName : MSSQLSERVER SqlInstance : SQL2017 Id : 1 Status : 1 IsRunning : True Path : C:\\Program Files\\Microsoft SQL Server\\MSSQL14.MSSQLSERVER\\MSSQL\\Log\\log_24.trc MaxSize : 20 StopTime : MaxFiles : 5 IsRowset : False IsRollover : True IsShutdown : False IsDefault : True BufferCount : 10 BufferSize : 1024 FilePosition : 10485760 ReaderSpid : StartTime : 4/8/2018 8:35:21 PM LastEventTime : 5/31/2018 11:38:14 AM EventCount : 20353 DroppedEventCount : ComputerName : SQL2017 InstanceName : MSSQLSERVER SqlInstance : SQL2017 Id : 2 Status : 0 IsRunning : False Path : C:\\temp\\LongRunningQueries.trc MaxSize : 5 StopTime : MaxFiles : 2 IsRowset : False IsRollover : True IsShutdown : False IsDefault : False BufferCount : 2 BufferSize : 1024 FilePosition : 10485760 ReaderSpid : StartTime : LastEventTime : EventCount : 0 DroppedEventCount : Read-DbaTraceFile Next command is Read-DbaTraceFile, which is used to read the contents of the trace file. This basically returns the results of select * from [fn_trace_gettable]('$file', DEFAULT). Here\u0026rsquo;s some sample usage:\n# Read every trace file on sql2014 Get-DbaTrace -SqlInstance sql2014 | Read-DbaTraceFile # Read the tracefile C:\\traces\\big.trc, stored on sql2016. Filter only results that have master or tempdb as the DatabaseName. Read-DbaTraceFile -SqlInstance sql2016 -Database master, tempdb -Path C:\\traces\\big.trc # Read the tracefile C:\\traces\\big.trc, stored on sql2016. Filter only results that have master or tempdb as the DatabaseName and that have \u0026#39;EXEC SP_PROCOPTION\u0026#39; somewhere in the text. Read-DbaTraceFile -SqlInstance sql2016 -Database master, tempdb -Path C:\\traces\\big.trc -TextData \u0026#39;EXEC SP_PROCOPTION\u0026#39; # Read the tracefile C:\\traces\\big.trc, stored on sql2016. Filter only results where LinkServerName = myls and StartTime is greater than \u0026#39;5/30/2017 4:27:52 PM\u0026#39;. Read-DbaTraceFile -SqlInstance sql2016 -Path C:\\traces\\big.trc -Where \u0026#34;LinkedServerName = \u0026#39;myls\u0026#39; and StartTime \u0026gt; \u0026#39;5/30/2017 4:27:52 PM\u0026#39;\u0026#34; PowerShell PS C:\\github\\dbatools\u003e Get-DbaTrace -SqlInstance sql2017 -Id 1 | Read-DbaTraceFile ComputerName : SQL2017 InstanceName : MSSQLSERVER SqlInstance : SQL2017 TextData : BACKUP DATABASE [db] TO DISK = N'\\\\dc\\sql_db_Final_Before_Drop_20180409_105536.bak' WITH DESCRIPTION = N'Final Full Backup of db Prior to Dropping', NOFORMAT, NOINIT, NOSKIP, REWIND, NOUNLOAD, STATS = 10, CHECKSUM BinaryData : DatabaseID : 14 TransactionID : LoginSid : 1 NTUserName : ctrlb NTDomainName : BASE HostName : BASE-STATIONX ClientProcessID : 68176 ApplicationName : dbatools PowerShell module - dbatools.io LoginName : BASE\\ctrlb SPID : 55 Duration : StartTime : 4/9/2018 10:55:36 AM EndTime : Reads : Writes : CPU : Permissions : Severity : EventSequence : 1 EventClass : 1 ObjectID : 1 Success : 1 IntegerData : ServerName : SQL2017 EventClass : 115 ObjectType : 16964 NestLevel : 0 State : Error : Mode : Handle : ObjectName : db DatabaseName : db FileName : dbo OwnerName : RoleName : TargetUserName : DBUserName : dbo LoginSid : {1, 5, 0, 0...} TargetLoginName : TargetLoginSid : ColumnPermissions : LinkedServerName : ProviderName : MethodName : RowCounts : RequestID : 0 XactSequence : 0 EventSequence : 8299 BigintData1 : BigintData2 : GUID : IntegerData2 : ObjectID2 : Type : OwnerID : ParentName : IsSystem : Offset : SourceDatabaseID : SqlHandle : SessionLoginName : BASE\\ctrlb PlanHandle : GroupID : Remove-DbaTrace Next command is Remove-DbaTrace, which is used to stop and remove a trace. This command basically executes sp_trace_setstatus $traceid, 0 then sp_trace_setstatus $traceid, 2. Here\u0026rsquo;s some sample usage:\n# To stop and remove all traces on sql2008 Remove-DbaTrace -SqlInstance sql2008 # To stop and remove the trace with id 2 on sql2008 Remove-DbaTrace -SqlInstance sql2008 -Id 2 # To stop and remove selected traces on sql2008 using Out-GridView Get-DbaTrace -SqlInstance sql2008 | Out-GridView -PassThru | Remove-DbaTrace PowerShell PS C:\\github\\dbatools\u003e Remove-DbaTrace -SqlInstance sql2017 -Id 2 ComputerName : SQL2017 InstanceName : MSSQLSERVER SqlInstance : SQL2017 Id : 2 Status : Stopped, closed and deleted Start-DbaTrace Next command is Start-DbaTrace, which is used to start one or more traces. This command basically executes sp_trace_setstatus $traceid, 1. Here\u0026rsquo;s some sample usage:\n# To start all traces on sql2008 Start-DbaTrace -SqlInstance sql2008 # To start the trace with ID 2 on sql2008 Start-DbaTrace -SqlInstance sql2008 -Id 2 # To start selected traces on sql2008 using Out-GridView Get-DbaTrace -SqlInstance sql2008 | Out-GridView -PassThru | Start-DbaTrace PowerShell PS C:\\github\\dbatools\u003e Start-DbaTrace -SqlInstance sql2017 -Id 1 ComputerName : SQL2017 InstanceName : MSSQLSERVER SqlInstance : SQL2017 Id : 1 Status : 1 IsRunning : True Path : C:\\temp\\LongRunningQueries_1.trc MaxSize : 5 StopTime : MaxFiles : 2 IsRowset : False IsRollover : True IsShutdown : False IsDefault : False BufferCount : 2 BufferSize : 1024 FilePosition : 10485760 ReaderSpid : StartTime : 5/31/2018 3:15:22 PM LastEventTime : EventCount : 0 DroppedEventCount : Stop-DbaTrace Next command is Stop-DbaTrace, which is used to stop one or more traces. This command basically executes sp_trace_setstatus $traceid, 0. Here\u0026rsquo;s some sample usage:\n# To stop all traces on sql2008 Stop-DbaTrace -SqlInstance sql2008 # To stop the trace with ID 2 on sql2008 Stop-DbaTrace -SqlInstance sql2008 -Id 2 # To stop selected traces on all servers within $serverlist using Out-GridView Get-DbaTrace -SqlInstance $serverlist | Out-GridView -PassThru | Stop-DbaTrace PowerShell PS C:\\github\\dbatools\u003e Stop-DbaTrace -SqlInstance sql2017 -Id 1 ComputerName : SQL2017 InstanceName : MSSQLSERVER SqlInstance : SQL2017 Id : 1 Status : 0 IsRunning : False Path : C:\\temp\\LongRunningQueries_1.trc MaxSize : 5 StopTime : MaxFiles : 2 IsRowset : False IsRollover : True IsShutdown : False IsDefault : False BufferCount : 2 BufferSize : 1024 FilePosition : 10485760 ReaderSpid : StartTime : 5/31/2018 3:15:22 PM LastEventTime : EventCount : 0 DroppedEventCount : PowerShell Is Awesome These commands really highlight my favorite thing about managing SQL Server with PowerShell. First, you can manage multiple servers as easily as managing one, and the naming convention is straight forward and easy to remember.\nEven after years of using traces, I always had to look up the syntax for sp_trace_setstatus or fn_trace_gettable. Now, though, it\u0026rsquo;s as easy as remembering Get, Start, Stop, Read and Remove 👍\n- Chrissy\n","date":"2018-05-31","summary":"If you\u0026rsquo;re still using super old versions of SQL Server and don\u0026rsquo;t have access to awesome XEvents, we\u0026rsquo;ve got some commands to help simplify trace management.\nBefore I Begin Just a quick note, if you use newer versions of SQL Server and haven\u0026rsquo;t seen the XEvents Profiler in SSMS 17, it\u0026rsquo;s awesome! In my experience, it\u0026rsquo;s much faster than using Profiler and just as useful.\nSadly, however, it\u0026rsquo;s only available for SQL Server version 2012 and up.","tags":[],"title":"Stuck on Older Versions of SQL Server? Check Out Our Trace Commands.","type":"post","url":"https://dbatools.io/traces/"},{"categories":["announcements"],"content":"Congrats to our teammate Rob Sewell! Rob was invited by PASS to present about PowerShell at PASS Summit 2018 on Tuesday, November 6 2018.\nIn his day-long session, Rob will talk about a variety of super interesting subjects including: dbachecks, PowerShell module-making, GitHub, VSTS, and dbatools. Rob is a vibrant, knowledgeable speaker and I can\u0026rsquo;t recommend this precon enough! I learn a ton every time that Rob and I present together.\nProfessional and Proficient PowerShell Professional and Proficient PowerShell: From Writing Scripts to Developing Solutions\nDBA\u0026rsquo;s are seeing the benefit of using PowerShell to automate away the mundane. A modern data professional needs to be able to interact with multiple technologies and learning PowerShell increases your ability to do that and your usefulness to your company.\nAt the end of this fun filled day with Rob, a former SQL Server DBA turned professional automator, you will be much more confident in being able to approach any task with PowerShell and you will leave with all of the code and demos. You can even follow along if you bring a laptop with an instance of SQL Server installed.\nHow to learn how to interact with any technology using PowerShell Understanding the syntax The importance of Get-Help and how PowerShell enables you to help yourself Why to write your own Modules and how to make them available to all of your team A quick automated method to creating your module framework Unit testing and debugging your code How to continuously deliver changes to your PowerShell modules using GitHub and VSTS Tips and tricks for script writing with the popular open-source community dbatools module How to validate your SQL Server estate with PowerShell Advanced SQL Server Agent and PowerShell management We will have a lot of fun along the way and you will return to work with a lot of ideas, samples and better habits to become a PowerShell ninja and save yourself and your organisation time and effort.\nRegister Now To register, visit the shortlink sqlps.io/precon\n- Chrissy\n","date":"2018-04-12","summary":"Congrats to our teammate Rob Sewell! Rob was invited by PASS to present about PowerShell at PASS Summit 2018 on Tuesday, November 6 2018.\nIn his day-long session, Rob will talk about a variety of super interesting subjects including: dbachecks, PowerShell module-making, GitHub, VSTS, and dbatools. Rob is a vibrant, knowledgeable speaker and I can\u0026rsquo;t recommend this precon enough! I learn a ton every time that Rob and I present together.","tags":["dbachecks","party"],"title":"PowerShell Precon at PASS Summit 2018","type":"post","url":"https://dbatools.io/psprecon/"},{"categories":["announcements"],"content":"Azure Data Studio (formerly SQL Server Operations Studio) by Microsoft is like SSMS for ops, all open source and published on GitHub! They updated their wiki\u0026rsquo;s Performance page, addressing why SQL Operations Studio starts up slowly. Their startup stats are pretty cool!\nThis screenshot reminded me that I should write about our own import time stats.\nConfession You may remember years ago when I expressed how upset I was about SQLPS, SqlServer\u0026rsquo;s predecessor, taking so long to import. Five whole seconds! Thanks to the community response, Microsoft took note and now it\u0026rsquo;s down to an amazing 00:00:00.9531216!\nThat\u0026rsquo;s about 1 second, though often times, I\u0026rsquo;ve seen it load in 500ms. Congrats to Microsoft! I\u0026rsquo;m jealous 😊 At the PASS Summit PowerShell Panel last year, people asked what we loved most and hated most about PowerShell. I already knew my answer for what I hated most: long import times.\nAnd I immediately copped to my embarrassment that I complained about SQLPS taking so long to load, yet here we were, back in November 2017, taking just as long to load. Now to be fair, we support more SQL Server functionality and we also use non-compiled code (functions/ps1 vs cmdlets/C#) which makes it easier for the community to contribute. This means we can only do so much.\nRedemption I asked C# wizard, Fred, how we can improve import times, and he immediately jumped on it by adding a class that breaks down how long each section takes.\nYou can test this yourself by importing dbatools then running:\n[Sqlcollaborative.dbatools.dbaSystem.DebugHost]::ImportTime What you\u0026rsquo;ll notice is that on that supafast machine, dbatools is now down to about a 1.78 second load! Incredible. This is how we did it:\nRunspaces We noticed that the longest part of importing the module was importing all the extra SMO DLL\u0026rsquo;s that we require for many of the commands. We import about 150 DLLs and it looks like that number will only grow as we begin to support more functionality (such as Integration services, etc.)\nTo address this concern, Fred added multi-threading via runspaces to our import process. Too cool! This resulted in a significant decrease in time.\nAllcommands.ps1 The other thing we did to significantly decrease import times was we combined all of the individual .ps1 files in public to a single .ps1 file. So now, before every release, I combine all the newly updated commands, sign it using our code signing certificate, then publish it to the PowerShell Gallery.\nIt also means that we had to modify our import process to accommodate our developers because nobody, including me, wants to work on a 90,000 line file. We handled this by detecting if a .git folder exists in the dbatools path, and if it does, then it\u0026rsquo;ll skip allcommands.ps1 and import the individual .ps1 files in the public directory.\nThe .git folder only exists when the git repository is cloned. This means it won\u0026rsquo;t exist in our module in the PowerShell Gallery or in a zip downloaded from GitHub.\nEdit: I took this a step further and compressed the ps1 to a zip. Turns out it works super well! Check out the post for more information.\nThe Future I\u0026rsquo;ve heard that PowerShell Core (PSv6) is insanely fast. Unfortunately, SMO is not entirely ported to .NET Core, so we can\u0026rsquo;t yet support 6.0. However! SMO is the only portion of our module that is not 6.0 ready, so once SMO is ported, dbatools will be too 👍. Hopefully this will result in faster load times.\nYour Miles May Vary On my Windows 7 test box, dbatools loads in 2.3 seconds. On a more locked down Windows 2012 server, the import takes about 4-6 seconds.\nNote that you should never experience import times over 20 seconds. If you do, check your Execution Policy, which could be impacting load times. dbatools is fancy and signed by a code-signing certificate; this is awesome for code integrity, but it\u0026rsquo;s also known to slow down imports when mixed with certain Execution Policies.\n- Chrissy 🍰\n","date":"2018-04-11","summary":"Azure Data Studio (formerly SQL Server Operations Studio) by Microsoft is like SSMS for ops, all open source and published on GitHub! They updated their wiki\u0026rsquo;s Performance page, addressing why SQL Operations Studio starts up slowly. Their startup stats are pretty cool!\nThis screenshot reminded me that I should write about our own import time stats.\nConfession You may remember years ago when I expressed how upset I was about SQLPS, SqlServer\u0026rsquo;s predecessor, taking so long to import.","tags":["party"],"title":"Decreasing Module Import Times","type":"post","url":"https://dbatools.io/import-times/"},{"categories":["announcements"],"content":"Years ago, I wrote Watch-DbaDbLogin which keeps an inventory of accounts, hosts and programs that log into a SQL Server. It was pretty crude, but helped immensely during my migration, as this inventory ensured that my documentation was in order and no unexpected downtime would occur.\nI found that about 80-90% of logins/applications were covered within 48-hours, but two months of data gave me total confidence.\nI always wanted to update the command, though I\u0026rsquo;m not sure Watch-DbaDbLogin is still within the scope of the module. It\u0026rsquo;ll likely remove it in dbatools 1.0 so please accept this far cooler post in its place.\nThere are several ways to capture logins, all with their own pros and cons. In this post, we\u0026rsquo;ll outline four possibilities: default trace, audits, extended events and session enumeration.\nNote: The code in this post requires dbatools version 0.9.323. I found two bugs while testing sample scenarios 😔 Also, this post addresses tracking logins for migration purposes, not for security purposes. Edit the where clauses as suitable for your environment.\nUsing a Default Trace Using the default trace is pretty lightweight and backwards compatible. While I generally try to avoid traces, I like this method because it doesn\u0026rsquo;t require remote access, it works on older SQL instances, it\u0026rsquo;s accurate and reading from the trace isn\u0026rsquo;t as CPU-intensive as it would be with an Extended Event.\nSet Up the SQL Table Basically, no matter which way you track your logins, you\u0026rsquo;ll need to store them somewhere. Below is some T-SQL which sets up a table that is ideal for bulk importing (which we\u0026rsquo;ll do using Write-DbaDataTable).\nThe table is created with an index that ignores duplicate sessions. When IGNORE_DUP_KEY is ON, a duplicate row is simply ignored. So we\u0026rsquo;re going to setup a clustered index using SqlInstance, LoginName, HostName, DatabaseName, ApplicationName and StartTime. Then the collector will send a bunch of rows via bulkcopy to the table, and the table will ignore the dupes.\n# This creates a \u0026#34;watchlogins\u0026#34; in the \u0026#34;inventory\u0026#34; database $sql = \u0026#34;CREATE TABLE watchlogins ( SqlInstance varchar(128), LoginName varchar(128), HostName varchar(128), DatabaseName varchar(128), ApplicationName varchar(256), StartTime datetime ) -- Create Unique Clustered Index with IGNORE_DUPE_KEY=ON to avoid duplicates CREATE UNIQUE CLUSTERED INDEX [ClusteredIndex-Combo] ON watchlogins ( SqlInstance ASC, LoginName ASC, HostName ASC, DatabaseName ASC, ApplicationName ASC, StartTime ASC ) WITH (IGNORE_DUP_KEY = ON)\u0026#34; # Execute your SQL - in this case, my centralized collection server is localhost Invoke-DbaQuery -SqlInstance localhost -Query \u0026#34;CREATE DATABASE inventory\u0026#34; Invoke-DbaQuery -SqlInstance localhost -Database inventory -Query $sql To clarify, \u0026ldquo;duplicate\u0026rdquo; logins may show up, but not duplicate sessions. Watch-DbaDbLogin only recorded the first time it ever saw a login/db/host/app combination which many people found to be less useful, especially if you run the login tracker for years. What if a login became stale?\nIf you\u0026rsquo;d like the first login only, remove StartTime ASC from the index.\nSet Up the Default Trace # Set all of your servers $servers = \u0026#34;sql2014\u0026#34;,\u0026#34;sql2016\u0026#34;,\u0026#34;sql2017\u0026#34; # Check to see if default trace is enabled $servers | Get-DbaSpConfigure -ConfigName DefaultTraceEnabled | Where-Object RunningValue -eq $false | Set-DbaSpConfigure -Value $true Set Up the Collector Next, you\u0026rsquo;ll want to setup a collector as a scheduled SQL Agent Job.\n# Exclude noise using T-SQL syntax - customize for your environment $where = \u0026#34;DatabaseName is not NULL and DatabaseName != \u0026#39;tempdb\u0026#39; and SERVERPROPERTY(\u0026#39;MachineName\u0026#39;) != HostName and ApplicationName not like \u0026#39;dbatools%\u0026#39; and ApplicationName not like \u0026#39;Microsoft SQL Server Management Studio%\u0026#39; and ApplicationName not like \u0026#39;\\[%\\].Net SqlClient Data Provider\u0026#39; ESCAPE \u0026#39;\\\u0026#39;\u0026#34; # ignore sharepoint guid stuff # Collect the results into a variable so that the bulk import is supafast $results = $servers | Get-DbaTrace -Id 1 | Read-DbaTraceFile -Where $where | Select-Object SqlInstance, LoginName, HostName, DatabaseName, ApplicationName, StartTime # Bulk import to the centralized database in an efficient manner (piping would write line by line) if ($results) { Write-DbaDataTable -InputObject $results -SqlInstance localhost -Database inventory -Table watchlogins } How often should you run the job? It depends. I have one server that has login information going back to November. But I\u0026rsquo;ve found that SharePoint or System Center dedicated instances only have about 20 minutes worth of login data in the default trace.\nHow long does the collection take? Polling 15 servers took 14 seconds to read 55,000 records and 18 seconds to write that data. Of the 55,000 records, only 115 were unique!\nUsing a SQL Server Audit Audits are cool because audits can \u0026ldquo;force the instance of SQL Server to shut down, if SQL Server fails to write data to the audit target for any reason\u0026rdquo;. This ensures that 100% of your logins are captured. But my requirements for collecting migration information aren\u0026rsquo;t that high and I haven\u0026rsquo;t found the magical Audit Spec that only logs what I need. Here\u0026rsquo;s what the .sqlaudit file for SUCCESSFUL_LOGIN_GROUP looks like when you rename it to .xel and open it.\nEh, I\u0026rsquo;m missing so much stuff. And since Audits are Extended Events anyway, and I have more control over what I do and don\u0026rsquo;t want to see, we\u0026rsquo;ll skip right to Extended Events.\nUsing Extended Events You can also use Extended Events. This option is pretty cool but collecting the data does require UNC access for remote servers.\nSet Up the SQL Table # Create the table with a special index $sql = \u0026#34;CREATE TABLE watchlogins ( server_instance_name varchar(128), server_principal_name varchar(128), client_hostname varchar(128), [database_name] varchar(128), client_app_name varchar(256), timestamp datetime ) -- Create Unique Clustered Index with IGNORE_DUPE_KEY=ON to avoid duplicates CREATE UNIQUE CLUSTERED INDEX [ClusteredIndex-Combo] ON watchlogins ( server_instance_name ASC, server_principal_name ASC, client_hostname ASC, [database_name] ASC, client_app_name ASC, timestamp ASC ) WITH (IGNORE_DUP_KEY = ON)\u0026#34; # Execute your SQL - in this case, my centralized collection server is localhost Invoke-DbaQuery -SqlInstance localhost -Query \u0026#34;CREATE DATABASE inventory\u0026#34; Invoke-DbaQuery -SqlInstance localhost -Database inventory -Query $sql Login Tracker Template We\u0026rsquo;ve provided a \u0026ldquo;Login Tracker\u0026rdquo; Extended Event session template that you can easily add to your estate.\nThis template creates a session that:\nIs initiated by sql_statement_starting event Collects the minimum possible columns Ignores connections from dbatools and SSMS Ignores queries to tempdb Ignores system queries Keeps 50 MB of data on disk (10×5) I chose sql_statement_starting because it\u0026rsquo;s the only one that I found that actually included the database name. If this doesn\u0026rsquo;t work for you, you can modify then export/import the modified Session. If you have a better suggestion, I\u0026rsquo;d love that. Please let me know; I kinda feel like this one is overkill.\nSet Up the XESession # Specify your servers $servers = Get-DbaRegServer -SqlInstance sql2017 # Import the \u0026#39;Login Name\u0026#39; XESession Template available in dbatools 0.9.320 and above $sessions = Get-DbaXESessionTemplate -Template \u0026#39;Login Tracker\u0026#39; | Import-DbaXESessionTemplate -SqlInstance $servers # Set each one to auto-start foreach ($session in $sessions) { $session.AutoStart = $true $session.Alter() } Set Up the Collector # Collect the results into a variable so that the bulk import is supafast $results = $servers | Get-DbaXESession -Session \u0026#39;Login Tracker\u0026#39; | Read-DbaXEFile | Select-Object server_instance_name, server_principal_name, client_hostname, database_name, client_app_name, timestamp # Bulk import to the centralized database in an efficient manner (piping would write line by line) Write-DbaDataTable -InputObject $results -SqlInstance localhost -Database inventory -Table watchlogins UNC Access So instead of placing the burden of XML shredding on the CPU of the destination SQL instance, Read-DbaXEFile uses the local resources. It does this by using the RemoteTargetFile which is available in Get-DbaXESession but is not a default field. To unhide non-default fields, pipe to *SELECT **.\nKeep in mind that the entire file is read each time you enumerate. Which is not a big deal, but should be considered if you have millions of logins.\nNote that I did set a max on the Login Tracker file size to 50 MB so if you want to modify that, you can use PowerShell or SSMS (Instance ➡ Management ➡ Extended Events ➡ Sessions ➡ Login Tracker ➡ right-click Properties ➡ Data Storage ➡ Remove/Add). There is no dbatools command available to do this in PowerShell yet, so you\u0026rsquo;ll have to do it manually until it\u0026rsquo;s added.\nUsing Session Enumeration This one requires no setup at all, but only captures whoever is logged in at the time that you run the command. This approach is what I originally used in Watch-DbaDbLogin (scheduled to run every 5 minutes) and it worked quite well.\nSo if you\u0026rsquo;ve never seen the output for Get-DbaProcess, which does session enumeration, it\u0026rsquo;s pretty useful. If you\u0026rsquo;d like something even more lightweight that still gives you most of the information you need, you can use $server.EnumProcesses()\nActually, scratch all that. Let\u0026rsquo;s go with some lightweight, backwards-compatible T-SQL that gets us only what we need and nothing more. Honestly, of all the ways, I\u0026rsquo;ve personally defaulted back to this one. It\u0026rsquo;s just so succinct and efficient. There is the possibility that I\u0026rsquo;ll miss a login, but this isn\u0026rsquo;t a security audit and really, I inventoried 100% of the logins I needed for my last migration.\nSet Up the SQL Table # This creates a \u0026#34;watchlogins\u0026#34; in the \u0026#34;inventory\u0026#34; database $sql = \u0026#34;CREATE TABLE watchlogins ( SqlInstance varchar(128), Login varchar(128), Host varchar(128), [Database] varchar(128), ApplicationName varchar(256), StartTime datetime ) -- Create Unique Clustered Index with IGNORE_DUPE_KEY=ON to avoid duplicates CREATE UNIQUE CLUSTERED INDEX [ClusteredIndex-Combo] ON watchlogins ( SqlInstance ASC, Login ASC, Host ASC, [Database] ASC, ApplicationName ASC, StartTime ASC ) WITH (IGNORE_DUP_KEY = ON)\u0026#34; # Execute your SQL - in this case, my centralized collection server is localhost Invoke-DbaQuery -SqlInstance localhost -Query \u0026#34;CREATE DATABASE inventory\u0026#34; Invoke-DbaQuery -SqlInstance localhost -Database inventory -Query $sql Set Up the Collector # Specify your servers $servers = \u0026#34;sql2014\u0026#34;,\u0026#34;sql2012\u0026#34;,\u0026#34;sql2016\u0026#34;,\u0026#34;sql2017\u0026#34; # Setup the T-SQL $sql = \u0026#34;SELECT SERVERPROPERTY(\u0026#39;ServerName\u0026#39;) AS SqlInstance, login_name as [Login], [host_name] as Host, DB_NAME(p.dbid) as [Database], s.[program_name] as Program, s.login_time as LoginTime FROM sys.dm_exec_sessions s inner join sys.sysprocesses p on s.session_id = p.spid WHERE p.dbid is not NULL and DB_NAME(p.dbid) != \u0026#39;tempdb\u0026#39; and SERVERPROPERTY(\u0026#39;MachineName\u0026#39;) != [host_name] and s.[program_name] not like \u0026#39;dbatools%\u0026#39; and s.[program_name] not like \u0026#39;Microsoft SQL Server Management Studio%\u0026#39; and s.[program_name] not like \u0026#39;\\[%\\].Net SqlClient Data Provider\u0026#39; ESCAPE \u0026#39;\\\u0026#39;\u0026#34; # Collect relevant results foreach ($instance in $servers) { $results = Invoke-DbaQuery -SqlInstance $instance -Query $sql if ($results) { Write-DbaDataTable -InputObject $results -SqlInstance localhost -Database inventory -Table watchlogins } } Testing Your Results If you\u0026rsquo;re testing the scripts on a non-busy system like I did, you may not get any results back because we\u0026rsquo;re ignoring connections from dbatools and SQL Server Management Studio.\nIf you\u0026rsquo;d like to ensure some results, just run this before performing a collection. This connects to SQL Server using a fake client name and performs a query that gathers database names.\n$server = Connect-DbaInstance -SqlInstance sql2017 -ClientName \u0026#39;My test client\u0026#39; $server.Databases.Name Scheduling To schedule the collection, you can use my favorite method, SQL Server Agent. I wrote about this in-depth in a post, Scheduling PowerShell Tasks with SQL Agent.\nDuring my own migration, I used session enumeration and setup the collector to run every 5 minutes. With Traces or Extended Events, you can collect the logins far less frequently since they are stored on the remote server.\nHope this was helpful! Chrissy\n","date":"2018-04-10","summary":"Years ago, I wrote Watch-DbaDbLogin which keeps an inventory of accounts, hosts and programs that log into a SQL Server. It was pretty crude, but helped immensely during my migration, as this inventory ensured that my documentation was in order and no unexpected downtime would occur.\nI found that about 80-90% of logins/applications were covered within 48-hours, but two months of data gave me total confidence.\nI always wanted to update the command, though I\u0026rsquo;m not sure Watch-DbaDbLogin is still within the scope of the module.","tags":["party"],"title":"Three Ways to Track Logins Using dbatools","type":"post","url":"https://dbatools.io/track-logins/"},{"categories":["announcements"],"content":"Last week I performed a server migration from SQL Server 2014 to SQL Server 2016 using dbatools. A lot of work is done up front to prepare and plan for these migrations to have the least impact on our customers. So I always do my best to improve the process each time we do it.\nBackstory This is the second product server we have migrated to SQL 2016. The first migration had automation to a certain point.\nConfigure the servers using some dbatools commands Take a full backup the day before the migration Take and apply a differential backup the night of the migration My comfort level with dbatools last year when the migration was done was low, so the migration was a mix of TSQL and manual processes.\nGoal The goal this time around was to enhance the process with more automation. With that in mind I decided to use the Invoke-DbaDbLogShipping command to build log shipping for the primary database that was part of the migration. The current size of the database is 650GB which is not too outrageous, but it has growth of 30GB a day and by Wednesday my differential backup would have been 90GB. So time to take the backup and restore the backup would have been time consuming during the migration window.\nWhy Log Shipping? The reason I decided to go with Log Shipping is the ease of setup, made even easier by the dbatools commands. Also, the ability to minimize downtime which I pointed out earlier, even for large databases.\nLog shipping also supports mixed versions as far back as 2005 to current versions and mixed editions like Standard, Workgroup or Enterprise which other migration options lack. See this great article on using Log Shipping to minimize downtime for more detail.\nMigration Steps So we used our standard build configuration process to get the servers configured to our standards. This process has not been converted to use dbatools like I had hoped, but time has been my enemy on that project. Currently we have 12, yes 12 environments for each of our products. That means this exercise is done 12 times before it is all said and done.\nHowever, this time we did things a little different. Our development teams now follow the Agile life cycle and our development teams do two week sprints. For our first phase we migrated the primary Continuous Integration environment and the main Integration environment using the automated process. However, log shipping does not come in to play due to the size of these environments. So it gives us practice and testing of the migration process. Then on the next sprint we migrated the Regression and Production environments. This is where the fun starts.\nLast week I decided to use Invoke-DbaDbLogShipping to get the production database built on the new server and keep it in sync with the current server.\nSteps to Build Log Shipping To get the secondary going I restored the latest Full backup and left the database in NO RECOVERY Then I ran the Invoke-DbaDbLogShipping command with the parameters that were needed for my environment Once everything was in place I monitored the Backup, Copy and Restore SQL Agent Jobs # Restore Latest Full $restoreDbaDatabaseSplat = @{ SqlInstance = \u0026#39;localhost\\sql2017\u0026#39; DatabaseName = \u0026#39;WideWorldImporters\u0026#39; Path = \u0026#39;C:\\SQLData\\Backups\\WideWorldImporters_201804011846.bak\u0026#39; NoRecovery = $true WithReplace = $true } Restore-DbaDatabase $restoreDbaDatabaseSplat # Configure Log Shipping $invokeDbaLogShippingSplat = @{ SourceSqlInstance = \u0026#39;localhost\\sql2016\u0026#39; DestinationSqlInstance = \u0026#39;localhost\\sql2017\u0026#39; Database = \u0026#39;WideWorldImporters\u0026#39; BackupNetworkPath = \u0026#39;\\\\LXDW17181\\C$\\SQLData\\LSBackups\u0026#39; BackupLocalPath = \u0026#39;C:\\SQLData\\LSBackups\u0026#39; BackupScheduleFrequencySubdayType = \u0026#39;Minutes\u0026#39; BackupScheduleFrequencySubdayInterval = 5 CopyDestinationFolder = \u0026#39;C:\\SQLData\\LS\u0026#39; CopyScheduleFrequencySubdayType = \u0026#39;Minutes\u0026#39; CopyScheduleFrequencySubdayInterval = 5 RestoreScheduleFrequencySubdayType = \u0026#39;Minutes\u0026#39; RestoreScheduleFrequencySubdayInterval = 5 NoInitialization = $true NoRecovery = $true Force = $true } Invoke-DbaDbLogShipping @invokeDbaLogShippingSplat Once all the jobs are verified to be working from the proper locations, you can see that the Transaction Log Shipping Status built in report shows that we are current on our log shipping.\nMigration Day 11:00 PM on Wednesday was go time.\nOur product site was put in maintenance mode so no new traffic is coming in My steps in preparation for the migration Time to verify that the latest Log Backup was taken, Copied and Restored on the secondary Now it is time to bring that secondary copy online I did not use the command below, as I had not had time to do any testing. So I used TSQL, but after testing this now it would have been even easier. The Invoke-DbaDbLogShipRecovery sets the jobs to disabled and then brings the database online.\n# Recover Log Shipping $invokeDbaLogShippingRecoverySplat = @{ SqlInstance = \u0026#39;localhost\\sql2017\u0026#39; Database = \u0026#39;WideWorldImporters\u0026#39; Force = $true } Invoke-DbaDbLogShipRecovery @invokeDbaLogShippingRecoverySplat And just like that we are done. 17 total minutes of downtime for our product and we are back, with only replication and AG to be done after the fact.\nAlternative Configurations Considering the number of parameters available in Invoke-DbaDbLogShipping, there are a number of ways to setup Log Shipping. Here are a couple available configurations using the parameters -UseExistingFullBackup and -GenerateFullBackup. These help automate the initial backup/restore process.\nUseExistingFullBackup If the database is not yet initialized on the secondary instance it can be done by selecting an existing full backup and restore it for you.\n$params = @{ SourceSqlInstance = \u0026#39;sql1\u0026#39; DestinationSqlInstance = \u0026#39;sql2\u0026#39; Database = \u0026#39;db1\u0026#39; UseExistingFullBackup = $true BackupNetworkPath = \u0026#39;\\\\sql1\\logshipping\u0026#39; BackupLocalPath = \u0026#39;D:\\Data\\logshipping\u0026#39; CompressBackup = $true Force = $true } Invoke-DbaDbLogShipping @params GenerateFullBackup If database is not yet initialized on the secondary instance it can be also be done by telling the command to create a new backup and restore it for you.\n$params = @{ SourceSqlInstance = \u0026#39;sql1\u0026#39; DestinationSqlInstance = \u0026#39;sql2\u0026#39; Database = \u0026#39;db1\u0026#39; GenerateFullBackup = $true BackupNetworkPath = \u0026#39;\\\\sql1\\logshipping\u0026#39; BackupLocalPath = \u0026#39;D:\\Data\\logshipping\u0026#39; CompressBackup = $true Force = $true } Invoke-DbaDbLogShipping @params UseBackupFolder Or, if you\u0026rsquo;ve already got all of your backups in a folder, you can also use that as well.\n$params = @{ SourceSqlInstance = \u0026#39;sql1\u0026#39; DestinationSqlInstance = \u0026#39;sql2\u0026#39; Database = \u0026#39;db1\u0026#39; UseBackupFolder = \u0026#39;C:\\SQL\\Backup\u0026#39; BackupNetworkPath = \u0026#39;\\\\sql1\\logshipping\u0026#39; BackupLocalPath = \u0026#39;D:\\Data\\logshipping\u0026#39; CompressBackup = $true Force = $true } Invoke-DbaDbLogShipping @params If you have any migration in your future, or want to learn more, please take a look at the Log Shipping commands that dbatools has to offer. You can use the command help for more detail.\nGet-Help Invoke-DbaDbLogShipping -Detailed Get-Help Invoke-DbaDbLogShipRecovery -Detailed Additional Information Check out Sander Stad\u0026rsquo;s blog at sqlstad.nl for more information about log shipping with dbatools. Sander (blog) is the author of most of these awesome log shipping commands.\nThanks for reading, Garry (GitHub)\n","date":"2018-04-04","summary":"Last week I performed a server migration from SQL Server 2014 to SQL Server 2016 using dbatools. A lot of work is done up front to prepare and plan for these migrations to have the least impact on our customers. So I always do my best to improve the process each time we do it.\nBackstory This is the second product server we have migrated to SQL 2016. The first migration had automation to a certain point.","tags":["party"],"title":"Minimal-Downtime Migrations Using Invoke-DbaLogShipping","type":"post","url":"https://dbatools.io/logshipping/"},{"categories":["announcements"],"content":"Back around the time we did SQL Bits, Rob Sewell spoke to Richard Campbell at RunAs Radio.\nThe show, Managing SQL Server using dbatools with Rob Sewell, is a fun and fantastic listen. Not only does Rob talk at length about the migration capabilities in dbatools, but also other cool things like CI/CD, containers and more. Check it out!\n","date":"2018-04-04","summary":"Back around the time we did SQL Bits, Rob Sewell spoke to Richard Campbell at RunAs Radio.\nThe show, Managing SQL Server using dbatools with Rob Sewell, is a fun and fantastic listen. Not only does Rob talk at length about the migration capabilities in dbatools, but also other cool things like CI/CD, containers and more. Check it out!","tags":["party"],"title":"Rob Sewell Talks About dbatools on RunAs Radio","type":"post","url":"https://dbatools.io/runasradio/"},{"categories":["announcements"],"content":"Happy Belated World Backup Day! I wish it was Backup and Restore Day, Test Your Backups Day, or World Recoverability Day, but alas.\nI\u0026rsquo;m currently working on my portion of the effort to get dbatools to 1.0 - integration tests for our commands. And while I wait for AppVeyor to run all of our tests, I\u0026rsquo;ve got a few minutes to post.\nInitially, I wanted to highlight our Backup/Restore commands but there are sooo many, it\u0026rsquo;d take a few days to write about them. So today, I\u0026rsquo;m going to focus on Export-DbaScript or I\u0026rsquo;ll never get this out the door 😊.\nExport-DbaScript Export-DbaScript exports SMO or \u0026ldquo;SQL Management Objects\u0026rdquo;. SMO is what powers SQL Server Management Studio and many of the commands in dbatools.\nYou know how SQL Server 2000\u0026rsquo;s underlying system tables vary drastically from SQL Server 2017? With SMO, we don\u0026rsquo;t have to care. $server.Databases is $server.Databases no matter which version we\u0026rsquo;re working with.\nSMO exports do have some limitations. For instance, it doesn\u0026rsquo;t include the roles and hashed passwords from logins (use Export-DbaLogin for that). For the most part, though, it\u0026rsquo;s awesome! This is how easy it is to export all of the jobs on all of your servers across your estate:\n$servers | Get-DbaAgentJob | Export-DbaScript\n$servers is a variable with the servers sql2008\\sql2k8, sql2012, sql2014, sql2016 and sql2017. You can specify a path but if you don\u0026rsquo;t, then we automatically generate the file name and output to the current directory.\nWant to see the output? Here are the contents of sql2017-Job-Export-04012018215831.sql.\nWhat Else? Basically, whatever you can script out in SSMS, you can script out using Export-DbaScript.\nYou can also add extra options using New-DbaScriptingOption, which is a wrapper for Microsoft.SqlServer.Management.Smo.ScriptingOptions.\n$options = New-DbaScriptingOption $options.ScriptDrops = $false $options.WithDependencies = $true Get-DbaDbTable -SqlInstance sql2017 -Database perfstore | Export-DbaScript -ScriptingOptionsObject $options If you\u0026rsquo;d like to script out each object to its own file, you can do the following:\nGet-DbaAgentJob -SqlInstance sql2017 | ForEach-Object { Export-DbaScript -InputObject $_ -Path \u0026#34;C:\\temp\\output\\sql2017-$($_.Name).sql\u0026#34; } Other Commands to Ease Your Recovery Process Here are nearly 80 commands that we created to ease recovery or migration.\nBackup-DbaDatabase Backup-DbaDbMasterKey Backup-DbaDbCertificate Copy-DbaAgentAlert Copy-DbaAgentJobCategory Copy-DbaAgentJob Copy-DbaAgentOperator Copy-DbaAgentProxy Copy-DbaAgentSchedule Copy-DbaBackupDevice Copy-DbaRegServer Copy-DbaCredential Copy-DbaCustomError Copy-DbaDatabase Copy-DbaDbAssembly Copy-DbaDbMail Copy-DbaEndpoint Copy-DbaXESession Copy-DbaLinkedServer Copy-DbaLogin Copy-DbaDbQueryStoreOption Copy-DbaResourceGovernor Copy-DbaInstanceAudit Copy-DbaInstanceAuditSpecification Copy-DbaInstanceTrigger Copy-DbaSpConfigure Copy-DbaDataCollector Copy-DbaPolicyManagement Copy-DbaAgentServer Copy-DbaSsisCatalog Copy-DbaSystemDbUserObject Copy-DbaDbTableData Copy-DbaXESessionTemplate Export-DbaAvailabilityGroup Export-DbaDacPackage Export-DbaDiagnosticQuery Export-DbaExecutionPlan Export-DbaLogin Export-DbaUser Export-DbaXECsv Export-DbaXESessionTemplate Find-DbaBackup Format-DbaBackupInformation Get-DbaBackupDevice Get-DbaDbBackupHistory Get-DbaBackupInformation Get-DbaDbSnapshot Get-DbaLastBackup Get-DbaDbLogShipError Get-DbaDbRestoreHistory Import-DbaCsv Import-DbaPfDataCollectorSetTemplate Import-DbaSpConfigure Import-DbaXESessionTemplate Invoke-DbaAdvancedRestore Invoke-DbaDbLogShipping Invoke-DbaDbLogShipRecovery Measure-DbaBackupThroughput New-DbaDbSnapshot New-DbaLogShippingPrimaryDatabase New-DbaLogShippingPrimarySecondary New-DbaLogShippingSecondaryDatabase New-DbaLogShippingSecondaryPrimary Publish-DbaDacPackage Read-DbaBackupHeader Remove-DbaBackup Remove-DbaDbSnapshot Restore-DbaBackupFromDirectory Restore-DbaDatabase Restore-DbaDbCertificate Restore-DbaFromDatabaseSnapshot Select-DbaBackupInformation Start-DbaMigration Test-DbaBackupInformation Test-DbaLastBackup Test-DbaDbLogShipStatus We ❤️ Tests I\u0026rsquo;ve mentioned it before, but there are few things that are more reassuring than knowing that our commands will restore your data properly. In the post a migration with every commit, you can see that we run a ton of tests with each and every commit to our GitHub repo.\nWhen tests pass, we can automatically merge to our master branch and the PowerShell Gallery (known as CI/CD or Continuous Integration/Continuous Delivery).\nSo check out this awesome video of all of the tests we run just for Restore-DbaDatabase.\nMost of our commands run far fewer tests, but few commands are as important as our backup and restore commands. Thanks to Stuart Moore for making Restore-DbaDatabase so robust!\n-Chrissy\n","date":"2018-04-02","summary":"Happy Belated World Backup Day! I wish it was Backup and Restore Day, Test Your Backups Day, or World Recoverability Day, but alas.\nI\u0026rsquo;m currently working on my portion of the effort to get dbatools to 1.0 - integration tests for our commands. And while I wait for AppVeyor to run all of our tests, I\u0026rsquo;ve got a few minutes to post.\nInitially, I wanted to highlight our Backup/Restore commands but there are sooo many, it\u0026rsquo;d take a few days to write about them.","tags":["party"],"title":"Happy Belated World Backup Day","type":"post","url":"https://dbatools.io/happy-belated-world-backup-day/"},{"categories":["announcements"],"content":"Nearly every time I inherit a SQL Server environment, I\u0026rsquo;m only given a partial list of SQL Servers that exist on the network. It\u0026rsquo;s my usual routine to get permission to sniff the network then run about five different programs including Idera\u0026rsquo;s SQL Discovery and Microsoft\u0026rsquo;s Assessment and Planning Toolkit.\nI always thought it\u0026rsquo;d be cool to have one comprehensive PowerShell command that could do the work of all the above and was ecstatic to see NetSPI\u0026rsquo;s Scott Sutherland had written a few commands to do just that in his awesome PowerShell module PowerUpSQL.\nFind-DbaInstance When I saw Scott\u0026rsquo;s multi-pronged approach (including some UDP magic 🎸), I asked if he\u0026rsquo;d be interested in contributing to dbatools and he said yes! He submitted a gorgeous mock-up and I was so excited. Then came the PR, complete with great documentation and multithreading.\nI asked our architect Fred Weinmann to perform a code review and he was so taken by the command, he refactored it with some C# magic including strong types. This command, which is available in 0.9.314, is a beauty!\nThe Basics This command searches for SQL Server Instances. It supports a variety of scans for this purpose which can be separated in two categories: Discovery and Scan.\nDiscoveryType This is where it compiles a list of computers / addresses to check. It supports any combination of:\nDomain Connects to Active Directory to look up all computers with registered SQL Instances. Not all instances need to be registered properly, so this is not 100% reliable. By default, your nearest Domain Controller is contacted for this scan, but you can specify its DistinguishedName and the -DomainController parameter for greater control. If credentials were specified using the -Credential parameter, those same credentials are used to perform this lookup, allowing the scan of other domains.\nDataSourceEnumeration This uses the default UDP Broadcast based instance enumeration used by SSMS to detect instances. Note that the result from this is not used in the actual scan, but only to compile a list of computers to scan. To enable the same results for the scan, ensure that the -Browser scan is enabled.\nIPRange This discovery uses a range of IPAddresses and simply passes them on to be tested. By default, it will enumerate all ethernet network adapters on the local computer and scan the entire subnet they are on. By using the -IpAddress parameter, custom network ranges can be specified. Check out the help for more information on range formats.\nScanType Once a list of computers has been provided, this command will execute a variety of actions to determine any instances present for each of them.\nDNSResolve Tries resolving the computername in DNS Ping Tries pinging the computer. Failure will NOT terminate scans. SQLService Tries listing all SQL Services using CIM/WMI This scan uses credentials specified in the -Credential parameter if any. This scan detects instances. Success in this scan guarantees high confidence (See parameter -MinimumConfidence for details). Browser Tries discovering all instances via the browser service This scan detects instances. TCPPort Tries connecting to the TCP Ports. By default, port 1433 is connected to. The parameter -TCPPort can be used to provide a list of port numbers to scan. This scan detects possible instances. Since other services might bind to a given port, this is not the most reliable test. This scan is also used to validate found SPNs if both scans are used in combination SqlConnect Tries to establish a SQL connection to the server Uses windows credentials by default Specify custom credentials using the -SqlCredential parameter This scan is not used by default Success in this scan guarantees high confidence (See parameter -MinimumConfidence for details). SPN Tries looking up the Service Principal Names for each instance Will use the nearest Domain Controller by default Target a specific domain controller using the -DomainController parameter If using the -DomainController parameter, use the -Credential parameter to specify the credentials used to connect Example Usage Here are just a few usage examples.\nUsing Active Directory Get-ADComputer -Filter { name -like 'sql*' } | Find-DbaInstance | Out-GridView\nScans all computers named like sql% in the domain for SQL Instances, using a deep probe:\nTries resolving the name in DNS Tries pinging the computer Tries listing all SQL Services using CIM/WMI Tries discovering all instances via the browser service Tries connecting to the default TCP Port (1433) Tries connecting to the TCP port of each discovered instance Tries to establish a SQL connection to the server using default windows credentials Tries looking up the Service Principal Names for each instance And for more detailed information, you can use Select * to expose all properties, including those hidden by default.\nGet-ADComputer -Filter { name -like 'sql*' } | Find-DbaInstance | Select *\nSPN and Auto-Discovery Find-DbaInstance -DiscoveryType Domain, DataSourceEnumeration\nPerforms a network search for SQL Instances by:\nLooking up the Service Principal Names of computers in active directory Using the UDP broadcast based auto-discovery of SSMS After that it will extensively scan all hosts thus discovered for instances Servers From File $params = @{ ScanType = \u0026#39;Browser\u0026#39;, \u0026#39;SqlConnect\u0026#39; Credential = Get-Credential ad\\winadmin SqlCredential = \u0026#39;ad\\sqladmin\u0026#39; } Get-Content .\\servers.txt | Find-DbaInstance @params Reads all servers from the servers.txt file (one server per line) Scans each of them for instances using the browser service using the ad\\winadmin account Attempts to connect to each instance found using the ad\\sqladmin account Do Everything Warning! This one takes a long time due to the IP scan. How long? About 2 hours on my single subnet lab.\nFind-DbaInstance -DiscoveryType All -ScanType All\nPerforms a network search for SQL Instances, using all discovery protocols and scan types:\nActive directory search for Service Principal Names SQL Instance Enumeration (same as SSMS does) All IPAddresses in the current computer\u0026rsquo;s subnets of all connected network interfaces Tries resolving the name in DNS Tries pinging the computer Tries listing all SQL Services using CIM/WMI Tries discovering all instances via the browser service Tries connecting to the default TCP Port (1433) Tries connecting to the TCP port of each discovered instance Tries to establish a SQL connection to the server using default windows credentials Tries looking up the Service Principal Names for each instance Want to know more? Check out Get-Help Find-DbaInstance -Detailed. This includes additional information and discusses parameters like -SqlCredential, -MinimumConfidence and more.\nThank you so very much for sharing your hard work, Scott! I\u0026rsquo;ve wanted a command like this for years. And thank you, Fred, for the time and love you invested into the dbatools refactor.\n- Chrissy\n","date":"2018-03-27","summary":"Nearly every time I inherit a SQL Server environment, I\u0026rsquo;m only given a partial list of SQL Servers that exist on the network. It\u0026rsquo;s my usual routine to get permission to sniff the network then run about five different programs including Idera\u0026rsquo;s SQL Discovery and Microsoft\u0026rsquo;s Assessment and Planning Toolkit.\nI always thought it\u0026rsquo;d be cool to have one comprehensive PowerShell command that could do the work of all the above and was ecstatic to see NetSPI\u0026rsquo;s Scott Sutherland had written a few commands to do just that in his awesome PowerShell module PowerUpSQL.","tags":["party"],"title":"A New Command to Find All of Your SQL Instances","type":"post","url":"https://dbatools.io/find-sql-instances/"},{"categories":["announcements"],"content":"I\u0026rsquo;ve been working on a project this year to upgrade SQL Server versions for around 80 application databases, with most of the upgrades requiring both SQL Server and Windows Server upgrades to get to the future state we were looking for. The general process for each of these was to build a new virtual machine with the upgraded operating system, install the desired SQL Server version and then migrate the application databases during an arranged downtime window.\nI\u0026rsquo;m going to focus on the final step of this process for this post - migrating the databases during the downtime windows. Luckily for me, dbatools made this both easy and repeatable.\nStep 1 - Check for Connections First step when we get into the downtime window is to check whether there are any active connections to the database you want to migrate. We don\u0026rsquo;t want any data being changed while we migrate, there\u0026rsquo;s a command for that:\nGet-DbaProcess -SqlInstance SourceServer -Database MigratingDatabase | Select Host, login, Program PowerShell PS C:\\Users\\Administrator\u003e Get-DbaProcess -SqlInstance localhost\\SQL2016 -Database ApplicationDatabase | \u003e\u003e Select Host, login, Program Host Login Program ---- ----- ------- SQLPOMF SQLPOMF\\Administrator Microsoft SQL Server Management Studio - Query If there are connections and it\u0026rsquo;s safe to remove them (if they are still coming from the application it might be worth talking to the app owners first) you can pipe them to another handy dbatools command:\nGet-DbaProcess -SqlInstance SourceServer -Database MigratingDatabase | Stop-DbaProcess Step 2 - Migrate the Database Now that there are no connections we can move the database. Depending on the situation it might be worth setting the database to read only or single user mode first. In my case, I had the application taken down so I felt confident no connections would be coming in.\nWith one line of code we can select the source and destination servers, the database name, specify that we want to use the backup and restore method, and then provide the path to a file share that both instance service accounts have access to:\nCopy-DbaDatabase -Source SourceServer -Destination DestinationServer -Database MigratingDatabase -BackupRestore -SharedPath \\fileshare\\ PowerShell PS C:\\Users\\Administrator\u003e Copy-DbaDatabase -Source localhost\\SQL2016 -Destination localhost\\SQL2017 ` \u003e\u003e -Database ApplicationDatabase -BackupRestore -NetworkShare \\SQLPomf\\Migration\\ Type Name Status Notes ---- ---- ------ ----- Database (BackupRestore) ApplicationDatabase Successful There are a lot more options available on this command, including setting the number of backup files to use, which can speed things up if you have a large database. I recommend checking out the command based help for all the available options.\nStep 3 - Migrate the User Logins Once the database is on the new server we can use the following to copy the associated logins across. The nice thing about using this command is it ensures the user SIDs match up on the destination and you don\u0026rsquo;t end up with any orphan SQL Logins.\nCopy-DbaLogin -Source SourceServer -Destination DestinationServer -Login AppReadOnly, AppReadWrite, DOMAIN\\AppUser PowerShell PS C:\\Users\\Administrator\u003e Copy-DbaLogin -Source localhost\\SQL2016 -Destination localhost\\SQL2017 ` \u003e\u003e -Login AppReadOnly, AppReadWrite Type Name Status Notes ---- ---- ------ ----- Login - SqlLogin AppReadOnly Successful Login - SqlLogin AppReadWrite Successful Step 4 - Set the Source Database Offline Now that the database and associated logins have been migrated we can set the source database offline. I did this so if there were any issues getting the application up we could quickly revert back while ensuring nothing was still accessing the old copy.\nSet-DbaDbState -SqlInstance SourceServer -Database MigratingDatabase -Offline -Force In the end I was able to use 5 lines of PowerShell to get these application databases migrated to their new homes. After some testing I dropped the old offline copy of the database and eventually decommissioned the old servers.\nI hope this gives you some ideas of how dbatools can help make your database migrations easier and more efficient.\nJess 🇨🇦\n","date":"2018-03-15","summary":"I\u0026rsquo;ve been working on a project this year to upgrade SQL Server versions for around 80 application databases, with most of the upgrades requiring both SQL Server and Windows Server upgrades to get to the future state we were looking for. The general process for each of these was to build a new virtual machine with the upgraded operating system, install the desired SQL Server version and then migrate the application databases during an arranged downtime window.","tags":["party"],"title":"Migrating Application Databases with dbatools","type":"post","url":"https://dbatools.io/migrating-application-dbs/"},{"categories":["announcements"],"content":"An Issue Defined In software development, an \u0026ldquo;issue\u0026rdquo; can be anything from you hit an error running an application or you get an unexpected result from an operation. You can also say an issue is a spelling error in our documentation. Our goal is to fix any \u0026ldquo;issue\u0026rdquo; whether it is a bug, an unexpected error (especially these) or considering a feature you think is missing from the module.\nHowever, before we can fix it…you have to let us know.\nWhere to Begin This is purely based on what type of an issue you need to submit, but all of them will start by going to our repository and filling out an issue on GitHub. You can do this in 4 easy steps:\nOpen your favorite browser, go to our GitHub issues shortlink dbatools.io/issues Click on the \u0026ldquo;Issues\u0026rdquo; tab of the repository Take a minute or two and search the current issues (helps us to keep duplicate count low; if you find a match give it a thumbs up.) If you do not find anything in the current issues, click on \u0026ldquo;new issue\u0026rdquo; button and fill out a new one. The remainder of this post is going to do a review of filling out a new issue. The more information you can provide helps our unpaid developers in getting a fix!\nBefore You Start Your New Issue Just like you submit a request to your own internal IT support, it helps to give as much information as you can up front when you submit an issue. Understand that this project is 100% community supported and we do this in our free time. If we get all the information up front, it is a huge time saver for us to fix the issue and return a resolution in a timely manner.\nFeature Request A feature that you want is to submit is basically: tell the story of what problem you are looking to solve. When you open a new issue we have a template setup. You can delete everything up to where you see the text ## Feature Request, below that, is where we need you to answer the question. Remember that even with a feature request the more details you can provide will help your cause in potentially getting the feature added.\nWhat Problem or Scenario Would You Like to Solve With dbatools? This is the primary question we need you to answer for the feature you desire. We provide some header sections but you can add/remove those if it helps to organize your thoughts. We are not asking for an essay mind you but think of it as if you were going down an elevator with one of us, you have about 2-3 minutes to verbally explain what you wanted. Obviously, you can provide more information and detail, but consider putting that conversation down as a synopsis so we know where you are coming from and such.\nBugs and Errors Bugs and errors are both a little different but in the area of submitting an issue, we will treat them the same for this post. While some errors may be expected we cannot really help you determine that unless you give us all the details. There are just some scenarios that you may find bugs and errors that we have not, or cannot account for due to limitations in our test lab(s). Every environment will be different and telling us about it all will aid in getting it fixed.\nA Few General Steps The top section of our issue template has 3 items that we ask you to verify, sometimes this can resolve your problem right off the bat…sometimes not.\nVerified Running the Latest Release of dbatools? We push a new release to our master branch and the PowerShell Gallery on average every 2-3 days (based on when Chrissy\u0026rsquo;s on vacation). A release, on average, will always contain bug and error fixes, so just doing an Update-Module dbatools and restarting your PowerShell session may resolve your issue.\nVerified Errors Are Not Related to Permissions? You would be surprised how often this can happen, so we have to ask. With the number of security issues, companies are having that affect their profits the whole least-privilege administration is more common nowadays. So if you know you are not sysadmin in SQL Server or local administrator if the command happens to touch the OS in some manner, it is a good thing to double-check before continuing.\nCan Duplicate in New/Clean PowerShell Session? Not all modules play nice with each other. We have found in particular that the sqlserver module can cause issues with our module loading properly. So if you happen to import modules prior to or after importing dbatools, it helps to identify that none of those modules are adversely affecting dbatools execution.\nVersion and Edition Information Just the basics. This information is pivotal when we get down to debugging bugs and errors, helps to ensure we have a similar setup in our lab(s) to more closely get root cause. As well, we may identify flavors of each that may not play well together (e.g. credential prompts when using CIM/WMI). In particular, if you happen to be working with the migration commands (Copy-Dba* commands) or moving an object in some other process, it can help to include the version information for your source and destination/target.\nSteps to Reproduce Reproducible issues are the best kind, they also tend to be the ones that are the easiest to fix (tend to be mind you).\nIn order to reproduce the problem, we will need you to provide the command you are executing. If you can provide the values you are passing into the command it will help, but if for security reasons you cannot provide it all try to give some example values. You may also need to obfuscate the output from your PowerShell session if you want to provide screenshots.\nCollecting Logs and Errors We have added two commands to the module that can help us more quickly determine the issue if you are able to provide them.\nGet-DbatoolsLog This command simply outputs the messaging that has been generated since you imported the module into your session. This is one reason why duplicating your issue in a new/fresh console can help. Reissue the command and let the error or bug occur again, then run this command and you will see all the output generated from the command. This output includes an internal command that may have been executed as well.\nNew-DbatoolsSupportPackage This command will generate a compressed file of collected information from the client machine, one you are using dbatools on. Think of this like you submit a support ticket to Microsoft support, they will have your run a few utilities on the offending machine to let it collect various logs and in-memory information. We do not capture as much as Microsoft, but information pertinent to the PowerShell session you have in use. I encourage you to run this and review the contents of that compressed file before attaching to an issue; ensure you are not violating any security policies.\nError Record This is a quick and dirty method and depends on the number of errors you may have encountered. PowerShell has a buffer or cache that errors from your PowerShell session are stored in. Checking this cache of errors right after you encounter an error will let you get the low down on what happened.\nIn order to see this you simply need to execute $error, that variable will contain the recent errors. To pull out the last error that happened you can run the following line:\n$error[0] | Select-Object * Closure Just to give some closure…The process that follows once you submit an issue will on average be:\nOne of the team will post the issue either verifying the information, providing some things to try, or confirming the issue. Once the issue is confirmed that a code change will be required, as time permits, a developer will take on getting the code fixed. You will see the issue closed either by the developer or once the change is committed to the master branch. Thanks for reading, Shawn 🇺🇸\n","date":"2018-03-14","summary":"An Issue Defined In software development, an \u0026ldquo;issue\u0026rdquo; can be anything from you hit an error running an application or you get an unexpected result from an operation. You can also say an issue is a spelling error in our documentation. Our goal is to fix any \u0026ldquo;issue\u0026rdquo; whether it is a bug, an unexpected error (especially these) or considering a feature you think is missing from the module.\nHowever, before we can fix it…you have to let us know.","tags":[],"title":"Submitting an Issue","type":"post","url":"https://dbatools.io/new-issue/"},{"categories":["announcements"],"content":"Nearly two years ago, I wrote that as a open source GPL-licensed project, dbatools was free as in speech and free as in beer.\nI chose the GNU GPL for nostalgic reasons and I also wanted companies who used dbatools to contribute back to the project. What I didn\u0026rsquo;t realize was that licensing dbatools as GPL would hurt integration which ultimately impacts adoption. Permissive licenses like the MIT do not subject users to such restrictions.\nMany of the tools we use on a daily basis, like VS Code and even .NET are MIT licensed, and MIT is the most popular license on GitHub.\nConsidering this and our lessons-learned from dbatools, we released dbachecks under the MIT license. The reception at SQL Bits was amazing. A number of comments were made expressing thanks and optimism about our selection of the MIT license.\nAnd, after speaking with a number of community members about the restrictive GPL license, it became clear that dbatools must also switch to MIT.\nAs of version 0.9.300, dbatools is now MIT licensed! If you would like to continue using the GPL version, please fork v0.9.211 and take it from there.\nIf your project appreciates this switch, please comment in the section below or email us to let us know!\n","date":"2018-03-05","summary":"Nearly two years ago, I wrote that as a open source GPL-licensed project, dbatools was free as in speech and free as in beer.\nI chose the GNU GPL for nostalgic reasons and I also wanted companies who used dbatools to contribute back to the project. What I didn\u0026rsquo;t realize was that licensing dbatools as GPL would hurt integration which ultimately impacts adoption. Permissive licenses like the MIT do not subject users to such restrictions.","tags":["mit","party"],"title":"dbatools is Now MIT Licensed!","type":"post","url":"https://dbatools.io/mit/"},{"categories":["announcements"],"content":"Gianluca Sartori and I recently presented Simplifying Extended Events with dbatools at SQL Bits and we had a lot of fun. Not only that, we helped convince several people to switch! Honestly, when we proposed the session, I was totally #TeamProfiler. I figured if PowerShell didn\u0026rsquo;t convince me, I would let people know where I stood, but I was open to switching teams.\nSlides | Code | Video\nSQLBits was awesome! The people, the events, the speaker shirt, the swag, the food, the everything. If you ever get a chance to go, I highly recommend it.\nSo Why Do People Keep Using Traces / Profiler? As you may know, Microsoft deprecated Profiler/traces 5 years ago in favor of Extended Events. Unlike traces, XEvents are lightweight and even offer more information about what\u0026rsquo;s going on within the engine.\nHow badly do traces impact performance? Jonathan Kehayias gives details in his article Measuring \u0026ldquo;Observer Overhead\u0026rdquo; of SQL Trace vs. Extended Events.\nSo why do people keep using traces? We compiled a list of reasons from Erin Stellato\u0026rsquo;s Why do YOU avoid Extended Events. And this list is LONG!\nTraces are straightforward and less complex than Extended Events Totally seems that way!\nTraces provide a consistent interface for mixed environments Whether you use SQL Server 7 or SQL Server 2017, the interface is pretty much the same.\nTraces are faster to setup quick traces Just open up Profiler, connect to a server, click a few times and you\u0026rsquo;re set.\n\u0026ldquo;Extended Events are more efficient for the SQL Server engine, but not more efficient for the DBA\u0026rdquo; Love this quote.\nPeople already have a library of Profiler templates Including me\nIgnorance of XML / Querying all the generated XML is outrageous When I first saw what it takes to query Extended Events, I bailed immediately. I am not learning XPATH, ever.\nTemplates work remotely across all instances This is also true for Extended Events, but the commenter did not know that.\nXEvents are persistent and must be stopped manually Once you close Profiler or restart SQL Server, all non-default traces will disappear. Extended Events will persist until you delete them.\nAbility to import PerfMon data and look at Trace and PerfMon counter data at the same time Most people that use Profiler don\u0026rsquo;t seem to know about this feature but those who do LOVE it. You can read more at Brad McGehee\u0026rsquo;s Correlating SQL Server Profiler with Performance Monitor.\nMicrosoft reportedly has no plans to provide this functionality.\nConsistent user experience across SSAS and Database Engine Gotta take their word, I don\u0026rsquo;t use SSAS.\nIt\u0026rsquo;s easy to train others to use Profiler Imagine - if it\u0026rsquo;s easier to learn Profiler, it\u0026rsquo;ll be far easier to teach.\nTraces can be easily replayed There are a number of Microsoft tools to replay traces, but none to replay Extended Events.\nMS Premier Support still asks for traces Likely because they also have tools that they want to work across all supported versions, which still includes SQL Server 2008 R2.\nxe_file_target_read_file is a CPU hog This wasn\u0026rsquo;t listed on Erin\u0026rsquo;s page but was told to me while I was performing my research.\nWhewf! That\u0026rsquo;s a lot of compelling reasons not to make the switch. So let\u0026rsquo;s see how we can address each of them using PowerShell. All code listed here can be found at sqlps.io/xecode.\nPowerShell/dbatools Can Help First, I\u0026rsquo;ll start with the bad news. There were a few things we couldn\u0026rsquo;t address.\n# Complaint: Consistent interface for mixed environments # Answer: CLOSED, WON\u0026#39;T FIX # Complaint: MS Premier Support still asks for traces # Answer: CLOSED, WON\u0026#39;T FIX # Complaint: Consistent user experience across SSAS and Database Engine # Answer: Need more information But now for those we could!\nExisting Library of Profiler Templates No problem! We took Jonathan Kehayias\u0026rsquo;s awesome sp_SQLskills_ConvertTraceToExtendedEvents script, wrapped it in PowerShell and made it easy to convert all of your traces on all of your servers to Extended Events.\n# Complaint: Already have a library of Profiler templates # Answer: Convert them instantly to Sessions (h/t Jonathan Kehayias) Get-DbaTrace -SqlInstance localhost\\sql2017 -Id 1 | ConvertTo-DbaXESession -Name \u0026#39;Default Trace\u0026#39; | Start-DbaXESession # Go look in SSMS! :D # Stop or remove those bad boys Get-DbaTrace -SqlInstance localhost\\sql2017 -Id 2 | Stop-DbaTrace Get-DbaTrace -SqlInstance localhost, localhost\\sql2016, localhost\\sql2017 | Out-GridView -PassThru | Remove-DbaTrace It\u0026rsquo;s Faster to Setup Quick Traces To setup a trace in Profiler, you connect to a single server, click, click, click and you\u0026rsquo;re set.\nNow, it\u0026rsquo;s even easier to setup a \u0026ldquo;quick session\u0026rdquo; in Extended Events. Just select an included template from dbatools and import!\n# Complaint: Faster to setup quick traces # Complaint: Templates work remotely across all instances # Answer: Now you can easily deploy all of your session templates SUCH AS LONG RUNNING QUERIES $servers = \u0026#34;localhost\\sql2016\u0026#34;,\u0026#34;localhost\\sql2017\u0026#34; Get-DbaXESessionTemplate | Out-GridView -PassThru | Import-DbaXESessionTemplate -SqlInstance $servers \u0026lt;# No suitable template? Use SSMS to create New Sessions #\u0026gt; # now redeploy existing sessions across your whole enterprise Get-DbaXESession -SqlInstance localhost\\sql2017 -Session \u0026#39;Acme Sample\u0026#39; | Export-DbaXESessionTemplate | Import-DbaXESessionTemplate -SqlInstance localhost\\sql2016 Start-Process \u0026#34;$home\\Documents\\SQL Server Management Studio\\Templates\\XEventTemplates\u0026#34; Note that while we do enable the ability to easily export/import your own newly created XEvent, we currently don\u0026rsquo;t have a nice and easy way to create XEvents. If you\u0026rsquo;d like to contribute your own template, please do feel free!\nUnlike Traces, Extended Event Sessions Persist It\u0026rsquo;s true, they do! And this annoyed me at first too, but now I appreciate it. One reason is that XEvents are so hard to manage. You gotta go server by server, click Management -\u0026gt; Extended Events -\u0026gt; Sessions.\nIt took time for me to come around, though. And I want to give you that time too. So here\u0026rsquo;s our solution.\n# Complaint: XEvents are persistent # Answer: Actually a good thing, especially if they are managable. But, you can discover that for yourself. Until then... \u0026#34;localhost\u0026#34;, $servers | Get-DbaXESession | Out-GridView -PassThru | Remove-DbaXESession # But that\u0026#39;s not all! Get-Command -Module dbatools -Name *DbaXe* | Out-GridView Ultimately, when it\u0026rsquo;s hard to manage Extended Events, you don\u0026rsquo;t want many of them around. But look at how easy it is to get a listing of my lab\u0026rsquo;s XEvent Sessions. You can pipe any of these to remove, stop, start or export them.\nRemembering to Stop a Session Within Profiler, it\u0026rsquo;s easy to set a time to stop a trace. But traces don\u0026rsquo;t support this functionality out of the box - Profiler does. If you need to stop a session after a set amount of time, we can help!\n# Complaint: Remembering to turn off Xevent # Answer: PowerShell can help in 3 ways # Answer: Auto create a disappearing Agent job Start-DbaXESession -SqlInstance localhost\\sql2017 -Session \u0026#39;Long Running Queries\u0026#39; -StopAt (Get-Date).AddMinutes(30) # Answer: Use dbachecks Set-DbcConfig -Name policy.xevent.requiredstoppedsession -Value \u0026#39;Long Running Queries\u0026#39; # Imagine a scheduled run Invoke-DbcCheck -SqlInstance localhost\\sql2017 -Check XESessionStopped # Sessions can be easily stopped (or started) en masse $servers | Get-DbaXESession | Out-GridView -PassThru | Stop-DbaXESession Extended Events Requires Knowledge of XML and XPATH to Query I know - I was horrified when I saw a sample XEvent Query. But now with SQL Server Management Studio 17.x and dbatools, it\u0026rsquo;s way easier to see and filter the results of XEvents.\nThe limitation with SSMS is that you work with just one server at a time. The benefit is that it\u0026rsquo;s quick, easy and filterable.\nThe good thing about dbatools is that you can get the same benefits with more than one server. This is especially good for total instance aggregation. And like plain-ol T-SQL, PowerShell is human readable.\n# Complaint: Don\u0026#39;t know XML and XPATH, which are required to query the results # Answer: Now you can easily use PowerShell syntax - also works with Watch-DbaXESession # This will read ALL FILES from ALL SESSIONS if they exist Get-DbaXESession -SqlInstance localhost\\sql2017 | Read-DbaXEFile | Where-Object client_app_name -eq \u0026#39;dbatools PowerShell module - dbatools.io\u0026#39; | Out-GridView And here\u0026rsquo;s the human-readable output\nExtended Events Are a Lot of Work PowerShell enables laziness, or as I prefer calling it, \u0026ldquo;efficiency\u0026rdquo; But heck, PowerShell MVP Francois-Xavier Cat even calls himself lazywinadmin. So if you\u0026rsquo;re lazy, we\u0026rsquo;ve got you.\n# Complaint: I\u0026#39;m lazy and XEs are a lot of work # Answer: Can\u0026#39;t get any lazier than using PowerShell Get-ChildItem C:\\corpxetemplates | Import-DbaXESessionTemplate -SqlInstance $servers Can\u0026rsquo;t Replay Extended Events Profiler offers a number of ways to replay data. We offer two solutions, including a preview version of Gianluca\u0026rsquo;s XESmartTarget Replay.\nUpdate (2025): The XESmartTarget commands (New-DbaXESmartReplay, Start-DbaXESmartTarget, New-DbaXESmartEmail) mentioned in this section were removed from dbatools in August 2025 due to dependency maintenance challenges. The Invoke-DbaXEReplay command shown below remains available. For advanced Extended Events streaming and response capabilities, consider using XESmartTarget directly.\n# Complaint: Can\u0026#39;t replay events from Session # Answer: You can now read and execute from a xel file Get-ChildItem small-sample.xel | Read-DbaXEFile | Invoke-DbaXEReplay -SqlInstance localhost\\sql2017 Email Notification Bonus (Legacy) The XESmartTarget integration within dbatools previously offered email notifications when events occurred. While these commands have been removed from dbatools, you can still use the standalone XESmartTarget tool for this functionality.\nProfiler Offers the Ability to Compare PerfMon and Trace So Microsoft does not offer this ability and according to Erin Stellato\u0026rsquo;s session at Bits, they don\u0026rsquo;t plan to. When attempting to provide a solution for this, I immediately thought of putting it in Power BI and making it beautiful. Because Profiler\u0026rsquo;s version ain\u0026rsquo;t pretty\nSo then my question was: how can we make XEvents accessible to Power BI?\nXevents to CSV or SQL Table Perfmon to CSV or SQL Table Mash them together Here\u0026rsquo;s what we came up with:\nUpdate (2025): The Export-DbaXECsv command mentioned below was removed from dbatools in August 2025. You can export Extended Events data using Read-DbaXEFile and standard PowerShell export cmdlets like Export-Csv, or write directly to a database table using Write-DbaDbTableData.\n# Perfmon commands still work great! Get-DbaPfDataCollectorSetTemplate | Out-GridView -PassThru | Import-DbaPfDataCollectorSetTemplate | Start-DbaPfDataCollectorSet # Export perfmon to CSV for Power BI Get-DbaPfDataCollectorSet -CollectorSet \u0026#39;PAL - SQL Server 2014 and Up\u0026#39; | Invoke-DbaPfRelog | Select -Expand FullName | Invoke-Item # Export Extended Events to database for analysis Get-DbaXESession -SqlInstance localhost\\sql2017 -Session \u0026#39;Queries and Resources\u0026#39; | Read-DbaXEFile | Write-DbaDbTableData -SqlInstance localhost\\sql2016 -Table tempdb.dbo.queriesandresources -AutoCreateTable And from the Perfmon, we created a universal dashboard:\nBut! It still needs some work. At SQLBits, we asked for Power BI pros to help us with performance and mashing this data and the eternally awesome Johan Ludvig Brattås volunteered I cannot wait to see what Johan comes up with with the Power BI dashboard.\nAlso, I\u0026rsquo;m planning to write more in-depth about the Performance Monitor commands so expect more about that soon.\nReading Using xe_file_target_read_file Taxes the SQL Server CPU Now you can offload that resource usage to your local workstation. Behind the scenes, we use Microsoft\u0026rsquo;s streaming API, similar to the one, I assume, used in SSMS.\n# Complaint: Reading using xe_file_target_read_file taxes the SQL Server CPU # Answer: Now you can read files from any workstation or server Get-ChildItem small-sample.xel | Read-DbaXEFile Get-DbaXESession -SqlInstance localhost\\sql2017 -Session \u0026#39;Deadlock Graphs\u0026#39; | Read-DbaXEFile # Or, again, you can read locally and export to remote table Get-DbaXESession -SqlInstance localhost\\sql2017 -Session \u0026#39;Deadlock Graphs\u0026#39; | Read-DbaXEFile | Write-DbaDbTableData -SqlInstance localhost\\sql2016 -Table tempdb.dbo.profiler -AutoCreateTable In Conclusion Hope this article has convinced you to switch from #TeamProfiler! PowerShell sure convinced me\n- Chrissy\n","date":"2018-02-26","summary":"Gianluca Sartori and I recently presented Simplifying Extended Events with dbatools at SQL Bits and we had a lot of fun. Not only that, we helped convince several people to switch! Honestly, when we proposed the session, I was totally #TeamProfiler. I figured if PowerShell didn\u0026rsquo;t convince me, I would let people know where I stood, but I was open to switching teams.\nSlides | Code | Video\nSQLBits was awesome!","tags":["party"],"title":"Simplifying Extended Events Management with dbatools","type":"post","url":"https://dbatools.io/xevents/"},{"categories":["announcements"],"content":"dbachecks is a new PowerShell module from the SQL Server Community! For more information, read introducing dbachecks.\nAs of version v1.0, dbachecks contains 15 commands. This article provides an overview of these commands. Rob Sewell offers a fantastic deep-dive article that explains the commands below in greater depth.\nUsage Usage can be approached in two ways:\nRun Directly From the Command Line As simple as Invoke-DbcCheck -SqlInstance sqlprod01 -Checks SuspectPage, LastBackup\nSchedule Checks Command line execution is good in a pinch, but ongoing checks are the ultimate goal. In order to do this, you can do the following:\nSet your desired configuration Configs can be set for specific environments like Production, Test or Development or for an application, like SharePoint or a custom-built app\nExport your configuration Export your environment or application configuration so that it can be easily imported by your scheduled task\nSchedule checks using Task Scheduler or SQL Server Agent I personally prefer SQL Server Agent\nGet notified via email or load up in Power BI Since the output of Invoke-DbcCheck is a PowerShell object, you can extend responses and notifications any way you wish. We provide two built-in ways.\nWhichever approach you use, the commands below will help you easily accomplish validation of your environment.\nPrimary Commands Invoke-DbcCheck All checks are performed using Invoke-DbcCheck. This command is basically a wrapper for Invoke-Pester. This means that supported Invoke-Pester parameters work against Invoke-DbcCheck, plus a few bonus parameters.\nIn this module, a \u0026ldquo;Check\u0026rdquo; is synonymous with a \u0026ldquo;Tag\u0026rdquo; in Pester. So you can Invoke-DbcCheck and specify a Check that you want to run. You can see a list of the available Checks with Get-DbcCheck.\nWe also made it convenient to run groups of checks. So LastBackup will run LastFullBackup, LastDiffBackup and LastLogBackup.\nGet-DbcCheck This command lists all checks, check groups along with their required server type, either SqlInstance or ComputerName.\nPowerShell PS C:\\github\\dbatools\u003e Get-DbcCheck Type Description AllTags ---- ----------- ------- SqlInstance Ad Agent Account Agent,agent-account SqlInstance Ad Agent Account Agent,agent-account SqlInstance Backup Compression Check Backup,BackupCompression SqlInstance Backup Destination Backup,BackupDestination SqlInstance Backup Encryption Backup,BackupEncryption SqlInstance Backup Network Backup,BackupNetwork SqlInstance Backup Redundancy Backup,BackupRedundancy SqlInstance Backup Test Backup,BackupTest SqlInstance Backup Times Backup,BackupTimes SqlInstance Certificate Expiration CertificateExpiration SqlInstance Cluster Node Paused ClusterNodePaused SqlInstance Command Log Volume CommandLogVolume SqlInstance Database Growth Event DatabaseGrowthEvent SqlInstance Dump Files DumpFiles SqlInstance Error Log Count ErrorLogCount SqlInstance Error Log Size Check ErrorLogSizeCheck SqlInstance File Growth Type Check FileGrowthTypeCheck SqlInstance Last Backup Times LastBackup,LastFullBackup,LastDiffBackup,LastLogBackup SqlInstance Log Shipping Disabled LogShippingDisabled SqlInstance Orphaned User OrphanedUser SqlInstance Recovery Model RecoveryModel SqlInstance Replication Latency ReplicationLatency SqlInstance SQL Server Database Mail DatabaseMail SqlInstance SSL/TLS Certificate Expiration SSLCertificateExpiration SqlInstance Suspended Service Broker Queue SuspendedServiceBrokerQueue SqlInstance Temp DB Configuration TempDbConfiguration SqlInstance Test Last Backup Latency LastBackupLatency SqlInstance Traceflag Recommended Global Traceflag Check GlobalTraceFlag SqlInstance Windows Event Log WindowsEventLog SqlInstance Failed Logins Cluster Members FailedLogins,ClusterMembers ComputerName Ping Computer PingComputer ComputerName Windows Update Status WindowsUpdate Set-DbcConfig dbachecks comes with its own configuration system! This allows you to set values that are required for your environments. We set reasonable defaults, but your requirements may vary, especially between production and test/dev.\nWhat are reasonable defaults? Well for instance, out of the box, dbachecks tests to ensure that log backups have been taken within the last 15 minutes. You may want this to be 60 minutes instead. To set this new value, run the following:\nSet-DbcConfig -Name policy.backup.logmaxminutes -Value 60\nPowerShell PS C:\\github\\dbatools\u003e Set-DbcConfig -Name policy.backup.logmaxminutes -Value 60 Name Value Description ---- ----- ----------- policy.backup.logmaxminutes 60 Maximum number of minutes before Log Backups are considered outdated Get-DbcConfig Retrieves dbachecks configuration elements. You can run this command with or without a search pattern.\nPowerShell PS C:\\github\\dbatools\u003e Get-DbcConfig \"backup\" Name Value Description ---- ----- ----------- policy.backup.datapath [empty] Destination server data directory, should be enabled true or disabled policy.backup.enforcedefaultpath True Default backup compression check should be enabled true or disabled policy.backup.fullmaxdays 7 Maximum number of days before Full Backups are considered outdated policy.backup.diffmaxhours 24 Maximum number of hours before Diff Backups are considered outdated policy.backup.logmaxminutes 15 Maximum number of minutes before Log Backups are considered outdated policy.backup.newdbgraceperiod 1 The number of hours a newly created database is allowed to not have had a backup for policy.backup.lastrestorationdate [empty] The minimum amount of time a database should have been restored for a table policy.backup.recognizablerecoveryblocksizedir True Enable DBA Checks: The checks that should be flagged to ensure that CYE is not disabled policy.backup.backupuncpath [empty] Backup UNC Path Piping Get-DbcConfig to Out-GridView will help make the results even more searchable.\nGet-DbcConfig piped to Out-GridView PS C:\\github\\dbatools\u003e Get-DbcConfig | Out-GridView [Grid View Window showing configuration options] agent.databasemailprofile Name of the Database Mail Profile in SQL Agent agent.dbaoperatorname Email address of the DBA Operator in SQL Agent agent.dbaoperatorname Name of the DBA Operator in SQL Agent app.checkrepos C:\\github\\dbatools\\checks app.localdbachecks List of Windows Servers that Windows tests will run against app.maildirectory Persisted files live here app.maildirectory For mail size store here app.sqlcredential The universal SQL credential if Trusted/Windows Authentication is not used app.sqlinstance Invoke-DbcCheck: The checks that should be configured per instance command-includedpath [0] domain-domaincontroller The domain controller to process your requests domain-organizationalunit The OU that your server is part of domain.domaincontroller The Active Directory domain that your server is part of mail.failurethreshold [0] mail.faildirectorythreshold Number of errors that must be present in an email report mail.fromsender Email address the email reports should come from mail.smtpender Store the name of the smtp server to send mail records mail.subject dbachecks results mail.to Destination server directory policy-backup-datapath [hidden] Export-DbcConfig Exports dbachecks configs to a json file to make it easier to modify or be used for specific configurations.\nRob\u0026rsquo;s deep-dive article mentioned above provides awesome insight as to how you can make the most of our Export/Import commands.\nImport-DbcConfig Imports dbachecks configs from a json file. The basic idea is that you set your configs, export them, then import them and run on a regular basis.\nSend-DbcMailMessage Converts Pester results and emails results formatted using ReportUnit. Basically wraps the Send-MailMessage cmdlet which sends an e-mail message from within Windows PowerShell.\nUpdate-DbcPowerBiDataSource Converts Pester results and exports file in the required format for launching the Power BI command. You will need to refresh the Power BI dashboard every time to see the new results. Basically, behind the hood it is running this:\nInvoke-DbcCheck | ConvertTo-Json -Depth 3 | Out-File \u0026quot;$env:windir\\temp\\dbachecks.json\u0026quot;\nSupports alternative paths.\nStart-DbcPowerBi Launches the included Power BI dashboard. You will need to refresh the Power BI dashboard every time to see the new results.\nStart-DbcPowerBi also supports alternative paths, in the event, you specify a new path using Start-DbcPowerBi.\nSupporting Commands Clear-DbcPowerBiDataSource Clears the data source directory created by Update-DbcPowerBiDataSource (\u0026ldquo;C:\\windows\\temp\\dbachecks*.json\u0026rdquo; by default). This command makes it easier to clean up data used by PowerBI via Start-DbcPowerBi.\nGet-DbcConfigValue Retrieves raw configuration values by name. Can be used to search the existing configuration list.\nGet-DbcTagCollection Retrieves a list of all available tags. Simplistic, similar to Get-Verb.\nInvoke-DbcConfigFile Opens the default location of the json config file for easy edits. Follow with Import-DbcConfig to import changes.\nSave-DbcRequiredModules Saves all required modules, including dbachecks, dbatools, Pester and PSFramework to a directory. Ideal for offline installs.\nUpdate-DbcRequiredModules Updates all required modules, including dbachecks.\nThis command reference will continue to be updated as we add more commands. The shortlink is dbachecks.io/commands.\n- Chrissy\n","date":"2018-02-22","summary":"dbachecks is a new PowerShell module from the SQL Server Community! For more information, read introducing dbachecks.\nAs of version v1.0, dbachecks contains 15 commands. This article provides an overview of these commands. Rob Sewell offers a fantastic deep-dive article that explains the commands below in greater depth.\nUsage Usage can be approached in two ways:\nRun Directly From the Command Line As simple as Invoke-DbcCheck -SqlInstance sqlprod01 -Checks SuspectPage, LastBackup","tags":["dbachecks","party"],"title":"dbachecks Commands","type":"post","url":"https://dbatools.io/dbachecks-commands/"},{"categories":["announcements"],"content":"In mid-December, we began working on a new PowerShell module for the SQL Server Community. This free and open-source project can be found in the SQL Server Community Collaborative\u0026rsquo;s repository. Contributions from the community are welcomed and encouraged!\nIntro dbachecks is a framework created by and for SQL Server pros who need to validate their environments. Basically, we all share similar checklists and mostly just the server names and RPO/RTO/etc change.\nThis module allows us to crowdsource our checklists using Pester tests. Such checks include:\nBackups are being performed Identity columns are not about to max out Servers have access to backup paths Database integrity checks are being performed and corruption does not exist Disk space is not about to run out All enabled jobs have succeeded Network latency does not exceed a specified threshold We currently provide over 80 checks, as can be easily seen using Get-DbcCheck:\nPowerShell PS C:\\github\\dbachecks\u003e Get-DbcCheck Group Type Description UniqueTag AllTags ----- ---- ----------- --------- ------- Agent SqlInstance SQL Agent Account AgentServiceAccount AgentServiceAccount, ServiceAccount, Agent Agent SqlInstance DBA Operators DbaOperatorName DbaOperatorName, Operator, Agent Agent SqlInstance Failed Jobs FailedJob FailedJob, Agent Agent SqlInstance Valid Job Owner ValidJobOwner ValidJobOwner, Agent Agent SqlInstance Agent Alerts AgentAlert AgentAlert, Agent Agent SqlInstance Long Running Jobs LongRunningJob LongRunningJob, Agent Agent SqlInstance Last Job Run Time LastJobRunTime LastJobRunTime, Agent Backup Database Last Diff Backup Times LastDiffBackup LastDiffBackup, Backup, DISA, Database Backup Database Last Full Backup Times LastFullBackup LastFullBackup, Backup, DISA, Database Backup Database Last Log Backup Times LastLogBackup LastLogBackup, Backup, DISA, Database Backup Database Valid Backup Path ValidBackupPath ValidBackupPath, Backup, Database Backup Database Backup Compression BackupCompression BackupCompression, Backup, Database Backup Database Test Last Backup TestLastBackup TestLastBackup, Backup, Database Backup Database Recovery Model RecoveryModel RecoveryModel, Backup, DISA, Database Compliance Database Database Growth Event DatabaseGrowthEvent DatabaseGrowthEvent, Database Compliance Database Page Verify PageVerify PageVerify, Database Compliance SqlInstance Compatibility Level CompatibilityLevel CompatibilityLevel, Database Compliance SqlInstance Guest User has Connect Permission GuestUserConnect GuestUserConnect, Database Compliance SqlInstance Contained DB Orphaned Users ContainedDBOrphanedUser ContainedDBOrphanedUser, Database Compliance SqlInstance Auto Close AutoClose AutoClose, Database Compliance SqlInstance Auto Shrink AutoShrink AutoShrink, Database Compliance SqlInstance Last Good CheckDB LastGoodCheckDB LastGoodCheckDB, DISA, Database Compliance Database Audit Statistics Asynchrony AutoUpdateStatisticsAsynchronously AutoUpdateStatisticsAsynchronously, Database Compliance Database Audit Statistics AutoUpdateStatistics AutoUpdateStatistics, Database Compliance Database Database Collation DatabaseCollation DatabaseCollation, Database Compliance SqlInstance Suspect Pages SuspectPage SuspectPage, Corruption, Integrity, Database Compliance Database Pseudo Simple Recovery Model PseudoSimple PseudoSimple, Database Compliance SqlInstance Max DOP MaxDOP MaxDOP, Database Compliance SqlInstance Orphaned File OrphanedFile OrphanedFile, Database Compliance SqlInstance Failed Jobs FailedJob FailedJob, Agent Compliance SqlInstance Duplicate Index DuplicateIndex DuplicateIndex, Database Compliance SqlInstance Unused Index UnusedIndex UnusedIndex, Database Compliance SqlInstance Disabled Index DisabledIndex DisabledIndex, Database ComputerName ComputerName Server Health ServerHealth ServerHealth, DISA, Instance ComputerName ComputerName Server Power Plan ServerPowerPlan ServerPowerPlan, DISA, Instance ComputerName ComputerName Server Disk Configuration ServerDiskConfiguration ServerDiskConfiguration, DISA, Instance Compression Database Compressible Tables CompressibleTables CompressibleTables, Database Database SqlInstance Database Growth Event DatabaseGrowthEvent DatabaseGrowthEvent, Database Database SqlInstance Database Collation DatabaseCollation DatabaseCollation, Database Database SqlInstance Suspect Pages SuspectPage SuspectPage, Corruption, Integrity, Database Database SqlInstance Last Good CheckDB LastGoodCheckDB LastGoodCheckDB, DISA, Database Database SqlInstance Valid Database Owner ValidDatabaseOwner ValidDatabaseOwner, Database Database SqlInstance Invalid Database Owner InvalidDatabaseOwner InvalidDatabaseOwner, Database Database Database Auto Close AutoClose AutoClose, Database Database Database Auto Shrink AutoShrink AutoShrink, Database Database Database Last Full Backup Times LastFullBackup LastFullBackup, Backup, DISA, Database Database Database Last Diff Backup Times LastDiffBackup LastDiffBackup, Backup, DISA, Database Database Database Last Log Backup Times LastLogBackup LastLogBackup, Backup, DISA, Database Database Database Virtual Log Files VirtualLogFile VirtualLogFile, Database Database Database Log File Count LogFileCount LogFileCount, Database Database Database Log File Size LogFileSize LogFileSize, Database Database Database Duplicate Index DuplicateIndex DuplicateIndex, Database Database Database Unused Index UnusedIndex UnusedIndex, Database Database Database Disabled Index DisabledIndex DisabledIndex, Database Database Database Database Compatibility Level CompatibilityLevel CompatibilityLevel, Database Database Database Foreign Keys and Check Constraints FKCKTrusted FKCKTrusted, Database Database Database Maximum VLF MaximumVLF MaximumVLF, Database Domain ComputerName Domain Name DomainName DomainName, Domain Domain ComputerName Organization Unit OrganizationUnit OrganizationUnit, Domain Instance SqlInstance SQL Memory Max MaxMemory MaxMemory, DISA, Instance Instance SqlInstance SQL Memory Min MinMemory MinMemory, Instance Instance SqlInstance SQL Windows Admin Members SqlWindowsAdminMembers SqlWindowsAdminMembers, Instance Instance SqlInstance TempDB Size TempDBSize TempDBSize, DISA, Instance Instance SqlInstance SQL AdHocWorkload AdHocWorkload AdHocWorkload, Instance LogShipping Database Log Shipping Primary LogShippingPrimary LogShippingPrimary, LogShipping, Database, DISA LogShipping Database Log Shipping Secondary LogShippingSecondary LogShippingSecondary, LogShipping, Database, DISA MaintenanceSolution Database Ola Installed OlaInstalled OlaInstalled, Database MaintenanceSolution Database Ola System Full Backup SystemFullBackup SystemFullBackup, Backup, Database MaintenanceSolution Database Ola User Full Backup UserFullBackup UserFullBackup, Backup, Database MaintenanceSolution Database Ola User Diff Backup UserDiffBackup UserDiffBackup, Backup, Database MaintenanceSolution Database Ola User Log Backup UserLogBackup UserLogBackup, Backup, Database MaintenanceSolution Database Ola CommandLog Cleanup CommandLogCleanup CommandLogCleanup, Database MaintenanceSolution Database Ola System Integrity Check SystemIntegrityCheck SystemIntegrityCheck, DBCC, Corruption, Integrity, Database MaintenanceSolution Database Ola User Integrity Check UserIntegrityCheck UserIntegrityCheck, DBCC, Corruption, Integrity, Database MaintenanceSolution Database Ola User Index Optimize UserIndexOptimize UserIndexOptimize, Database MaintenanceSolution Database Ola Output File Cleanup OutputFileCleanup OutputFileCleanup, Database MaintenanceSolution Database Ola Delete Backup History DeleteBackupHistory DeleteBackupHistory, Database MaintenanceSolution Database Ola Purge Job History PurgeJobHistory PurgeJobHistory, Database Network SqlInstance Network Latency NetworkLatency NetworkLatency, Connectivity, Instance Network SqlInstance Linked Server Connection LinkedServerConnection LinkedServerConnection, Connectivity, Instance Server ComputerName Ping Computer PingComputer PingComputer, ComputerName Server ComputerName CPU Priority CPUPriority CPUPriority, ComputerName Server ComputerName Disk Capacity DiskCapacity DiskCapacity, DISA, ComputerName Server SqlInstance Disk Allocation Unit DiskAllocationUnit DiskAllocationUnit, ComputerName Server SqlInstance Power Plan PowerPlan PowerPlan, ComputerName Server SqlInstance SPN SPN SPN, Instance Server SqlInstance Disk Max Transfer DiskMaxTransfer DiskMaxTransfer, ComputerName Server SqlInstance Server Hardware ServerHardware ServerHardware, ComputerName Server SqlInstance Server Memory ServerMemory ServerMemory, ComputerName Server SqlInstance Dedicated Admin Connection DedicatedAdminConnection DedicatedAdminConnection, Instance Server SqlInstance SQL + Windows names match ServerNameMatch ServerNameMatch, Instance How to Use Usage can be approached in two ways:\nRun Directly From the Command Line As simple as Invoke-DbcCheck -SqlInstance sqlprod01 -Checks SuspectPage, LastBackup\nSchedule Checks Command line execution is good in a pinch, but ongoing checks are the ultimate goal. In order do this, you can do the following:\nSet your desired configuration Configs can be set for specific environments like Production, Test or Development or for an application, like SharePoint or a custom-built app Export your configuration Export your environment or application configuration so that it can be easily imported by your scheduled task Schedule checks using Task Scheduler or SQL Server Agent I personally prefer Agent Get notified via email or load up in Power BI Check out our commands post page for more information.\nPower BI Is Awesome dbachecks also includes a built-in Power BI dashboard and it\u0026rsquo;s gorgeous.\nWhaaaaaat! Thanks to Cláudio Silva and Rob Sewell for that work of art. And thanks to Rob for making a sample dashboard available online.\nInstall To learn more about prerequisites and installation, please visit installing dbachecks.\nDevelopment Have questions about development? Please visit our creating tests for dbachecks.\nWebsite Unlike dbatools, there is no dedicated website for dbachecks at this time. The domain dbachecks.io does exist, however, and will be used for shortlinks \u0026lt;3.\ndbachecks.io dbachecks.io/install dbachecks.io/blog dbachecks.io/git dbachecks.io/youtube dbachecks.io/slack dbachecks.io/issues dbachecks.io/contributors dbachecks.io/git dbachecks.io/gallery License dbachecks is MIT licensed\nThe MIT license is a short and simple permissive license with conditions only requiring preservation of copyright and license notices. Licensed works, modifications, and larger works may be distributed under different terms and without source code.\nLearn More This post just touched on an overview of the new dbachecks module. To learn more about dbachecks, check out these posts\nAnnouncing dbachecks - Configurable PowerShell Validation For Your SQL Instances by Rob Sewell install dbachecks by Chrissy LeMaire dbachecks commands by Chrissy LeMaire My wrapper for dbachecks by Tony Wilhelm Checking backups with dbachecks by Jess Pomfret dbachecks please! by Garry Bargsley dbachecks - Configuration Deep Dive by Rob Sewell Test Log Shipping with dbachecks by Sander Stad Checking your backup strategy with dbachecks by Joshua Corrick Enterprise-level reporting with dbachecks by Jason Squires Adding your own checks to dbachecks by Shane O\u0026rsquo;Neill If you have any questions, join us in #dbachecks on the SQL Server Community Slack.\nThanks for reading and we look forward to your feedback!\nChrissy ","date":"2018-02-22","summary":"In mid-December, we began working on a new PowerShell module for the SQL Server Community. This free and open-source project can be found in the SQL Server Community Collaborative\u0026rsquo;s repository. Contributions from the community are welcomed and encouraged!\nIntro dbachecks is a framework created by and for SQL Server pros who need to validate their environments. Basically, we all share similar checklists and mostly just the server names and RPO/RTO/etc change.","tags":["dbachecks","party"],"title":"Introducing dbachecks - A New Module From the dbatools Team!","type":"post","url":"https://dbatools.io/introducing-dbachecks/"},{"categories":["announcements"],"content":"A number of dbatools contributors will be presenting at SQL Bits next week in London! To start, Rob Sewell and I will be presenting a PowerShell and dbatools heavy precon on Wednesday.\nPrecon Reliable, Repeatable, \u0026amp; Automated: PowerShell for DBAs Automating and testing your SQL Server environment has never been easier. Now you can put down your manual checklists and skillfully:\nTrack SQL Server instance configurations Promptly provide required information to managmement, change configuration or developers Deftly respond to audit change requirements across your entire estate (and impress your auditor with PowerShell; it happened to us!) Restore SQL Servers to their correct state prior and post deployment Test everything from configuration to permissions, SQL service account share access to sysadmins, Agent Jobs to SPNs During this session, we will also be premiering our new project, dbachecks.\nRegular Sessions The sessions below either include PowerShell or are presented by dbatools contributors.\nAdministering SSRS Without Boring Web Based Clicks In Cláudio Silva\u0026rsquo;s Friday morning session, he\u0026rsquo;ll be focusing on how Microsoft\u0026rsquo;s SSRS module, ReportingServicesTools, can help make you happier and more productive.\nCláudio is a PowerShell MVP and SQL Server DBA 🙏 Shout out to the SQL Server team at Microsoft for investing more in PowerShell!\nManaging Always On Availability Groups with PowerShell Also on Friday morning, Marcos Freccia will be presenting on PowerShell commands that can help tame Always On Availability Group Management. Microsoft\u0026rsquo;s official SqlServer module (formerly SQLPS) has quite a few AG commands so I imagine it will be featured at length.\nSimplifying XEvents Management With dbatools On Friday afternoon, @spaghettidba and I will be presenting a session about our new Extended Events commands. Admittedly, I was still #TeamProfiler when we proposed this session quite a few months back. I had no idea where I\u0026rsquo;d be once the Powershell commands were created. Am I still #TeamProfiler? Come to the session and find out!\nJust kidding, I\u0026rsquo;ve totally switched and I\u0026rsquo;m loving it 😄\nSQL Operations Studio: The State of the Art and Future Also on Friday afternoon, Microsoft\u0026rsquo;s Ken Van Hyning will be presenting about SQL Operations Studio. Ken has been incredibly important to the SQL PowerShell movement and we appreciate all that he does for the community. SQL Operations Studio is an awesome new Ops-focused tool from Microsoft that is built upon VS Code. So super cool.\nIntroduction to Pester-TDD for PowerShell On Friday afternoon, Rob Sewell will be presenting an introduction Pester Test Driven Development. During this session, he\u0026rsquo;ll \u0026ldquo;Start from nothing and use Test Driven Development to write a PowerShell function that uses the Microsoft Cognitive Services API to analyse pictures.\u0026rdquo; Very fun session on one of my favorite topics! Never thought I\u0026rsquo;d say that, but Pester really makes TDD fun and easy.\nCreating Complex Labs From Start to Finish With Lability Also on Friday afternoon, André Kamman will present a session that will show you how to set up a fairly complex lab from start to finish and take you through his lessons learned.\nI saw André present about AppVeyor at psconf.eu last year and it literally changed my life! I now sleep better at night knowing that a majority of our commands are tested against live SQL Server instances. As a homelabber, I\u0026rsquo;m hoping for the same from this super-fun looking session.\nQuery Store Without SQL 2016 = Open Query Store On Saturday morning, William Durkin and Enrico van de Laar will be presenting about an open source, community driven version of Query Store. Learn how you can have Query Store in all editions of SQL Server from version 2008-2014.\nAdvice and Guidance on Becoming a Speaker or Volunteer Around noon on Saturday, Rob will be presenting about becoming a speaker or volunteer. Rob is an award-winning speaker and one of the awesomest presenters I\u0026rsquo;ve ever seen!\nThat about wraps it up. If I\u0026rsquo;ve missed anyone, please comment below and I\u0026rsquo;ll add your name to the list.\nSee you at Bits!\nChrissy ","date":"2018-02-15","summary":"A number of dbatools contributors will be presenting at SQL Bits next week in London! To start, Rob Sewell and I will be presenting a PowerShell and dbatools heavy precon on Wednesday.\nPrecon Reliable, Repeatable, \u0026amp; Automated: PowerShell for DBAs Automating and testing your SQL Server environment has never been easier. Now you can put down your manual checklists and skillfully:\nTrack SQL Server instance configurations Promptly provide required information to managmement, change configuration or developers Deftly respond to audit change requirements across your entire estate (and impress your auditor with PowerShell; it happened to us!","tags":[],"title":"PowerShell at SQL Bits!","type":"post","url":"https://dbatools.io/powershell-at-sql-bits/"},{"categories":["announcements"],"content":"In today\u0026rsquo;s post, I will tell you about how we managed to successfully complete a migration during a ~12 hour maintenance window. This could have taken a LOT longer if we didn\u0026rsquo;t have dbatools to automate several of the steps.\nAlthough I will not go in to every detail about our process, I want to emphasize the areas were we chose to use dbatools to make our lives easier.\nThe Goal Recently, we got the green light for upgrading to SQL Server 2016 and we were ready to roll. Our task was to migrate multiple servers, each having several TDE encrypted databases on them. All the databases were mirrored on SQL Servers hosted in a different datacenter.\nWhen protecting data using TDE, special care must be taken when it comes to migrations. We had two primary options for migrating TDE protected databases.\nFirst Option One option would be decrypt the databases on the old servers prior to the migration. This can take a while depending on the database size as the process would touch every single data page on disk. Same would be true once we encrypted the databases on the new servers.\nIf you ever decide to take this route during your migration, make sure you follow the correct and complete process to disable TDE. Otherwise you can lock your data if you don\u0026rsquo;t have the certificates and keys backed up somewhere else, ready to be restored in case of emergency. And perhaps most importantly, make sure you test this process!\nSecond Option The second option (and the one we chose) was to leave the encryption enabled. In order to be able to attach the files, or to do restores from the backups you need to have the same certificate that was used for encryption. This certificate is protected by the master key.\nTo accomplish this:\nMake backups of the master key and the certificates Restore the key and certificates on the new principal and mirror pairs Be aware that each database can have its own certificate! You must be sure which database is protected by which certificate. Failing to have this sorted out will leave you with some files you cannot attach or restore anywhere. Basically, you\u0026rsquo;d lose the data 😢\nNeed help figuring all of this out? Check out Microsoft\u0026rsquo;s article Move a TDE Protected Database to Another SQL Server. As I mentioned before make sure you test this process ahead of time!\nPreparation In preparation for the migration day, we built all the new servers (primaries and mirrors) ahead of time and configured them based on our requirements.\nA key point is to restore the keys used for encryption to the new servers. From this point on you won\u0026rsquo;t have to worry too much about TDE.\nNext is where dbatools comes into play:\n$serverList = @( \u0026#39;server_01\u0026#39;, \u0026#39;server_02\u0026#39;, \u0026#39;server_03\u0026#39; ) foreach ($server in $serverList) { Set-DbaSpConfigure -SqlInstance $server -ConfigName CostThresholdForParallelism -Value 50 Set-DbaSpConfigure -SqlInstance $server -ConfigName DefaultBackupCompression -Value 1 Set-DbaSpConfigure -SqlInstance $server -ConfigName OptimizeAdhocWorkloads -Value 1 Set-DbaSpConfigure -SqlInstance $server -ConfigName RemoteDacConnectionsEnabled -Value 1 Set-DbaSpConfigure -SqlInstance $server -ConfigName ShowAdvancedOptions -Value 1 # Insert all your config options here Set-DbaPowerPlan -ComputerName $server Set-DbaDbOwner -SqlInstance $server # Suppress all successful backups in SQL server error log Enable-DbaTraceFlag -SqlInstance $server -TraceFlag 3226 # Set max memory to the recommended MB Set-DbaMaxMemory -SqlInstance $server } Doesn\u0026rsquo;t matter how many servers you have in your environment, doing it like this saves you a lot of time and you can be sure you have the same configuration for all of them.\nNext, we created our DBA toolkit database where we keep all the handy stuff:\nforeach ($server in $serverList) { # Create DBA database Invoke-DbaQuery -SqlInstance $server -Query $SQL # Install sp_WhoIsActive Install-DbaWhoIsActive -SqlInstance $server -Database DBA } Couldn\u0026rsquo;t be easier than this!\nMoving Forward Next, we created our backup jobs:\nforeach ($server in $serverList) { # Install Ola Hallengren\u0026#39;s solution Install-DbaMaintenanceSolution -SqlInstance $server -Database DBA -ReplaceExisting -CleanupTime 72 -LogToTable -Solution \u0026#34;All\u0026#34; -BackupLocation \u0026#34;X:\\SQLBackup\u0026#34; -OutputFileDirectory \u0026#34;X:\\SQLMaintenanceLogs\u0026#34; -InstallJobs } For auditing purposes we even saved the old server configuration and compare it to the new ones, all with only a few lines of code:\n$propcompare = foreach ($prop in $oldprops) { [pscustomobject]@{ Config = $prop.DisplayName \u0026#39;SQL Server 2008R2\u0026#39; = $prop.RunningValue \u0026#39;SQL Server 2016\u0026#39; = ($newprops | Where ConfigName -eq $prop.ConfigName).RunningValue } } Save $propcompare to a database using Write-DbaDataTable and you\u0026rsquo;re set.\nTransfering the logins from the old server is now easier than ever (no more sp_help_revlogin):\nCopy-DbaLogin -Source oldServer -Destination newServer Beat that if you can! This way we ensured that old logins will work as soon as we start the applications.\nWe started to build the mirrors ahead of time (we have some big databases). We got the details for the last full backups on the old servers:\n$OldServerList | ForEach-Object { Get-DbaDbBackupHistory -SqlInstance $_ -LastFull | Select SqlInstance, Database, Start, End, Duration, Path, TotalSize } | Format-Table -AutoSize Based on the output of the above we fired up a quick PowerShell script that got everything copied over to a network share. From there, restoring the backups to the new mirrors was simple as:\nRestore-DbaDatabase -SqlInstance $newSQLServer_01 -Database db_1 -Path \\\\SharedPath\\Migration\\db_1 -NoRecovery -WithReplace -Verbose Restore-DbaDatabase -SqlInstance $newSQLServer_02 -Database db_2 -Path \\\\SharedPath\\Migration\\db_2 -NoRecovery -WithReplace -Verbose ... Restore-DbaDatabase -SqlInstance $newSQLServer_0N -Database db_N -Path \\\\SharedPath\\Migration\\db_N -NoRecovery -WithReplace -Verbose I can do this all day long, especially when piping it directly to the Backup-DbaDatabase 😊\nFinalizing the Migration During the maintenance window we just got a last DIFF for each database and restored that to the new mirrors. Some manual growth on some of the databases and the restore of the DIFFs took us the longest time (those contained several days of data for each server).\nTo shorten the time for the principals, we used detach/attach of the data and log drives approach which went pretty smooth with no unexpected incidents.\nAnd, in case you\u0026rsquo;re wondering, we do have valid backups. We even restore and test those automatically on a separate server using dbatools as well. These jobs take around 17 hours per day.\nI must confess, we did a bit of T-SQL to bring the mirroring up and now we\u0026rsquo;re back in business, HA included.\nPost Migration Now to the post migration stuff.\nOnce we\u0026rsquo;re running on the new instances, we made sure we enable all the jobs we already created ahead of time:\n$serverList = @( \u0026#39;server_01\u0026#39;, \u0026#39;server_02\u0026#39;, \u0026#39;server_03\u0026#39; ) foreach ($server in $serverList) { $jobs = Get-DbaAgentJob -SqlInstance $server $jobs | ForEach-Object {Set-DbaAgentJob -SqlInstance $server -Job $_ -Enabled} } Alternatively, piping support was added to today\u0026rsquo;s release, 0.9.191. With this release and above, you can use the following syntax:\nOnce we\u0026rsquo;re running on the new instances, we made sure we enable all the jobs we already created ahead of time:\n# much less code 👍 $serverlist | Get-DbaAgentJob | Set-DbaAgentJob -Enabled We decided we need some more RAM on a few of the servers and after we added it, we just executed the following to make SQL Server aware of the change.\nSet-DbaMaxMemory -SqlInstance $server Now, the moment of truth. Application started and what do you know, everything just works!\nNo orphaned logins No SID mismatches for the logins No error messages. Automation is Awesome As you can see, a lot of steps were automated using dbatools and this saved us a lot of time overall, making this multi-terabyte database migration across 5 environments very smooth.\nThere is still room for a lot more automation, for even more efficiency. I\u0026rsquo;m sure we\u0026rsquo;ll do better next time.\nThanks again to all of you contributing to this project and Chrissy, thanks for starting all this. Can\u0026rsquo;t wait to see what the future will bring for dbatools and I hope I\u0026rsquo;ll be able to contribute more.\nHappy migrations everyone!\n- Viorel 🇷🇴\n","date":"2018-02-07","summary":"In today\u0026rsquo;s post, I will tell you about how we managed to successfully complete a migration during a ~12 hour maintenance window. This could have taken a LOT longer if we didn\u0026rsquo;t have dbatools to automate several of the steps.\nAlthough I will not go in to every detail about our process, I want to emphasize the areas were we chose to use dbatools to make our lives easier.\nThe Goal Recently, we got the green light for upgrading to SQL Server 2016 and we were ready to roll.","tags":["migration","migration-party","party"],"title":"Real-World TDE Database Migrations","type":"post","url":"https://dbatools.io/real-world-tde-database-migrations/"},{"categories":["announcements"],"content":"We have now reached more than 370 public functions and nearly 1000 unit and integration tests, all thanks to over 100 community contributors!\nAs you may have noticed, we release a 0.9.x update with bug fixes and new features almost daily, so why haven\u0026rsquo;t we released 1.0 yet?\nShifting From \u0026ldquo;A Bag of Functions\u0026rdquo; to a Proper Module We love new functionality, of course, but we must take a step back from new development and consolidate what we have in a properly usable module.\nMost of the contributors are damn good SQL Server Pros, a few are damn good PowerShell programmers, with the majority of \u0026ldquo;casual\u0026rdquo; developers being able to successfully publish a new function in less than a week time. But what we aren\u0026rsquo;t so good at is advertising our needs. We recently updated our contributing.md to be more on par with the latest months of developing. Stay tuned there, as the few TODOs left are coming, but the path is mostly set.\nWe Need Your Help We\u0026rsquo;re looking for contributors to help us finally reach version 1.0. Currently, we are on par with Gmail\u0026rsquo;s beta schedule: a whopping 4 years. But, we\u0026rsquo;re almost there and need your help finalizing our changes. If you\u0026rsquo;re interested in helping us bring 1.0 alive, we identified four areas with 5 primary contacts on the SQL Server Community Slack:\nStandardize param names (@wsmelton) Create tests for existing functions (@cl and @niphlod) Review existing function documentation (@alevyinroc or @gbargsley) Prepare for 1.0 with \u0026ldquo;code style\u0026rdquo; (Bill of Health, more on that later) As you can see, a few of us are the main reference (on GitHub and Slack, mostly) for each area.\nBill of Health As dbatools is full of sooo many features, it\u0026rsquo;s hard to tackle everything in one sweep. That\u0026rsquo;s why we made the Bill of Health available. That\u0026rsquo;s for you, and us, to track progress towards 1.0. It includes every single activity that will bring us closer to 1.0.\nData will be refreshed once or twice a week (you can see the trend on top with the details), giving everybody a good understanding on what\u0026rsquo;s the pace of development. For details on each column, click on the Legend details, you\u0026rsquo;ll be able to see what they mean.\nBasically, we gave each function a scorecard, composed by checks that need to be tackled before 1.0.\nBecoming a Core Developer Some of the checks are \u0026ldquo;reserved for core-devs\u0026rdquo;, but that doesn\u0026rsquo;t mean you shouldn\u0026rsquo;t tackle those, it\u0026rsquo;s just you need to read on how we want the code to look like (we\u0026rsquo;ll eventually group everything in a more consolidated guide, ranging from the simpler to the \u0026ldquo;most complex\u0026rdquo;):\ndo and do not Style Guide The Messaging System Sign-offs It may scare PowerShell newbies, but trust us, to get the gist of it and be a successful \u0026ldquo;core-dev\u0026rdquo;, all you need is one week of coding. Most of us learned from Slack and Pull Request Code reviews. Sqlcollaborative is a wonderful place to learn coding in PowerShell! Checks for core-devs, despite being numerous, are a minority of the total.\nGetting Started The most important things you can fix even without being a skilled developer: ScriptAnalyzer and Coverage. ScriptAnalyzer checks are the de-facto standard for any Powershell module and some are really, really easy to fix.\nCoverage is a \u0026ldquo;higher level\u0026rdquo; metric: it tells you how much code is tested. It builds up on having tests written. We can\u0026rsquo;t (and won\u0026rsquo;t) stress enough on this point: if it\u0026rsquo;s tested, tests describe the way the function behaves, so the more coverage a function has, the more stable it is. This means you can build up your scripts being sure there won\u0026rsquo;t be regressions (i.e. the code that \u0026ldquo;worked before\u0026rdquo; continues to work as expected).\nHaving a strong suite of tests also help the casual developer contributing code, being sure it doesn\u0026rsquo;t break existing functionality. It\u0026rsquo;s only a recommendation, but I feel like most of the \u0026ldquo;devs\u0026rdquo; should spend most of their time writing tests, because it\u0026rsquo;s the single best wealth indicator for any module.\nFor dbatools in particular: if you factor all the things dbatools supports (think PS versions times SQL releases times editions times Azure/cloud envs times x86/x64 times remote/local times functions times … ).\nWe\u0026rsquo;ve Made It Easy You can copy and paste from our templates for a starting point, or dive right in to an existing tests.\nImproving existing tests is an easy first step to \u0026ldquo;dip your toes\u0026rdquo; into coverage.\nWant to Help? Right now there are more than 500 tasks ready to be tackled by everyone and more than 1300 for intermediate developers. To make sure everyone doesn\u0026rsquo;t jump on the same activity, you\u0026rsquo;re invited to see if there\u0026rsquo;s an issue opened on GitHub by someone else. If nothing pops up, open an \u0026ldquo;issue\u0026rdquo; , stating that you want to work the issue.\nYou can then issue a PR, there will be a swift review of the changes, and the code will be committed. A few hundred PR\u0026rsquo;s later (hopefully it\u0026rsquo;ll take just three or four by yourself), 1.0 will be shipped. And just wait to see what we have in mind for 2.0!\nGot any questions? Hit me up on Slack. I\u0026rsquo;m @niphlod.\nCiao! Simone 🇮🇹\n","date":"2018-01-16","summary":"We have now reached more than 370 public functions and nearly 1000 unit and integration tests, all thanks to over 100 community contributors!\nAs you may have noticed, we release a 0.9.x update with bug fixes and new features almost daily, so why haven\u0026rsquo;t we released 1.0 yet?\nShifting From \u0026ldquo;A Bag of Functions\u0026rdquo; to a Proper Module We love new functionality, of course, but we must take a step back from new development and consolidate what we have in a properly usable module.","tags":[],"title":"The Path to 1.0","type":"post","url":"https://dbatools.io/the-path-to-1-0/"},{"categories":["announcements"],"content":"\nToday\u0026rsquo;s blog post is part of T-SQL Tuesday. T-SQL Tuesday is the brainchild of Adam Machanic. It is a blog party on the second Tuesday of each month. Everyone is welcomed to participate.\nThis month\u0026rsquo;s T-SQL Tuesday, hosted by Arun Sirpal (blog), is all about overcoming technical challenges.\nThe Challenge I always try to solve my technical issues with natively available (aka Microsoft) solutions. It\u0026rsquo;s one of the many reasons I love PowerShell.\nWhen it comes to monitoring, I know there are some really wonderful solutions out there. SolarWinds SQL Sentry (formerly SentryOne) and SolarWinds Database Performance Monitor come to mind but I don\u0026rsquo;t always need deep query level monitoring or I may not be able to pay licencing costs for all of my SQL Instances. But I do need to easily know if they are all set up correctly.\nEver since I was a baby DBA, I\u0026rsquo;ve wanted to create a centralized solution that I could roll in with and get going with after finding all of my servers. Over the years, I\u0026rsquo;ve tried to put together some ASP/VBScript solutions, then when I learned PowerShell, tried PowerShell and SQL Agent, but I just wasn\u0026rsquo;t feeling it. I could never figure out how to make the checks modular and universal. That is, until I learned about Pester in-depth from Rob Sewell.\nThe Solution The solution I\u0026rsquo;ve been looking for turns out to be a mix of dbatools and Pester. Pester is the first Open Source community project formally included in a Windows release! Windows 10 and Windows Server 2016 include Pester by default.\nPester makes it easy to standardize tests or \u0026ldquo;checks\u0026rdquo; because it can output its results in a number of standardized formats, including NunitXml and JSON. It\u0026rsquo;s all PowerShell, after all.\ndbatools makes it easy to perform these checks without installing additional software or stored procedures on each of my servers. I have one central workstation that needs to be updated and checking hundreds of servers is as easy as checking just one.\nSo after poring over Rob\u0026rsquo;s prodigious GitHub Presentation Repository, I found a bunch of his tests, and added them to a newly created module. I then created an index of the checks to make them easy to access. Once I got the proof of concept down, I invited a few people from the community who I know are involved in Pester and asked them to help.\nThe result has been a dream come true!\nIndex Index of checks. You can run them all, run by group or only run the specific tests that matter to your environment.\nPower BI Universal Dashboard Courtesy of Cláudio Silva. Just hit refresh and you\u0026rsquo;re all set!\nIncluded Parser \u0026amp; Mailer Also from Rob\u0026rsquo;s repo!\nWe are still working on the checks, but these screenshots should give you an idea about the new SQL PowerShell module that Rob and I will be premiering at our SQLBits PowerShell Precon, Reliable, Repeatable, \u0026amp; Automated: PowerShell for DBAs, in London on Thursday, February 22 2018.\nInterested in finding out more? Find us at SQLBits!\n","date":"2018-01-09","summary":"Today\u0026rsquo;s blog post is part of T-SQL Tuesday. T-SQL Tuesday is the brainchild of Adam Machanic. It is a blog party on the second Tuesday of each month. Everyone is welcomed to participate.\nThis month\u0026rsquo;s T-SQL Tuesday, hosted by Arun Sirpal (blog), is all about overcoming technical challenges.\nThe Challenge I always try to solve my technical issues with natively available (aka Microsoft) solutions. It\u0026rsquo;s one of the many reasons I love PowerShell.","tags":["dbachecks","party","pester"],"title":"T-SQL Tuesday and New Module Teaser","type":"post","url":"https://dbatools.io/new-module-coming-soon/"},{"categories":["announcements"],"content":"Pétur Grétarsson, here. Long time dbatools fan, first time blogger. I really love the new Invoke-DbaQuery command and wanted to share how I use it.\nI have well over 100 Availability Groups to look after in different domains so it can be a bit difficult to check things when needed. We have opened required ports allowing connections from one SQL management server to those for monitoring purposes including using Idera SQL Inventory Manager for basic health checks.\nHaving said that, there\u0026rsquo;s some additional monitoring I like to be able to do such as checking the health status of Availability Groups to see if there are any potential resource issues.\nInvoke-DbaQuery Makes Monitoring Easy I\u0026rsquo;ve used Invoke-DbaQuery for so many things. Here\u0026rsquo;s one example: how I used the new function in my latest Availability Group check.\nI created and stored a SQL Server Credential on the SQL management server using Credential Manager (found from Control Panel) using the account that executes the PowerShell scripts in schedule. I scheduled the script below to run via Visual Studio Team Services online (or the Agent on my SQL management server) I executed a procedure from PowerShell script that for example checks if any Availability Group is unhealthy and if so then sends email to our support team # DOMAIN1 SQL Replica Nodes (this one has 90% of the availability groups). $result = Get-DbaRegisteredServer -SqlServer [INSTANCENAME] -Group SqlAlwaysOnReplicaNodes | Invoke-DbaQuery -File \u0026#34;FULL_PATH\\aog_health.sql\u0026#34; | SELECT INSTANCE_NAME, SQL_VERSION, MAX_SERVER_MEMORY,NAME, PAGE_LIFE_EXPECTANCY, MAX_DEGREE_OF_PARALLELISM, LOGICAL_CPU_COUNT, TEMPDB_FILE_COUNT, PERCENTAGE_CPU_SIGNAL_WAIT, PERCENTAGE_RESOURCE_WAITS, DNS_NAME, DATABASE_COUNT, IP_CONFIGURATION_STRING_FROM_CLUSTER, ROLE_DESC, AVAILABILITY_MODE_DESC, FAILOVER_MODE_DESC, SYNCHRONIZATION_HEALTH_DESC, AUTOMATED_BACKUP_PREFERENCE_DESC | ConvertTo-DbaDataTable Write-DbaDataTable -InputObject $result -SqlServer [INSTANCENAME] -Table SqlManagementRepository.dbo.SqlAvailabilityGroupsHealth -Confirm:$false # DOMAIN2 SQL Replica Nodes $cred1 = Get-StoredCredential -Target DOMAIN2 $result = \u0026#34;INSTANCE1\u0026#34;, \u0026#34;INSTANCE2\u0026#34;, \u0026#34;ETCINSTANCES\u0026#34; | Invoke-DbaQuery -SqlCredential $cred1 -File \u0026#34;FULL_PATH\\aog_health.sql\u0026#34; | SELECT INSTANCE_NAME, SQL_VERSION, MAX_SERVER_MEMORY,NAME, PAGE_LIFE_EXPECTANCY, MAX_DEGREE_OF_PARALLELISM, LOGICAL_CPU_COUNT, TEMPDB_FILE_COUNT, PERCENTAGE_CPU_SIGNAL_WAIT, PERCENTAGE_RESOURCE_WAITS, DNS_NAME, DATABASE_COUNT, IP_CONFIGURATION_STRING_FROM_CLUSTER, ROLE_DESC, AVAILABILITY_MODE_DESC, FAILOVER_MODE_DESC, SYNCHRONIZATION_HEALTH_DESC, AUTOMATED_BACKUP_PREFERENCE_DESC | ConvertTo-DbaDataTable Write-DbaDataTable -InputObject $result -SqlServer [INSTANCENAME] -Table SqlManagementRepository.dbo.SqlAvailabilityGroupsHealth -Confirm:$false # DOMAIN3 SQL Replica Nodes $cred2 = Get-StoredCredential -Target DOMAIN2 $result = \u0026#34;INSTANCE1\u0026#34;, \u0026#34;INSTANCE2\u0026#34;, \u0026#34;ETCINSTANCES\u0026#34;| Invoke-DbaQuery -SqlCredential $cred2 -File \u0026#34; FULL_PATH\\aog_health.sql\u0026#34; | SELECT INSTANCE_NAME, SQL_VERSION, MAX_SERVER_MEMORY,NAME, PAGE_LIFE_EXPECTANCY, MAX_DEGREE_OF_PARALLELISM, LOGICAL_CPU_COUNT, TEMPDB_FILE_COUNT, PERCENTAGE_CPU_SIGNAL_WAIT, PERCENTAGE_RESOURCE_WAITS, DNS_NAME, DATABASE_COUNT, IP_CONFIGURATION_STRING_FROM_CLUSTER, ROLE_DESC, AVAILABILITY_MODE_DESC, FAILOVER_MODE_DESC, SYNCHRONIZATION_HEALTH_DESC, AUTOMATED_BACKUP_PREFERENCE_DESC | ConvertTo-DbaDataTable Write-DbaDataTable -InputObject $result -SqlServer [INSTANCENAME] -Table SqlManagementRepository.dbo.SqlAvailabilityGroupsHealth -Confirm:$false This script:\nGets a list of servers using Get-DbaRegisteredServer Pipes that list to Invoke-DbaQuery which executes a script against each of the servers Converts the results of the script to a datatable Writes the converted output to a table in my management database And here is the simple T-SQL script I use in the above example. It is now so nice to be able to see version, max memory, PLE, logical CPU count, tempdb files, CPU signal wait, listener name, IP Address, failover mode, synchronization health etc. for all of the availability groups from one table which gets updated frequently values.\nSELECT (SELECT @@SERVERNAME) instance_name, (SELECT @@VERSION) sql_version, (SELECT value_in_use FROM sys.configurations WHERE name = \u0026#39;max server memory (MB)\u0026#39;) max_server_memory, (SELECT cntr_value / 3600 AS PLE_HOURS FROM sys.dm_os_performance_counters WHERE object_name LIKE \u0026#39;%Manager%\u0026#39; AND counter_name = \u0026#39;Page life expectancy\u0026#39;) page_life_expectancy, (SELECT value_in_use FROM sys.configurations WHERE name = \u0026#39;max degree of parallelism\u0026#39;) max_degree_of_parallelism, (SELECT cpu_count FROM sys.dm_os_sys_info) logical_cpu_count, (SELECT COUNT(name) FROM sys.master_files WHERE database_id = 2 AND type_desc = \u0026#39;ROWS\u0026#39;) tempdb_file_count, (SELECT CAST(100.0 * SUM(signal_wait_time_ms) / SUM(wait_time_ms) AS NUMERIC(20,2)) FROM sys.dm_os_wait_stats) percentage_cpu_signal_wait, (SELECT CAST(100.0 * SUM(wait_time_ms - signal_wait_time_ms) / SUM(wait_time_ms) AS NUMERIC(20, 2)) FROM sys.dm_os_wait_stats) percentage_resource_waits, name, dns_name, (SELECT COUNT(*) FROM sys.databases WHERE state_desc = \u0026#39;ONLINE\u0026#39; AND database_id \u0026gt; 4) database_count, ip_configuration_string_from_cluster, role_desc, availability_mode_desc, failover_mode_desc, synchronization_health_desc, automated_backup_preference_desc FROM sys.availability_groups_cluster AS AGC INNER JOIN [master].sys.dm_hadr_availability_replica_cluster_states AS RCS ON RCS.group_id = AGC.group_id INNER JOIN [master].sys.dm_hadr_availability_replica_states AS ARS ON ARS.replica_id = RCS.replica_id INNER JOIN [master].sys.availability_group_listeners AS AGL ON AGL.group_id = ARS.group_id INNER JOIN [master].sys.availability_replicas AS ARN ON ARS.replica_id = ARN.replica_id AND ars.is_local = 1; We have thousands of databases in these Availability Groups so it is important to ensure that they are healthy. We have monitoring systems for the most important ones but you can imagine the cost. Therefore, it is nice to be able to build some basic checks like these. Running customized scripts and using the Get-DbaRegisteredServer is just fantastic 😊.\nAdditional Uses for dbatools I also use other dbatools commands for getting a daily summary email report for all our SQL Agent jobs which are either failing or not having failure notifications configured from all our environments. We have many people adding SQL Agent Jobs and sometimes the notifications get forgotten so this allows me to catch that immediately and get daily status report of all our SQL Agent failed jobs.\nI scheduled the script below to run via Visual Studio Team Services online (or the Agent on my SQL management server). This script runs just before office hours, so we can have the most recent status in the morning.\n# Get SQL Agent Job information # Fetch from DOMAIN1 $result = Get-DbaRegisteredServer -SqlServer [INSTANCENAME] -Group SqlAlwaysOnReplicaNodes | Get-DbaAgentJob | SELECT ComputerName, InstanceName, SqlInstance, Name, Category, OwnerLoginName, CurrentRunStatus, CurrentRunRetryAttempt, Enabled, LastRunDate, LastRunOutcome, DateCreated, HasSchedule, OperatorToEmail, CreateDate | ConvertTo-DbaDataTable Write-DbaDataTable -InputObject $result -SqlServer [INSTANCENAME] -Table SqlManagementRepository.dbo.SqlAgentJobs -Truncate -Confirm:$false $result = Get-DbaRegisteredServer -SqlServer [INSTANCENAME] -Group SqlStandalone | Get-DbaAgentJob | SELECT ComputerName, InstanceName, SqlInstance, Name, Category, OwnerLoginName, CurrentRunStatus, CurrentRunRetryAttempt, Enabled, LastRunDate, LastRunOutcome, DateCreated, HasSchedule, OperatorToEmail, CreateDate | ConvertTo-DbaDataTable Write-DbaDataTable -InputObject $result -SqlServer [INSTANCENAME] -Table SqlManagementRepository.dbo.SqlAgentJobs -Confirm:$false # Fetch from DOMAIN2 $cred1 = Get-StoredCredential -Target DOMAIN2 $result = \u0026#34;INSTANCE1\u0026#34;, \u0026#34;INSTANCE2\u0026#34;, \u0026#34;ETCINSTANCES\u0026#34; | Get-DbaAgentJob -SqlCredential $cred1 | SELECT ComputerName, InstanceName, SqlInstance, Name, Category, OwnerLoginName, CurrentRunStatus, CurrentRunRetryAttempt, Enabled, LastRunDate, LastRunOutcome, DateCreated, HasSchedule, OperatorToEmail, CreateDate | ConvertTo-DbaDataTable Write-DbaDataTable -InputObject $result -SqlServer [INSTANCENAME] -Table SqlManagementRepository.dbo.SqlAgentJobs -Confirm:$false # Fetch from DOMAIN3 $cred2 = Get-StoredCredential -Target DOMAIN3 $result = \u0026#34;INSTANCE1\u0026#34;, \u0026#34;INSTANCE2\u0026#34;, \u0026#34;ETCINSTANCES\u0026#34; | Get-DbaAgentJob -SqlCredential $cred2 | SELECT ComputerName, InstanceName, SqlInstance, Name, Category, OwnerLoginName, CurrentRunStatus, CurrentRunRetryAttempt, Enabled, LastRunDate, LastRunOutcome, DateCreated, HasSchedule, OperatorToEmail, CreateDate | ConvertTo-DbaDataTable Write-DbaDataTable -InputObject $result -SqlServer [INSTANCENAME] -Table SqlManagementRepository.dbo.SqlAgentJobs -Confirm:$false Then I have a job that runs soon after the above check. This job is also PowerShell script that just executes a procedure in the database management repository and if the procedure has result set then it gets sent to the database team.\nThe procedure is just very basic and simple check from the table that is created in the above check.\nCREATE PROCEDURE [dbo].[SqlAgentJobsSummary] AS IF (SELECT COUNT(*) FROM SqlAgentJobs WHERE Enabled = \u0026#39;True\u0026#39; AND LastRunOutcome NOT IN(\u0026#39;Succeeded\u0026#39;, \u0026#39;Cancelled\u0026#39;) ) \u0026gt;= 1 BEGIN SELECT SqlInstance AS \u0026#34;SQL Instance.............\u0026#34;, Name AS \u0026#34;SQL Agent Job............\u0026#34; , LastRunDate AS \u0026#34;Last Run.................\u0026#34;, LastRunOutcome AS \u0026#34;Last Run Status.....\u0026#34;, OperatorToEmail AS \u0026#34;Notified To..............\u0026#34; FROM SqlAgentJobs WHERE Enabled = \u0026#39;True\u0026#39; AND LastRunOutcome NOT IN(\u0026#39;Succeeded\u0026#39;, \u0026#39;Cancelled\u0026#39;) ORDER BY LastRunDate; END; GO Alternatively, I could use some dbatools commands and Send-MailMessage but I appreciated the fact that I could so easily integrate with my existing SQL solutions.\nI also use the command for many of our functions which run against all our +300 instances and +12.000 databases and store the result in central management database. Other validations I use dbatools for: file allocation unit size is incorrect, proper power plan is being used, SPN is configured, transaction log VLF count does not exceed threshold, SQL orphaned files do not exist, invalid SQL logins do not exist and much more. All those checks are done with dbatools and visible in one central database repository.\nThanks for reading! Pétur 🇮🇸\n","date":"2018-01-08","summary":"Pétur Grétarsson, here. Long time dbatools fan, first time blogger. I really love the new Invoke-DbaQuery command and wanted to share how I use it.\nI have well over 100 Availability Groups to look after in different domains so it can be a bit difficult to check things when needed. We have opened required ports allowing connections from one SQL management server to those for monitoring purposes including using Idera SQL Inventory Manager for basic health checks.","tags":["party"],"title":"I ❤ Invoke-DbaQuery","type":"post","url":"https://dbatools.io/i-love-invoke-query/"},{"categories":["announcements"],"content":"We\u0026rsquo;ve updated the site a bit and wanted to let you know.\nGetting Started Finally! The Getting Started page has accurate information, way more code samples and useful links. So if you\u0026rsquo;re a bit lost wondering where to start, I included a slightly modified version of the code I often show at conferences. This code in particular was heavily updated just a few weeks ago for the dbatools presentation in Glasgow.\nCommands Page and Command Index Garry Bargsley updated like 100 command pages which required us to reorganize our commands page. Now it\u0026rsquo;s all pretty, but more importantly, it\u0026rsquo;s organized by topic area which makes it a lot easier to find what you\u0026rsquo;re looking for.\nTopics Include: Migration Backup and Restore Export Detach and Attach Diagnostics and Performance Traces, Profiler and Extended Events Databases tempdb Snapshots Login and User Management SQL Agent Mail and Logging High Availability Log Shipping Security and Encryption Community Tools Writing to SQL Tables Services Server Management dbatools Support Tools File System and Storage Utilities Connection Strings Network and Connectivity Service Principal Names (SPNs) SQL Client Configuration SSIS General Finders SQL Management Objects sp_configure System Startup Max Memory Replication Registered Servers dbatools Configuration dbatools Computer Management dbatools Update Watcher\nWhew! That\u0026rsquo;s almost as many topics as there are commands 😄 Just kidding, we\u0026rsquo;re now up to around 325 commands. Whattt.\n","date":"2017-12-01","summary":"We\u0026rsquo;ve updated the site a bit and wanted to let you know.\nGetting Started Finally! The Getting Started page has accurate information, way more code samples and useful links. So if you\u0026rsquo;re a bit lost wondering where to start, I included a slightly modified version of the code I often show at conferences. This code in particular was heavily updated just a few weeks ago for the dbatools presentation in Glasgow.","tags":[],"title":"Website Updates","type":"post","url":"https://dbatools.io/website-updates/"},{"categories":["announcements"],"content":"Hey all! Andy Levy here. I\u0026rsquo;m a SQL Server DBA and major contributor for dbatools. My current focus within the project is fixing the docs and more specifically, the help content and documentation that\u0026rsquo;s included with every function.\nMost folks don\u0026rsquo;t like writing documentation. It\u0026rsquo;s seen as a necessary evil, something you do to just check a box, complete requirements, and move on. With many open source projects, you\u0026rsquo;re lucky to get much documentation at all.\ndbatools \u0026amp; Documentation dbatools is different. Every function comes with extensive help including documentation of all parameters, examples for usage, and an explanation of what the function does, how and why. PowerShell\u0026rsquo;s built-in comment-based help system is tremendously helpful with developing this; write documentation into your function using the standard template, and it\u0026rsquo;s instantly accessible with Get-Help.\nBut there\u0026rsquo;s always room for improvement. Just having up-to-date documentation is good, but little things can have a big impact on the perception of your open source project. Spelling \u0026amp; grammatical errors, broken sample code, and awkward composition can all make prospective users (and their managers) wary of using your code. Addressing these issues gives your project an extra level of polish, making it look like the solid, professionally-developed product that it is, not just another GitHub project.\nHow I Got Involved What started for me as a simple attempt to correct spelling errors in dbatools has become a much larger mission - to review all of the comment-based help (CBH) and clean up examples, grammar, style and more. It\u0026rsquo;s turned out to be a larger undertaking than expected, but it\u0026rsquo;s come along far enough now that we\u0026rsquo;re able bring more people into the process to distribute the work.\nHow You Can Get Involved Working on the CBH is a great way to get started with the dbatools project, even (especially) if you\u0026rsquo;re not a PowerShell expert or MVP-level DBA. Getting everything clean and consistent in the CBH is an important step on the road to 1.0. Along the way, you\u0026rsquo;ll pick up on how dbatools is put together, discover functions that you can use in your day-to-day work, and get a feel for PowerShell best practices. You will learn from this experience! To get started:\nSet up a GitHub account, fork the project, and clone it to your desktop. If you\u0026rsquo;re new to the process, check out the CONTRIBUTING.md guide in the dbatools repository to get started. Make sure your editor\u0026rsquo;s formatting is configured to be consistent with the rest of the project. If you use Visual Studio Code, check the .vscode directory in the dbatools repository for sample workspace settings files. Take a look at the dbatools-templates repository for samples of the CBH style that should be used (note: this repository is archived but available for reference). You can also look at functions in the main dbatools repository which have already been updated to the standard style. Create a branch, pick a handful of functions and get to work! We try to keep each batch to 5-6 functions at most, to minimize code review time and mitigate the risk of merge issues. A sampling of items to tackle (this is not a complete list; please review the templates to get familiar with what we\u0026rsquo;re looking for): If you\u0026rsquo;re working on a function which has not yet gotten \u0026ldquo;the treatment\u0026rdquo;, please update all of the CBH in it, not just selected elements Proper indenting/formatting of the CBH sections Spelling and grammar Remove manual linebreaks in sentences and paragraphs. The console will line-wrap as appropriate when the CBH is rendered to the user, and if you enable \u0026ldquo;soft wrap\u0026rdquo; in your code editor, the same will happen there. Verify that examples are valid. In some cases, the SqlInstance used in calling the function in the example may not match the text description under it. This needs to be corrected. For switch parameters, the description should start with \u0026ldquo;If this switch is enabled\u0026hellip;\u0026rdquo; For parameters which have valid values determined by the instance you\u0026rsquo;re connecting to, the language \u0026ldquo;Options for this parameter are auto-populated from the server\u0026rdquo; should be used Add Tags: to the .NOTES section if it\u0026rsquo;s missing (Optional) If you\u0026rsquo;re using VS Code and have configured it with the appropriate formatting settings, format the code. Be careful here! In cases where there\u0026rsquo;s a curly brace followed by a comment at the end of the line, the VS Code auto-formatter will break the code (the curly brace will end up inside the comment) and you\u0026rsquo;ll have to seek these out and correct manually. Commit your code, push it to GitHub, and issue a pull request. You can use PR #2434 as a template and please reference issue #2219 in your description. Request a review of your PR from alevyinroc Before you know it, you\u0026rsquo;ll branch out from documentation and start working on bugs, just like I did.\n","date":"2017-11-29","summary":"Hey all! Andy Levy here. I\u0026rsquo;m a SQL Server DBA and major contributor for dbatools. My current focus within the project is fixing the docs and more specifically, the help content and documentation that\u0026rsquo;s included with every function.\nMost folks don\u0026rsquo;t like writing documentation. It\u0026rsquo;s seen as a necessary evil, something you do to just check a box, complete requirements, and move on. With many open source projects, you\u0026rsquo;re lucky to get much documentation at all.","tags":["party"],"title":"Cleaning Up Comment-Based Help","type":"post","url":"https://dbatools.io/clean-cbh/"},{"categories":["announcements"],"content":"No matter how hard the dbatools team tries, there\u0026rsquo;s always someone who wants to do things we\u0026rsquo;d never thought. This is one of the great things with getting feedback direct from a great community. Unfortunately a lot of these ideas are either too niche to implement, or would be a lot of complex code for a single use case.\nAs part of the Restore-DbaDatabase stack rewrite, I wanted to do make things easier for users to be able to get their hands dirty within the Restore stack. Not necessarily needing to dive into the core code and the world of GitHub Pull Requests, but by manipulating the data flowing through the pipeline using standard PowerShell techniques, all the while being able to do the heavy lifting without code.\nSo, below we\u0026rsquo;ll be looking at some examples of how you can start going to town with your restores.\nImproving Header Scan Performance One of the most common requests has been ways of speeding up reading the headers from the backup files. Unfortunately we have to do this so we can be sure of what they contain, and there aren\u0026rsquo;t any shortcuts (I\u0026rsquo;ve looked into it in some depth before).\nSo we can now offer a couple more options to do this:\nSpread the Load Over Time Using Get-DbaBackupInformation it\u0026rsquo;s now possible to scan the headers ahead of time, and just add to them in small batches going forward. So you could scan every 3 hours, and if you needed more recent file, you\u0026rsquo;d only have to scan the files written since the last scan:\nRun Parallel Jobs on a Single Server Another option is to run multiple scans at the same time. For this example I\u0026rsquo;m using the PoshRsJob module as it\u0026rsquo;s one I use a bit, but any other runspace/jobs options would work just as well.\nIn the first example we scan multiple directories on the same SQL Server Instance. We pass an array of folders into Start-RsJob and scan each folder in parallel as a seperate job.\nRun Parallel Jobs on Multiple Servers Perhaps you want to spread the load even more? The run the scans across multiple SQL Instances. This example uses a simple allocation routine that just \u0026lsquo;cross joins\u0026rsquo; the options:\nCustom Log and Data Folders for Each Database Perhaps you want to restore a number of databases, and you want seperate Data and Log folders for each database, eg:\ndb1 - c:\\folder\\data\\db1 and c:\\folder\\log\\db1 db2 - c:\\folder\\data\\db2 and c:\\folder\\log\\db2\nBy dipping into the restore pipleine we can loop through the databases contained within the backup information and apply custom formatting to each database:\nCreating Multiple Environments Perhaps you need to refresh multiple environments at the same time. Using Get-DbaBackupInformation to create a BackupHistory you can use the same scanned files multiple times, saving scanning them repeatedly:\nCreating Different Points in Time for Comparison Perhaps you\u0026rsquo;re trying to find out when an issue occured. This example restores the same database to multiple points in time so you can compare the state between them.\nRolling Forward Looking for Data Building on the one above, perhaps you\u0026rsquo;d rather something else did the checking for you? With this script we gradually roll forward a database a minute at a time. We use a SQL query (quite a simple one here) to indicate when the process should stop.\nComplex Rebasing of Backups When people use Get-DbaDbBackupHistory to get the pre-created Backup History directly from SQL Server, it\u0026rsquo;s a very common request for a way of changing the path of where the backup files were to where they are now. One thing that catches a lot of people out is that the Backup History object stores the Backup file paths as an array. This allows us to easily cope with striped backupsets where the backup consists of multiple files. The simplest way is a nested ForEach loop:\nWith this method you can manipulate the strings to your heart\u0026rsquo;s content using any standard PowerShell technique.\n","date":"2017-11-28","summary":"No matter how hard the dbatools team tries, there\u0026rsquo;s always someone who wants to do things we\u0026rsquo;d never thought. This is one of the great things with getting feedback direct from a great community. Unfortunately a lot of these ideas are either too niche to implement, or would be a lot of complex code for a single use case.\nAs part of the Restore-DbaDatabase stack rewrite, I wanted to do make things easier for users to be able to get their hands dirty within the Restore stack.","tags":["party"],"title":"Getting Complex with Restore-DbaDatabase","type":"post","url":"https://dbatools.io/complex-restores/"},{"categories":["announcements"],"content":"A recent addition to the release pipeline is the \u0026ldquo;code coverage\u0026rdquo; report. Although you can find several posts about the intricacies of code coverage for PowerShell, you may be asking yourself what is code coverage in simple terms.\nDefining Code Coverage Coupled with tests, code coverage is a metric that measures how much of the code is tested.\nThis is helpful to realize the test written is really covering for all the \u0026ldquo;features\u0026rdquo; of the code. A function with a test is a good thing. A function with a test that covers the 10% of the lines definitely helps, but tells you that a lot of the code involved may not be failproof.\nWhile reaching 100% is not entirely possible due to Powershell limitations, it should be the goal for everyone. The more code coverage we reach:\nthe more stable the module. the more \u0026ldquo;situations\u0026rdquo; are being checked and handled correctly the more tests will be complete, documenting what to expect from the function the more documentation about how a function needs to behave, the more users can fiddle with the code and add features being sure they don\u0026rsquo;t break anything in the process We run a suite of tests at each commit via appveyor. The service we chose for code coverage is codecov. We chose them mostly due to the fact that their support is great and we needed their exclusive feature of \u0026ldquo;merge report\u0026rdquo; because we run different test suites for each build (even some C# code). Also, its interface is as good as a code coverage report can be, you can see the full source code and line-by-line coverage.\ndbatools Coverage For public consumption, our development branch shows the most current coverage report for the whole project.\nNow that the project is open about coverage metrics, you can contribute to the project writing more complete tests for all functions which are not 100% covered.\nLet\u0026rsquo;s see a practical example.\nA few days ago, on 2017-11-13, the development branch showed Get-DbaDbRecoveryModel.ps1 with a 90% coverage. Codecov\u0026rsquo;s urls are prettier but for the sake of this blogpost, which must point to specific commits, they\u0026rsquo;ll be lengthy and ugly.\nClicking on the function itself, you can see that only one line is specifically not covered\nLine 87 basically is about the possibility to specify a specific recovery model as a filter to retrieve only matching databases.\nIf you run Get-Help Get-DbaDbRecoveryModel you\u0026rsquo;ll see this parameter\n-RecoveryModel \u0026lt;String[]\u0026gt; Filters the output based on Recovery Model. Valid options are Simple, Full and BulkLogged Details about the recovery models can be found here: https://learn.microsoft.com/en-us/sql/relational-databases/backup-restore/recovery-models-sql-server If you inspect the relevant test you\u0026rsquo;ll see there is nothing relative to that specific parameter.\nUnfortunately, this means that if someone makes a modification to the function in the future, there won\u0026rsquo;t be any assurance that parameter continues to work as expected. We want to extend that test to include that too, so that the behaviour will always be the same.\nGiving More Coverage First, we need to create a database to test against the new case. Remembering that dbatoolsci_ is the default prefix for any resource created, let\u0026rsquo;s go with dbatoolsci_getrecoverymodel.\nCannibalizing a recurrent pattern seen in most tests, let\u0026rsquo;s add a new Context with a BeforeAll and an AfterAll stanzas to keep everything clean\nContext \u0026#34;RecoveryModel parameter works\u0026#34; { BeforeAll { $server = Connect-DbaInstance -SqlInstance $script:instance2 $dbname = \u0026#34;dbatoolsci_getrecoverymodel\u0026#34; Get-DbaDatabase -SqlInstance $server -Database $dbname | Remove-DbaDatabase -Confirm:$false $server.Query(\u0026#34;CREATE DATABASE $dbname; ALTER DATABASE $dbname SET RECOVERY BULK_LOGGED WITH NO_WAIT;\u0026#34;) } AfterAll { Get-DbaDatabase -SqlInstance $script:instance2 -Database $dbname | Remove-DbaDatabase -Confirm:$false } } Summing up, BeforeAll runs before ANY test within the upper-level stanza (in our case, the brand new Context), while AfterAll runs after, no matter the results (keeping things clean is a priority, so cleanup needs to run no matter what)\nYou\u0026rsquo;ll see the BeforeAll checks and removes any preexisting dbatoolsci_getrecoverymodel database, it then proceeds to create a new one with BULK_LOGGED. The AfterAll instead just removes the database we created. Then, we create the real test case:\nIt \u0026#34;gets the newly created database with the correct recovery model\u0026#34; { $results = Get-DbaDbRecoveryModel -SqlInstance $script:instance2 -Database $dbname $results.RecoveryModel -eq \u0026#39;BulkLogged\u0026#39; | Should Be $true } It \u0026#34;honors the RecoveryModel parameter filter\u0026#34; { $results = Get-DbaDbRecoveryModel -SqlInstance $script:instance2 -RecoveryModel BulkLogged $results.Name -contains $dbname | Should Be $true } Now, let\u0026rsquo;s run the test locally, before submitting our changes. Create a C:\\Temp\\constants.ps1 or a .\\tests\\local.constants.ps1 that points to a live instance (in my case, the simplest of them all, localhost, results in this)\nPS C:\\dbatools-dev\\tests\u0026gt; get-content .\\constants.local.ps1 $script:instance1 = \u0026#34;localhost\u0026#34; $script:instance2 = \u0026#34;localhost\u0026#34; $script:instance1_detailed = \u0026#34;localhost,1433\u0026#34; $script:appveyorlabrepo = \u0026#34;C:\\github\\appveyor-lab\u0026#34; $instances = @($script:instance1, $script:instance2) $ssisserver = \u0026#34;localhost\u0026#34; Then, let\u0026rsquo;s launch the test\n.\\manual.pester.ps1 -path .\\Get-DbaDbRecoveryModel.Tests.ps1 -TestIntegration Merging to the dbatools Repository Now that we\u0026rsquo;ve confirmed that everything checks out, let\u0026rsquo;s create the pull request (PR).\nFirst, we open a proper feature branch spawned from development\ngit checkout development git checkout -b tests/Get-DbaRecoveryModel add the relevant commits, then push the new branch\ngit push origin tests/Get-DbaRecoveryModel wait a few seconds, go on github and create the PR\nchange the base branch to development\nOnce you filled out the details, you\u0026rsquo;ll have written something like this PR\nNow, we just wait for the build to complete (impatient ones, watch appveyor\u0026rsquo;s dbatools \u0026ldquo;homepage\u0026rdquo; to monitor the status in real-time)\nInspecting the Results Once the build has done, the list of recent opened PRs on codecov is at dbatools.io/coverage\nIf you inspect the one I created with this blogpost, which is #2646 , when you browse to the functions folder to see what happened with the coverage of Get-DbaRecoveryModel.ps1 … voilà\nYou can click further to see the details: you can see that the line which wasn\u0026rsquo;t covered is now green.\nEnjoyed this post? Come join the Pester-lovers on Slack\u0026rsquo;s #dbatools-pester to improve current tests!\nCiao! Simone 🇮🇹\n","date":"2017-11-17","summary":"A recent addition to the release pipeline is the \u0026ldquo;code coverage\u0026rdquo; report. Although you can find several posts about the intricacies of code coverage for PowerShell, you may be asking yourself what is code coverage in simple terms.\nDefining Code Coverage Coupled with tests, code coverage is a metric that measures how much of the code is tested.\nThis is helpful to realize the test written is really covering for all the \u0026ldquo;features\u0026rdquo; of the code.","tags":["party"],"title":"Improving Tests: Code Coverage Use Case","type":"post","url":"https://dbatools.io/improving-tests/"},{"categories":["announcements"],"content":"I have to wake up at 3am to go to the airport and start a solid two weeks of vacation, so I\u0026rsquo;ll keep this incredibly short.\nTonight, we released picklerick. It has 323 super useful, tested commands but what\u0026rsquo;s especially great about this release is that now, we get along better with your SQL Servers. We no longer hang out longer than we\u0026rsquo;re supposed to and dbatools creates connections that are part of the SQL Connection Pool.\nI actually thought we already were, but it appears that creating the connection with an explicit $server.ConnectionContext.Connect() bypasses the connection pool. Turns out, we should use $server.ConnectionContext.SqlConnectionObject.Open() instead. Hat tip to (newly minted MVP!) Shawn Melton and Jay Robinson for that super solid fix.\nSo if you found dbatools hanging out for too long, please do update to 0.9.105 or above.\nAlso, this GitHub/Power BI/dbatools post from Marcos Freccia is super cool and you should check it out!\nIn addition, just an FYI: 2018 will be dedicated to more formalized releases, hella documentation and hopefully a tech book about dbatools. So expect to see that soon. Meanwhile, I\u0026rsquo;m off to 🇯🇵 with one of my high school best friends and my wife.\nAu revoir! - Chrissy\n","date":"2017-11-17","summary":"I have to wake up at 3am to go to the airport and start a solid two weeks of vacation, so I\u0026rsquo;ll keep this incredibly short.\nTonight, we released picklerick. It has 323 super useful, tested commands but what\u0026rsquo;s especially great about this release is that now, we get along better with your SQL Servers. We no longer hang out longer than we\u0026rsquo;re supposed to and dbatools creates connections that are part of the SQL Connection Pool.","tags":["party"],"title":"New Release - PickleRick","type":"post","url":"https://dbatools.io/picklerick/"},{"categories":["announcements"],"content":"A few months back, dbatools wizard Fred created a prompt that was so awesome, I never had to use Measure-Command again. It was cool enough that a number of us ended up adopting it, so I figured I\u0026rsquo;d share.\nPerformance is important to us so that\u0026rsquo;s what the prompt is all about. Nothing fancy, just the current working directory and how long the command took to run.\nPowerShell [16:46:06] C:\\github\\dbatools\u003e Get-DbaDatabase -SqlInstance sql2016 -Database master ComputerName : sql2016 InstanceName : MSSQLSERVER SqlInstance : sql2016 Name : master Status : Normal IsAccessible : True RecoveryModel : Full LogReuseWaitStatus : Nothing SizeMB : 92 Compatibility : Version130 Collation : SQL_Latin1_General_CP1_CI_AS Owner : sa LastFullBackup : 10/11/2017 2:39:07 PM LastDiffBackup : 1/1/0001 12:00:00 AM LastLogBackup : 1/1/0001 12:00:00 AM [16:46:21][740.43 ms] C:\\github\\dbatools\u003e Get-DbaDatabase -SqlInstance sql2016 -Database master ComputerName : sql2016 InstanceName : MSSQLSERVER SqlInstance : sql2016 Name : master Status : Normal IsAccessible : True RecoveryModel : Full LogReuseWaitStatus : Nothing SizeMB : 92 Compatibility : Version130 Collation : SQL_Latin1_General_CP1_CI_AS Owner : sa LastFullBackup : 10/11/2017 2:39:07 PM LastDiffBackup : 1/1/0001 12:00:00 AM LastLogBackup : 1/1/0001 12:00:00 AM [16:47:19][110.55 ms] C:\\github\\dbatools\u003e As you can see in the output above, the first time Get-DbaDatabase runs, it takes 740 ms. This is because we\u0026rsquo;re caching the database names, login names, and some other auto-populated variables in the background.\nWhen the command runs again, it takes a more reasonable 110ms to complete because it is not performing any caching.\nWant this prompt for yourself? Here it is. Just notepad $profile, paste this in, save and restart your console. Note that you may have to restart ISE twice if you\u0026rsquo;re using the ISE.\nfunction Prompt { Write-Host \u0026#34;[\u0026#34; -NoNewline Write-Host (Get-Date -Format \u0026#34;HH:mm:ss\u0026#34;) -ForegroundColor Gray -NoNewline try { $history = Get-History -ErrorAction Ignore if ($history) { Write-Host \u0026#34;][\u0026#34; -NoNewline if (([System.Management.Automation.PSTypeName]\u0026#39;Sqlcollaborative.Dbatools.Utility.DbaTimeSpanPretty\u0026#39;).Type) { Write-Host ([Sqlcollaborative.Dbatools.Utility.DbaTimeSpanPretty]($history[-1].EndExecutionTime - $history[-1].StartExecutionTime)) -ForegroundColor Gray -NoNewline } else { Write-Host ($history[-1].EndExecutionTime - $history[-1].StartExecutionTime) -ForegroundColor Gray -NoNewline } } } catch { } Write-Host \u0026#34;] $($executionContext.SessionState.Path.CurrentLocation.ProviderPath)\u0026#34; -NoNewline \u0026#34;\u0026gt; \u0026#34; } What the heck is DbaTimeSpanPretty? I asked Fred for a pretty timespan and he created a C# type to make timespans a bit tidier and… pretty 😂\nThanks, Fred, for all the features!\n- Chrissy\n","date":"2017-10-25","summary":"A few months back, dbatools wizard Fred created a prompt that was so awesome, I never had to use Measure-Command again. It was cool enough that a number of us ended up adopting it, so I figured I\u0026rsquo;d share. Performance is important to us so that\u0026rsquo;s what the prompt is all about. Nothing fancy, just the current working directory and how long the command took to run. PowerShell [16:46:06] C:\\github\\dbatools\u003e Get-DbaDatabase -SqlInstance sql2016 -Database master ComputerName : sql2016 InstanceName : MSSQLSERVER SqlInstance : sql2016 Name : master Status : Normal IsAccessible : True RecoveryModel : Full LogReuseWaitStatus : Nothing SizeMB : 92 Compatibility : Version130 Collation : SQL_Latin1_General_CP1_CI_AS Owner : sa LastFullBackup : 10/11/2017 2:39:07 PM LastDiffBackup : 1/1/0001 12:00:00 AM LastLogBackup : 1/1/0001 12:00:00 AM [16:46:21][740.","tags":["party"],"title":"Our Prompt","type":"post","url":"https://dbatools.io/prompt/"},{"categories":[],"content":"Before Apple created the App Store and Microsoft created the Microsoft Store, Linux users basked in the glory of how easy it was to install programs or packages from centralized stores using Package Managers and remote repositories.\nFor years, power users requested a PowerShell version of apt-get and in 2014 Microsoft delivered with the introduction of the PowerShell Gallery and an accompanying module that allowed users to just Install-Module to install new modules, PowerShell\u0026rsquo;s version of a package.\nInstalling dbatools From a Super Fresh Windows 10 Install It\u0026rsquo;s easy for PowerShell toolmakers to forget that new users may have questions about ExecutionPolicy and Repositories. If dbatools is the first module you\u0026rsquo;ve ever installed and used, this guide is intended to help you with all of your install/setup questions and concerns.\nIn order to emulate what your experience may be like, I spun up a fresh Windows 10 instance in Azure and went through all of the required steps which include addressing:\nSetting the Execution Policy Explicitly trusting Microsoft\u0026rsquo;s PowerShell Gallery repository Installing dbatools Explicitly trusting dbatools as a Publisher, before first use Execution Policy PowerShell\u0026rsquo;s ExecutionPolicy is often misunderstood, but basically it\u0026rsquo;s there for safety not security. Jeffrey Snover once noted that Microsoft intentionally added the Bypass option. Looking for security? Security experts like Matt Graeber recommend Application white listing.\nThe default Execution Policy is Restricted. Microsoft says this about Restricted:\nDoes not load configuration files or run scripts. Restricted is the default execution policy.\nPowerShell PS C:\\Users\\dbatools\u003e Get-ExecutionPolicy Restricted PS C:\\Users\\dbatools\u003e I haven\u0026rsquo;t dug around too much, but I it appears that at least one module, PSReadLine, is allowed to run, because the text is still colorful and pretty. Based on this and the fact that Install-Module is allowed to run even in Restricted mode, I assume that all default Microsoft-signed modules are allowed.\ndbatools Minimum Requirement Most PowerShell books directed at local development suggest you change your ExecutionPolicy to RemoteSigned. RemoteSigned basically means that all scripts and modules not located on your local computer must be signed. It is what most books will tell you to set your ExecutionPolicy to so that you can code locally.\nThanks to CloudDBA\u0026rsquo;s generosity, our module is professionally signed using a code signing certificate from DigiCert. This means that you can use our module even if your environment is set to the second most restrictive Execution Policy, AllSigned. AllSigned is probably most popular on restrictive Enterprise networks.\nPowerShell PS C:\\Users\\dbatools\u003e Set-ExecutionPolicy AllSigned Execution Policy Change The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose you to the security risks described in the about_Execution_Policies help topic at http://go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is \"N\"): Code:\nSet-ExecutionPolicy -Scope CurrentUser AllSigned\nOR, more realistically, set your execution policy to RemoteSigned so you can create scripts on your local machine.\nSet-ExecutionPolicy -Scope CurrentUser RemoteSigned\nTrusting Microsoft\u0026rsquo;s Default Repository Now that we\u0026rsquo;ve got the Execution Policy squared away, let\u0026rsquo;s move on to the PowerShell Gallery.\nFollowing PowerShell\u0026rsquo;s Security Guiding Principles, Microsoft doesn\u0026rsquo;t trust its own repository by default. This is in spite of the fact that it\u0026rsquo;s super safe and all uploads are analyzed for viruses and malicious code.\nNow that you know the Gallery is trustworthy, tell your computer to trust it as well (otherwise you\u0026rsquo;ll be prompted every time.)\nPowerShell PS C:\\Users\\dbatools\u003e Set-PSRepository -Name PSGallery -InstallationPolicy Trusted NuGet provider is required to continue PowerShellGet requires NuGet provider version '2.8.5.201' or newer to interact with NuGet-based repositories. The NuGet provider must be available in 'C:\\Program Files\\PackageManagement\\ProviderAssemblies' or 'C:\\Users\\dbatools\\AppData\\Local\\PackageManagement\\ProviderAssemblies'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet to install and import the NuGet provider now? [Y] Yes [N] No [S] Suspend [?] Help (default is \"Y\"): Code:\nSet-PSRepository -Name PSGallery -InstallationPolicy Trusted\nInstall dbatools Now that you trust the PowerShell Gallery, you can install the module, prompt free.\nPowerShell PS C:\\Users\\dbatools\u003e Install-Module dbatools PowerShell Installing package 'dbatools' - Unzipping [oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ] Code:\nInstall-Module dbatools\ndbatools as a Trusted Publisher I was so excited when we published our first signed version, reversegiraffe but was kind of disappointed that users were required to explicitly trust us as a publisher. I was under the impression that a good code signing cert (which took a lot of work, proof of identity and faxing of documents) was automatically trusted.\nConsidering Microsoft doesn\u0026rsquo;t trust its own Gallery by default, this made sense. Go ahead and trust us by forcing an import of the module, then A for Always.\nPowerShell PS C:\\Users\\dbatools\u003e Import-Module dbatools Do you want to run software from this untrusted publisher? File C:\\Program Files\\WindowsPowerShell\\Modules\\dbatools\\0.9.69\\xml\\dbatools.Format.ps 1xml1 is published by CN=dbatools, O=dbatools, L=Vienna, S=Virginia, C=US and is not trusted on your system. Only run scripts from trusted publishers. [V] Never run [D] Do not run [R] Run once [A] Always run [?] Help (default is \"D\"): Code:\nImport-Module dbatools\nNote: dbatools is installed to your $env:PSModulePath so explicit imports are not required at any other point; dbatools will automatically load once you run one of our commands.\nWhat does trusting a publisher do? It places our public key into your Current User\u0026rsquo;s Trusted Publisher PKI store.\nCool!\nGo to Town Now that you\u0026rsquo;ve set your execution policy, trusted the gallery, installed dbatools, and trusted us as a publisher, you\u0026rsquo;re set. Just run a command!\nPowerShell PS C:\\Users\\dbatools\u003e Get-DbaDatabase -SqlInstance Want to see more? dbatools Major Contributor William Durkin of CloudDBA made a video! And it\u0026rsquo;s not even silent!\nhttps://www.youtube.com/embed/p8N2jaxBc08\nThanks for reading,\nChrissy ","date":"2017-10-18","summary":"Before Apple created the App Store and Microsoft created the Microsoft Store, Linux users basked in the glory of how easy it was to install programs or packages from centralized stores using Package Managers and remote repositories.\nFor years, power users requested a PowerShell version of apt-get and in 2014 Microsoft delivered with the introduction of the PowerShell Gallery and an accompanying module that allowed users to just Install-Module to install new modules, PowerShell\u0026rsquo;s version of a package.","tags":["party"],"title":"Walk-Thru: Installing Modules from the PowerShell Gallery","type":"post","url":"https://dbatools.io/soup2nutz/"},{"categories":["announcements"],"content":"Yet another post from the dbatools team, I\u0026rsquo;m Simone Bizzotto. Hit me up on Slack, I\u0026rsquo;m @niphlod.\nThe Problem Even the accidental DBA has to manage those pesky SQL Server Updates. Be it a bug fix, a security fix, a \u0026ldquo;new features\u0026rdquo; release, well… it needs to be installed.\nPut auditor in the mix: what build are you on ? Put your bosses\u0026rsquo; boss in the mix: is the farm still officially supported by MS ? Put a developer in the mix: do we have that bug fixed, or that shiny new feature ? Put every DBA in the mix: we manage a fleet of SQL Servers and we want them to be updated regularly, with all of the versions on par of what it has been carefully tested on a non-production instance. A quick search on google sends you - probably - to the most famous \u0026ldquo;build list\u0026rdquo; : sqlserverbuilds.blogspot.com\nIf you\u0026rsquo;re managing other MS product, you\u0026rsquo;d have this bookmarked already : buildnumbers.wordpress.com\nIf you\u0026rsquo;re subscribed to sqlservercentral (and you haven\u0026rsquo;t missed the post), you know about sqlbuilds.ekelmans.com\nIf you follow Brent Ozar, you\u0026rsquo;ll know about sqlserverupdates.com\nIf you\u0026rsquo;re a technet addict, you\u0026rsquo;ll end up on Learn Microsoft: Latest Updates for SQL Server\nIf someone comes up with \u0026ldquo;are you still on an officially supported version?\u0026rdquo; question, you\u0026rsquo;ll go on to search Microsoft Product Lifecycle Information.\nAnd I\u0026rsquo;m totally sure I\u0026rsquo;m missing a few.\nAll of the above sites/lists are maintained by a different set of people (kudos to everyone), who helped DBAs, but all for different \u0026ldquo;angles\u0026rdquo;; every time you need a complete set of information, you need to go on more than one of those lists. And every time you need to get what version your instance is, well, you need to go fetch it.\nThe Solutions Enter the JSON-based dbatools commmand, Get-DbaBuildReference, and accompanying build website! Back in March, dbatools released a shiny new command, which will save you a lot of time in the \u0026ldquo;inventory\u0026rdquo; part of the deal.\nThe Command You get back on a jiffy:\nthe Build the Major Release the Service Pack the Cumulative Update the KB related to that version when the support for that version ends if all of the above are matching a verified build if a warning is shown, you passed a bad build or the JSON must be updated How can it do that? We needed to compose yet another source of information, coming from all of the information we could get our hands on.\nIt\u0026rsquo;s been a crafty work, but we just couldn\u0026rsquo;t fetch that info programmatically while being sure it was correct (or speedy). If you dabble in Powershell, you can execute the following and note an -Update switch.\nGet-Help Get-DbaBuildReference\nIf you are more curious , you can check out the source.\nYou\u0026rsquo;ll see that information comes from a json file, which is shipped with the module, and that the -Update switch fetches a publicly available json file from https://sqlcollaborative.github.io/assets/dbatools-buildref-index.json.\nOMG the Website Our PowerShell command is easy to use but some just won\u0026rsquo;t dabble in Powershell. For everyone\u0026rsquo;s delight (hopefully), we crafted a page that builds a nice table containing all the build information, and it just does that based on that json file. So the same JSON file that powers Get-DbaBuildReference is being used to power this super easy to use site.\nHell, you can even fetch the source and host it yourself.\nNeed the info? Bookmark dbatools.io/builds, hit it, enter your build number in the search box and have all the info back. I\u0026rsquo;m not a fast clicker and had this done in less than 2 seconds.\nAre you a spreadsheet fan? Presto! Press on \u0026ldquo;Copy\u0026rdquo; or \u0026ldquo;Excel\u0026rdquo; and lookup (or VLOOKUP) all the way.\nOpen Source Means Even Faster Updates The website, the command and the json are all publicly available and editable. The website is hosted on gh-pages, and dbatools is on GitHub.\nMoreover, dbatools welcome any type of contributors, even casual ones (there\u0026rsquo;s more than 900 people in Slack). This means that anyone, even drive-by contributors, can help keep the build reference updated. If you know of a missing build, you can hit us up on Slack, open a GitHub issue, send a mail, send pigeons… The index will be updated, and everyone will benefit.\nJoin us, help every other person tracking builds effectively!\nCiao! Simone 🇮🇹\n","date":"2017-10-16","summary":"Yet another post from the dbatools team, I\u0026rsquo;m Simone Bizzotto. Hit me up on Slack, I\u0026rsquo;m @niphlod.\nThe Problem Even the accidental DBA has to manage those pesky SQL Server Updates. Be it a bug fix, a security fix, a \u0026ldquo;new features\u0026rdquo; release, well… it needs to be installed.\nPut auditor in the mix: what build are you on ? Put your bosses\u0026rsquo; boss in the mix: is the farm still officially supported by MS ?","tags":["party"],"title":"Introducing the Community-Driven Build Reference","type":"post","url":"https://dbatools.io/buildref/"},{"categories":["announcements"],"content":"We\u0026rsquo;ve been working on our precon and we\u0026rsquo;re super excited to share the agenda with you!\nIn Case You Missed It dbatools teammates Constantine Kokkinos, Rob Sewell and I will be presenting a full-day session at PASS Summit in Seattle, WA, USA on Tuesday, October 31, 2017! Our precon will have a lab and we\u0026rsquo;re nearly at capacity — you\u0026rsquo;ll need to sign up now to ensure a spot.\nMajor Contributors Shawn Melton, Sander Stad and Brandon Abshire will help proctor the docker-based SQL Server lab.\nYou may notice that Aaron Nelson is no longer a part of the precon 😌 He had a scheduling conflict and will be presenting with his coworker Paul Turley at the BI Precon, which is also the same day.\nAgenda Here is our carefully crafted agenda. It is intended to provide a solid overview of SQL Server PowerShell and leave you feeling pumped about getting ready to code in PowerShell, whether you are a SQL DBA, Developer or BI Dev.\nMorning In the morning, we open with a short session about the history of SQL PowerShell and where we are today. CK will then give an introductory session that demonstrates how PowerShell and T-SQL can be alike.\nNext, I will talk about the benefits of PowerShell and give practical examples that demonstrate when to choose PowerShell and when to stick with T-SQL. Then, by request, I\u0026rsquo;ll briefly discuss PowerShell remoting, which provides a natural segue to addressing community concerns about PowerShell security.\nFinally, Rob will no doubt explode onto the stage, sharing how Pester is a game changer for SQL Server DBAs and developers. He\u0026rsquo;ll also discuss how we use Pester and live SQL Server instances within our own projects to keep quality high and bugs low.\nAfternoon After lunch we will jump into dbatools where CK will lead you through a docker-based lab. The lab will include audience participation where we will perform a migration and demonstrate some of our most useful (and fun) commands in an isolated, contained environment.\nNext up, Rob will share best practices about scheduling PowerShell tasks in SQL Server Agent. Then I\u0026rsquo;ll discuss SQL PowerShell development within dbatools and perform some live coding.\nFinally, we\u0026rsquo;ll conclude with a roundtable of SQL PowerShell lessons learned.\nSlack-Integrated Precon Before and during the precon, we\u0026rsquo;re offering a private channel in the SQL Server Community Slack where you can ask questions and get answers from teammates in real time. This is offered, in addition to asking questions in person, for those that are a bit shy or need an extended explanation during the precon.\nSeats Are Limited Because of the hands-on lab, seats have been limited so if you want to learn PowerShell from the dbatools team, head to the PASS Summit Precon Page and sign up! We\u0026rsquo;re all looking forward to seeing you there.\nFor those of you who have already signed up, expect to hear from us soon about the simplified lab setup and private Slack channel.\n- Chrissy\n","date":"2017-10-08","summary":"We\u0026rsquo;ve been working on our precon and we\u0026rsquo;re super excited to share the agenda with you!\nIn Case You Missed It dbatools teammates Constantine Kokkinos, Rob Sewell and I will be presenting a full-day session at PASS Summit in Seattle, WA, USA on Tuesday, October 31, 2017! Our precon will have a lab and we\u0026rsquo;re nearly at capacity — you\u0026rsquo;ll need to sign up now to ensure a spot.\nMajor Contributors Shawn Melton, Sander Stad and Brandon Abshire will help proctor the docker-based SQL Server lab.","tags":["precon","summit"],"title":"PASS Summit PowerShell Precon Agenda Now Available","type":"post","url":"https://dbatools.io/precon/"},{"categories":["announcements"],"content":"We\u0026rsquo;ve had a lot of people ask about the best way to schedule dbatools tasks in SQL Server Agent. I recently switched Agent from Task Scheduler and here\u0026rsquo;s what I learned.\ntl;dr for those of you who just want to skip the commentary of pros vs cons and head straight to the tutorial, click Scheduling PowerShell Tasks using Agent\u0026rsquo;s CmdExec.\nTask Scheduler Task Scheduler was decent but ultimately, not as cool as SQL Server Agent for a number of reasons:\nTask Scheduler lacks credential management The console can\u0026rsquo;t be completely hidden without administrator access Email on failure is a pain Logging is lackluster Scheduling is not as granular as the Agent Credentials With regards to credentials, you can add a task under another credential but it\u0026rsquo;s so manual. Got fifteen scheduled tasks? Get ready to add that credential fifteen different times. Need to update the password? Yep, fifteen times.\nScheduling PowerShell tasks in Task Scheduler\nNow, as Fred Weinmann pointed out, you can also use PowerShell itself to manage credentials in a number of ways. But I prefer built-in management.\nThe Dreaded Popup Window Next is the PowerShell window that pops up for a millisecond when tasks are running. You can avoid this by selecting \u0026ldquo;Run whether the user is logged in or not\u0026rdquo; but this requires Administrator access.\nThe internet has a bunch of other suggestions that are usually cautioned with \u0026ldquo;but this does show for a moment\u0026rdquo;. A moment too long, for sure.\nEmail Options for emailing were nasty, too. Unlike SQL Server where it\u0026rsquo;s managed and built-in, natively emailing in Task Scheduler is awkward at best and deprecated at worst.\nAgain, Fred pointed out that email can be sent using PowerShell\u0026rsquo;s Send-MailMessage but the Agent handles emailing on failure in a more straightforward manner. Similar to credentials, email management is just easier and built-in to Agent.\nLogging Like email, logging in Task Scheduler leaves a lot to be desired. Unless you generate a log or write to Windows Events, it is difficult to find out why it failed. In Agent, it\u0026rsquo;s easy to find the failures in Job History.\n(What\u0026rsquo;s fun about blogging is sometimes, you realize just how bad something is because you have to write it all out. Wow, Task Scheduler is really inferior to SQL Server Agent.)\nGranularity of Scheduling Shawn Melton pointed out that in Task Scheduler, he was unable to setup a task that runs every hour between 8am and 6pm. However, this is possible in SQL Server Agent.\nSQL Server Agent Agent is awesome and the solution to all of my issues so far. Well, Agent with a CmdExec Job Step is the solution to all of my issues so far. I really wanted to use the PowerShell Job Step but I\u0026rsquo;ve lost faith in it. I encountered all kinds of issues, including the inability to access UNC shares without prepending the variable with Microsoft.PowerShell.Core\\FileSystem::\nIn Shawn\u0026rsquo;s fantastic post about Agent and dbatools, he outlines other problems including the fact that many (all?) external modules can\u0026rsquo;t load in the SQLPS host, which the PowerShell step still uses, even in SQL Server 2016. Note that the SQLPS host on the server-side is different from the updated SqlServer module, which is now available in the PowerShell Gallery.\nCmdExec Job Step vs PowerShell Job Step Derik Hammer also had a great post back in 2015 that detailed the differences between the two most popular ways to invoke PowerShell in an Agent job.\nHere\u0026rsquo;s a (slightly updated) version of Derik\u0026rsquo;s chart.\nSo it basically boils down to this:\nPowerShell Job Step CmdExec Job Step sqlps.exe powershell.exe via cmd.exe Version varies by SQL Server version Version is always the system version Doesn\u0026rsquo;t always (rarely?) work as expected Often (always?) works as expected And now that we\u0026rsquo;re all convinced to use the CmdExec Job Step, let\u0026rsquo;s set one up.\nScheduling Tasks using Agent\u0026rsquo;s CmdExec By default, only members of the sysadmin role are allowed to create jobs with the CmdExec Job Step, but adding non-sysadmins as principals to the CmdExec proxy works as well.\nSo here are the steps that I use to schedule my tasks:\nCreate a Windows-based Login in SQL Server Ensure dbatools is available to the account Create a SQL Server Credential Create the Agent Proxy Create the PowerShell .ps1 file Create the Job and Job Step Create a Windows-Based Login in SQL Server This is out of scope for this post, but check out Microsoft\u0026rsquo;s page on logins if you need.\nNote that you can easily manage remote SQL Servers from a centralized SQL Server Agent. In order to do this, you will need to provide the login with appropriate permissions on the remote SQL and Windows servers.\nEnsure dbatools is Available to the Account Basically, you can do this by performing an explicit import of the module (Import-Module path\\to\\dbatools\\dbatools.psd1) to the exact path or, my preference, ensuring dbatools is globally available to all accounts on the server.\nYou can do this by placing dbatools in Program Files\\WindowsPowerShell\\Modules or using Install-Module dbatools from an admin prompt, which will do the same.\nSetup a SQL Server Credential After the login has been created, I use the credentials (the AD username \u0026amp; password) to create a SQL Server Credential (Instance -\u0026gt; Security -\u0026gt; Credentials).\nIn this example, I called it the PowerShell Service Account, but admittedly, that\u0026rsquo;s a bit broad. In reality, I probably created an account like \u0026ldquo;SQL Server Audit Account\u0026rdquo; and limited my distinct auditing task requirements to that user.\nWhile the SQL Server Agent service account could be used across the board, it\u0026rsquo;s better to use a distinct credential for my PowerShell tasks. This enables the granting of specific permissions to the account, as they are required.\nSetup a SQL Agent Proxy Once the credential has been created, it must be associated with the CmdExec proxy (Instance -\u0026gt; SQL Server Agent -\u0026gt; Proxies) to ensure it appears in the drop down once you create your SQL Agent Job Step.\nIn this case, I named the proxy \u0026ldquo;PowerShell Proxy\u0026rdquo; and gave it the credential I just created, \u0026ldquo;PowerShell Service Account\u0026rdquo;.\nCreate the PowerShell .ps1 file Since we\u0026rsquo;ll be calling PowerShell from the command line, it\u0026rsquo;s easiest to create a .ps1 file and save it to a location that is accessible by the the Windows Server running the SQL instance. Remember, the job will run from the SQL Server\u0026rsquo;s perspective, so that instance should be able to access it.\nI usually have a management SQL Server that runs all the jobs, so I save the file locally, but if I didn\u0026rsquo;t, I\u0026rsquo;d likely have a repository of scripts on a file share.\nIt\u0026rsquo;s also possible to setup an internal PowerShell Gallery as a central repository for scripts and modules that Agent Job Scripts can import. This could make it simpler from a management, version control and updatability point of view.\nCreate the Job and Job Step Next, create the job as whatever you like, then when you get to the Job Step, create it as Operating System (CmdExec) and change the Run as: to your newly created proxy account.\nIn the Command: area, enter powershell.exe -File \\location\\to\\file.ps1\nNeed to Run As Administrator? Use -Verb runAs\nIn place of a -File path\\filename, you could actually pass a base64 string into the -EncodedCommand parameter, but I\u0026rsquo;d rather have the ability to easily modify the script without having to reencode it.\nNow You\u0026rsquo;re Set! Now you\u0026rsquo;re all set and can schedule this job just like you would any other. You can even have it email an operator on failure after enabling Agent to use Database Mail.\nTo see PowerShell and SQL Agent in practice, check out Björn Peters\u0026rsquo;s post Daily Database Copy using Powershell.\nEnsuring Failures Fail To ensure your failed jobs show a failure in SQL Agent, you must throw a terminating exception.\nTo throw a terminating exception in dbatools, use -EnableException. In most PowerShell commands, use try/catch with -ErrorAction Stop.\nIf you\u0026rsquo;re having issues and just can\u0026rsquo;t get it to fail, throw in a [System.Environment]::Exit(1) and that should certainly work.\nIn Conclusion You may be wondering why I am showing you the GUI when we\u0026rsquo;ve probably got some PowerShell commands to do this for us (we have a lot of \u0026rsquo;em!). The reason is that I wanted to convey a concept.\nOnce we\u0026rsquo;ve got the whole suite of commands, including creating a credential and proxy, we\u0026rsquo;ll create a tutorial for doing all of this but with dbatools. For the curious, we do currently offer the following Agent commands, thanks to Sander Stad.\nNew-DbaAgentJob New-DbaAgentJobStep Also, if you have any good posts about SQL Agent and PowerShell to recommend, please let me know in the comments and I\u0026rsquo;ll update the post.\nHope that was helpful! Let us know if you have any questions.\n- Chrissy\n","date":"2017-09-26","summary":"We\u0026rsquo;ve had a lot of people ask about the best way to schedule dbatools tasks in SQL Server Agent. I recently switched Agent from Task Scheduler and here\u0026rsquo;s what I learned.\ntl;dr for those of you who just want to skip the commentary of pros vs cons and head straight to the tutorial, click Scheduling PowerShell Tasks using Agent\u0026rsquo;s CmdExec.\nTask Scheduler Task Scheduler was decent but ultimately, not as cool as SQL Server Agent for a number of reasons:","tags":["party"],"title":"Scheduling PowerShell Tasks with SQL Agent","type":"post","url":"https://dbatools.io/agent/"},{"categories":["announcements"],"content":"Last month, I went through an audit that consumed every waking moment of my life. I would literally wake up, get ready for work, grab the three meals my wife made for me, go to work for 16-18 hours, come back, sleep then wake up, rinse, repeat. I tried to stay as healthy as possible by prioritizing sleep, taking vitamins, eating vegetarian meals that were easy to digest and drinking tea (and not energy drinks) as an energy source.\nAfter passing my audit (😄👍) and taking a long nap, I started a new project for crowd-sourcing the DISA Documentation Template for SQL Server. People often ask DISA for templates but they don\u0026rsquo;t have anything to provide so I\u0026rsquo;d like to change that, if only for my future self.\nIf you work for an organization that is subject to DISA inspections and believe you have some good anonymized documentation to contribute, please do! The templates are in markdown.\nProgress [============·······] Really, I said all that so that you\u0026rsquo;d hopefully excuse the recent lack of communication 😊 Not only did I have the big ol\u0026rsquo; audit, but we are also preparing for two dbatools pre-cons. One with Klaas Vandenberghe and Rob Sewell in Ghent, Belgium at dataminds and then the one in Seattle at PASS Summit.\nThis means that communication will slow a bit until December, but I wanted to give you an update. First, we\u0026rsquo;re now at a whopping 287 magical commands! We\u0026rsquo;ve got three kind folks working on the webpages and once they are all ready, I\u0026rsquo;ll do a new release. Until then, here\u0026rsquo;s over 80 newish commands that you can explore using Get-Help -Detailed.\nAdd-DbaComputerCertificate Get-DbaDbMailLog Invoke-DbaDbLogShipRecovery Backup-DbaDbMasterKey Get-DbaDbQueryStoreOption New-DbaAgentSchedule Copy-DbaAgentAlert Get-DbaDbStoredProcedure New-DbaComputerCertificate Copy-DbaInstanceAuditSpecification Get-DbaDefaultPath New-DbaCredential Disable-DbaAgHadr Get-DbaDependency New-DbaServiceMasterKey Disable-DbaForceNetworkEncryption Get-DbaFile New-DbaConnectionString Enable-DbaAgHadr Get-DbaForceNetworkEncryption New-DbaConnectionStringBuilder Enable-DbaForceNetworkEncryption Get-DbaMaintenanceSolutionLog Read-DbaTraceFile Find-DbaSimilarTable Get-DbaNetworkCertificate Remove-DbaAgentSchedule Find-DbaTrigger Get-DbaOperatingSystem Remove-DbaCmConnection Find-DbaView Get-DbaPbmPolicy Remove-DbaComputerCertificate Get-DbaAgDatabase Get-DbaRegisteredServersStore Remove-DbaDbCertificate Get-DbaAgentJobHistory Get-DbaInstanceInstallDate Remove-DbaDbMasterKey Get-DbaAgentLog Get-DbaInstanceProperty Remove-DbaDatabaseSafely Get-DbaAgentSchedule Get-DbaInstanceUserOption Remove-DbaNetworkCertificate Get-DbaAgHadr Get-DbaSqlLog Remove-DbaDbOrphanUser Get-DbaAgReplica Get-DbaManagementObject Restart-DbaService Get-DbaAvailableCollation Get-DbaRegistryRoot Restore-DbaDbCertificate Get-DbaCmConnection Get-DbaSsisEnvironmentVariable Save-DbaDiagnosticQueryScript Get-DbaComputerCertificate Get-dbatoolsLog Set-DbaAgentJobStep Get-DbaComputerSystem Get-DbaTraceFlag Set-DbaAgentSchedule Get-DbaDbPartitionFunction Get-DbaWindowsLog Set-DbaDbCompression Get-DbaDbPartitionScheme Import-DbaCsv Set-DbaDbQueryStoreOption Get-DbaDbSpace Install-DbaFirstResponderKit Set-DbaNetworkCertificate Get-DbaDbUdf Install-DbaMaintenanceSolution Start-DbaService Get-DbaDbUser Invoke-DbaCycleErrorLog Stop-DbaService Get-DbaDbView Invoke-DbaDbUpgrade Test-DbaDbCompression Get-DbaDbMailHistory Invoke-DbaDbLogShipping Test-DbaManagementObject So many of these commands are insanely useful and I can\u0026rsquo;t thank our 78 (!!) contributors enough. Also, Shawn Melton, Andy Levy and Simone Bizzotto have recently invested extra insane-o hours into moving the project forward and I\u0026rsquo;d like to give them a special shout out.\nThank you so very very much for helping the 1.0 progress during this sprint!\nThe Long, Long Road to 1.0 😂 I can\u0026rsquo;t decide if this is because I can be a perfectionist or because it legitimately takes a super long time to put out an Enterprise grade release, but you may have noticed 1.0 didn\u0026rsquo;t quite debut in June. Or July. Or August or even September. Now I know why gmail took so long to get out of beta.\nThe original goals for 1.0 were:\nStandardized names Standardized parameters Standardized documentation Standardized codebase Pipe support Tests Andy is helping like mad with standardizing the docs, and Shawn is doing a fabulous job leading a team to update the code base to the 1.0 standard - 231 out of 287 commands complete! Pipe support is still lacking and may just becoming a focus for 1.1 instead of 1.0.\nThat leaves us with tests, which Simone has been acing. He fixed our Appveyor setup and really pushed for us to create non-destructive tests, which I appreciate. Before, I was building tests as though the Appveyor environment was the ONLY environment the tests would be run on so it\u0026rsquo;d drop everything and start fresh.\nNevertheless, I\u0026rsquo;d love to see all of our commands get the 1.0 rewrite prior to 1.0 and then at least one Pester Test for each command. So that\u0026rsquo;s the final goal, whenever that\u0026rsquo;ll be, likely in December/January (maybe;))\nIn the Meantime In the meantime, we\u0026rsquo;re actually releasing quite often nowadays – sometimes up to 3 times a day! That\u0026rsquo;s because I feel a lot more confident when I see all the green generated by our integration tests.\nIf you\u0026rsquo;d like to keep up with the latest releases and use Windows 10, consider Watch-DbaUpdate. Note that Install-DbatoolsWatchUpdate does require running as admin in order to automatically setup the scheduled task.\nTTYS Once the webpages for these commands have been written, I\u0026rsquo;ll do the formal, beautiful release of picklerick.\n- Chrissy\n","date":"2017-09-13","summary":"Last month, I went through an audit that consumed every waking moment of my life. I would literally wake up, get ready for work, grab the three meals my wife made for me, go to work for 16-18 hours, come back, sleep then wake up, rinse, repeat. I tried to stay as healthy as possible by prioritizing sleep, taking vitamins, eating vegetarian meals that were easy to digest and drinking tea (and not energy drinks) as an energy source.","tags":[],"title":"287 Commands and Counting","type":"post","url":"https://dbatools.io/287-commands-and-counting/"},{"categories":["announcements"],"content":"Not a Snoozefest You may be thinking \u0026ldquo;oh man, a post about testing. booooring!\u0026rdquo; I used to, too, but have since come around and now find that creating tests is actually a lot of fun 🎉. I even have a personal goal that that every command touched by a PR gets a corresponding test. That way, we know the command works as expected and will continue to with each and every merge.\nHere\u0026rsquo;s how I came around.\nMy Nightmare When it comes to dbatools, my biggest fear is creating or allowing a command that causes data loss. What if Copy-DbaLogin -Force dropped the login on the source instead of the destination? What if the -WhatIf parameter actually executed code that modifies a setting instead of just reading and reporting on it? I was horrified when I found out that even Microsoft\u0026rsquo;s own SqlServer module, then known as SQLPS, actually did this and I\u0026rsquo;ve literally lost sleep over such possibilities with dbatools.\nEven though we\u0026rsquo;ve got our own team lab complete with over 15 test instances, I dreamed of a dedicated Azure-based lab that could spin up fresh VMs, add some objects, do a whole migration, reset all settings, then turn off until the next time we wanted to run our tests.\nTurns out, the service we actually wanted wasn\u0026rsquo;t Azure, it was a free service we were already using - Appveyor! Appveyor, when combined with Pester, the PowerShell-based unit testing framework, was exactly what I was looking for.\nMy Dream Come True Appveyor is awesome and free for open source projects. It hooks into GitHub and launches a fresh VM with each and every commit. It comes with 4 or 5 different versions of SQL Server pre-installed, and with the way we\u0026rsquo;ve got it setup, performs 8 migrations every time code is committed to our repo. How?\nWe configured Appveyor to turn on two of its pre-configured SQL Server instances once it\u0026rsquo;s booted up We chose 2008 R2 Express and 2016 Developer for widest coverage We configured Pester and Appveyor to test files in the tests directory within our repo We wrote tests for 8 of our migration (Copy-) commands and migrated between the 2008 R2 and 2016 Appveyor instances Now, I no longer have to worry that Copy-DbaLogin or Copy-DbaDatabase will inadvertently drop the object on the wrong server when the -Force parameter is used. Why? Because the tests I wrote for those two commands perform the migration, and tests the source (2008) server to ensure the object still exists.\nUltimately, the team has written nearly 600 tests that touch at least 88 of our 287 commands. Our goal for 1.0 is to at least one test for 100% of our commands. And best of all, I now have so much more confidence in the state of dbatools after I hit that Merge button.\nIt Gets Even Better One of my favorite parts of this whole testing thing happened a few months ago when when a community member submitted a GitHub Pull Request that modified Restore-DbaDatabase. Now, Restore-DbaDatabase is one of our largest and most important commands - it\u0026rsquo;s used within Copy-DbaDatabase, Test-DbaLastBackup and Invoke-DbaDbLogShipping. It was written primarily by Stuart Moore and I consider it his baby.\nIt\u0026rsquo;s rare I\u0026rsquo;ll approve a PR for this command myself because of its intricacy, and usually leave it for Stuart. So with this PR, he merges it with the comment \u0026ldquo;looks good to me and passes all tests.\u0026rdquo; Wait, what? Which tests? Then I take a look at Restore-DbaDatabase.Tests.ps1 and holy moly, this thing contains 53 glorious tests! FIFTY THREE!\nRestore-DbaDatabase Test Output Running C:\\github\\dbatools\\tests\\Restore-DbaDatabase.Tests.ps1 Context Calling with database name, no matching db on server [+] Should return successful restore 1.09s [+] Should Return the proper backup file location 2.35s Context Should not return object 57ms [+] Should return successful restore if database already exists Context Database is properly removed again after all tests [+] Should have moved file sare 207ms [+] Should have restored 39ms [+] Should restore the 2 files snapping singlerestore_log for RestoreTime 30ms Context Properly restores a database on the local drive using cat results [-] Should have the proper backup file location 2.07s [+] Should have moved file sare (output) 34ms [+] Should have moved file sare (output) 34ms Context Database is properly removed again, post prefix and suffix tests [+] Should have the status was dropped 1.01s Context Primary restores a database on the local drive using piped cat [+] Should return successful restore with prefix 4.42s [+] Should restore successful restore with prefix and suffix 1.98s [+] Should return the 2 files snapping singlerestore_log for prefix 1.98s [+] Should Return successful restore with prefix and suffix and prefix 30ms [+] Program Files\\Microsoft SQL Server\\MSSQL10.50.SQLEXPRESS\\MSSQL\\DATA\\restoreddf_should_exist_on_filesystem 59ms [+] Should be restored in c:\\temp\\singlerestore.mdf should exist on filesystem 30ms [+] Program Files\\Microsoft SQL Server\\MSSQL10.50.SQLEXPRESS\\MSSQL\\DATA\\restoreddf_should_exist_on_filesystem 31ms [+] c:\\temp\\singlerestore_log.ldf should exist on filesystem 31ms [+] c:\\temp\\singlerestore.mdf should exist on filesystem 30ms Context Database is properly removed again after ola tests [+] Should have the status was dropped 1.01s Context Primary restores are removed post WhatifTime check Context All test databases are removed post ola-style backups [+] Should have count should be 72 43 3.03s Context All test databases are removed post ola-style test [+] Should have the status was dropped 1.01s Context RestoreTime point in time 4.71s [+] Should be restored 97s [+] Should have restored to 2017-06-01 12:59:17 37ms [+] Should have restored to 2017-06-01 13:28:43 43ms Context Database is properly removed post RestoreTime check [+] Should have the status was dropped 1.01s Context RestoreTime point in time and continue Context Primary restores an instance using piped cat results [+] Should restore cleanly 5.65s [+] Should be restored x7s [+] Should have restored to the 1st 12:59:17 37ms [+] Should have restored to 2017-06-01 13:28:43 43ms Now, gone are the days of us manually testing if a command will work, forgetting to test a specific scenario or hoping that we properly remembered to test all related commands. Now, the same 53 tests will run every single time any command in the repo is modified.\nWhat a relief 😌\nMore About Pester I was first introduced to Pester by the host of this T-SQL Tuesday, Rob. I\u0026rsquo;ve gotten a chance to see many of his Pester presentations because Rob and I often present together and we even won the Best Speaker award back in June at SQL Saturday Dublin for our dbatools presentation!\nI always enjoy Rob\u0026rsquo;s sessions and find his use of Pester to test his own presentation environment totally meta and fun.\nStill, when it came to creating Pester Tests for dbatools, I deferred to other team members because I didn\u0026rsquo;t really get the type of testing we first started with - Unit Testing. Turns out, I better relate to and love Integration tests. I learned about this style of testing at PSConf.eu when I dropped in on Rob and André\u0026rsquo;s session, Test your PowerShell code with AppVeyor for ITPros.\nUnit Testing vs Integration Testing Here\u0026rsquo;s my understanding of Unit Tests vs Integration Tests.\nUnit Testing - Testing a small portion of a command in isolation and in theory. Since it\u0026rsquo;s theory, data can be faked or \u0026ldquo;mocked\u0026rdquo;. Integration Testing - Testing to see if the whole command really works, not just in theory. For us, Integration tests usually require a working SQL Server instance 😊 I think the easiest two examples of testing commands with Unit Tests are Get-DbaBuildReference.Tests.ps1 and Get-DbaMaxMemory.Tests.ps1. Note, however, that Get-DbaMaxMemory.Tests.ps1 starts with a single Integration test and then goes into a bunch of Unit Tests.\nKeeping It Simple Check out this simple Integration test for the super cool command Get-DbaSchemaChangeHistory, also created by Stuart Moore.\nHere\u0026rsquo;s a simple breakdown of this test\u0026rsquo;s structure:\nDescribe - a group of types of tests (Unit vs Integration, etc) Context - a group of tests BeforeAll - do this before all the rest of the entire test AfterAll - do this after all the tests, even if all of them fail It - the actual test In order to allow our developers (or even you!) to run these tests in their own environment without leaving junk behind, we started prepending \u0026ldquo;dbatoolsci_\u0026rdquo; to all of the objects that we create and cleaning up by deleting any objects we create. To set your own $script:instance1 and $script:instance2, add your own constants.ps1 to C:\\temp.\nSo the test\nCreates a table named in tempdb Changes the table\u0026rsquo;s schema Runs Get-DbaSchemaChangeHistory and assigns the results to $results Ensures dbatoolsci_schemachange exists in $results Drops the table dbatoolsci_schemachange This test could get a lot more detailed, of course. Microsoft\u0026rsquo;s Unit tests for just one command clocks in at over 6000 lines! But this will at least ensure the change is detected.\nHow did I come up with the test? I just thought about what I\u0026rsquo;d do if I were running the command manually and what I\u0026rsquo;d check.\nA Slightly More Advanced Example Another example of a test would be for, say, New-DbaAgentJob. The test for that command (which hasn\u0026rsquo;t been migrated to use BeforeAll \u0026amp; AfterAll)\nCreates a new job and assigns the output to $results Checks to ensure $results.Name and $results.Description are correct Tests to ensure that the job actually exists when called by Get-DbaAgentJob Ensures that attempting to create the job again doesn\u0026rsquo;t overwrite the existing job Drops the job AppVeyor in Action If you\u0026rsquo;d like to see Appveyor in action, you can watch it live (we do alll the time) at dbatools.io/ci. Some days, we\u0026rsquo;re looking really good and it\u0026rsquo;s all green\nOther days are not as good\nSometimes, failed tests are because of our code. Other times, it\u0026rsquo;s an exhaustion of resources because Appveyor only gives 2GB of ram per VM. In response, we split up our tests and now run them on three different VMs. It takes a little longer, but it\u0026rsquo;s worth it for more reliable testing.\nIf you\u0026rsquo;re wondering what a live run of Appveyor looks like, you can watch it on YouTube (sped up 4x).\nIn Conclusion There\u0026rsquo;s sooo much that could be written about Pester and Appveyor, it was a challenge to keep this post to a reasonable length. But I hope, at least, that you understand our process a little better and got some ideas on how to apply it to your own development environment. For day-to-day testing, check out Cláudio Silva\u0026rsquo;s post, which applies Pester and dbatools to regularly scheduled environmental checks!\nIf you\u0026rsquo;d like to learn more, we\u0026rsquo;ll be covering Pester during our PASS Summit Precon on October 31 in Seattle 👍 Aaron Nelson had to bail due to a scheduling conflict and the Pester-man himself Rob will be taking his place!\n- Chrissy\n","date":"2017-09-12","summary":"Not a Snoozefest You may be thinking \u0026ldquo;oh man, a post about testing. booooring!\u0026rdquo; I used to, too, but have since come around and now find that creating tests is actually a lot of fun 🎉. I even have a personal goal that that every command touched by a PR gets a corresponding test. That way, we know the command works as expected and will continue to with each and every merge.","tags":["party"],"title":"Performing a Migration With Every Commit: Testing With Pester and AppVeyor","type":"post","url":"https://dbatools.io/testing/"},{"categories":["announcements"],"content":"Constantine and I recently presented for 24 Hours of PASS and the video is now online! Our goal in this intro-level session was to help make PowerShell feel approachable and demonstrate its immediate value with commands like Get-DbaLastGoodCheckDb, Test-DbaSpn and Invoke-DbaDiagnosticQuery.\nSlides | Demo Code Entire Presentation | Demo Portion of Presentation | Included SPN Sample Video\nIf you\u0026rsquo;re already familiar with the project and would like to bypass the intro, you can jump right to the demo.\nWant to Know More? During our PASS Summit pre-con, we\u0026rsquo;re aiming to go in-depth with topics like when to use T-SQL vs. when to use PowerShell, and how you can build your own SQL PowerShell commands, complete with Pester tests, too. We\u0026rsquo;ll also touch on important topics like PowerShell Security Myths vs. Facts.\nWe\u0026rsquo;re excited about our agenda, but would also like to know what you\u0026rsquo;re looking to learn. Feel free to hit us up with requests or questions.\nChrissy\nSQL Server Community Slack (@cl) Constantine\nSQL Server Community Slack (@ck) - Chrissy\n","date":"2017-08-03","summary":"Constantine and I recently presented for 24 Hours of PASS and the video is now online! Our goal in this intro-level session was to help make PowerShell feel approachable and demonstrate its immediate value with commands like Get-DbaLastGoodCheckDb, Test-DbaSpn and Invoke-DbaDiagnosticQuery.\nSlides | Demo Code Entire Presentation | Demo Portion of Presentation | Included SPN Sample Video\nIf you\u0026rsquo;re already familiar with the project and would like to bypass the intro, you can jump right to the demo.","tags":["precon"],"title":"24 Hours of PASS Presentation - Now Online","type":"post","url":"https://dbatools.io/24hop/"},{"categories":["announcements"],"content":"If you work in a secure environment or your computers cannot access the Internet for any reason, you can still install dbatools with ease by downloading the zip from a workstation that does have Internet access 🎉 And now that our module is digitally signed, you can keep your Execution Policy set to AllSigned, too.\nThere are essentially 3 ways to get the zip of our module\nFrom PowerShell Gallery using Save-Module From PowerShell Gallery by downloading from powershellgallery.com/api/v2/package/dbatools By downloading from dbatools.io/zip Once the file has been downloaded, copy it to your secure server and place it in one of the directories in your $env:PSModulePath (type $env:PSModulePath at the prompt and press enter). This will allow PowerShell to autoload the module, saving you from having to Import-Module each time you start a new session.\nPowerShell Gallery PowerShell Gallery is Microsoft\u0026rsquo;s official repository for PowerShell modules and scripts. It\u0026rsquo;s likely unblocked at your organization, so using the Gallery is a great option.\nMethod 1 If you run Windows 10 or Windows Server 2016, you\u0026rsquo;ve already got support for the Gallery and can just issue the following command.\nSave-Module -Name dbatools -Path C:\\temp\nThis will download the package, unzip it and place it into C:\\temp\\dbatools. Saving modules and investigating their content is actually a recommended practice by the PowerShell team, as it\u0026rsquo;s always good to know what you\u0026rsquo;re installing on your system.\nMethod 2 If your system is older and you do not have PowerShellGet or you haven\u0026rsquo;t upgraded to PowerShell 5.1 (which comes with PowerShellGet), then you can just download the zip directly from the Gallery\u0026rsquo;s API.\nNote that this will download a file ending in .nupkg. Simply rename the file to .zip, extract and you\u0026rsquo;re set. You can also use PowerShell to download the module and rename it, all in one shot.\nInvoke-WebRequest -Uri powershellgallery.com/api/v2/package/dbatools -OutFile c:\\temp\\dbatools.zip\nInvoke-WebRequest is a bit slow, however, because of the progress bar, so I usually just download via GUI and rename.\nGitHub via dbatools.io/Zip You can also easily download the latest version of our master GitHub repository by simply clicking on dbatools.io/zip. If you\u0026rsquo;re adventurous, you can even download our latest dev (beta) version at dbatools.io/devzip.\nThis is just an easy-to-remember redirector to GitHub\u0026rsquo;s repo zip.\nNote that there is a small difference between our GitHub repo and the PowerShell Gallery. The GitHub repo does not include a pre-compiled version of our library (dbatools.dll), while the PowerShell Gallery does. Ultimately, both ways work and there\u0026rsquo;s really no difference. Excluding the dll from the GitHub repo just made it easier for our developers to avoid conflicts.\nOnce you\u0026rsquo;ve extracted the folder, make sure you rename it from dbatools-master or dbatools-development to plain o\u0026rsquo; dbatools.\nUnblocking DLLs Our .psm1 takes care of Unblocking DLLs, but if you use the download and unzip method for other PowerShell modules, keep in mind that the DLLs will likely be blocked by default. If this happens, simply run\nGet-ChildItem -Recurse C:\\path\\to\\module | Unblock-File\n$env:PSMODULEPATH Just a quick note about $env:PSMODULEPATH. If you\u0026rsquo;re not familiar with PSMODULEPATH, you may remember PATH from the DOS days and PSMODULEPATH is similar. Any module placed within your $env:PSMODULEPATH will automatically load once you execute a command from that module. Here, you can see the contents of my path and that I manually added my git repo.\nThanks for reading,\nChrissy ","date":"2017-07-26","summary":"If you work in a secure environment or your computers cannot access the Internet for any reason, you can still install dbatools with ease by downloading the zip from a workstation that does have Internet access 🎉 And now that our module is digitally signed, you can keep your Execution Policy set to AllSigned, too.\nThere are essentially 3 ways to get the zip of our module\nFrom PowerShell Gallery using Save-Module From PowerShell Gallery by downloading from powershellgallery.","tags":["party"],"title":"Offline Installs of dbatools","type":"post","url":"https://dbatools.io/offline-old/"},{"categories":["announcements"],"content":"Well, first we\u0026rsquo;d like to give a big ol\u0026rsquo; shoutout to our teammate and new PowerShell MVP Rob Sewell!\nRob is one of the most visible members of the SQL PowerShell community, an officer in the PASS PowerShell Virtual Group and an outstanding evangelist \u0026amp; Pester test maker for dbatools. We\u0026rsquo;re all so excited about Rob\u0026rsquo;s well-deserved recognition - love you, buddy! ❤️\nBagofbobbish Beta Testing Before the official release of bagofbobbish to master and the PowerShell Gallery, we need help finding bugs. Then, we\u0026rsquo;ll need some time to resolve those bugs. Hopefully this can be done before community members show off dbatools at a few key SQLSaturdays around the world this Saturday, July 8th.\nWe would really appreciate it if you would download the beta from GitHub and (in a test environment) see if you can find anything that doesn\u0026rsquo;t work as expected.\nIf you find any bugs, please file a report on GitHub. You can also reach out to us in the Slack channel.\nCurrently, there aren\u0026rsquo;t any webpages for the commands listed in this post, but all commands have help, so when you need help, simply type Get-Help commandName -Examples or Get-Help commandName -Full.\nWhat\u0026rsquo;s Changed? It\u0026rsquo;s been two months since our last major release and we\u0026rsquo;ve made leaps and bounds towards 1.0. Here\u0026rsquo;s a list of some of the changes included in the 1700+ commits since our last release:\nChanged command names. Particularly, all Sql prefixes have changed to Dba. Previous names are aliased, should work, and should come with a warning that the name will go away in version 1.0 Standardized many parameters such as SqlInstance Changed all plural parameters to singular (Databases → Database) Switched the backend tab-completion process from native Dynamic Parameters to TabExpansion++ Added a caching system for tab-completion Switched to pre-compiling the library into a DLL file. This allows us to improve the module import speed and make the development logistics better. Speaking of compiling, C# dev Justin Dearing recently joined the team! Now we\u0026rsquo;ll have someone to provide Fred, our in-house magician, some relief. So far, Justin\u0026rsquo;s added some efficiency cleanup, code style and tests - thanks, man!\n63 New Commands In addition to making all of those changes, we also added 63 new commands! The number is a bit high because we hadn\u0026rsquo;t announced a couple extra special ones that were previously included in the code, but not the site or blog post.\nNamely, we merged André Kamman\u0026rsquo;s Diagnostic Query commands that make working with Glenn Berry\u0026rsquo;s Diagnostic DMV Queries incredibly easy!\nDiagnostic Query Scripts Invoke-DbaDiagnosticQuery Executes the scripts provided by Glenn Berry\u0026rsquo;s DMV scripts on specified servers.\nExport-DbaDiagnosticQuery Converts output generated by Invoke-DbaDiagnosticQuery to an automatically generated CSV or Excel.\nSave-DbaDiagnosticQueryScript Automatically downloads the most recent version of all Glenn Berry DMV scripts.\nI made a pretty crude video showing Invoke-DbaDiagnosticQuery | Export-DbaDiagnosticQuery in action. It\u0026rsquo;s on YouTube, along with another quick video about Save-DbaDiagnosticQueryScript.\nMore in-depth blog post coming soon!\nSecurity Commands A bunch of security-related commands were added. I\u0026rsquo;m looking forward to a detailed blog post about these, they really simplify things like forcing network encryption.\nAdd-DbaComputerCertificate Backup-DbaDbCertificate Backup-DbaDbMasterKey Disable-DbaForceNetworkEncryption Enable-DbaForceNetworkEncryption Get-DbaComputerCertificate Get-DbaDbCertificate Get-DbaDbMasterKey Get-DbaForceNetworkEncryption Get-DbaNetworkCertificate New-DbaComputerCertificate New-DbaDbCertificate New-DbaDbMasterKey New-DbaServiceMasterKey Remove-DbaCmConnection Remove-DbaComputerCertificate Remove-DbaDbCertificate Remove-DbaDbMasterKey Remove-DbaNetworkCertificate Restore-DbaDbCertificate Set-DbaNetworkCertificate Troubleshooting Commands Along with our C# framework comes a really amazing logging system. The newest release introduces two commands that help you export logs and detailed system info for the times you encounter challenging issues.\nGet-dbatoolsLog New-dbatoolsSupportPackage Computer Management Commands We also introduced a computer management system that we\u0026rsquo;ll detail soon. These commands are primarily for our developers, but also help provide you insight into how we are connecting to your remote computers when you use a Windows-based command such as Test-DbaDiskSpace.\nWhy don\u0026rsquo;t we just use what\u0026rsquo;s out of the box with PowerShell? Well, in order to support as many systems as possible, even legacy or those with restricted access, we have a bunch of fail backs to ensure that we\u0026rsquo;ve tried our best to connect. These commands encapsulate all of our fail backs.\nGet-DbaCmObject Get-DbaCmConnection New-DbaCmConnection Set-DbaCmConnection Test-DbaCmConnection Log Shipping Sander Stad created some really cool Log Shipping wrappers! We\u0026rsquo;d love some testers to give feedback.\nInvoke-DbaDbLogShipping Invoke-DbaDbLogShipRecovery Agent Commands A bunch of Agent commands in support of the Log Shipping wrappers and Get-DbaAgentJobHistory was a cherry on top.\nGet-DbaAgentJobHistory Get-DbaAgentSchedule New-DbaAgentJob New-DbaAgentJobStep New-DbaAgentSchedule Remove-DbaAgentJob Remove-DbaAgentJobStep Remove-DbaAgentSchedule Set-DbaAgentJob Set-DbaAgentJobStep Set-DbaAgentSchedule Other Awesome Commands And here are a bunch of super fun commands! Check them out in your lab, let us know what you think.\nFind-DbaTrigger Find-DbaView Get-DbaDbSpace Get-DbaEndpoint Get-DbaMaintenanceSolutionLog Get-DbaSchemaChangeHistory Get-DbaInstanceAudit Get-DbaInstanceInstallDate Get-DbaInstanceProperty Get-DbaInstanceUserOption Get-DbaManagementObject Get-DbaSsisEnvironmentVariable Install-DbaFirstResponderKit Invoke-DbaDbUpgrade New-DbaConnectionString New-DbaConnectionStringBuilder Read-DbaTraceFile Set-DbaTcpPort Test-DbaManagementObject Testing and Reporting Issues For those of you interested in testing, thank you! Again, you can get this release by downloading the zip manually from GitHub. From there, you can manually import it using Import-Module C:\\pathto\\dbatools\\dbatools.psd1 -Force. Note that this beta release is not digitally signed but the final release will be.\nIf you find any bugs - even anything obvious like the command can\u0026rsquo;t run at all, or didn\u0026rsquo;t get aliased and therefore no longer exists, please file a bug report at dbatools.io/issues.\nIf you like any of these commands, pop in and let us know on our Slack channel. We now have nearly 800 members!\n- Chrissy\n","date":"2017-07-04","summary":"Well, first we\u0026rsquo;d like to give a big ol\u0026rsquo; shoutout to our teammate and new PowerShell MVP Rob Sewell!\nRob is one of the most visible members of the SQL PowerShell community, an officer in the PASS PowerShell Virtual Group and an outstanding evangelist \u0026amp; Pester test maker for dbatools. We\u0026rsquo;re all so excited about Rob\u0026rsquo;s well-deserved recognition - love you, buddy! ❤️\nBagofbobbish Beta Testing Before the official release of bagofbobbish to master and the PowerShell Gallery, we need help finding bugs.","tags":[],"title":"Can You Help Us Test This Beta?","type":"post","url":"https://dbatools.io/bagofbobbish-beta/"},{"categories":["announcements"],"content":"How cool is this? dbatools Major Contributor Constantine Kokkinos and I will be presenting a full-day session at PASS Summit in Seattle, WA, USA on Tuesday, October 31, 2017! Our precon will have a lab so seats are limited — you\u0026rsquo;ll need to sign up now to ensure a spot.\nRob Sewell will also be joining us as a guest presenter and it looks like teammates Sander Stad and Shawn Melton will help proctor the lab 😊\nPresenters:\nChrissy CK Rob Sander Shawn Want to know more? Here\u0026rsquo;s our abstract.\nStanding on the Shoulders of Giants: Community-proven PowerShell Solutions for Every Data Platform Pro\nYou\u0026rsquo;ve heard a lot about PowerShell recently because a lot has changed. Now, you don\u0026rsquo;t need to be a coder to get things done; you can lean on hundreds of community-created commands that solve many of the problems we all share.\nIn development and need a nightly refresh? Architecting and need to find duplicate indexes fast and easy? Putting on your BI hat and need quick importing and exporting of data? Join us and we\u0026rsquo;ll supply a hands-on lab for your laptop where you can experience PowerShell\u0026rsquo;s realized potential, crafted by both Microsoft and the SQL community.\nWhether you need a prepackaged solution or the building blocks to roll your own fix, you will leave with awesome tools to manage your most annoying problems. And maybe - hopefully - you\u0026rsquo;ll even be confident enough to contribute your own solutions to share with the community.\nSo come hang out with us at PASS Summit! You\u0026rsquo;ll get access to a super fun lab and learn more about PowerShell through both dbatools and awesome Microsoft projects at our pre-con: sqlps.io/precon.\n- Chrissy\n","date":"2017-06-14","summary":"How cool is this? dbatools Major Contributor Constantine Kokkinos and I will be presenting a full-day session at PASS Summit in Seattle, WA, USA on Tuesday, October 31, 2017! Our precon will have a lab so seats are limited — you\u0026rsquo;ll need to sign up now to ensure a spot.\nRob Sewell will also be joining us as a guest presenter and it looks like teammates Sander Stad and Shawn Melton will help proctor the lab 😊","tags":["precon","summit"],"title":"The dbatools Team Will Present a Full-Day PASS Summit Precon!","type":"post","url":"https://dbatools.io/precon-old/"},{"categories":["announcements"],"content":"\nToday\u0026rsquo;s article is part of T-SQL Tuesday. T-SQL Tuesday is the brainchild of Adam Machanic. It is a blog party on the second Tuesday of each month. Everyone is welcome to participate.\nThis month\u0026rsquo;s T-SQL Tuesday, hosted by Grant Fritchey (b), is all about Databases and DevOps.\nWhat Is DevOps? Recently, I took an Intro to DevOps Engineering class in my Masters program at Regis University. I actually found one of our first assignments to be one of the most challenging: define DevOps.\nOne Definition Many of my cohorts and myself pointed to The Agile Admin\u0026rsquo;s definition, which was presented in a simplified manner.\nDevOps is the practice of operations and development engineers participating together in the entire service lifecycle, from design through the development process to production support.\nThat\u0026rsquo;s a little generic, and the entire post goes into much greater depth, of course. Here are a few highlights from the rest of the post:\nDevOps Values: \u0026ldquo;People over Process over Tools\u0026rdquo; DevOps Principles: \u0026ldquo;Infrastructure as code\u0026rdquo; which means writing code to manage configurations and automate provisioning of infrastructure in addition to deployments DevOps Tools - Tools you\u0026rsquo;d use in the commission of these principles. Pester, Appveyor, Slack, virtualization, containerization, etc. By employing the above, it\u0026rsquo;s easier to achieve DevOps goals:\nFaster time to market Lower failure rate of new releases Shortened lead time between fixes Faster mean time to recovery (in the event of a new release crashing or otherwise disabling the current system) Another Definition Another definition was recently shared with me by former PowerShell MVP (and now DevOps advocate at Microsoft) Steve Murawski. This definition is an acronym, CAMS, which describes the core values of the DevOps Movement: Culture, Automation, Measurement, and Sharing.\nDevOps and dbatools I remember when I was taking the class, I made a list of what we\u0026rsquo;re doing at dbatools that aligns with DevOps. Because how cool would it be to not only add it to my own resume, but to be able to offer that skillset and experience to all of our contributors? Turns out, after we added automated tests, we were 100% DevOps!\ndbatools ❤️ You We\u0026rsquo;ve now got nearly 60 contributors to our GitHub repository. Our team is an awesome mix of database administrators, systems engineers, data architects, C# devs, BI devs, PowerShell dev and more. Quite a nice combo of dev and ops 😊\nIn our Slack channel and within our code reviews, we aim to be incredibly inclusive and polite. Our culture is one of encouragement. You can even see this in our contributing.md. Don\u0026rsquo;t know git? We want to help! Do you learn best by reading a tutorial? We\u0026rsquo;ve got you covered. Or do you learn better by watching a video? We still got you. Or maybe you want someone to talk you through it. You\u0026rsquo;re in luck! Constantine Kokkinos (@ck) in the Slack channel is more than willing to help.\nWant to use VS Code to code for dbatools? Major Contributor Shawn Melton has written some articles to help. Whatever roadblocks you may be experiencing, we want to help. If you\u0026rsquo;ve got a ton of experience with DevOps processes already, we\u0026rsquo;d love if you\u0026rsquo;d join us and help guide our processes.\nInfrastructure and Automation PowerShell Desired State Configuration (DSC) can help provide your environment with Infrastructure as Code (IaC), but right now, dbatools doesn\u0026rsquo;t do any DSC. What we do, however, is take advantage of Appveyor\u0026rsquo;s IaC which helps us provide Continuous Integration through automated testing.\nI\u0026rsquo;d heard about IaC and \u0026ldquo;ephemeral servers\u0026rdquo; for a while (and you may have, too) but I could never quite grasp how temporary servers could be beneficial to our project until I watched our teammates André Kamman \u0026amp; Rob Sewell present Test Your PowerShell Code With AppVeyor for ITPros at PSconf.eu.\nyoutube: 8Nljk1deSmU\nBasically, we hook our repo into AppVeyor and each time we commit to a branch, AppVeyor spins up a temporary Windows server with a bunch of SQL instances (Express mostly, plus 2016 Developer), then follows a few PowerShell scripts we have in our repo, including appveyor.sqlserver.ps1 and appveyor.pester.ps1.\nIt runs all of the tests listed in the tests directory and if all is good, we get a beautiful green check mark on the commit. Then the server is then destroyed and a new one appears with the next commit, just like that. You can even view it live as it\u0026rsquo;s happening! Check this out:\nyoutube: LiD4Z4gJdUM\nWant to watch our automated testing, happening live? Click on this AppVeyor link.\nDevOps Tools, Measurement and Sharing In addition to setting up automated tests and loving you (and you, and you, and you 👍), we also hang out and help each other on a DevOps favorite, Slack. We\u0026rsquo;re part of a greater Slack community located at sqlcommunity.slack.com. Right now, we\u0026rsquo;ve got over 3,000 members in the SQL slack and 730+ in our channel.\nWe also use the hell out of GitHub for both communicating with end-users and with contributors. We provide code reviews and accept bug reports. We used to use kanban tool, Trello, but moved away from it in favor of GitHub issues. We\u0026rsquo;re still waiting for GitHub Projects to be good enough.\nWe explored Azure and Jenkins for Continuous Integration but ultimately decided on AppVeyor. AppVeyor hooks exceptionally well into our PowerShell Pester tests.\nOur measurement is kind of weak right now, but it comes in the form of being extremely transparent about what we\u0026rsquo;re up to. Stats, including our website stats, are shared widely and regularly. And, of course, our source code.\nDevOps Release Cycle In continuing with the DevOps theme, we also adopted a pretty fast release cycle. We aim to release early and release often, as can be seen on our download page.\nCurrently, our non-publicized releases occur with far greater frequency than our formal, publicized releases. If a major bug is reported, it can be tested and released to PowerShell Gallery and master in less than 4 hours. As you may be aware, we\u0026rsquo;re working towards 1.0 right now. Each formal release takes about 8-16 hours of work for documentation and manual testing, so considering this, our formal release cycle is lagging. However, we\u0026rsquo;ve made AMAZING strides towards 1.0.\nThe dbatools team announced in early June 2017 that the next release would arrive around the following Wednesday, featuring renames galore, a fully signed module, dynamic parameter caching, and more tests.\nWe\u0026rsquo;re super pumped (and I\u0026rsquo;m hoping we can pull off that Wednesday deadline - it\u0026rsquo;ll be a challenge but I\u0026rsquo;d love for the newest release to be ready for our presentations at SQL Saturday Dublin).\nSpeaking of Releases Our dev branch is a bit unstable right now, but it\u0026rsquo;s filled with some really amazing things. As mentioned above, every command now has the Dba PowerShell prefix, our auto-populated parameters actually work well and now use caching, and the dev branch contains 232 commands as of today. Many of the newer ones revolve around encryption and certificates. We can\u0026rsquo;t wait to share more soon!\nJoin Us Want to help the community and add some DevOps to your resume? We can offer you experience with git, GitHub, Slack, regular releases, being awesome and more. Join us on Slack, GitHub, BlueSky, YouTube, LinkedIn.\n- Chrissy\n","date":"2017-06-13","summary":"Today\u0026rsquo;s article is part of T-SQL Tuesday. T-SQL Tuesday is the brainchild of Adam Machanic. It is a blog party on the second Tuesday of each month. Everyone is welcome to participate.\nThis month\u0026rsquo;s T-SQL Tuesday, hosted by Grant Fritchey (b), is all about Databases and DevOps.\nWhat Is DevOps? Recently, I took an Intro to DevOps Engineering class in my Masters program at Regis University. I actually found one of our first assignments to be one of the most challenging: define DevOps.","tags":[],"title":"dbatools - A DevOps Success Story","type":"post","url":"https://dbatools.io/devops/"},{"categories":["announcements"],"content":"While we are still hard at work getting everything ready for the 1.0 release, thought I would share something I figured out with VS Code. If you are not familiar with VS Code you can check the link out on how it is used to contribute to dbatools.\nPester One of the big initiatives we are working fearlessly on for the module is getting the Pester test added and cleaned up. Appveyor is configured for the repository in GitHub so it will utilize the Pester test found in the tests folder. However, this also means that you, the developer, the ultimiate contributor, can utilize these test as you are working on a function.\nPester is a special syntax that lets you code in almost plain English. It is one of those that once it clicks you are like \u0026ldquo;where have you been all my life!\u0026rdquo;. If you are interested in learning more on Pester I\u0026rsquo;ve included a short list of some excellent resources to help:\nAdam Bertram - The Pester Book (Could be the last book you buy on it.) Microsoft Learn - Testing PowerShell with Pester (Ashley McGlone and Adam Bertram) Test-Driven Development with Pester, June Blender (YouTube) Green is Good Red is Bad - Turning your Checklists into Pester Test, Rob Sewell (YouTube) Testing PowerShell with Pester (Pluralsight) Task in VS Code Task in VS Code allow you to integrate external tools into your development process/cycle. So in PowerShell one of those is utilizing Pester to drive test driven development. (The Pester resources speak on this as writing your test before your functions.) If you are developing or writing code it can improve the process by periodically running your test to validate if you broke anything. This is dependent upon your test validating the code. You can fix as many of the bugs you can find now before it gets pushed out.\nRight off I want to show a caveat for using Task:\nTask in Code are only supported when you are working in a workspace folder.\nA workspace is simply a folder of scripts/files, like the dbatools module. If you have dbatools open in VS Code, you can open the command palette (CTRL+SHIFT+P) and type task to see all the commands:\nTo generate the initial \u0026ldquo;task.json\u0026rdquo; file for your workspace just select the Task: Configure Task Runner. In the next prompt you can simply select Others.\nTasking I will let you go through the documentation on task to get down to the nitty-gritty on the options you have in the syntax. I can tell you reading through that documentation will make the remainder of this post much more clear.\nI generated the configuration for these task by using Plaster in VS Code. The PowerShell extension includes Plaster, which is a project around template-based project or module generation. When you build a module using Plaster for the first time it will ask you if you want to use Pester, and then proceeds to generate the task.json file for you. I simply took that file and expanded it. The repository for Plaster contains the initial file which only contains one task.\nOur Task The sample task that is generated comes with one simple task called Test, at this time. I renamed that task and then have added two additional task:\nTask Purpose Run.AllTest Runs every Pester test for the module. Run.IntegrationTests Run all the Pester test but only those tagged as IntegrationTests. Run.CurrentFile Will run the Pester test for for the function or file you have active/open, if one exist. The full json file is provided at the end of this post. I wanted to just go over a few areas to help you understand what it is doing.\nHow Do Tasks Run? As stated before a task allows you to run an external process, so our first step is to configure that external process. Which in our case is just the PowerShell.exe executable.\n\u0026#34;_runner\u0026#34;: \u0026#34;terminal\u0026#34;, // (1) forces process to run in terminal panel, instead of the output // Start PowerShell \u0026#34;windows\u0026#34;: { // (2) \u0026#34;command\u0026#34;: \u0026#34;${env.windir}\\\\sysnative\\\\windowspowershell\\\\v1.0\\\\PowerShell.exe\u0026#34; \u0026#34;command\u0026#34;: \u0026#34;powershell.exe\u0026#34; This setting tells VS Code to run the task in the terminal panel and not the output. The output has no color by default so you don\u0026rsquo;t see all those pretty green and purple colors from Pester. The commented (\u0026quot;//\u0026quot;) command is what the initial file provides. It utilizes a predefined variable called env.windir, which does the same thing that $env:WINDIR does in PowerShell. I had errors always showing in the terminal using the default path, about the PowerShell.exe not being found as a cmdlet. I realized that since I am running this in the terminal I am already in the context of the console so I only needed to call PowerShell.exe. Trying to reference the full path was causing the problem. I changed this to just powershell.exe and it cleaned up the initial errors.\nStructure of a Task Configuration \u0026#34;taskName\u0026#34;: \u0026#34;Run.Something\u0026#34;, //(1) referenced in command palette \u0026#34;isTestCommand\u0026#34;: false, // (2) if set to true it maps to \u0026#34;Task: Run Test Task\u0026#34; \u0026#34;showOutput\u0026#34;: \u0026#34;always\u0026#34;, //(3) options are always, never, silent \u0026#34;args\u0026#34;: [ \u0026#34;PS comands to run Invoke-Pester\u0026#34; // (4) ], \u0026#34;problemMatcher\u0026#34;: [ \u0026#34;Some fancy regex to place output in the problem pane\u0026#34; //(5) ] I will go over each part in the above example, but you can find more on each property in the documentation on schema for tasks.json. That document goes over each option and value.\nWhen you run the task command in the command palette, the taskName is displayed when you select to run a task. Setting isTestCommand to true will simply map the specific task to the command Task: Run Test Task in the command palette. You can also set that task command to a key binding if you want to save more time. If you want to see the output when it executes set showOutput to always. You can check the schema for what the other values will do. What is placed in args will be executed in the terminal window. The problemMatcher is the fancy part. This would be where you do some regex to parse the output to set if any of it is an issue (info, warning or error). This allows you to utilize the problem panel in VS Code, a shortcut to find the exact test that failed. Test a Single Function I wanted to have a task that would perform one main task for me: invoke the Pester test file for the current function.ps1 file I have open in VS Code. It took a bit to work this out, because I was not focusing on what was right in front of me. Once I figured that out I set the task isTestCommand property to true. This means you can easily validate your changes for a function by running the test just for that function and see if it passes or not. In the command palette that is select/typing Tasks: Run Test Task or you can map that to a key binding to make it more accessible.\n\u0026#34;taskName\u0026#34;: \u0026#34;Run.CurrentFile\u0026#34;, // (1) name of the task \u0026#34;suppressTaskName\u0026#34;: true, // (2) don\u0026#39;t want the task name as argument \u0026#34;isTestCommand\u0026#34;: true, // (3) map to run test task \u0026#34;showOutput\u0026#34;: \u0026#34;always\u0026#34;, // (4) show the output and open terminal window each time \u0026#34;args\u0026#34;: [ \u0026#34;Write-Host \u0026#39;Invoking Pester\u0026#39; for ${fileBasename}; Invoke-Pester -PesterOption @{IncludeVSCodeMarker=$true} -Script \u0026#39;${workspaceRoot}/tests/${fileBasenameNoExtension}.Tests.ps1\u0026#39;;\u0026#34;, \u0026#34;Invoke-Command { Write-Host \u0026#39;Completed Test task in task runner.\u0026#39; }\u0026#34; ], To burst your bubble up front: No you have to use Write-Host in this situation. Just like you do in Pester as well.\nThe taskName I try to keep where the name explains what is being done. So simply named this one Run.CurrentFile. The supressTaskName prevents the it from being added as an extra argument, which in most cases can cause it to fail or error. I set isTestCommand to true so I can use the command palette shortcut. Again, you can also use key binding to make it easier. I\u0026rsquo;m setting showOutput to always because I want to see the output in the terminal window. I will show you the difference in setting this to false later. The args is where the meat of it all sits. This section calls Invoke-Pester on the script found in the: root folder of the current workspace (dbatools repository folder), the test folder and then takes the name of the function file (minus the extension, .ps1) and appends .Tests.ps1 to it. So the end result if I run this task for Get-DbaDatabase would be dbatools\\tests\\Get-DbaDatabase.Test.ps1.\nTask for Specific Pester Test The additional task I added was to have only the integration test executed for the whole module. In Pester you can organize your test using tags, and we utilize this by setting it to Integrationtests. So I can use the Invoke-Pester command to only go through all the test and just run those context blocks.\n\u0026#34;Write-Host \u0026#39;Invoking Pester\u0026#39;; Invoke-Pester -PesterOption @{IncludeVSCodeMarker=$true} -Tag \u0026#39;Integrationtests\u0026#39;;\u0026#34;, \u0026#34;Invoke-Command { Write-Host \u0026#39;Completed Test task in task runner.\u0026#39; }\u0026#34; The args value for this task is to simply use the -Tag parameter for Invoke-Pester and then pass it the tag I need to run. You can create additional task for each tag you use in your test if you wanted.\nExample Running Test Task I have intentionally changed a test for the Get-DbaDatabase function to show a passed test and a failed test. The video below illustrates the output you see in the terminal panel. It also shows that you can use the problem panel to see the exact test that failed with simpler output.\nOne additional thing you can do in both panels is click on the failed test and VS Code will open the test file and put your cursor on that test. In the terminal panel you have a URL link for the test file, so it will require the CTRL+ clicking on the link to open it up.\nyoutube: ufL5kE5_82Q\nFull task.json File // Available variables which can be used inside of strings. // ${workspaceRoot}: the root folder of the team // ${file}: the current opened file // ${relativeFile}: the current opened file relative to workspaceRoot // ${fileBasename}: the current opened file\u0026#39;s basename // ${fileDirname}: the current opened file\u0026#39;s dirname // ${fileExtname}: the current opened file\u0026#39;s extension // ${cwd}: the current working directory of the spawned process { // See https://code.visualstudio.com/docs/editor/tasks // for the documentation about the tasks.json format \u0026#34;version\u0026#34;: \u0026#34;0.1.0\u0026#34;, \u0026#34;_runner\u0026#34;: \u0026#34;terminal\u0026#34;, // Start PowerShell \u0026#34;windows\u0026#34;: { // \u0026#34;command\u0026#34;: \u0026#34;C:\\\\WINDOWS\\\\Sysnative\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe\u0026#34; \u0026#34;command\u0026#34;: \u0026#34;powershell.exe\u0026#34; }, // \u0026#34;linux\u0026#34;: { // \u0026#34;command\u0026#34;: \u0026#34;/usr/bin/powershell\u0026#34; // }, // \u0026#34;osx\u0026#34;: { // \u0026#34;command\u0026#34;: \u0026#34;/usr/local/bin/powershell\u0026#34; // }, // The command is a shell script \u0026#34;isShellCommand\u0026#34;: true, // Show the output window always \u0026#34;showOutput\u0026#34;: \u0026#34;always\u0026#34;, \u0026#34;args\u0026#34;: [ \u0026#34;-NoProfile\u0026#34;, \u0026#34;-ExecutionPolicy\u0026#34;, \u0026#34;Bypass\u0026#34; ], // Associate with test task runner \u0026#34;tasks\u0026#34;: [ { \u0026#34;taskName\u0026#34;: \u0026#34;Run.AllTest\u0026#34;, \u0026#34;suppressTaskName\u0026#34;: true, \u0026#34;isTestCommand\u0026#34;: false, \u0026#34;showOutput\u0026#34;: \u0026#34;always\u0026#34;, \u0026#34;args\u0026#34;: [ \u0026#34;Write-Host \u0026#39;Invoking Pester\u0026#39;; Invoke-Pester -PesterOption @{IncludeVSCodeMarker=$true};\u0026#34;, \u0026#34;Invoke-Command { Write-Host \u0026#39;Completed Test task in task runner.\u0026#39; }\u0026#34; ], \u0026#34;problemMatcher\u0026#34;: [ { \u0026#34;owner\u0026#34;: \u0026#34;powershell\u0026#34;, \u0026#34;fileLocation\u0026#34;: [ \u0026#34;absolute\u0026#34; ], \u0026#34;severity\u0026#34;: \u0026#34;error\u0026#34;, \u0026#34;pattern\u0026#34;: [ { \u0026#34;regexp\u0026#34;: \u0026#34;^\\\\s*(\\\\[-\\\\]\\\\s*.*?)(\\\\d+)ms\\\\s*$\u0026#34;, \u0026#34;message\u0026#34;: 1 }, { \u0026#34;regexp\u0026#34;: \u0026#34;^\\\\s+at\\\\s+[^,]+,\\\\s*(.*?):\\\\s+line\\\\s+(\\\\d+)$\u0026#34;, \u0026#34;file\u0026#34;: 1, \u0026#34;line\u0026#34;: 2 } ] } ] }, { \u0026#34;taskName\u0026#34;: \u0026#34;Run.IntegrationTests\u0026#34;, \u0026#34;suppressTaskName\u0026#34;: true, \u0026#34;isTestCommand\u0026#34;: false, \u0026#34;showOutput\u0026#34;: \u0026#34;always\u0026#34;, \u0026#34;args\u0026#34;: [ \u0026#34;Write-Host \u0026#39;Invoking Pester\u0026#39;; Invoke-Pester -PesterOption @{IncludeVSCodeMarker=$true} -Tag \u0026#39;Integrationtests\u0026#39;;\u0026#34;, \u0026#34;Invoke-Command { Write-Host \u0026#39;Completed Test task in task runner.\u0026#39; }\u0026#34; ], \u0026#34;problemMatcher\u0026#34;: [ { \u0026#34;owner\u0026#34;: \u0026#34;powershell\u0026#34;, \u0026#34;fileLocation\u0026#34;: [ \u0026#34;absolute\u0026#34; ], \u0026#34;severity\u0026#34;: \u0026#34;error\u0026#34;, \u0026#34;pattern\u0026#34;: [ { \u0026#34;regexp\u0026#34;: \u0026#34;^\\\\s*(\\\\[-\\\\]\\\\s*.*?)(\\\\d+)ms\\\\s*$\u0026#34;, \u0026#34;message\u0026#34;: 1 }, { \u0026#34;regexp\u0026#34;: \u0026#34;^\\\\s+at\\\\s+[^,]+,\\\\s*(.*?):\\\\s+line\\\\s+(\\\\d+)$\u0026#34;, \u0026#34;file\u0026#34;: 1, \u0026#34;line\u0026#34;: 2 } ] } ] }, { \u0026#34;taskName\u0026#34;: \u0026#34;Run.CurrentFile\u0026#34;, \u0026#34;suppressTaskName\u0026#34;: true, \u0026#34;isTestCommand\u0026#34;: true, \u0026#34;showOutput\u0026#34;: \u0026#34;always\u0026#34;, \u0026#34;args\u0026#34;: [ \u0026#34;Write-Host \u0026#39;Invoking Pester\u0026#39; for ${fileBasename}; Invoke-Pester -PesterOption @{IncludeVSCodeMarker=$true} -Script \u0026#39;${workspaceRoot}/tests/${fileBasenameNoExtension}.Tests.ps1\u0026#39;;\u0026#34;, \u0026#34;Invoke-Command { Write-Host \u0026#39;Completed Test task in task runner.\u0026#39; }\u0026#34; ], \u0026#34;problemMatcher\u0026#34;: [ { \u0026#34;owner\u0026#34;: \u0026#34;powershell\u0026#34;, \u0026#34;fileLocation\u0026#34;: [ \u0026#34;absolute\u0026#34; ], \u0026#34;severity\u0026#34;: \u0026#34;error\u0026#34;, \u0026#34;pattern\u0026#34;: [ { \u0026#34;regexp\u0026#34;: \u0026#34;^\\\\s*(\\\\[-\\\\]\\\\s*.*?)(\\\\d+)ms\\\\s*$\u0026#34;, \u0026#34;message\u0026#34;: 1 }, { \u0026#34;regexp\u0026#34;: \u0026#34;^\\\\s+at\\\\s+[^,]+,\\\\s*(.*?):\\\\s+line\\\\s+(\\\\d+)$\u0026#34;, \u0026#34;file\u0026#34;: 1, \u0026#34;line\u0026#34;: 2 } ] } ] } ] } ","date":"2017-06-09","summary":"While we are still hard at work getting everything ready for the 1.0 release, thought I would share something I figured out with VS Code. If you are not familiar with VS Code you can check the link out on how it is used to contribute to dbatools.\nPester One of the big initiatives we are working fearlessly on for the module is getting the Pester test added and cleaned up.","tags":[],"title":"VS Code and Task","type":"post","url":"https://dbatools.io/vscode-task/"},{"categories":["announcements"],"content":"In the latest release, we gained 8 new commands and 5 new contributors to the dbatools master repository for a grand total of 53! We even added a few new Major Contributors to the team. Thanks to all who have joined in to make the awesomest toolset for SQL Server DBAs — we\u0026rsquo;re now offering the community nearly 190 quality commands!\nExport Commands Export-DbaScript Exports scripts from SQL Management Objects.\nEven though this command has great coverage for easy-to-export SMO objects, there will always be exceptional things like Export-DbaLogin or Export-DbaDiagnosticQuery (coming next week in the next release). Either way, Export-DbaScript is cool.\nNew-DbaScriptingOption Creates a new Microsoft.SqlServer.Management.Smo.ScriptingOptions object. Basically saves you the time from remembering the SMO assembly name 😉 Works well in conjunction with Export-DbaScript.\nSee Microsoft\u0026rsquo;s page for more information.\nGeneral Commands Based on the popularity of Get-DbaDatabase and a general agreement within the team, 1.0 will include a bunch of basic Gets and Sets within the module that return SMO objects.\nGet-DbaLinkedServer Gets all linked servers and summary of information from the sql servers listed\nGet-DbaLogin Function to get an SMO login object of the logins for a given SQL Instance. Takes a server object from the pipe\nSet-DbaStartupParameter Sets the Startup Parameters for a SQL Server instance\nOther Commands Get-DbaEstimatedCompletionTime Gets execution and estimated completion time information for queries\nInvoke-DbaDbShrink Shrinks all files in a database. Databases should be shrunk only when completely necessary. Many awesome SQL people have written about why you should not shrink your data files - Paul Randal and Kalen Delaney included. Sometimes, though, you gotta shrink your database. This command simplifies the process and also warns you of potential downsides (like excessively fragmented indexes.)\nGet-DbaDbFile This command is intended to avoid the enumeration issues that SMO causes when getting information about files and filegroups.\nName Changes Invoke-DbaWhoisActive Invoke-DbaWhoIsActive is now Invoke-DbaWhoisActive. To get the same Grid-View behavior, you\u0026rsquo;ll have to pipe Invoke-DbaWhoisActive out to Out-GridView.\nInstall-DbaWhoisActive Install-DbaWhoIsActive is now Install-DbaWhoisActive. That\u0026rsquo;s all.\nQuality Assurance Lead Needed Our amazing QA guy, Dan Alexander, has stepped aside for a while. Our project has seen a lot of people come and go, including myself. It\u0026rsquo;s absolutely understood and even expected. With Dan\u0026rsquo;s absence, however, we desperately need someone to lead the QA effort.\nDon\u0026rsquo;t have PowerShell skills? No problem. Dan\u0026rsquo;s strongest suit was that he knew how to run our commands and find ways to break them. We all miss being politely informed of how we could improve our code so that it works in more circumstances.\nRequirements Beginner PowerShell experience Believing in the possibility of bugs in every Pull Request and doggedly trying to find them A few of your own SQL Servers. We have a lab but would like the commands tested in other configurations. Knowing how to kindly deliver frustrating news to excited and well intentioned people The new QA lead would be considered the owner of the process and would help getting Pull Requests closed in a timely manner. The whole QA process happens in GitHub, so GitHub skills would be nice, but we can teach you if you aren\u0026rsquo;t quite there yet. Dan and I both learned GitHub together when he joined last summer.\nIf you\u0026rsquo;re up for the task, please visit our Slack.\nCode Signing One day I woke up and decided that we really must digitally sign the dbatools module. There are a number of reasons for this, but the two biggest reasons is that\nIt\u0026rsquo;s professional AF Changes to the default Execution Policy will no longer be required Figuring out code signing is a bit of a journey and I\u0026rsquo;ll be writing about it more in-depth on my personal blog. Something interesting about Code Signing certs - they\u0026rsquo;re expensive. Unlike the $0-$5 email verified SSL certs, a code signing cert requires verification of identity.\nI was disappointed to see that the cheapest code signing certs went for around $200 year. I put out a plea on social media and the community response was SO AMAZING. I was so moved, I teared up.\nAlmost immediately after I Tweeted, I got a DM from William Durkin and André Kamman of clouddba.io, offering to fund our cert for the foreseeable future :O Ultimately, however, it turns out that MVPs get free code signing certs from digicert so William and André will be hooking us up with a paid Appveyor subscription instead. Amazing!\nThank you so much to everyone that offered any amount. I\u0026rsquo;m still so floored. Our first fully signed script will come in about 2 weeks after I work out the details.\nLicensing dbatools is open source software that will always be free to download. We\u0026rsquo;ve been licensed under the GPLv3 since day one, and recently discussed as a team potentially switching licensing from GPLv3 to the more permissive MIT license. Ultimately, the decision was made to stay with GPLv3. If you\u0026rsquo;re wondering about the differences, visit choosealicense.com.\n1.0 Reminder On March 1, 2017, we initiated a new command freeze. This means that we will no longer be accepting commands that are not within the scope of version 1.0, which we hope to debut on June 1. We\u0026rsquo;re running a little behind because I had severe burnout, pretty much starting with the release of realfakedoors but I\u0026rsquo;m back now.\nIf you\u0026rsquo;re available to help, we\u0026rsquo;d love it! Even if you don\u0026rsquo;t know PowerShell, we\u0026rsquo;ll need help updating the website with screenshots and examples with the updated parameters and command names, and other tasks of that nature. We especially need testers.\nJoin Us! We\u0026rsquo;re all hanging out on the SQL Server Community Slack in the #dbatools channel. There\u0026rsquo;s over 640 of us there now, but the conversation load is reasonable.\nThanks for reading 😂\nChrissy ","date":"2017-05-04","summary":"In the latest release, we gained 8 new commands and 5 new contributors to the dbatools master repository for a grand total of 53! We even added a few new Major Contributors to the team. Thanks to all who have joined in to make the awesomest toolset for SQL Server DBAs — we\u0026rsquo;re now offering the community nearly 190 quality commands!\nExport Commands Export-DbaScript Exports scripts from SQL Management Objects.","tags":[],"title":"New Release - Reverse Giraffe","type":"post","url":"https://dbatools.io/reversegiraffe/"},{"categories":["announcements"],"content":"My favorite vacation ever was the time I visited Steve Jones\u0026rsquo; wardrobe. It bore a striking resemblance to Maui and even came with complimentary piña coladas.\nThe year was 2009. The sun was out, Colbie Caillat was on the radio and I hadn\u0026rsquo;t mastered PowerShell yet, so I was left feeling frantic about the health of my SQL Server estate.\nNow, though, I\u0026rsquo;ve got dbatools which allows me to quickly check the things that concern me most. Even with monitoring systems in place, who monitors the monitors? I want reassurance everything is as I expect.\nBefore I Begin Before I begin running these commands against every SQL Server in my organization, I get a list from my Central Management Server using Get-DbaRegServer. This command will undergo a definite overhaul during the 1.0 makeover, but for now, I run the following to get a list from my Central Management Server on my server dedicated to SQL Server management.\nHere are the servers in my Central Management server\nSo I go and grab the instance names and add them to the variable $allservers. I actually do this in my $profile, but it works directly from the command line, of course.\n$allservers = Get-DbaRegServer -SqlInstance localhost PowerShell PS C:\\github\\dbatools\u003e $allservers = Get-SqlRegisteredServerName -SqlInstance sql2014 PS C:\\github\\dbatools\u003e $allservers sql2000 sql2005 sql2005express\\sqlexpress sql2008 sql2008\\sql2k8 sql2012 sql2014 PS C:\\github\\dbatools\u003e Of course, $allservers can be a plain-text list of servers such as $allservers = \u0026ldquo;sql2014\u0026rdquo;,\u0026ldquo;sql2016\u0026rdquo;,\u0026ldquo;etc\u0026rdquo; or even a list of connected SMO servers if alternative credentials are needed. I\u0026rsquo;ll get into that in the future when we introduce a few new commands that keep a local JSON database of your servers and credentials.\nAre Any Servers Running Low on Disk Space? Next, I always try to keep at least 20% free disk space on my SQL Server drives (including C:) so I check to see if any fall below that threshold using Get-DbaDiskSpace.\n$allservers | Get-DbaDiskSpace | Where-Object PercentFree -lt 20 PowerShell PS C:\\github\\dbatools\u003e $allservers = Get-SqlRegisteredServerName -SqlInstance sql2014 PS C:\\github\\dbatools\u003e $allservers | Get-DbaDiskSpace | Where-Object PercentFree -lt 20 | Format-Table -AutoSize Server Name Label SizeInGB FreeInGB PercentFree BlockSize ------ ---- ----- -------- -------- ----------- --------- sql2005express\\... C:\\ 59.9 7.47 10.47 4096 sql2008 C:\\ 59.9 8.41 14.03 4096 PS C:\\github\\dbatools\u003e Here, I can easily see that two of my servers may need attention while I\u0026rsquo;m out of town.\nHave Any Jobs Failed in the Past 30 Days? Failed jobs are the worst, especially if they\u0026rsquo;re my backup jobs. Let\u0026rsquo;s check failed jobs for the last 30 days using Find-DbaAgentJob with either syntax below\n$allservers | Find-DbaAgentJob -Failed -Since (Get-Date).AddDays(-30) $allservers | Find-DbaAgentJob -Failed -Since 1/5/2017 PowerShell PS C:\\github\\dbatools\u003e $allservers | Find-DbaAgentJob -Failed -Since 1/1/2017 | Format-Table -Wrap SqlInstance JobName LastRunDate LastRunOutcome IsEnabled Category Description ----------- ------- ----------- -------------- --------- -------- ----------- MSSQLSERVER DatabaseIntegrityCheck - USER_DATABASES 2017/04/13 12:00:00 AM Failed True Database Maintenance MSSQLSERVER DatabaseBackup - USER_DATABASES - FULL 2017/03/27 12:00:00 AM Failed True Database Maintenance MSSQLSERVER DatabaseBackup - USER_DATABASES - DIFF 2017/04/06 12:00:00 AM Failed True Database Maintenance MSSQLSERVER DatabaseBackup - USER_DATABASES - LOG 2017/03/30 12:00:00 AM Failed True Database Maintenance MSSQLSERVER IndexOptimize - USER_DATABASES 2017/04/06 12:00:00 AM Failed True [Uncategorized (Local)] MSSQLSERVER sp_delete_backuphistory 2017/04/11 12:00:00 AM Failed True [Uncategorized (Local)] MSSQLSERVER LSBackup_ServerA-DB1 2017/03/23 12:00:00 AM Failed True Log Shipping MSSQLSERVER LSRestore_ServerA-DB1 2017/03/23 12:00:00 AM Failed True Log Shipping LS Backup Job MSSQLSERVER collection_set_1_noncached_collect_and_up 2017/04/13 12:00:00 AM Failed True Data Collector PS C:\\github\\dbatools\u003e Uh oh, looks like my log shipping isn\u0026rsquo;t so healthy. Probably shouldn\u0026rsquo;t go on vacation anytime soon 😭\nHow About My Backups? Next I check to ensure that my Fulls, Diffs and Logs are in order. My servers perform FULL backups once a week, DIFFs once a day, and LOG backups every 15 minutes. Let\u0026rsquo;s check to ensure this is happening with Get-DbaLastBackup\n$lastbackups = $allservers | Get-DbaLastBackup $lastbackups | Where { $_.LastLogBackup -lt (Get-Date).AddMinutes(-15) -and $_.RecoveryModel -ne \u0026#34;Simple\u0026#34; } $lastbackups | Where LastDiffBackup -lt (Get-Date).AddDays(-1) $lastbackups | Where LastFullBackup -lt (Get-Date).AddDays(-7) PowerShell PS C:\\github\\dbatools\u003e $lastbackups = $allservers | Get-DbaLastBackup PS C:\\github\\dbatools\u003e $lastbackups | Where { $_.LastLogBackup -lt (Get-Date).AddMinutes(-15) -and $_.RecoveryModel -ne 'Simple' } PS C:\\github\\dbatools\u003e $lastbackups | Where LastDiffBackup -lt (Get-Date).AddDays(-1) PS C:\\github\\dbatools\u003e $lastbackups | Where LastFullBackup -lt (Get-Date).AddDays(-7) PS C:\\github\\dbatools\u003e No results here is good; it means that all of my scheduled backups are working and no last backups were older than I expected 😊 If you\u0026rsquo;re curious about the the output of Get-DbaLastBackup, it looks something like this\nPowerShell PS C:\\github\\dbatools\u003e Get-DbaLastBackup -SqlInstance localhost | Format-Table -AutoSize Server Database RecoveryModel LastFullBackup LastDiffBackup LastLogBackup SinceFull SinceDiff SinceLog DatabaseCreated ------ -------- ------------- -------------- -------------- ------------- --------- --------- -------- --------------- WORKSTATIONS FireFlyDW Full 4/28/2017 1:19:14 AM 4/28/2017 1:19:47 AM 4/28/2017 2:00:01 AM 00:04:14 00:03:41 00:00:13 4/27/2017 2:10:53 PM WORKSTATIONS master Full 4/28/2017 1:18:44 AM 4/28/2017 1:19:50 AM 4/28/2017 2:00:01 AM 00:04:44 00:03:38 00:00:13 4/8/2003 9:13:36 AM WORKSTATIONS model Full 4/28/2017 1:18:45 AM 4/28/2017 1:19:49 AM 00:04:43 00:03:39 10/14/2005 1:54:07 AM WORKSTATIONS msdb Full 4/28/2017 1:18:46 AM 4/28/2017 1:19:48 AM 4/28/2017 2:00:01 AM 00:04:42 00:03:40 00:00:13 4/8/2003 9:13:38 AM WORKSTATIONS tempdb Simple 4/27/2017 2:17:24 PM PS C:\\github\\dbatools\u003e Also, if you\u0026rsquo;re into backups as much as me, check out this post I wrote about Test-DbaLastBackup called building a dedicated backup test server.\nHave Any Databases Been Failing Integrity Checks? Next up! Such a great command - Get-DbaLastGoodCheckDb. This function retrieves the last good CHECKDB of each database.\n$allservers | Get-DbaLastGoodCheckDb | Where LastGoodCheckDb -lt (Get-Date).AddDays(-1) PowerShell PS C:\\github\\dbatools\u003e $allservers | Get-DbaLastGoodCheckDb | Where LastGoodCheckDb -lt (Get-Date).AddDays(-1) | Format-Table -AutoSize SqlInstance Database DatabaseCreated LastGoodCheckDb DaysSinceDbCreated DaysSinceLastGoodCheckDb Status ----------- -------- --------------- --------------- ------------------ ------------------------ ------ WORKSTATIONS\\MSSQLSERVER master 4/8/2003 9:13:36 AM 1/11/2017 4:12:27 AM 47 107 Checkdb should be performed WORKSTATIONS\\MSSQLSERVER model 10/14/2005 1:54:07 AM 30 New database, not checked yet WORKSTATIONS\\MSSQLSERVER msdb 4/8/2003 9:13:38 AM 47 Checkdb should be performed WORKSTATIONS\\MSSQLSERVER NCI 1/12/2017 6:17:24 PM 14 New database, not checked yet WORKSTATIONS\\MSSQLSERVER NCI2 1/12/2017 6:17:24 PM 14 New database, not checked yet WORKSTATIONS\\MSSQLSERVER tempdb 4/12/2017 5:19:24 PM 4 Checkdb should be performed PS C:\\github\\dbatools\u003e Oops! Looks like one of my servers is in really bad shape and CHECKDB hasn\u0026rsquo;t been run on the databases or they\u0026rsquo;ve failed for a while. Better run a check so I can get to my 🍕!\nSpeaking of Vacation You may be wondering about the status of 1.0. It\u0026rsquo;s coming along, albeit a little slower than we expected. One of the biggest reasons was that I had really bad burnout that lasted 1.5 months. I just couldn\u0026rsquo;t get motivated. It started sometime in early March but I\u0026rsquo;m back at it now.\nBurnout is nothing new to me, but I did have an epiphany this time around. My burnout isn\u0026rsquo;t caused by excessive working and the need for a vacation. For me, burnout is caused by absence of progress . I was indeed stuck on a persistent issue and just hadn\u0026rsquo;t progressed for nearly two weeks.\nIn the future, I\u0026rsquo;m going to ensure that I don\u0026rsquo;t get stuck by allowing myself to move on, even if it means gifting the pesky task to someone else.\nWorld Tour The reason I was reminded to do this post was because I\u0026rsquo;m gonna be out of town next week for PSConf.eu! PSConf.eu is an awesome PowerShell conference where you\u0026rsquo;re surrounded by great friends and Hefeweizen. \u0026ldquo;Let\u0026rsquo;s all have a great time together\u0026rdquo; is one of the tenets of the conference and last year\u0026rsquo;s conference was the best conference I\u0026rsquo;d ever been to.\nThe dbatools team will have a heavy presence there, too! I know that Rob, Stuart, Fred, André and William will be there and I\u0026rsquo;m hoping a few others show up as well. Kinda like recently at SQLBits!\nDan Alexander, André Kamman, Mötz Jensen, Shane O\u0026rsquo;Neill, Rob Sewell and Stephen Bennett (not pictured), Thomas LaRock (not pictured)\nAnd if you\u0026rsquo;re speaking about dbatools, let us know and we\u0026rsquo;ll promote your session 🙏❤️\nI left this small so you would click 😁\nFinishing Up So here\u0026rsquo;s a big ol\u0026rsquo; chunk of code you can paste into your environment. You\u0026rsquo;ll have to customize it a lil\u0026rsquo; bit, but it\u0026rsquo;s a good start.\n# Get all servers $allservers = Get-DbaRegServer -SqlInstance localhost # Check disk space $allservers | Get-DbaDiskSpace | Where-Object PercentFree -lt 20 # Find failed jobs $allservers | Find-DbaAgentJob -Failed -Since (Get-Date).AddDays(-30) $allservers | Find-DbaAgentJob -Failed -Since 1/5/2017 # Check backups $lastbackups = $allservers | Get-DbaLastBackup $lastbackups | Where { $_.LastLogBackup -lt (Get-Date).AddMinutes(-15) -and $_.RecoveryModel -ne \u0026#34;Simple\u0026#34; } $lastbackups | Where LastDiffBackup -lt (Get-Date).AddDays(-1) $lastbackups | Where LastFullBackup -lt (Get-Date).AddDays(-7) # Check integrity checks $allservers | Get-DbaLastGoodCheckDb | Where LastGoodCheckDb -lt (Get-Date).AddDays(-1) Do you have commands or routines you run before leaving town? I\u0026rsquo;m looking for ideas to add to my list.\nTill next time (probably sometime next week)!\n- Chrissy\n","date":"2017-04-28","summary":"My favorite vacation ever was the time I visited Steve Jones\u0026rsquo; wardrobe. It bore a striking resemblance to Maui and even came with complimentary piña coladas.\nThe year was 2009. The sun was out, Colbie Caillat was on the radio and I hadn\u0026rsquo;t mastered PowerShell yet, so I was left feeling frantic about the health of my SQL Server estate.\nNow, though, I\u0026rsquo;ve got dbatools which allows me to quickly check the things that concern me most.","tags":["party"],"title":"The Commands I Run Before Going on Vacation","type":"post","url":"https://dbatools.io/vacation/"},{"categories":["announcements"],"content":"Recently, Constantine, Rob, Aaron, and I got together to record a podcast for SQL Data Partners with Steve Stedman and Carlos L Chacon. We talked mostly dbatools, the community, open source projects and then I answered some SQL Family questions.\nToday, the SQL Data Partners team released the podcast, along with a corresponding transcript.\nSpoiler Alert: I know you\u0026rsquo;re all wondering what my superhero power would be, so here\u0026rsquo;s my answer 😊\nAlright, so my superhero power would be regeneration. And the reason I want it is because I\u0026rsquo;m a hypochondriac and I\u0026rsquo;m always worrying about getting some disease or getting to an accident. And if I had regeneration powers then I wouldn\u0026rsquo;t have to worry about that anymore because it would just fix itself.\nThe experience was actually a lot of fun! So much of a blast, in fact, that I asked Constantine if he wanted to co-host a new podcast that focuses on SQL Server and PowerShell. He agreed and you can expect our debut sometime next month!\n","date":"2017-04-12","summary":"Recently, Constantine, Rob, Aaron, and I got together to record a podcast for SQL Data Partners with Steve Stedman and Carlos L Chacon. We talked mostly dbatools, the community, open source projects and then I answered some SQL Family questions.\nToday, the SQL Data Partners team released the podcast, along with a corresponding transcript.\nSpoiler Alert: I know you\u0026rsquo;re all wondering what my superhero power would be, so here\u0026rsquo;s my answer 😊","tags":["party"],"title":"dbatools Teammates Join Carlos and Steve for an Episode of the SQL Data Partners Podcast","type":"post","url":"https://dbatools.io/sql-data-partners-podcast/"},{"categories":["announcements"],"content":"So, there\u0026rsquo;s a World Backup Day, but what about World Restore Day? We\u0026rsquo;ve all been told over and over, backups are useless if they can\u0026rsquo;t be restored and verified. Grant Fritchey has even yelled it at us a couple times.\nUsing dbatools to Automate Tests dbatools makes it crazy easy to automate your backup testing, as demonstrated by Sander Stad, Rob Sewell and Anthony Nocentino. It even works on Linux!\nIn my environment, I have a server dedicated for testing SQL Server backups and use Test-DbaLastBackup. Here\u0026rsquo;s how you can, too.\nFirst, Centralize Your SQL Server Backups I use and recommend Ola Hallengren\u0026rsquo;s SQL Server Maintenance Solution to centralize database backups. Every SQL Server in my estate backs up its databases to a write-only UNC share.\nIf you\u0026rsquo;re required to backup locally, you can centralize your backups by automating the copy process from the SQL Servers\u0026rsquo; local disks to a network share using PowerShell\u0026rsquo;s Copy-Item or robocopy. The reason this is required is because your dedicated test server must have access to the backups.\nNext, Build Your Server Even though I built my server in a pretty simplified manner, I still learned a couple things along the way.\nEdition The edition (Enterprise, Standard, Express, etc) should match the highest of edition in your estate. My initial test server was Standard edition and a number of my Enterprise backups failed to restore because they were using Enterprise features.\nLicensing\nWith regards to licensing, I recently spoke to Data Platform MVP Joey D\u0026rsquo;Antoni to get better clarification about required licensing. It appears that if you\u0026rsquo;ve got Software Assurance, creating a dedicated testing server for your backups would not require additional licenses, HOWEVER, you will have to skip the DBCC CHECKDB by specifying the -NoCheck parameter because CHECKDB is considered a \u0026ldquo;production offload process.\u0026rdquo;\nAlternatively, the SQL Server 2016 licensing model basically says that \u0026ldquo;anything that isn\u0026rsquo;t prod is free.\u0026rdquo; This means that, even without Software Assurance, you can use SQL Server 2016 as your test restore server without additional license requirements. But again, CHECKDB is considered production and is not covered under this licensing model.\nUltimately, licensing this type of server is a \u0026ldquo;murky gray\u0026rdquo; area and you should consult with your organization\u0026rsquo;s licensing rep.\nIf you end up needing a higher edition of SQL Server, are properly licensed and the configuration is supported, you can always change your edition.\nFeatures Remember if you\u0026rsquo;ve got a database with FILESTREAM enabled, you must have FILESTREAM enabled on your test server. Same goes for FULLTEXT indexes and other things I can\u0026rsquo;t recall right now.\nService Account The SQL Server service account must have access to the centralized network share.\nDisks This was a lot of fun! I used Get-DbaDatabase to search all of my servers to easily find the largest database so that I could properly size my dedicated restore disk. I always keep a list of my SQL Servers as a variable in my $profile, so I just piped that. Check it:\n$servers | Get-DbaDatabase | Select SqlInstance, Name, Size, Owner | Out-GridView (Out-GridView, or OGV, is a powerful PowerShell cmdlet that allows for easy sorting, searching and filtering.)\nSearching 15 SQL Servers and 315 databases took less than 4 seconds! The size is in MB, and in this example screenshot, the largest database is BDTlog at 16GB. This includes both data and log files. In reality, my largest database was 500GB, so I created a 700GB expandable restore disk.\nIn my environment, I setup just one additional disk and placed both the data and logs on that disk. Test-DbaLastBackup allows you to specify different destination data and log drives, however, so you can create two additional drives instead of one if you prefer.\nTempdb If you\u0026rsquo;re running the checks, you must also ensure you have enough space for tempdb to grow. It\u0026rsquo;s possible to estimate how much space you\u0026rsquo;ll need with DBCC CHECKDB(0) WITH ESTIMATEONLY (read more at sqlskills.com), but honestly, the estimation wasn\u0026rsquo;t even close to accurate for me and I ran out of space. I ended up throwing an extra 50GB at tempdb, which sufficed.\nUpdate dbatools So first, I literally updated Test-DbaLastBackup today, so make sure you are at least at version 0.8.946. This version is better in a variety of ways, but most importantly, it tests the entire available backup chain back to FULL and allows us to pipe in servers. Update/Edit It also fixes a bug from 0.8.946 that didn\u0026rsquo;t calculate all the logs.\nSo first, run either Update-Module -Name dbatools (if you\u0026rsquo;ve installed dbatools from the Gallery) or Update-dbatools if you\u0026rsquo;ve used the installer script.\nExecute a One-Liner Next, it\u0026rsquo;s time to create the script that can\nCollect all of your SQL Server database names Test your entire SQL Server estate Convert your results to a .NET DataTable Write the results to a database For my lab, I just keep a manual list of SQL Servers and all of them work with Windows authentication, so it greatly simplifies the process. Here\u0026rsquo;s how I test every backup and log it to the database, all in one fell swoop.\n$servers | Test-DbaLastBackup -Destination localhost -DataDirectory R:\\ -LogDirectory R:\\ | ConvertTo-DbaDataTable | Write-DbaDataTable -SqlInstance localhost -Table dbatools.dbo.lastbackuptests -AutoCreateTable Let\u0026rsquo;s break this command down\n$servers: plain-text list of servers, though they could also be SMO server objects Test-DbaLastBackup: performs all test restores and checkdbs on localhost. Restores both data and log files to the R:\\ drive. ConvertTo-DbaDataTable: Casts the results into a DataTable type (instead of being output to screen) so that they can be consumed by SQL Server Write-DbaDataTable: Finally, the datatable is written to the dbatools database, to a table named lastbackuptests. If the table does not exist, it will be automatically created. The Output! Here is a screenshot of the output, which has been saved to a SQL Server database:\nWhat\u0026rsquo;s just so cool about this is that, in addition to the backup testing, I can also see how long a database will take to restore on a sub-optimized system, how long a CHECKDB will take and how long an entire instance would take to restore from backups.\nUltimately, it takes about 8 hours to test my entire SQL Server estate. I can check my results the next morning and rest easy knowing that my backups can be restored and the resulting data is corruption free!\nScheduling Test restores, like entire instance migrations, can be scheduled. Check out the post scheduling a migration for detailed instructions on scheduling PowerShell tasks.\nYou can even email yourself the results using Send-MailMessage. If you do go this route, ensure you assign the output of Test-DbaLastBackup to a variable so that you can use it to both write to SQL Server and email yourself (ConvertTo-Html will probably be helpful here).\nCaveats If you don\u0026rsquo;t backup directly to centralized storage, you\u0026rsquo;ll need to write your own version of Test-DbaLastBackup. Get-DbaDbBackupHistory -Last, Restore-DbaDatabase and Invoke-DbaQuery (for DBCC CHECKDB) will be helpful here.\nAlso, if you need to use alternative credentials to login to SQL Server, you\u0026rsquo;d need to do something like\n$credential = (Get-Credential sqladmin) $localcredential = (Get-Credential ad\\myadminacct) foreach ($server in $servers) { Connect-DbaInstance -SqlInstance $server -SqlCredential $credential | Test-DbaLastBackup -Destination localhost -DataDirectory R:\\ -LogDirectory R:\\ -DestinationCredential $localcredential | ConvertTo-DbaDataTable | Write-DbaDataTable -SqlInstance sql2016 -Table tempdb.dbo.lastbackuptests -AutoCreateTable } Video Want to see Test-DbaLastBackup in action? Check out this sample video. The output is a little outdated but you can still see how cool the whole thing is.\nConclusion Test-DbaLastBackup simplifies one of a DBA\u0026rsquo;s the most important tasks. It\u0026rsquo;s also pretty fun! Impress your boss and your friends by rolling your very own dedicated testing solution.\n- Chrissy\n","date":"2017-04-11","summary":"So, there\u0026rsquo;s a World Backup Day, but what about World Restore Day? We\u0026rsquo;ve all been told over and over, backups are useless if they can\u0026rsquo;t be restored and verified. Grant Fritchey has even yelled it at us a couple times.\nUsing dbatools to Automate Tests dbatools makes it crazy easy to automate your backup testing, as demonstrated by Sander Stad, Rob Sewell and Anthony Nocentino. It even works on Linux!","tags":["party"],"title":"Building a Dedicated Backup Test Server","type":"post","url":"https://dbatools.io/dedicated-server/"},{"categories":["announcements"],"content":"In the latest release, we gained 22 new commands and 2 new contributors to the dbatools master repository for a grand total of 48! We even added a couple new Major Contributors to the team. Thanks to all who have joined in to make the awesomest toolset for SQL Server DBAs — we\u0026rsquo;re now offering the community 180 quality commands!\n1.0 Reminder On March 1, 2017, we initiated a new command freeze. This means that we will no longer be accepting commands that are not within the scope of version 1.0, which we hope to debut on June 1. You may notice that this release still contains a lot of new commands — that\u0026rsquo;s because there was a mad dash to get a bunch of commands in before March 1 😉 We actually still have a few more left to vet.\nA new command freeze is necessary because we invest time vetting each PR and in order to reach 1.0 in a timely manner, we need to focus on bug and style resolutions. We\u0026rsquo;re asking anyone who can code to help fix the 35 bugs currently filed at GitHub and address the style changes that the community decided upon.\nIf you\u0026rsquo;re available to help, we\u0026rsquo;d love it! Even if you don\u0026rsquo;t know PowerShell, we\u0026rsquo;ll need help updating the website with screenshots and examples with the updated parameters and command names, and other tasks of that nature. We will be working on the following:\nBug fixes Standardized documentation Standardized names for parameters, commands, etc Standardized outputs Testing We plan to resolve all bug issues first and will continue releasing on a regular basis until the style changes are implemented.\nNew Commands Of the 22 new commands in this release, one command, Get-DbaBuildReference, fulfills a need that I\u0026rsquo;ve seen talked about in the community for quite some time. Major Contributor Simone Bizzotto parsed a ton of SQL Server build information, created a JSON database then coded Get-DbaBuildReference to parse it. We\u0026rsquo;ll also be placing the data on sqlcollaborative.github.io once we get that going. Thank you, Simone!\nGet-DbaNetworkActivity Gets the Current traffic on every Network Interface on a computer.\nGet-DbaQueryExecutionTime Displays Stored Procedures and Ad hoc queries with the highest execution times. Works on SQL Server 2008 and above.\nGet-DbaBuildReference Returns info about the specific build of a SQL instance, including the SP, the CU and the reference KB, wherever possible.\nGet-DbaTempdbUsage Gets Tempdb usage for running queries.\nFind-DbaDbGrowthEvent Finds any database AutoGrow events in the Default Trace.\nNew-DbaSsisCatalog Enables the SSIS Catalog on a SQL Server 2012+\nRemove-DbaDatabase Drops a database, hopefully even the really stuck ones.\nTest-DbaIdentityUsage Displays information relating to IDENTITY seed usage. Works on SQL Server 2008 and above.\nTest-DbaLinkedServerConnection Tests the connection to a linked server. If the test is unsuccessful the command returns the reason of the failure.\nRead-DbaTransactionLog Reads the live Transaction log from specified SQL Server Database\nGeneral Commands Based on the popularity of Get-DbaDatabase and a general agreement within the team, 1.0 will include a bunch of basic Gets and Sets within the module that return SMO objects. Here\u0026rsquo;s the first batch!\nGet-DbaAgentJob Gets SQL Agent Job information for each instance(s) of SQL Server.\nGet-DbaAgentJobOutputFile Returns the Output File for each step of one or many agent job with the Job Names provided dynamically if required for one or more SQL Instances.\nGet-DbaBackupDevice Gets SQL Backup Device information for each instance(s) of SQL Server.\nGet-DbaCredential Gets SQL Credential information for each instance(s) of SQL Server.\nGet-DbaCustomError Gets SQL Custom Error Message information for each instance(s) of SQL Server.\nGet-DbaDbAssembly Gets SQL Database Assembly information for each instance(s) of SQL Server.\nGet-DbaDbEncryption Returns a summary of encryption used on databases based to it. Shows if a database has Transparent Data encryption, any certificates, asymmetric keys or symmetric keys with details for each.\nGet-DbaAgentJobCategory Gets SQL Agent Job Category information for each instance(s) of SQL Server.\nGet-DbaInstanceAuditSpecification Gets SQL Security Audit Specification information for each instance(s) of SQL Server.\nGet-DbaDbTable Shows table information around table row and data sizes and if it has any table type information.\nSet-DbaAgentJobOutputFile Sets the OutPut File for a step of an agent job with the Job Names and steps provided dynamically if required.\nSet-DbaSpConfigure This function changes the configured value for sp_configure settings. If the setting is dynamic this setting will be used, otherwise the user will be warned that a restart of SQL is required.\nNew to dbatools? Visit the downloads page for information about how to download and install dbatools (it\u0026rsquo;s 1 command). I actually created a video to demonstrate just how easy the install is on Windows 7 with PowerShell 3. The video is now on our YouTube channel.\nJoin Us! We\u0026rsquo;re all hanging out on the SQL Server Community Slack in the #dbatools channel. There\u0026rsquo;s over 500 of us there now, but the conversation load is reasonable.\nThanks for reading 😄\nChrissy ","date":"2017-03-16","summary":"In the latest release, we gained 22 new commands and 2 new contributors to the dbatools master repository for a grand total of 48! We even added a couple new Major Contributors to the team. Thanks to all who have joined in to make the awesomest toolset for SQL Server DBAs — we\u0026rsquo;re now offering the community 180 quality commands!\n1.0 Reminder On March 1, 2017, we initiated a new command freeze.","tags":[],"title":"New Release - realfakedoors","type":"post","url":"https://dbatools.io/realfakedoors/"},{"categories":["announcements"],"content":"This time it\u0026rsquo;s not Chrissy, not Drew, not Stuart, not even Shawn…today it\u0026rsquo;s Claudio writing to you! 😊\nWith our recent release, \u0026ldquo;twentyfiveschmeckles (v0.8.694)\u0026rdquo;, we introduced the command Find-DbaStoredProcedure.\nThis command allows us to find which stored procedures have a specific string or regular expression. While that may not be groundbreaking, what is new are the features we provide and the speed at which we return them.\nUse Cases Let me explain at least two cases where I think this command is (very) useful:\nBack in the days when I was a full time T-SQL developer each time we needed to build a new feature or implement an improvement that required new columns in tables, we had to find which stored procedures to target for refactoring. Modifying stored procedures that perform CRUD (Create, Read, Update, Delete) operations was a common target because of the multiple phases required in maintaining data correctly:\nwe need to insert values on the new columns (Create) we then need to read and retrieve those new columns (Read) if the value is suitable of changes we need to update it (Update) and finally if we need to delete records, that column may be part of some WHERE clause (Delete). It\u0026rsquo;s clear we need a way find all stored procedures that use a specific table or a sibling column and we want the results to be returned as quickly and with as little work as possible; often times you may need to implement many changes and simply searching through the database or results can be frustrating or inexact.\nAs a full-time DBA you may receive complaints like \u0026ldquo;a stored procedure is failing on instance A\u0026rdquo; or vague information like \u0026ldquo;I received an error incorrect syntax near \u0026lsquo;blah\u0026rsquo;.\u0026rdquo; Often we don\u0026rsquo;t have further input and we need to narrow down which database, procedure, and now line this issue belongs to belongs. If a developer asks for help, or you need to check a version of a module, you typically starts with determining which change was made, visiting the database on all environments (eg. DEV, QA, PRD and more!) to verify which environments it was made, when it happened, and in which environments changes might be missing\nThat\u0026rsquo;s just two scenarios, I\u0026rsquo;m sure that you have encountered dozens more, or will in the future.\nWhy Should You Care? Chrissy once shared her experience going through 9 servers and searching more than 37,000 stored procedures in less than 9 seconds.\nMy first thought was \u0026ldquo;WOW! that\u0026rsquo;s fast.\u0026rdquo; but given the results I honestly wondered how and if it could actually be that fast (Chrissy did, too, actually.)\nTurns out, it\u0026rsquo;s true and I\u0026rsquo;m here to share my findings with you!\nI\u0026rsquo;ve done four different tests comparing dbatools command and standard SSMS approaches I\u0026rsquo;ve used since the beginning of time:\nSearch only on one database in one server Search on all databases (40) on one server Search on one database in two different server Search on all databases (47) in two different servers Note: For the 3rd and 4th test I will be connected to a different instance (sql2012) in order to add the connect time. This will simulate better what dbatools uses.\nFor 1st Test: We will use the following T-SQL:\nUSE AdventureWorks2014 GO SELECT db_name() AS DBName, p.[name], m.[definition] as TextBody FROM sys.sql_modules m INNER JOIN sys.procedures p ON m.object_id = p.object_id WHERE m.[definition] like \u0026#39;%JobTitle%\u0026#39; dbatools command:\nFind-DbaStoredProcedure -SqlInstance sql2016 -Databases AdventureWorks2014 -Pattern JobTitle For 2nd Test: T-SQL:\nexec sp_MSforeachdb \u0026#39;USE [?] SELECT db_name() AS DBName, p.[name], m.[definition] as TextBody FROM sys.sql_modules m INNER JOIN sys.procedures p ON m.object_id = p.object_id WHERE m.[definition] like \u0026#39;\u0026#39;%JobTitle%\u0026#39;\u0026#39;\u0026#39; And the dbatools command looks like:\nFind-DbaStoredProcedure -SqlInstance sql2016 -Pattern JobTitle 3rd Test: T-SQL code (Note: sqlcmd mode must be enabled on SSMS to run this script):\n:connect sql2016 Use AdventureWorks2014 GO SELECT db_name() AS DBName, p.[name], m.[definition] as TextBody FROM sys.sql_modules m INNER JOIN sys.procedures p ON m.object_id = p.object_id WHERE m.[definition] like \u0026#39;%JobTitle%\u0026#39; GO :connect sql2014 Use AdventureWorks2014 GO SELECT db_name() AS DBName, p.[name], m.[definition] as TextBody FROM sys.sql_modules m INNER JOIN sys.procedures p ON m.object_id = p.object_id WHERE m.[definition] like \u0026#39;%JobTitle%\u0026#39; GO dbatools command:\nFind-DbaStoredProcedure -SqlInstance sql2016, sql2014 -Databases AdventureWorks2014 -Pattern JobTitle 4th and Final Test: T-SQL:\n:connect sql2016 SET STATISTICS TIME ON exec sp_MSforeachdb \u0026#39;USE [?] SELECT db_name() AS DBName, p.[name], m.[definition] as TextBody FROM sys.sql_modules m INNER JOIN sys.procedures p ON m.object_id = p.object_id WHERE m.[definition] like \u0026#39;\u0026#39;%JobTitle%\u0026#39;\u0026#39;\u0026#39; GO :connect sql2014 SET STATISTICS TIME ON exec sp_MSforeachdb \u0026#39;USE [?] SELECT db_name() AS DBName, p.[name], m.[definition] as TextBody FROM sys.sql_modules m INNER JOIN sys.procedures p ON m.object_id = p.object_id WHERE m.[definition] like \u0026#39;\u0026#39;%JobTitle%\u0026#39;\u0026#39;\u0026#39; dbatools command:\nFind-DbaStoredProcedure -SqlInstance sql2016, sql2014 -Pattern JobTitle Here Are the Results: The values are in ms (less is better)\nA Tie? Not even close. Lets look to the output and see which one appears richer.\nMore Detail in the Results T-SQL output:\ndbatools output:\nWe show the line number where pattern was found.\nAnd Similarly, More Powerful Search Abilities Consider accurately searching for all occurrences the following regex pattern, which represents an email address:\nFind-DbaStoredProcedure -SqlInstance sql2016 -Pattern \u0026#39;\\w+@\\w+\\.\\w+\u0026#39; We can even output this to a grid and filter:\nBut I Want Nice GUI! - Redgate SQL Search for the Rescue Well, for some of us PowerShell console is a nice GUI 😊\nIf you want to do this type of search, you can download and use the free SQL Search from Redgate. This is a great tool that allows us to search not only on Stored Procedures but also on other object definitions such as Tables, Views, Constraints, Triggers, Functions and even Agent Jobs.\nThis is fast! See it in action.\nYou can see additional details in the grid result, such as:\nThe type of object matched The type of match (such as column name, just a text match) The line of SQL that matches your search (Just like our Find-DbaStoredProcedure command) Wrap Up So for me and those that use the traditional query(SSMS) based methods, this is like night and day when dealing with multiple databases. It really is faster!\nI wanted to blog this for you because I think this brings new ways to gather and filter the output we often need and hopefully you can use them further in the pipeline.\nIf you have experience with this scenario or others that that you would like to share, please drop us a message 😊\nThanks for reading. Claudio\n","date":"2017-03-08","summary":"This time it\u0026rsquo;s not Chrissy, not Drew, not Stuart, not even Shawn…today it\u0026rsquo;s Claudio writing to you! 😊\nWith our recent release, \u0026ldquo;twentyfiveschmeckles (v0.8.694)\u0026rdquo;, we introduced the command Find-DbaStoredProcedure.\nThis command allows us to find which stored procedures have a specific string or regular expression. While that may not be groundbreaking, what is new are the features we provide and the speed at which we return them.\nUse Cases Let me explain at least two cases where I think this command is (very) useful:","tags":[],"title":"Need for Speed - Find-DbaStoredProcedure","type":"post","url":"https://dbatools.io/need-for-speed/"},{"categories":["announcements"],"content":"So, we\u0026rsquo;ve made the first step to 1.0 - we\u0026rsquo;ve stopped accepting Pull Requests that add new commands. It breaks my heart the most, but every moment that we spend vetting a new command is a moment we can\u0026rsquo;t spend bug fixing and we really need to focus on standardization and bug fixes.\nOur pull request queue is currently filled with new commands that we still need to review, along with a couple bug fixes. Early next week, we\u0026rsquo;ll release an update with all these newer commands.\nWhat to Expect in the Next Few Months We\u0026rsquo;re going to be really busy! Here\u0026rsquo;s a non-exhaustive list of what to expect:\nbug fixes and minor changes first increased command findability blog posts with updates about our progress and blog posts that highlight specific commands potentially outdated information on dbatools.io major breaking changes Major breaking changes? Yep, mostly, command names and parameters will change. This means, for instance, that if you reference Copy-DbaDatabase in a script, suddenly PowerShell will report command not found, because that will soon become Copy-DbaDatabase. We\u0026rsquo;ll also be removing many of the -Detailed parameters and show more output by default.\nBut while we will be introducing breaking changes, we\u0026rsquo;re also hoping to provide a script converter that searches for the changes we\u0026rsquo;re making and updates your scripts accordingly.\nWe Need You We want 1.0 to be as solid as possible and need you to report any bugs you\u0026rsquo;ve come across to our issues list. If you\u0026rsquo;ve been putting it off, now is the time.\nIf you don\u0026rsquo;t want to create a GitHub account, you can email clemaire@gmail.com, but GitHub offers two primary benefits: the developer fixing your issue can work directly with you to get more info, ask you to test and, ultimately, resolve the issue faster and more accurately. In addition, GitHub will keep you updated on the progress of your bug fix while I will not be able to.\nWe also need bug fixers and testers. We\u0026rsquo;ve got a number of people who have volunteered to help but the more help we have, the faster we can get 1.0 finalized. Right now, our hope is that 1.0 will be available on June 1, 2017.\nI Want to Help Fix Bugs, How Do I Start? First, from all of us, THANK YOU 🙏 Second..\nRead Shawn\u0026rsquo;s post, Contributing with Code, if you\u0026rsquo;d like an intro to contributing to our project using Microsoft\u0026rsquo;s free editor, Visual Studio Code. Using Code will be greatly beneficial because it has GitHub integration, code formatting (which fits in line with our style guide) and a bunch of other stuff. Follow up with Your First Pull Request or watch the accompanying video if you still don\u0026rsquo;t really get how to do a PR with GitHub. Join us in #dbatools on the SQL Server Community Slack We\u0026rsquo;ll guide you through how to participate and shower you with emoji gifts You\u0026rsquo;ll be paired up, hopefully with someone in your timezone, so that your pull requests can be vetted, tested and merged in a timely manner. You\u0026rsquo;ll also be vetting, testing and merging your buddy\u0026rsquo;s pull requests. And the big ol\u0026rsquo; bonus? Fixing a bunch of bugs will totally get you on the team page which also means you can add dbatools.io to your experience on LinkedIn like many Major Contributors do. Whaaat!\nThanks for reading. We\u0026rsquo;ll be back in touch next week.\n- Chrissy\n","date":"2017-03-03","summary":"So, we\u0026rsquo;ve made the first step to 1.0 - we\u0026rsquo;ve stopped accepting Pull Requests that add new commands. It breaks my heart the most, but every moment that we spend vetting a new command is a moment we can\u0026rsquo;t spend bug fixing and we really need to focus on standardization and bug fixes.\nOur pull request queue is currently filled with new commands that we still need to review, along with a couple bug fixes.","tags":["party"],"title":"Beginning the Journey to 1.0 and a Call for Bug Reports","type":"post","url":"https://dbatools.io/bugsplz/"},{"categories":["Announcements"],"content":"What follows is a walk-through in getting VSCode setup for contributing to dbatools, and also includes various tips for utilizing the PowerShell Extension and Git features.\nInstall VSCode is a cross-platform tool that works on Windows, Linux and Mac. You can download your specific OS flavor here. Just note that I only use Windows, so if you are on another OS your mileage may vary. If you favor being a beta tester you can download the Insiders Edition from the same page. The VSCode team made some visual cues to easily indicate what edition you are using, as they can be used side-by-side:\nYou will also need to download and install Git. If you already have GitHub Desktop installed, you will still need to install Git.\nWhere To Start Getting started with VSCode can be a bit challenging at first if you normally use something like the PowerShell ISE. Just like any new tool it requires a bit of time to acclimate yourself to it. The documentation for VSCode is laid out well and was a big help for me getting started. I would encourage you to spend time going through, at a minimum, the following sections:\nThe Basics of Code (layout and how to move around) Code Extension Marketplace (how to expand what VSCode can do, will go over these in a bit) Version Control (Git integration) Integrated Terminal Accessibility One additional resource that I think should be required reading, is the Tips and Tricks documentation on the VS Code site.\nCommand Palette I want to bring special attention to this because almost everything you can do via a menu or button in VSCode, can also be done via the command palette. The nice part of the palette is it will provide help along the way as you type. To open the command palette you can use the keyboard with CTRL+SHIFT+P or access it via the View menu.\nAny extension that has commands is going to show in the format of \u0026ldquo;extension name: command\u0026rdquo;, so typing \u0026ldquo;powershell\u0026rdquo; will show any command that comes with the extension (once you install it). You can do the same thing for Git, just type that in and all the commands that are supported show up. There are additional commands outside of the extensions that are provided with VSCode, that I tend to use a good bit. I\u0026rsquo;ve included the most common below, along with the keyboard shortcut (if they have one):\nTrim Trailing Whitespace (CTRL+K, CTRL+X) Change Language Mode (CTRL+K, M) Format Document (SHIFT+ALT+F) Change All Occurrences (CTRL+F2) Quick Open CTRL+P provides a quick open prompt. This will list any recent file you have opened, but you can also use it to find a file within your current session of VSCode. So if you have a folder open with multiple files, just hit CTRL+P and start typing the file name. If a match is found it will be selected, you can just hit enter to open it.\nAnother feature is if you open a PS1 file that may have multiple functions in it, hit CTRL+P and then type the at symbol (\u0026quot;@\u0026quot;):\nExtensions The single item below is the only extension you truly need to start developing PowerShell in VSCode:\nPowerShell This extension provides the meat and potatoes for PowerShell.\nNon-Administrator The installation for VSCode would require you to have Administrator privileges. If you find you need to work without Administrator rights to install extensions you can try the manual method. VSCode extensions are just VSIX files so you can download the file and manually add it in VSCode. You will find the latest VSIX file on the extension\u0026rsquo;s release page on GitHub. You can get to that repository by searching GitHub or from the \u0026ldquo;Resources\u0026rdquo; section on the marketplace page. The file for the PowerShell extension will be named something similar to \u0026ldquo;PowerShell-x.x.x.vsix\u0026rdquo;.\nOnce you download the file just follow the steps below:\nOpen the command palette. Type in \u0026ldquo;ext install from vsix\u0026rdquo; and hit enter Browse to the VSIX file you downloaded You will then receive a prompt to reload VSCode. Code\u0026rsquo;s Settings VSCode you work with files or folders. Opening a folder is equivalent to a project in Visual Studio. One thing to understand is adjusting the settings in VSCode can apply to the \u0026ldquo;user settings\u0026rdquo; or \u0026ldquo;workspace settings\u0026rdquo;. User Settings overwrite VSCode\u0026rsquo;s default settings, and Workspace Settings can overwrite User Settings.\nWorkspace Settings Workspace settings apply to a folder you open with VSCode. When you open a folder and first open workspace settings you will see a new folder is added, \u0026ldquo;.vscode\u0026rdquo;. Any Extension or settings in VSCode you manipulate within your workspace settings will be saved under \u0026ldquo;.vscode\\settings.json\u0026rdquo;.\nThe following are settings recommended (as a baseline) for contributing with dbatools. Just paste the below into the workspace settings. You can access it via the command palette, just start typing \u0026ldquo;Preferences\u0026rdquo;, and you will see \u0026ldquo;Open workspace settings\u0026rdquo; in the list.\n// Place your settings in this file to overwrite default and user settings. { \u0026#34;files.encoding\u0026#34;: \u0026#34;utf8\u0026#34;, \u0026#34;powershell.scriptAnalysis.enable\u0026#34;: true, \u0026#34;powershell.scriptAnalysis.settingsPath\u0026#34;: \u0026#34;bin//PSScriptAnalyzerRules.psd1\u0026#34;, \u0026#34;powershell.codeFormatting.newLineAfterOpenBrace\u0026#34;: true, \u0026#34;powershell.codeFormatting.openBraceOnSameLine\u0026#34;: true, \u0026#34;editor.formatOnPaste\u0026#34;: true, \u0026#34;editor.formatOnType\u0026#34;: true, //tab format \u0026#34;editor.tabCompletion\u0026#34;: true, \u0026#34;editor.tabSize\u0026#34;: 4, \u0026#34;editor.insertSpaces\u0026#34;: false, \u0026#34;editor.detectIndentation\u0026#34;: true // Windows 8.1 and below require you to specify PowerShell for the Integrated Terminal // If you are also on another OS you will need to specify the path to PowerShell.exe \u0026#34;terminal.integrated.shell.windows\u0026#34;: \u0026#34;C://WINDOWS//sysnative//WindowsPowerShell//v1.0//powershell.exe\u0026#34; } Clone dbatools Repository We first need to clone the repository before we can start contributing:\nGrab the \u0026ldquo;Clone with HTTPS\u0026rdquo; URL of your fork of dbatools. Open the command palette (CTRL + SHIFT + P) Type in \u0026ldquo;git clone\u0026rdquo; and press enter Paste the URL (CTRL + V) copied in step 1 into the prompt. Select the root folder where you want the repository to be kept (e.g C:\\GitHub). That is it! Once the repository is downloaded, VSCode will reload and open the dbatools folder. You can view the short recording to see the steps in action.\nAdd an Upstream VSCode includes Git integration, which means you can use the command palette or the Git sidebar to perform Git commands within the same program. There are, however, some that are not supported at this time. In those cases you will need to revert to the command line or your tool of choice (e.g GitHub Desktop). If you favor the command line this is where the integrated terminal (CTRL+\u0026ldquo;backtick\u0026rdquo;) allows you to stay in VSCode.\nWhen you fork dbatools to your GitHub account you will clone that repository, this is referred to as your \u0026ldquo;origin\u0026rdquo; remote. We just need to add another remote reference to the dbatools repository. This will make it a much smoother process to update your fork with the latest additions/modifications of dbatools.\nAdd Upstream Remote The following command create a remote reference. You can name it whatever you want, but the standard term used with Git is \u0026ldquo;upstream\u0026rdquo;.\ngit remote add upstream https://github.com/dataplat/dbatools.git After you run that command you can verify it was created as below:\nPull Down Updates Once you have the remote that points to dbatools, you can use a few commands to pull down the changes. The following command updates all of the references to your remote repositories (origin and upstream).\ngit remote update The development branch is the one all the changes to dbatools are initially committed to before making a release to master. You only really need to pull down the changes from this branch. The following command can be used for this purpose:\ngit pull upstream development The status bar in VSCode will show an indicator if any changes were pulled down.\nTo show the breadth of VSCode with Git, there are 3 different ways you can \u0026ldquo;sync\u0026rdquo; your changes to your GitHub repository:\nClick on indicator in the status bar (the circle will start rotating) Open the command palette (CTRL+SHIFT+P), type \u0026ldquo;git sync\u0026rdquo; and hit enter. Open the Git sidebar, click on \u0026ldquo;\u0026hellip;\u0026rdquo; at the top of the sidebar and click \u0026ldquo;sync\u0026rdquo;. Branching Out A branch is basically just a pointer to the current state of the current branch you have checked out. When you clone dbatools and open it in VSCode the first time should have the \u0026ldquo;development\u0026rdquo; branch checked out.\nIf you create a branch from development, you are basically making a copy of that branch in the current state. If you want to checkout a different branch, just click on that branch name from the status bar. This is going to open the command palette with the \u0026ldquo;git checkout\u0026rdquo; command entered, this also causes the branches found on your origin and upstream remotes to be listed. You can then select which one you want, or start typing the name to filter the list.\nYou can utilize the command palette to create a new branch as well, and is my preferred method. The following steps can be used:\nOpen the command palette Type \u0026ldquo;git branch\u0026rdquo; and hit enter Provide your desired branch name and hit enter After you hit enter you will see on the Git icon on the sidebar an icon shows it is working, once that goes away you will see the current branch change to your new branch.\nAfter you create the branch you can see another indicator you can click on to publish the branch. You have to publish it before you can start making commits.\nWhen you click to publish the new branch, since we have multiple remotes, you will get a prompt to select which remote you want to publish the branch to, select \u0026ldquo;origin\u0026rdquo;.\nCommit Often It is often said \u0026ldquo;commit often\u0026rdquo; when you are using Git. It can help to make small changes, commit them, test them, and if something breaks roll-back that commit. VSCode offers you the basic ability of performing a commit but you can only roll back your last commit. So if you make a modification to a file you will see an indicator on the Git sidebar. Once you open that sidebar you can add your commit message and commit your change, all within VSCode.\nYou can also right-click on any file listed in this sidebar to clean (remove any changes) and stage (make commits of only certain files at a time). If you open the file from the sidebar it will show you a comparison from your change and the original version of the file.\nAn Extra - Running PowerShell Code If you are coming from the PowerShell ISE you may have gotten used to clicking the buttons on the toolbar to run either the whole script, or just the current line (or selected). In VSCode there are a few shortcomings in this area because there are no buttons. There are however key bindings/mappings that can be used.\nExtensions - Keymaps If you work with Atom or Sublime you can search the marketplace for \u0026ldquo;keymaps\u0026rdquo; and find a few extensions offered that will give you similar keybindings…note there is also one for Visual Studio.\nKeybindings By default the following keys are bound to the noted actions:\nF5 - Starts debugging the current file (has to be saved with the ps1 extension) F8 - Runs the currently focus (line or selected code). There are a few caveats to the above keyboard bindings. The F8 keybinding runs the current line or selected code but outputs it to the Output pane and not the Integrated Terminal. If you go to your keyboard shortcuts, CTRL+K, CTRL+S and just paste the following to have it execute to the terminal:\n// Place your key bindings in this file to overwrite the defaults [ { \u0026#34;key\u0026#34;: \u0026#34;f8\u0026#34;, \u0026#34;command\u0026#34;: \u0026#34;workbench.action.terminal.runSelectedText\u0026#34;, \u0026#34;when\u0026#34;: \u0026#34;editorTextFocus \u0026amp;\u0026amp; editorLangId == \u0026#39;powershell\u0026#39;\u0026#34; } ] So a short example, open a new file add one or two PowerShell commands. You will need to open the Integrated Terminal, so a PowerShell session is running, and then just place the cursor on a line and hit F8.\nNow with F5 and debugging, it is up to you whether you want to change those around so they match up to what PowerShell ISE did. You would just need to find the command from the keyboard settings and add that to your keyboard settings.\nAn Extra-Extra - PSScriptAnalyzer The PowerShell extension packages the PSScriptAnalyzer module which allows VSCode to check an open PS1 files against the PSSA rules. As the extension is released they bundle the latest version of the PSSA module. You can find what version is included by checking the following path on a Windows machine:\n# \u0026#34;x.x.x\u0026#34; is current version of the extension you have installed $env:USERPROFILE\\.vscode\\extensions\\ms-vscode.PowerShell-x.x.x\\modules PSSA performs checks based on best coding practices and identifies the line of code that violates them. You can view these by using \u0026ldquo;CTRL+SHIFT+M\u0026rdquo; to open the \u0026ldquo;Problems\u0026rdquo; pane. You also have an indicator on the bottom left of the status bar of VSCode (clicking this will also open the \u0026ldquo;Problems\u0026rdquo; pane.\nAn added benefit as you open additional files, the problems pane will start grouping the problems by the file they are found in:\nJust click on one of the problems and VSCode will jump to that file and line.\nSummary While this post is a bit long it by no means covers all the features in VSCode. Read through the documentation to find out more that can be done. You can also search on YouTube for some good videos that show using code in various ways, generally with other languages. Happy contributing!\n","date":"2017-03-02","summary":"What follows is a walk-through in getting VSCode setup for contributing to dbatools, and also includes various tips for utilizing the PowerShell Extension and Git features.\nInstall VSCode is a cross-platform tool that works on Windows, Linux and Mac. You can download your specific OS flavor here. Just note that I only use Windows, so if you are on another OS your mileage may vary. If you favor being a beta tester you can download the Insiders Edition from the same page.","tags":[],"title":"Contributing with Code","type":"post","url":"https://dbatools.io/vscode/"},{"categories":["announcements"],"content":"In this release, we gained 22 new commands, 7 new contributors to the dbatools master repository for a grand total of 46! We even added a couple new Major Contributors to the team. Thanks to all who have joined in to make the awesomest toolset for SQL Server DBAs — we\u0026rsquo;re now offering the community 154 quality commands!\nUpdated Commands We released the follow two commands in snowball but wanted you to download the latest version of dbatools which includes some really awesome improvements to backup and restore.\nRestore-DbaDatabase The restore command is now especially impressive - imagine being able to restore a whole instance of Maintenance Solution backups with a single pipe like Get-ChildItem \\\\nas\\sql\\sql2016 | Restore-DbaDatabase -SqlInstance localhost. It\u0026rsquo;s now totally possible!\nWant to be even more blown away? How about Get-DbaDatabase -SqlInstance sql2005 -ExcludeSystem | Backup-DbaDatabase -BackupDirectory \\\\dc\\sql\\test | Restore-DbaDatabase -SqlInstance sql2016\\vnext\nThis makes it way easier to copy to an interim fileshare if needed ❤️\nBackup-DbaDatabase In case you missed it, we released a really nice Backup-DbaDatabase command.\nCheck out this demo video (includes blooper reel):\nNew Commands In this release we have 22 new commands, several bugs fixes and a bunch of improvements. Note that many of these commands were available in snowball but they weren\u0026rsquo;t officially released with a supporting webpage and additional testing.\nExecution Plans Get-DbaExecutionPlan Gets execution plans and metadata - useful for piping to Export-DbaExecutionPlan.\nExport-DbaExecutionPlan Exports execution plans to disk. Can pipe from Get-DbaExecutionPlan.\nQuery Store Get-DbaDbQueryStoreOption Get the Query Store configuration for Query Store enabled databases. Retrieves and returns the Query Store configuration for every database that has the Query Store feature enabled.\nSet-DbaDbQueryStoreOption Configure Query Store settings for a specific or multiple databases.\nCopy-DbaDbQueryStoreOption Copies the configuration of a Query Store enabled database and sets the copied configuration on other databases.\nFinding Things Find-DbaCommand Finds dbatools commands searching through the inline help text, building a consolidated json index and querying it because Get-Help is too slow.\nFind-DbaLoginInGroup Finds Logins in Active Directory groups that have logins on the SQL Instance. Outputs all the active directory groups members for a server, or limits it to find a specific AD user in the groups.\nFind-DbaUserObject Have a developer, DBA or other employee leaving the company and need to know what they own? This command can help. It searches SQL Server to find user-owned objects (ie. not dbo or sa) or for any object owned by a specific user specified by the Pattern parameter.\nProtocol Info Get-DbaClientProtocol Gets the SQL Server related client protocols on a computer.\nGet-DbaServerProtocol Gets the SQL Server related server protocols on a computer.\nUpdate Tracking We actually release to the gallery a little more often than we blog about. If you\u0026rsquo;re using Windows 10, have access to the PowerShell Gallery (some corporate networks may not) and would like to be notified about updates, use Watch-DbaUpdate. It\u0026rsquo;s super cute and tries not to be annoying.\nIt\u0026rsquo;s also our mascot, Tron\u0026rsquo;s, debut in the toolkit. You\u0026rsquo;ll be seeing more of him around, including in an upcoming blog post.\nWatch-DbaUpdate Just for fun - checks the PowerShell Gallery for updates to dbatools.\nInstall-dbatoolsWatchUpdate Sets up a scheduled task that checks the PowerShell Gallery every 3 hours for updates to dbatools. Notifies once max per release.\nUninstall-dbatoolsWatchUpdate Removes the scheduled task that checks the PowerShell Gallery every 3 hours for updates to dbatools.\nMisc Clear-DbaConnectionPool Clear all yo SQL connection pools. Simple but good for testing. After 1.0, I\u0026rsquo;d like to figure out a way to enumerate connections, that\u0026rsquo;d be cool!\nGet-DbaDatabase We\u0026rsquo;ll be adding a bunch of SMO Get commands, this is the first of the batch. The Get-DbaDatabase command gets SQL database information for each database that is present in the target instance(s) of SQL Server. If the name of the database is provided, the command will return only the specific database information.\nGet-DbaPrivilege Gets the users with local privileges \u0026lsquo;Lock Pages in Memory\u0026rsquo;, \u0026lsquo;Instant File Initialization\u0026rsquo;, \u0026lsquo;Logon as Batch\u0026rsquo; on one or more computers. Requires Local Admin rights on destination computer(s).\nGet-DbaService Gets the SQL Server related services on one or more computers.\nMeasure-DbaBackupThroughput Uses backup history to determine how quickly SQL Server is backing up databases to media.\nNew-DbaDirectory Uses master.dbo.xp_create_subdir to create the path. Returns $true if the path can be created, $false otherwise.\nInternal Configurations We\u0026rsquo;re gettin Enterprise up in here! Thanks to our newest Major Contributor Friedrich Weinmann, we\u0026rsquo;ve now got a really cool configuration system. This will be helpful for our developers. We\u0026rsquo;ll have more information in a blog post during the 1.0 redo, but here\u0026rsquo;s a quick lil overview.\nGet-dbatoolsConfig Retrieves configuration elements by name. Can be used to search the existing configuration list.\nGet-dbatoolsConfigValue Returns the configuration value stored under the specified name. This command is usually only called by functions.\nSet-dbatoolsConfig This function creates or changes configuration values. These are used in a larger framework to provide dynamic configuration information outside the PowerShell variable system.\nImprovements \u0026amp; Notable Bug Fixes The awesomest improvement is our full on Enterprise-lookin\u0026rsquo; logging implemented by Fred. We\u0026rsquo;ll be writing some blog in-depth blog posts which discuss the logging system in depth, but for now, check out what happens when I open our logging directory using Invoke-Item (Get-dbatoolsConfigValue -Name path.dbatoolslogpath)\nWhaat! Such good looking logging. Thank you Fred for all of your work on this!\nAs for other improvements and bug fixes, we\u0026rsquo;ll be releasing our last few commands (until 1.0) on on Wednesday March, 1, so I\u0026rsquo;ll cover other improvements more in-depth then. Writing the post for all these commands exhausted me 😅\n1.0 Reminder Just a reminder: on March 1, 2017, we will initiate a feature freeze. This means that we will no longer be accepting new commands or PRs for new features until we\u0026rsquo;ve fully implemented all changes that were decided upon for the 1.0 release.\nA feature freeze is necessary because we invest time vetting each PR and in order to reach 1.0 in a timely manner, we need to focus on bug and style resolutions. We\u0026rsquo;re asking anyone who can code to help fix the 43 bugs currently filed at GitHub and address the style changes that the community decided upon.\nIf you\u0026rsquo;re available to help, we\u0026rsquo;d love it! Even if you don\u0026rsquo;t know PowerShell, we\u0026rsquo;ll need help updating the website with screenshots and examples with the updated parameters and command names, and other tasks of that nature. We will be working on the following:\nBug fixes Standardized documentation Standardized names for parameters, commands, etc Standardized outputs Testing We plan to resolve all bug issues first and will continue releasing on a regular basis until the style changes are implemented.\nNew to dbatools? Visit the install page for information about how to download and install dbatools (it\u0026rsquo;s 1 command).\nJoin Us! Some of these commands are in their infancy. Want to help make them better? Come join the coding party! We\u0026rsquo;re all hanging out on the SQL Server Community Slack in the #dbatools channel. There\u0026rsquo;s almost 500 of us there now (but the conversation load is reasonable).\nThanks for reading 😄\nChrissy ","date":"2017-02-27","summary":"In this release, we gained 22 new commands, 7 new contributors to the dbatools master repository for a grand total of 46! We even added a couple new Major Contributors to the team. Thanks to all who have joined in to make the awesomest toolset for SQL Server DBAs — we\u0026rsquo;re now offering the community 154 quality commands!\nUpdated Commands We released the follow two commands in snowball but wanted you to download the latest version of dbatools which includes some really awesome improvements to backup and restore.","tags":[],"title":"New Release - Pieceoftoast","type":"post","url":"https://dbatools.io/pieceoftoast/"},{"categories":["announcements"],"content":"Just to confuse people, it\u0026rsquo;s not Chrissy or Drew this time. My name\u0026rsquo;s Stuart, and I\u0026rsquo;ve got a new dbatools release to tell you about; snowball.\nThis Release Is All About Restores DBAs spend a lot of time making sure backups work. Or at least they should, and if they aren\u0026rsquo;t then putting their spare time to fixing up their CV is probably a good plan.\nSo we\u0026rsquo;ve got terabytes of SQL backups stashed away on disk. Brilliant, we\u0026rsquo;re bombproof then aren\u0026rsquo;t we? Well, are you sure those backups can be restored?\nPart of a good backup strategy is proactively testing your backups by restoring. There are many benefits to doing this:\nPractice - You don\u0026rsquo;t want to be restoring a complex production database for the first time when the excrement is hitting the fan. Your restore procedures should be as simple as possible, and you should be able to do them correctly without thinking. Performance - Just how long does it take to restore your production system? You can bet your boss would like to know Trust - You need to know you can trust your backups. Just because they\u0026rsquo;ve been written to disk doesn\u0026rsquo;t mean everything\u0026rsquo;s OK. Corruption still happens unfortunately. Did you spot it before it became a problem? Confidence - You need to know you\u0026rsquo;ve got all the backups you think you do. Sure someone\u0026rsquo;s not removing transaction log backups before you\u0026rsquo;re finished with them? A prod outage isn\u0026rsquo;t the time to find out you need something from tape and the guy with the safe keys is tucked up in bed. Then T-SQL didn\u0026rsquo;t make automating restores easy! Each databases restore had to be hand crafted to make sure that you could cope with files in different locations, differing backup locations, and all the other individual quirks we know and love. And if you\u0026rsquo;d lost your production msdb then it was a world of pain trying to piece together restore files.\nJust imagine the pain if you\u0026rsquo;re running a weekly full, night differential and 15 minute log backups. Trying to work out what you need is a real pain.\nNot So Long Ago PowerShell started making that a lot easier. By combining it\u0026rsquo;s power in scanning the filesystem and talking to Sql Server it became easier to work out which files you needed and then queue them up for restore. But it still took quite a bit of patience to get it all working smoothly\nNow We\u0026rsquo;re proud to announce that dbatools is making it as simple as we can to do restores.\nNew Command - Restore-DbaDatabase Restore-DbaDatabase ties together a lot of new features and is probably going to be your main interface with the new restore functions.\nLaying the Groundwork For these examples we\u0026rsquo;ll be using the following backup files:\nPowerShell PS C:\\dbatools\u003e Get-ChildItem .\\backups\\ | Sort-Object -Property LastWriteTime Directory: C:\\dbatools\\backups Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 09/02/2017 10:53 2775552 RestoreDemo_Full1.bak -a---- 09/02/2017 10:58 86528 RestoreDemo_Log2.trn -a---- 09/02/2017 11:03 86528 RestoreDemo_Log3.trn -a---- 09/02/2017 11:08 743936 RestoreDemo_Diff4.bak -a---- 09/02/2017 11:13 2841088 RestoreDemo_Full5.bak -a---- 09/02/2017 11:14 86528 RestoreDemo_Log6.trn -a---- 09/02/2017 11:15 612864 RestoreDemo_Diff7.bak -a---- 09/02/2017 11:15 86528 RestoreDemo_Log8.trn PS C:\\dbatools\u003e This is a mix of Full, Differential and Log Backups.\nGetting Started At it\u0026rsquo;s simplest we can do the following:\nRestore-DbaDatabase -SqlInstance localhost\\sqlexpress2016 -Path C:\\dbatools\\backups This will scan all of the files in the folder C:\\dbatools\\backups and restore them onto the SQL Server instance localhost\\sqlexpress2016, up to the most recent record in the backups.\nPowerShell PS C:\\dbatools\u003e Restore-DbaDatabase -SqlServer localhost\\sqlexpress2016 -Path C:\\dbatools\\backups SqlInstance : localhost\\sqlexpress2016 DatabaseName : RestoreDemo DatabaseOwner : RestoreComplete : True BackupFilesCount : 1 RestoredFilesCount : 2 NoRecovery : True BackupSizeMB : 3 CompressedBackupSizeMB : 3 BackupFile : C:\\dbatools\\backups\\RestoreDemo_Full5.bak RestoredFile : C:\\dbatools\\DbOriginalLocation\\RestoreDemo.mdf;C:\\dbatools\\DbOriginalLocation\\RestoreDemo.ldf TSql : SqlInstance : localhost\\sqlexpress2016 DatabaseName : RestoreDemo DatabaseOwner : RestoreComplete : True BackupFilesCount : 1 RestoredFilesCount : 2 NoRecovery : True BackupSizeMB : 1 CompressedBackupSizeMB : 1 BackupFile : C:\\dbatools\\backups\\RestoreDemo_Diff7.bak RestoredFile : C:\\dbatools\\DbOriginalLocation\\RestoreDemo.mdf;C:\\dbatools\\DbOriginalLocation\\RestoreDemo.ldf TSql : SqlInstance : localhost\\sqlexpress2016 DatabaseName : RestoreDemo DatabaseOwner : RestoreComplete : True BackupFilesCount : 1 RestoredFilesCount : 2 NoRecovery : False BackupSizeMB : 0 CompressedBackupSizeMB : 0 BackupFile : C:\\dbatools\\backups\\RestoreDemo_Log8.trn RestoredFile : C:\\dbatools\\DbOriginalLocation\\RestoreDemo.mdf;C:\\dbatools\\DbOriginalLocation\\RestoreDemo.ldf TSql : PS C:\\dbatools\u003e When We Say Scan, We Mean It Will Do the Following: All the files in that folder will be checked to see if they are SQL Server backups The header information from each file will be read The files will then be filtered down to a set that meets your requirements. In this example we will restore your database to the latest point in time contained in those backups. This means we will find: The most recent full backup in those files. Any differential backups taken since that full backup All Transaction backups taken since the last differential backup Then we check that we have an unbroken chain of LSNs to ensure we can restore your database Then we check that the versions of your backup and target SQL instance are compatible Once we\u0026rsquo;re good to go we perform the restore, safe in the knowledge that it\u0026rsquo;ll work Then we\u0026rsquo;ll restore it for you With our example backups, it will have restored RestoreDemo_Full5.bak, RestoreDemo_Diff7 and RestoreDemo_Log8.trn\nAs you can see, we also return a rich object with details about the restore. For the rest of the examples I\u0026rsquo;ll be hiding the output by storing it in a variable, just to make the screenshots more readable.\nSpecifying the Destination Directories By default, Restore-DbaDatabase will restore to the default data and log directories, but maybe you want to move the data files around when you restore the database due to smaller drives:\nRestore-DbaDatabase -SqlInstance localhost\\sqlexpress2016 -Path C:\\dbatools\\backups -DestinationDataDirectory c:\\dbatools\\RestoreLocation\\ PowerShell PS C:\\dbatools\u003e Get-ChildItem .\\RestoreLocation\\ PS C:\\dbatools\u003e $r = Restore-DbaDatabase -SqlServer localhost\\sqlexpress2016 -Path C:\\dbatools\\backups -DestinationDataDirectory C:\\dbatools\\RestoreLocation\\ PS C:\\dbatools\u003e Get-ChildItem .\\RestoreLocation\\ Directory: C:\\dbatools\\RestoreLocation Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 10/02/2017 15:49 5242880 RestoreDemo.ldf -a---- 10/02/2017 15:49 10485760 RestoreDemo.mdf PS C:\\dbatools\u003e This time, all database files (Log, Full Text, Data, etc) will be restored into the folder c:\\dbatools\\RestoreLocation folder\nOr perhaps you want to separate logs and data files out, got you covered:\nRestore-DbaDatabase -SqlInstance localhost\\sqlexpress2016 -Path C:\\dbatools\\backups -DestinationDataDirectory c:\\dbatools\\RestoreLocation -DestinationLogDirectory c:\\dbatools\\RestoreLogsLocation All your data files end up in c:\\dbatools\\RestoreLocation and all your log files go into c:\\dbatools\\RestoreLogsLocation. Nice and easy\nPowerShell PS C:\\dbatools\u003e Get-ChildItem .\\RestoreLocation\\ PS C:\\dbatools\u003e Get-ChildItem .\\RestoreLogsLocation\\ PS C:\\dbatools\u003e $r = Restore-DbaDatabase -SqlServer localhost\\sqlexpress2016 -Path C:\\dbatools\\backups -DestinationDataDirectory c:\\dbatools\\RestoreLocation -DestinationLogDirectory c:\\dbatools\\RestoreLogLocation PS C:\\dbatools\u003e Get-ChildItem .\\RestoreLocation\\ Directory: C:\\dbatools\\RestoreLocation Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 10/02/2017 15:53 5242880 RestoreDemo.ldf PS C:\\dbatools\u003e Get-ChildItem .\\RestoreLogLocation\\ Directory: C:\\dbatools\\RestoreLogLocation Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 10/02/2017 15:53 10485760 RestoreDemo.mdf PS C:\\dbatools\u003e And if you want your restores to return to their original destinations, use the ReuseSourceFolderStructure switch:\nRestore-DbaDatabase -SqlInstance localhost\\sqlexpress2016 -Path C:\\dbatools\\backups -ReuseSourceFolderStructure If you really want to go to town with moving files around during the restore, then we offer the FileMapping parameter. To use this, you have to pass in a HashTable with a key/value pair for every file in the database you\u0026rsquo;re restoring. The key is the logical name of your data file, and the value is the full path of where you want the file to be placed. For example:\n$FileStructure = @{ \u0026#39;DataFile1\u0026#39;=\u0026#39;c:\\datafiles\\datafile1.mdf\u0026#39; \u0026#39;DataFile2\u0026#39;=\u0026#39;d:\\datafiles\\datafile2.mdf\u0026#39; \u0026#39;db_log\u0026#39;=\u0026#39;e:\\logfiles\\db_log.ldf\u0026#39; } Restore-DbaDatabase -SqlInstance localhost\\sqlexpress2016 -Path C:\\dbatools\\backups\\FullBackup.bak -FileMapping $FileStructure -DatabaseName RestoredDatabase Restoring to Specific Point in Time What if you don\u0026rsquo;t want to restore to the latest point in time? Then you can use the RestoreTime parameter to say when you want to restore to. In our example I want to restore to just before the full backup RestoreDemo_Full5.bak\n$RestoreTime = Get-Date(\u0026#34;01/01/2017 11:10\u0026#34;) Restore-DbaDatabase -SqlInstance localhost\\sqlexpress2016 -Path C:\\dbatools\\backups -RestoreTime $RestoreTime Now our file scan will work out which files it needs to use to perform this restore. By using the -Verbose switch we can see which ones it\u0026rsquo;s picked:\nPowerShell PS C:\\dbatools\u003e PS C:\\dbatools\u003e $RestoreTime = Get-Date(\"09/02/2017 11:10\") PS C:\\dbatools\u003e $r = Restore-DbaDatabase -SqlServer localhost\\sqlexpress2016 -Path C:\\dbatools\\backups -RestoreTime $RestoreTime -Verbose VERBOSE: Restore-DbaDatabase : Paths passed in VERBOSE: Restore-DbaDatabase : Standard Directory VERBOSE: Restore-DbaDatabase - Starting VERBOSE: Restore-DbaDatabase - Checking Path VERBOSE: Get-FilteredRestoreFile - Scanning C:\\dbatools\\backups\\* VERBOSE: Get-FilteredRestoreFile - Read File headers (Read-DBABackupHeader) VERBOSE: Get-FilteredRestoreFile - Connect to localhost\\sqlexpress2016 VERBOSE: Get-FilteredRestoreFile - 8 Files in Filter VERBOSE: Get-FilteredRestoreFile - 1 database to process VERBOSE: Get-FilteredRestoreFile - Find Newest Full backup VERBOSE: Get-FilteredRestoreFile - Got a Full backup, now to find diffs if they exist VERBOSE: Get-FilteredRestoreFile - Got a Full/Diff backups, now find all Tlogs after the last one VERBOSE: Get-FilteredRestoreFile - Transaction Log backups found VERBOSE: Get-FilteredRestoreFile - Returning Results to caller VERBOSE: Restore-DbaDatabase - dbs to restore VERBOSE: Restore-DbaDatabase - Starting FileSet VERBOSE: Restore-DbaDatabase - Dbname set from backup = RestoreDemo VERBOSE: Test-DbaLsnChain - Testing LSN Chain VERBOSE: Test-DbaLsnChain - Passed LSN Chain checks VERBOSE: Test-DbaRestoreVersion - RestoreVersion is 13 VERBOSE: Restore-DBFromFilteredArray - Starting VERBOSE: Restore-DBFromFilteredArray - Restoring backup starting at LSN 34000000006800179 in C:\\dbatools\\backups\\RestoreDemo_Full1.bak VERBOSE: Restore-DBFromFilteredArray - Beginning Restore VERBOSE: Restore-DBFromFilteredArray - restore action = Database VERBOSE: Restore-DBFromFilteredArray - More files to restore, NoRecovery set VERBOSE: Restore-DBFromFilteredArray - Performing restore action VERBOSE: Restore-DBFromFilteredArray - Closing Server connection VERBOSE: Restore-DBFromFilteredArray - Restoring backup starting at LSN 34000000021400005 in C:\\dbatools\\backups\\RestoreDemo_Diff4.bak VERBOSE: Restore-DBFromFilteredArray - Beginning Restore VERBOSE: Restore-DBFromFilteredArray - restore action = Database VERBOSE: Restore-DBFromFilteredArray - More files to restore, NoRecovery set VERBOSE: Restore-DBFromFilteredArray - Performing restore action VERBOSE: Restore-DBFromFilteredArray - Closing Server connection VERBOSE: Restore-DBFromFilteredArray - Restoring backup starting at LSN 34000000019800001 in C:\\dbatools\\backups\\RestoreDemo_Log6.trn VERBOSE: Restore-DBFromFilteredArray - Beginning Restore VERBOSE: Restore-DBFromFilteredArray - restore action = Log VERBOSE: Restore-DBFromFilteredArray - Doing Recovery on last file VERBOSE: Restore-DBFromFilteredArray - Performing restore action VERBOSE: Restore-DBFromFilteredArray - Closing Server connection VERBOSE: Restore-DbaDatabase - Database RestoreDemo restored PS C:\\dbatools\u003e We can see it\u0026rsquo;s restored RestoreDemo_Full1.bak, then RestoreDemo_Diff4, and finally used RestoreDemo_log6.trn to roll everything forward to the correct time.\nReplaying the Workload to Remote Lab Next up, perhaps your developers want to investigate some problems they\u0026rsquo;ve been seeing on production. They\u0026rsquo;d love to have a copy of production on a test server, but from 2 hours ago so they can replay the workload. How about this:\nRestore-DbaDatabase -SqlInstance TestDbServer -Path \\\\Server1\\backups\\ProdDb -DestinationDataDirectory D:\\data -RestoreTime (Get-Date).AddHours(-2) What happens if the devs ask you to rereset the database? That\u0026rsquo;s where the -WithReplace switch comes into play\nRestore-DbaDatabase -SqlInstance TestDbServer -Path \\\\Server1\\backups\\ProdDb -DestinationDataDirectory D:\\data -RestoreTime (Get-Date).AddHours(-2) -WithReplace Which will overwrite the existing database for you. Be careful with this switch, it will do exactly what you tell it to! And we\u0026rsquo;ll remove all the users from the database, so that safety net isn\u0026rsquo;t there\nScripting Out to File While helping your colleagues you\u0026rsquo;ll have noticed that there is a little bit of time taken to process all the backups. You hear through the grapevine that this rollback is going to have to be done a couple of times while they work out what\u0026rsquo;s wrong. So how about we generate the T-SQL scripts ahead of time, then you can just rerun those every time. Hey, you could even give them to the Devs to run!\nRestore-DbaDatabase -SqlInstance TestDbServer -Path \\\\Server1\\backups\\ProdDb -DestinationDataDirectory D:\\data -RestoreTime (Get-Date).AddHours(-2) -WithReplace -OutputScriptOnly This will generate all the T-Sql statements required to perform the requested action, but it won\u0026rsquo;t restore the database. By using the -WithReplace switch, the function will return the T-SQL statements with the correct REPLACE sections, it will also script out the file moves for you. For example, using our example backups:\n$RestoreTime = Get-Date(\u0026#34;09/02/2017 11:10\u0026#34;) Restore-DbaDatabase -SqlInstance localhost\\sqlexpress2016 -Path C:\\dbatools\\backups -RestoreTime $RestoreTime -DestinationDataDirectory C:\\dbatools\\DestinationDirectory\\ -WithReplace -OutputScriptOnly produces the following T-SQL scripts:\nRESTORE DATABASE [RestoreDemo] FROM DISK = N\u0026#39;C:\\dbatools\\backups\\RestoreDemo_Full1.bak\u0026#39; WITH MOVE N\u0026#39;RestoreDemo\u0026#39; TO N\u0026#39;C:\\dbatools\\DestinationDirectory\\\\RestoreDemo.mdf\u0026#39;, MOVE N\u0026#39;RestoreDemo_log\u0026#39; TO N\u0026#39;C:\\dbatools\\DestinationDirectory\\\\RestoreDemo.ldf\u0026#39;, NORECOVERY, NOUNLOAD, REPLACE, STATS = 1, STOPAT = N\u0026#39;02/09/2017 11:10:00\u0026#39; RESTORE DATABASE [RestoreDemo] FROM DISK = N\u0026#39;C:\\dbatools\\backups\\RestoreDemo_Diff4.bak\u0026#39; WITH MOVE N\u0026#39;RestoreDemo\u0026#39; TO N\u0026#39;C:\\dbatools\\DestinationDirectory\\\\RestoreDemo.mdf\u0026#39;, MOVE N\u0026#39;RestoreDemo_log\u0026#39; TO N\u0026#39;C:\\dbatools\\DestinationDirectory\\\\RestoreDemo.ldf\u0026#39;, NORECOVERY, NOUNLOAD, REPLACE, STATS = 1, STOPAT = N\u0026#39;02/09/2017 11:10:00\u0026#39; RESTORE LOG [RestoreDemo] FROM DISK = N\u0026#39;C:\\dbatools\\backups\\RestoreDemo_Log6.trn\u0026#39; WITH MOVE N\u0026#39;RestoreDemo\u0026#39; TO N\u0026#39;C:\\dbatools\\DestinationDirectory\\\\RestoreDemo.mdf\u0026#39;, MOVE N\u0026#39;RestoreDemo_log\u0026#39; TO N\u0026#39;C:\\dbatools\\DestinationDirectory\\\\RestoreDemo.ldf\u0026#39;, NOUNLOAD, STATS = 1, STOPAT = N\u0026#39;02/09/2017 11:10:00\u0026#39; Stash them away somewhere safe for when you need them. Or if you want to multi task then\n$Restore = Restore-DbaDatabase -SqlInstance TestDbServer -Path \\\\Server1\\backups\\ProdDb -DestinationDataDirectory D:\\data -RestoreTime (Get-Date).AddHours(-2) -WithReplace -OutputScript $Restore | Select-Object -Property Script Will perform the restore and generate the T-Sql for you. Twice the productivity for only a few characters more.\nAll the examples above assume you\u0026rsquo;ve a single folder containing all your backups. If you have another way of splitting your backups, then you can pass in multiple folders to the path statement:\nRestore-DbaDatabase -SqlInstance MyRestoreSvr\\Instance -Path e:\\FullBackups\\Database1, f:\\LogBackups\\Database1 Yes, We Do Support Ola Hallengren\u0026rsquo;s Maintenance Solution! If you\u0026rsquo;re running Ola Hallengren\u0026rsquo;s maintenance solutions, then we\u0026rsquo;ve got that covered as well. Set your path to the top of your backup folder, and we\u0026rsquo;ll do the rest.\nRestore-DbaDatabase -SqlInstance MyRestoreSvr\\Instance -Path \\\\Server1\\backups\\ProdDb -MaintenanceSolutionBackup This method has the benefit of being faster as we know which files are which, so can shortcut the reading of files before doing your restore.\nUsing xp_dirtree Maybe you don\u0026rsquo;t have access to the backup files, but your SQL Server instance does. In that case we offer xp_dirtree functionality to process the files.\nRestore-DbaDatabase -SqlInstance MyRestoreSvr\\Instance -Path \\\\Server1\\backups\\ProdDb -XpDirTree You will need to have sysadmin permissions on the SQL instance to use the underlying xp_dirtree stored procedure\nUsing the PowerShell Pipeline And like all good PowerShell functions we take input from the pipeline, so if you want to pipe in files we\u0026rsquo;ll take them!:\nGet-ChildItem c:\\backups | Where-Object {$_.name -like \u0026#39;ProdDb1*\u0026#39;} | Restore-DbaDatabase -SqlInstance MyRestoreSvr\\Instance And coming next week we\u0026rsquo;ll be able to take pipeline from our own commands! Not sure where a database is backed up? We will be able to use Get-DbaBackupHistory to answer that.\nGet-DbaBackupHistory -SqlInstance ProdSrv1 -Database Finance1 | Restore-DbaDatabase -SqlInstance TestSrv1 This will query ProdSrv1 to get the backup history for the Finance1 database using Get-DbaBackupHistory, this will then be piped to the Restore-DbaDatabase function which will use this information to restore the Finance1 database onto TestSrv1. And you will also be able to apply all the normal Restore-DbaDatabase goodness:\nGet-DbaBackupHistory -SqlInstance ProdSrv1 -Database Finance1 | Restore-DbaDatabase -SqlInstance TestSrv1 -DestinationDataDirectory d:\\DataDump -RestoreTime (Get-date).AddHours(-3) Restore-DbaDatabase Parameters Up till now, all our examples have assumed you\u0026rsquo;re only restoring a single database. But Restore-DbaDatabase will handle more than one backup at time.\nOnly certain parameters will work with multiple databases, as these are ones that can be applied to ALL databases passed in. Those parameters are:\nDestinationDirectory DestinationLogDirectory WithReplace Server Credential RestoreTime OutputScript OutputScriptOnly VerifyOnly With our last example, this means we will be able to do:\nGet-DbaBackupHistory -SqlInstance ProdSrv1 -Database Finance1, HR, CRM | Restore-DbaDatabase -SqlInstance TestSrv1 -DestinationDataDirectory d:\\DataDump -RestoreTime (Get-date).AddHours(-3) And restore all 3 database from ProdSrv1 onto TestSrv1 in one fell swoop! This feature is coming this week or next.\nAnd, Just One Last Thing So we\u0026rsquo;ve made it super easy to restore databases. But don\u0026rsquo;t think we\u0026rsquo;ve forgotten that you have to create the backups first. Snowball also marks the first appearance of our new backup command Backup-DbaDatabase.\nYou want to perform a full backup of every database on an instance:\nGet-DbaDatabase -SqlInstance Server1 | Backup-DbaDatabase -Type Full -BackupDirectory \\\\Server2\\share\\DbBackups and you\u0026rsquo;re done!\nThis is the first release of this command, so keep checking back as we add more features. So please let us know what you\u0026rsquo;d like to see added in future releases\nGoing Forward This is the first release of this functionality, and we\u0026rsquo;re looking at extending its capabilities over time. So we\u0026rsquo;d love to hear from you with your ideas for improvements. I\u0026rsquo;d also really like to hear about any unusual or different ways you can think of using this functionality.\nAnd please, if you come across something that doesn\u0026rsquo;t work, or doesn\u0026rsquo;t make sense. Please come and talk to us. We hang out over on Slack at sqlcommunity.slack.com or you can report issues over at our Github repo at github.com/dataplat/dbatools\nStuart ","date":"2017-02-23","summary":"Just to confuse people, it\u0026rsquo;s not Chrissy or Drew this time. My name\u0026rsquo;s Stuart, and I\u0026rsquo;ve got a new dbatools release to tell you about; snowball.\nThis Release Is All About Restores DBAs spend a lot of time making sure backups work. Or at least they should, and if they aren\u0026rsquo;t then putting their spare time to fixing up their CV is probably a good plan.\nSo we\u0026rsquo;ve got terabytes of SQL backups stashed away on disk.","tags":["backuprestore","disasterrecovery","dr"],"title":"New Release - Snowball - All About the Restore","type":"post","url":"https://dbatools.io/snowball/"},{"categories":[],"content":"Holler Thank you for your interest! It is best to write with questions or issues on our GitHub Repo. We are also on the SQL Server Community Slack in the channel #dbatools.\n","date":"2017-02-13","summary":"Holler Thank you for your interest! It is best to write with questions or issues on our GitHub Repo. We are also on the SQL Server Community Slack in the channel #dbatools.","tags":[],"title":"Contact","type":"page","url":"https://dbatools.io/contact/"},{"categories":["announcements"],"content":"These commands were updated Feb 8, 2017 (v0.8.709) to incorporate feedback ❤️\nRight, so the first thing you need to know is: I\u0026rsquo;m not Chrissy. My name\u0026rsquo;s Drew, and I\u0026rsquo;m here tell you about an exciting new release of dbatools: schwifty!\nIn this release we\u0026rsquo;ve added three new commands to help you manage SPNs for SQL Server Kerberos authentication. If you have a lot of linked servers in your environment, then this is probably a welcome addition to the toolset for you.\nThese commands leverage SQL Server instance info from commands that already existed in the dbatools code base and active directory PowerShell support to determine required SPNs for all instances on a given computer and whether they\u0026rsquo;re set or not. If they aren\u0026rsquo;t, we have commands to not only set the SPNs for you, but also enable constrained delegation to accounts for the SPNs that were just added.\nYouTube video: OVYFU3Ktqc0\nThen Before these functions were added to dbatools, you had a couple options when it came to checking/adding SPNs:\nsetspn.exe and ActiveDirectory Users and Computers. setspn.exe is a windows command that you could use to add an SPN to given Active Directory account. And it works great! You do need to know the SPN and account you want to set it for ahead of time; it doesn\u0026rsquo;t really care about what kind of SPN you\u0026rsquo;re setting, but it\u0026rsquo;ll let you set it. You could also use it to check for dupes, list out what SPNs exist for an account… it\u0026rsquo;s a pretty well documented command. Setting the SPN is only part of what makes SQL Server Kerberos authentication work, though. You still need to set delegation on the account to the services in question. That normally requires you going into the Active Directory Users and Computers application and adding delegation outside of the setspn.exe command prompt. Yuck!\nMicrosoft Kerberos Configuration Manager for SQL Server. Microsoft does have a tool to help you manage your SPNs for SQL Server too. It\u0026rsquo;s called Kerberos Configuration Manager for SQL Server and it\u0026rsquo;s awesome because not only does it tell you what SPNs need set, but it checks to see if they are there. If they aren\u0026rsquo;t, it\u0026rsquo;ll try and fix them for you, or generate a .cmd file that you can run on your own. It\u0026rsquo;s a neat tool that essentially generates SPNs based on best practice straight from Microsoft. While the auto fixing and script generation are neat, the program can be a little slow. Also: up until very recently (2017 Jan 31), it wasn\u0026rsquo;t compatible with SQL Server 2016. It also doesn\u0026rsquo;t set delegation for your accounts, either. Less yuck, but still: yuck!\nNow Now we have four new commands to help manage SPNs - Get-DbaSpn, Test-DbaSpn, Set-DbaSpn, and Remove-DbaSpn. Our goal with the new SPN commands was to make them fast, and make them at least as useful as the GUI tool provided by Microsoft, but to allow multi-server administration and automation of setting correct SPNs and enabling constrained delegation. And we\u0026rsquo;ve done it! These commands are based on guidance from MSDN about setting SQL Server Service Principal names which you can read more about here.\nOh and for the performance minded among you, we\u0026rsquo;ve built these functions to be super fast; faster than the traditional setspn.exe and Configuration Manager options by quite a bit. While the GUI tool took up to 51 seconds per server, our testing showed the ability to return required SPN info for 9 servers in 9 seconds. That\u0026rsquo;s 1 server per second, granted, we don\u0026rsquo;t test for SSAS or SSRS at this time, but we do have it planned, and it\u0026rsquo;ll still be quick.\nTake a look below for a detailed description of the new commands in this release. You can use these new functions by grabbing our latest release (0.8.709).\nA couple things to note when using these functions:\nYou\u0026rsquo;ll need at least permission to read from your domain\u0026rsquo;s Active Directory, and in the case of adding SPNs, the ability to modify. That means you\u0026rsquo;ll need to run the commands as a user with those permissions, or use the -Credential parameters.\nFully explore Get-DbaSpn and Test-DbaSpn commands before moving on to Set-DbaSpn. We also included -WhatIf support in Set-DbaSpn so you can see what SPNs will be added to which accounts before you actually apply them. We\u0026rsquo;ve done our best to make sure we fully support a variety of different configurations and network names, but you should know what will be applied before you actually do it.\nNew Commands - Get-DbaSpn Returns a list of any service principal names (SPNs) set for a given server or active directory account name\nPowerShell PS C:\\github\\dbatools\u003e Get-DbaSpn -ComputerName sql2016 | Format-Table Input AccountName ServiceClass Port SPN ----- ----------- ------------ ---- --- sql2016 base\\sqlserver MSSQLSvc MSSQLSvc/SQL2016.base.local sql2016 base\\sqlserver MSSQLSvc MSSQLSvc/SQL2016.base.local:SQLEXPRESS sql2016 base\\sqlserver MSSQLSvc MSSQLSvc/SQL2016.base.local:VWEXT sql2016 base\\sqlserver MSSQLSvc 1433 MSSQLSvc/SQL2016.base.local:1433 sql2016 base\\sqlserver MSSQLSvc 49903 MSSQLSvc/SQL2016.base.local:49903 sql2016 base\\sqlserver MSSQLSvc 49837 MSSQLSvc/SQL2016.base.local:49837 PS C:\\github\\dbatools\u003e $servers | Get-DbaSpn | Format-Table -AutoSize Input AccountName ServiceClass Port SPN ----- ----------- ------------ ---- --- sql2008 base\\sqlserver MSSQLSvc MSSQLSvc/sql2008.base.local sql2008 base\\sqlserver MSSQLSvc MSSQLSvc/sql2008.base.local:SQL2K8 sql2008 base\\sqlserver MSSQLSvc 1433 MSSQLSvc/sql2008.base.local:1433 sql2008 base\\sqlserver MSSQLSvc 49271 MSSQLSvc/sql2008.base.local:49271 sql2012 base\\sqlserver MSSQLSvc MSSQLSvc/sql2012.base.local sql2012 base\\sqlserver MSSQLSvc 1433 MSSQLSvc/sql2012.base.local:1433 sql2014 base\\sqlserver MSSQLSvc MSSQLSvc/sql2014.base.local sql2016 base\\sqlserver MSSQLSvc MSSQLSvc/SQL2016.base.local sql2016 base\\sqlserver MSSQLSvc MSSQLSvc/SQL2016.base.local:SQLEXPRESS sql2016 base\\sqlserver MSSQLSvc MSSQLSvc/SQL2016.base.local:VWEXT sql2016 base\\sqlserver MSSQLSvc 1433 MSSQLSvc/SQL2016.base.local:1433 sql2016 base\\sqlserver MSSQLSvc 49903 MSSQLSvc/SQL2016.base.local:49903 sql2016 base\\sqlserver MSSQLSvc 49837 MSSQLSvc/SQL2016.base.local:49837 sql2016a base\\sqlserver MSSQLSvc MSSQLSvc/sql2016a.base.local sql2016a base\\sqlserver MSSQLSvc 1433 MSSQLSvc/sql2016a.base.local:1433 sql2016b base\\sqlserver MSSQLSvc MSSQLSvc/sql2016b.base.local sql2016b base\\sqlserver MSSQLSvc 1433 MSSQLSvc/sql2016b.base.local:1433 sql2016c base\\sqlserver MSSQLSvc MSSQLSvc/sql2016c.base.local sql2016c base\\sqlserver MSSQLSvc 1433 MSSQLSvc/sql2016c.base.local:1433 sqlcluster base\\sqlserver MSSQLSvc MSSQLSvc/sqlcluster.base.local sqlcluster base\\sqlserver MSSQLSvc 1433 MSSQLSvc/sqlcluster.base.local:1433 PS C:\\github\\dbatools\u003e _ - Test-DbaSpn Returns of listing of \u0026ldquo;required\u0026rdquo; SPNs for a given computer\u0026rsquo;s instance of SQL Server. The cmdlet will discover all instances of SQL Server on a given computer name. For each instance found, the cmdlet will generate a list of required SPNs based on active TCP/IP ports. The cmdlet will also warn you if an instance is using dynamic ports. Each returned SPN object will also specify if the SPN is currently set or not.\nPowerShell PS C:\\github\\dbatools\u003e Test-DbaSpn -ComputerName sql2005 | Format-Table ComputerName InstanceName SqlProduct TcpEnabled DynamicPort RequiredSPN IsSet Cluster IsOnlineFail DomainPort Warning Error ------------ ------------ ---------- ---------- ----------- ----------- ----- ------- ------------ ---------- ------- ----- sql2005.base.local MSSQLSERVER SQL Server 2005 Enterprise Edition False False MSSQLSVC/sql2005.base.local False False False None sql2005.base.local MSSQLSERVER SQL Server 2005 Enterprise Edition False False MSSQLSVC/sql2005.base.local:1433 False False False 1433 None sql2005.base.local BASE\\sqlserver False False MSSQLSVC/sql2005.base.local False False False None sql2005.base.local BASE\\sqlserver False False MSSQLSVC/sql2005.base.local:1433 False False False 1433 None sql2005.base.local msdbs-AllowedDelegateto False False msdbs-AllowedDelegateto False False False None sql2005.base.local msdbs-AllowedDelegateto False False msdbs-AllowedDelegateto False False False None You can even check your entire estate in just one line. Here, you can see us testing several instances in our lab.\nOr use Test to help easily Set all required SPNs\nPowerShell PS C:\\github\\dbatools\u003e Test-DbaSpn -ComputerName sql2005 | Where-object { !..IsSet -eq $false } ComputerName : sql2005.base.local InstanceName : MSSQLSERVER SqlProduct : SQL Server 2005 Enterprise Edition (64-bit) TcpEnabled : False RequiredSPN : MSSQLSVC/sql2005.base.local IsSet : False Cluster : False TcpEnabled : True DynamicPort : False Warning : None Error : SPN missing ComputerName : sql2005.base.local InstanceName : MSSQLSERVER SqlProduct : SQL Server 2005 Enterprise Edition (64-bit) InstanceServiceAccount : BASE\\sqlserver RequiredSPN : MSSQLSVC/sql2005.base.local:1433 IsSet : False Cluster : False TcpEnabled : True DynamicPort : False Warning : None Error : SPN missing PS C:\\github\\dbatools\u003e Test-DbaSpn -ComputerName sql2005 | Where-object { !..IsSet -eq $false } | Set-DbaSpn | Format-Table Name ServiceAccountProperty IsSet Notes ---- ---------------------- ----- ----- MSSQLSvc/sql2005.base.local BASE\\sqlserver servicePrincipalName True Successfully added SPN MSSQLSvc/sql2005.base.local:1433 BASE\\sqlserver servicePrincipalName True Successfully added SPN MSSQLSvc/sql2005.base.local BASE\\sqlserver msdbs-AllowedToDelegateTo True Successfully added constrained delegation MSSQLSvc/sql2005.base.local:1433 BASE\\sqlserver msdbs-AllowedToDelegateTo True Successfully added constrained delegation PS C:\\github\\dbatools\u003e Test-DbaSpn -ComputerName sql2005 | Where-object { !..IsSet -eq $false } PS C:\\github\\dbatools\u003e _ - Set-DbaSpn Connects to Active Directory and sets a given SPN to a given account. Will also set constrained delegation to the account to the recently added SPN.\nPowerShell PS C:\\github\\dbatools\u003e Set-DbaSpn -SPN MSSQLSvc/sql2005.base.local:1433 -ServiceAccount base\\sqlserver | Format-Table Name ServiceAccount Property IsSet Notes ---- -------------- -------- ----- ----- MSSQLSvc/sql2005.base.local:1433 base\\sqlserver servicePrincipalName True Successfully added SPN MSSQLSvc/sql2005.base.local:1433 base\\sqlserver msdbs-AllowedToDelegateTo True Successfully added constrained delegation PS C:\\github\\dbatools\u003e _ Both Set and Remove fully support -WhatIf\nPowerShell PS C:\\github\\dbatools\u003e Test-DbaSpn -ComputerName sql2005 | Where-object { !..IsSet -eq $false } | Set-DbaSpn -WhatIf What If: Performing the operation 'Adding SPN to service account' on target 'MSSQLSvc/sql2005.base.local'. What If: Performing the operation 'Adding constrained delegation to service account' on target 'MSSQLSvc/sql2005.base.local'. What If: Performing the operation 'Adding SPN to service account' on target 'MSSQLSvc/sql2005.base.local:1433'. What If: Performing the operation 'Adding constrained delegation to service account for SPN' on target 'MSSQLSvc/sql2005.base.local:1433'. - Remove-DbaSpn Connects to Active Directory and removes a given SPN to a given account. Will also remove the associated constrained delegation.\nThe following screenshot shows a way to easily remove SPNS of decommissioned servers.\nPowerShell PS C:\\github\\dbatools\u003e Remove-DbaSpn -SPN MSSQLSvc/sql2014:1433 -ServiceAccount base\\sqlserver | Format-Table Name ServiceAccount Property IsSet Notes ---- -------------- -------- ----- ----- MSSQLSvc/sql2014:1433 base\\sqlserver servicePrincipalName False Successfully removed SPN MSSQLSvc/sql2014:1433 base\\sqlserver msdbs-AllowedToDelegateTo False Successfully removed delegation PS C:\\github\\dbatools\u003e Get-DbaSpn -ComputerName sql2005 | Remove-DbaSpn | Format-Table Name ServiceAccount Property IsSet Notes ---- -------------- -------- ----- ----- MSSQLSvc/sql2005.base.local base\\sqlserver servicePrincipalName False Successfully removed SPN MSSQLSvc/sql2005.base.local base\\sqlserver msdbs-AllowedToDelegateTo False Successfully removed delegation MSSQLSvc/sql2005.base.local:1433 base\\sqlserver servicePrincipalName False Successfully removed SPN MSSQLSvc/sql2005.base.local:1433 base\\sqlserver msdbs-AllowedToDelegateTo False Successfully removed delegation PS C:\\github\\dbatools\u003e _ Related Commands We also have a few other commands that can help you deal with SPNs.\nRepair-DbaInstanceName and Repair-DbaServerName\nWhen a SQL Server\u0026rsquo;s host OS is renamed, the SQL Server should be as well. This helps with Availability Groups and Kerberos. Repair-DbaInstanceName helps determine if your OS and SQL Server names match, and thus, if a rename is required. If a rename is required, run Repair-DbaServerName.\nTest-DbaConnectionAuthScheme\nThis command returns the transport protocol and authentication scheme of the connection. This is useful to determine if your connection is using Kerberos. By default, the ConnectName, ServerName, Transport and AuthScheme of the current connection will be returned.\nComing Soon These commands are just the start of our support for SPNs. Right now, they\u0026rsquo;re just focused on SQL-related services on your computers. In the future, we\u0026rsquo;re going to extend these scripts to look at ALL services on your computers and tie them back to service accounts and SPNs. This includes SSAS, SSIS, and SSRS SPN support. We\u0026rsquo;re also going to keep looking at the commands and adding support for anything we didn\u0026rsquo;t think of when we released, which is why it\u0026rsquo;s important that you give us feedback (more on that below).\nThanks for reading, and I hope you enjoy these new commands! If you have any issues or questions about their use, feel free to drop by our Slack channel, #dbatools, and let us know. We\u0026rsquo;d love to hear from you!\n- Drew\n","date":"2017-02-06","summary":"These commands were updated Feb 8, 2017 (v0.8.709) to incorporate feedback ❤️\nRight, so the first thing you need to know is: I\u0026rsquo;m not Chrissy. My name\u0026rsquo;s Drew, and I\u0026rsquo;m here tell you about an exciting new release of dbatools: schwifty!\nIn this release we\u0026rsquo;ve added three new commands to help you manage SPNs for SQL Server Kerberos authentication. If you have a lot of linked servers in your environment, then this is probably a welcome addition to the toolset for you.","tags":["kerberos","mrbulldops","security","serviceprincipalname","spn"],"title":"New Release - Schwifty - All About SPNs","type":"post","url":"https://dbatools.io/schwifty/"},{"categories":["announcements"],"content":"In this release, we gained 4 new contributors to the dbatools master repository for a grand total of of 39! We even added 4 new Major Contributors to the team. Thanks to all who have joined in to make the awesomest toolset for SQL Server DBAs — we\u0026rsquo;re now offering the community 126 quality commands.\nSorry for the Delay, We\u0026rsquo;ve Been Really Busy! Our last release came out around mid-December. Ideally, we aim for releasing more often, but Rob and I were out presenting about dbatools and dbareports at a few conferences and ran out of time. We did merge a mini-release (v0.8.693) to master in early January, though. So that kinda counts 😉\nThe rest of the team has been super busy, too, as you can see by all of the new commands, enhancements and fixes. Now we\u0026rsquo;ve had time to compile the documentation and screenshots, so here is the release in all of its amazing glory.\nNew Commands In this release we have 22 new commands, several bugs fixes and a bunch of improvements on the existing commands. There are so many exciting commands in this release, it\u0026rsquo;s hard to even highlight the top 22 best(har har). Let us know your favorites at bsky.app/profile/dbatools.io! We\u0026rsquo;re really curious.\nExport-DbaUser Exports SQL Server Database Users creation script with all database permissions (database and object level) to a T-SQL file. This is a function that is not available in SQL Server Management Studio.\nFind-DbaAgentJob Finds agent job(s) that fit certain search criteria.\nFind-DbaDatabase Search SQL Server instances for database that have either the same name, owner or service broker guid.\nFind-DbaStoredProcedure Returns all stored procedures that contain a specific string or regex pattern.\nGet-DbaAgentAlert Return all SQL Agent alerts on a SQL Server Agent.\nGet-DbaAgentOperator Returns all SQL Agent operators on a SQL Server Agent.\nGet-DbaDbState Gets some common \u0026ldquo;states\u0026rdquo; on databases like Read-Write (READ_ONLY or READ_WRITE), Status (ONLINE, OFFLINE, EMERGENCY) and Access options (SINGLE_USER, RESTRICTED_USER, MULTI_USER)\nGet-DbaHelpIndex This function will return detailed information on indexes (and optionally statistics) for all indexes in a database, or a given index should one be passed along.\nGet-DbaMemoryUsage Get amount of memory in use by all SQL Server components and instances. SSAS and SSIS are included.\nGet-DbaMsdtc Displays information about the Distributed Transaction Coordinator (MSDTC) on a server.\nGet-DbaPageFileSetting Returns detailed information about the Windows page file.\nGet-DbaTrigger Get all existing triggers at instance and database level.\nGet-DbaUptime Returns the uptime of the SQL Server instance. If you want you can get the value for the hosting windows server too.\nGet-DbaXEventsSession Retrieves a list of Extended Events Sessions.\nInvoke-DbaQuery Invoke-SqlCmd2, a community favorite, has also been added to dbatools! Updates will continue to occur in the Invoke-SqlCmd2 repository and we\u0026rsquo;ll just add the updates with each release\nInvoke-DbaQuery runs a T-SQL script. But only captures the first selected result set, such as the output of PRINT statements when -verbose parameter is specified. A big plus when comparing with native Invoke-Sqlcmd cmdlet is that this one supports parameterized queries.\nNew-DbaDbSnapshot Do you need to create a database snapshot? This command will do it without hassles.\nConvertTo-DbaDataTable Will creates a DataTable based on an objects properties. This allows you to easily write to SQL Server tables.\nRename-DbaLogin It can be a pain to update all of the mappings for a specific user when you rename a SQL login this does it for you, will rename login and database mapping for a specified login.\nRestore-DbaFromDatabaseSnapshot Restores the database from the snapshot, discarding every modification made to the database.\nSet-DbaDbState Want to change a database state? With this command you can chose between ReadOnly, ReadWrite, Online, Offline, Emergency, plus a special \u0026ldquo;Detached\u0026rdquo;, SingleUser, RestrictedUser, MultiUser.\nTest-DbaOptimizeForAdHoc Displays information relating to SQL Server Optimize for AdHoc Workloads setting.\nWrite-DbaDataTable Quickly and efficiently writes data to a SQL Server Table using a .NET DataTable to a SQL Server table using SQL Bulk Copy.\nImprovements Test-DbaMigrationConstraint Added support for SQL Server 2016 SP1 outstanding news! Almost all editions support what was, until now, Enterprise-only features. (#512)\nGet-SqlServerKey Added support for SQL Server 2016 (#610)\nCopy-DbaLogin If you try to transfer a local account (non-domain) you get a \u0026ldquo;Skipped\u0026rdquo;, because is a local machine account. (#275)\nNotable Bug Fixes Copy-DbaDatabase Fixed an issue where -WithReplace was not working properly (#601)\nExpand-DbaDbLogFile Fixed an issue where Expand-DbaDbLogFile grew TLog all at once. (#503)\nRemove-DbaDbOrphanUser Fixed an issue where Remove-DbaDbOrphanUser fails when the user was the owner of one or more schemas. (#296)\nRemove-DbaDatabaseSafely Remove-DbaDatabaseSafely failed to perform final drop w/ no additional information. (#238)\nHow\u0026rsquo;s 1.0 Coming Along? Very well! We\u0026rsquo;re working through the style guide right now and have been decisive and moving forward quickly. The feature code freeze is still planned for the end of February then we\u0026rsquo;ll begin working on:\nBug fixes Standardized documentation Standardized names for parameters, commands, etc Standardized outputs Testing We plan to resolve all bug issues first and will continue releasing on a regular basis until the style changes are implemented. If you\u0026rsquo;re available to help, we\u0026rsquo;d love it! Even if you don\u0026rsquo;t know PowerShell, we\u0026rsquo;ll need help updating the website with screenshots and examples with the updated parameters and command names, and other tasks of that nature.\nAppVeyor, Pester and Testing Rob Sewell of dbareports.io fame spent even more time adding Pester testing and enforced testing for each commit using AppVeyor. This helps us release more often and with higher quality.\nWant to help create tests? We\u0026rsquo;re in desperate need of testers and Pester fans. Or, if you want to learn Pester, this is a great opportunity. Both dbatools and dbareports are in need. Thanks so much to Iraklis Evangelinos for the tests he contributed in this release.\nNew to dbatools? Visit the installation page for information about how to download and install dbatools (it\u0026rsquo;s 1 command).\nJoin Us! Some of these commands are in their infancy. Want to help make them better? Come join the coding party! We\u0026rsquo;re all hanging out on the SQL Server Community Slack in the #dbatools channel. There\u0026rsquo;s like 430 of us there now.\nThanks for reading 😀\nChrissy ","date":"2017-02-01","summary":"In this release, we gained 4 new contributors to the dbatools master repository for a grand total of of 39! We even added 4 new Major Contributors to the team. Thanks to all who have joined in to make the awesomest toolset for SQL Server DBAs — we\u0026rsquo;re now offering the community 126 quality commands.\nSorry for the Delay, We\u0026rsquo;ve Been Really Busy! Our last release came out around mid-December. Ideally, we aim for releasing more often, but Rob and I were out presenting about dbatools and dbareports at a few conferences and ran out of time.","tags":[],"title":"New Release - Twentyfiveschmeckles","type":"post","url":"https://dbatools.io/twentyfiveschmeckles/"},{"categories":["announcements"],"content":"First, I\u0026rsquo;d like to thank everyone for a super amazing year! 🎉 Back at the start of 2016, GitHub reports that there were two contributors to the dbatools repository and now there are 32, excluding bots. THIRTY TWO! Cheers, y\u0026rsquo;all 🍺 That\u0026rsquo;s beyond amazing and I don\u0026rsquo;t even have the words to describe how excited I am to be a part of this incredibly fun and useful project.\nWith the help of these 32 contributors, the module has grown from 23 commands to 106! That\u0026rsquo;s 106 ways to help ease the administrative burden faced by SQL Server DBA\u0026rsquo;s and developers.\nThe Good, the Bad, and the Beautiful A large majority of the progress we made was beautiful, but there was some ugly. Along the way, during nights of caffeine-fueled coding streaks, I tried my best to keep parameter names, outputs and documentation consistent, but I wasn\u0026rsquo;t as successful as I\u0026rsquo;d hoped. Without a well thought out style guide, there were 31 other people who didn\u0026rsquo;t have a strict standard to follow, either. Our templates helped but they weren\u0026rsquo;t a perfect solution.\nI can say that I wish I had taken the time to make a style guide from the start but that wouldn\u0026rsquo;t be true. Now is actually the best time — now have a variety of commands with a variety of requirements that didn\u0026rsquo;t exist in January of 2016. We\u0026rsquo;ve got more things to think about and more things to define. Perfect.\nWe also have a larger team that can think of a greater number of implications for the decisions we make. A few team members are far more meticulous than I am when it comes to style and their input will be so vital to this big ol\u0026rsquo; process.\nGetting to 1.0 dbatools, which started as Start-DbaMigration.ps1 back around August or September of 2014 is now almost ready to move from pre-release to 1.0. As of today, our master repository is at version 0.8.693.\nInitially, I thought that some important features such as log shipping and mirroring for migrations would need to be implemented before I would consider dbatools a 1.0 product. But now I realize that while those would be amazing, dbatools will be ready for 1.0 once we standardize our code base.\nWe\u0026rsquo;ve already started working on the specifics as a team in #dbatools-style Slack channel and plan to use the next couple months to build a style guide.\nBeginning March 1, 2017, we will initiate a code freeze and work together to update our code to have standardized\nCommand names Parameter names Variable names Documentation Output Pipeline support Other stuff TBD From now until the March deadline, you may notice that new commands will begin using -SqlInstance instead of -SqlServer, which is one of the decisions we\u0026rsquo;ve already made. SqlServer will continue to be supported as an alias until 1.0 comes out.\nWe expect that the code freeze will take about 2 months while we\nImplement all standards, including documentation changes Fix all bugs listed in the repository\u0026rsquo;s issues Test everything Test everything again Update the website\u0026rsquo;s documentation and screenshots If you are interested in helping with this process, please do join in! We\u0026rsquo;ll need all the help we can get. You can hit us up in the #dbatools or #dbatools-style Slack channels.\n1.0 Will Contain Breaking Changes I want to emphasize sooner than later that 1.0 will contain breaking changes. Scripts that previously used -SqlServer, for instance, will have to be changed to use -SqlInstance. we\u0026rsquo;ll be removing all aliased commands, too. For instance, right now, if you run Reset-DbaAdmin (a command from the old days), it will run Reset-DbaAdmin for you. In 1.0, the Reset-DbaAdmin alias will be removed.\nWe will also rename all Sql-prefixed commands to Dba. Initially, I chose to use Sql as a prefix so that people would understand Copy-DbaDatabase copies a SQL database, and not just the \u0026ldquo;database administrator database\u0026rdquo; as perhaps would be suggested by Copy-DbaDatabase. By now, however, people are becoming familiar with the toolset so we\u0026rsquo;ll be doing away with all of the Sql prefixes and leave those for Microsoft to use.\nWe will also remove support for all pluralized parameter names.\nAbout Those Plural Parameters Initially when I was creating dbatools, I decided to break a few best practices in order to convey ideas better. For instance:\nCopy-DbaDatabase supports the -Databases parameter, so that people know that you can migrate more than one database at a time Copy-DbaLogin supports the -Logins parameter, so that people know that you can migrate more than one login at a time The PowerShell team has said that it is best practice to name commands and parameters using singulars and I gave in with naming the commands with the singular, but I just couldn\u0026rsquo;t do it with the parameters. I really thought that people understanding you can copy multiple, specific items would increase adoption. SQL people wouldn\u0026rsquo;t have to learn about the nuances of the PowerShell naming convention — I could save them some time.\nThen I talked to one of my heroes, Aleksandar Nikolić about using plural parameters and he said something that resonated very deeply with me\nWe should never use bad practice solutions to increase PowerShell adoption. Azure PowerShell team did that and look what happened. You now measure bad PowerShell cmdlets design with Azure PS cmdlets.\nDamn, so true. Looks like we\u0026rsquo;ll be making a concerted effort to ensure that people know about the support for multiple items, whether it be in the docs and examples, or within individual blog posts that we all work on (like this one ;)).\nBut What About the Burden on New Developers? I\u0026rsquo;d rather help rewrite all of someone\u0026rsquo;s code than to have anyone run away from the development process because it seems overwhelming. From now until the release of 1.0, we\u0026rsquo;re also going to work out how to best integrate new developers.\nI think it will be similar to the way we\u0026rsquo;re doing it now — provide some unintimidating templates and mention any needed changes during the code reviews. Either way, we\u0026rsquo;ll do our best to ensure that new contributors feel that contributing to dbatools is within reach without tedious onboarding.\nThank You So Much Thanks again to everyone who has helped make this an amazing year, whether you are an e-mail subscriber, an end-user, idea giver, bug reporter or developer.\nHere\u0026rsquo;s to an extra magical 2017!\n","date":"2017-01-03","summary":"First, I\u0026rsquo;d like to thank everyone for a super amazing year! 🎉 Back at the start of 2016, GitHub reports that there were two contributors to the dbatools repository and now there are 32, excluding bots. THIRTY TWO! Cheers, y\u0026rsquo;all 🍺 That\u0026rsquo;s beyond amazing and I don\u0026rsquo;t even have the words to describe how excited I am to be a part of this incredibly fun and useful project.\nWith the help of these 32 contributors, the module has grown from 23 commands to 106!","tags":[],"title":"New Year, New Standardized Coding Style","type":"post","url":"https://dbatools.io/new-style/"},{"categories":["announcements"],"content":"In this release, we gained 4 new contributors to the dbatools master repository for a grand total of of 33! We even added 4 new Major Contributors to the team. Thanks to all who have joined in to make the awesomest toolset for SQL Server DBAs — we\u0026rsquo;re now offering the community over 100 quality commands\nJust a Quick Highlight I\u0026rsquo;m especially excited about every one of the commands in this release. One in particular that stands out to me, though, is Test-DbaWindowsLogin. I like this one because it\u0026rsquo;s a perfect example of a simple PowerShell command that would be a nightmare to pull off using pure T-SQL.\nTest-DbaWindowsLogin gathers all of the surrounding Active Directory domains (trusted and within the forest), logs into a SQL Server, gets the list of logins that are Windows users and groups, then queries Active Directory to see if they are still valid.\nGorgeous! Thanks so much to Major Contributor Stephen Bennett for suggesting and creating this command. It\u0026rsquo;s something I\u0026rsquo;ve already started to use in my own environment.\nCommands We fixed about 16 bugs, made a couple commands more efficient and added 10 new commands.\nExport-DbaAvailabilityGroup Exports SQL Server Availability Groups creation scripts to a T-SQL file. This is a function that is not available in SQL Server Management Studio.\nGet-DbaDbBackupHistory This command returns backup history details for some or all databases on a SQL Server. You can even get detailed information (including file path) for latest full, differential and log files.\nGet-DbaDbSnapshot Retrieves the list of database snapshot available, along with their base (the db they are the snapshot of), Size in MB, creation time and other details.\nGet-DbaDbRoleMember Get members of all roles on a SQL instance. Default output includes columns SqlServer, Database, Role, Member.\nRead-DbaBackupHeader Reads detailed file information about full, differential and transaction log backups.\nRemove-DbaDbSnapshot Removes (drops) database snapshots from the server\nResolve-DbaNetworkName Returns information about the network connection of the target computer including NetBIOS name, IP Address, domain name and fully qualified domain name (FQDN).\nTest-DbaMaxMemory The Max Memory series (Get-DbaMaxMemory, Set-DbaMaxMemory, Test-DbaMaxMemory) first started out as Get-DbaMaxMemory and Set-DbaMaxMemory. Since then, things change a bit. First, the prefix was changed from Sql to Dba to better align with the rest of the commands, and Test was used to test and propose recommendations instead of Get.\nTest-DbaMaxMemory information relating to SQL Server Max Memory configuration settings. It was inspired by Jonathan Kehayias\u0026rsquo;s post about SQL Server Max memory, and displays a SQL Server\u0026rsquo;s: total memory, currently configured SQL max memory, and the calculated recommendation.\nTest-DbaWindowsLogin The purpose of this function is to find SQL Server logins that are used by Active Directory users that are either disabled or removed from the domain. It allows you to keep your logins accurate and up to date by removing accounts that are no longer needed.\nTest-DbaLastBackup Restores all or some of the latest backups, performs a DBCC CHECKTABLE then drops the test database. Here\u0026rsquo;s a video.\nNotable Bug Fixes Remove-DbaDatabaseSafely Fixed an issue with it not detecting that SQL Agent was running.\nFind-DbaOrphanedFile Good ol\u0026rsquo; Find-DbaOrphanedFile now works better with SQL Server 2005 and SQL Server 2000.\nExport-DbaLogin Now enumerates database permissions!\nGet-DbaRegServer Fixed to allow working with nested groups\nCopy-DbaLogin Fixed an issue where SQL Logins wouldn\u0026rsquo;t be copied over if Mixed-Mode authentication was not enabled.\nAppVeyor, Pester and Testing Rob Sewell of dbareports.io fame spent a few days adding Pester testing and enforced testing for each commit using AppVeyor. This will ultimately help us release more often and with higher quality.\nWant to help create tests? We\u0026rsquo;re in desperate need of testers and Pester fans. Or, if you want to learn Pester, this is a great opportunity. Both dbatools and dbareports are in need.\nWhat Is Schleem? Sounds Nasty All of our release names are taken from my favorite cartoon, Rick and Morty. I\u0026rsquo;m obsessed! What\u0026rsquo;s schleem? It\u0026rsquo;s the stuff that smooths out the dingle bop, which is an important part of a plumbus.\nNew to dbatools? Visit the downloads page for information about how to download and install dbatools (it\u0026rsquo;s 1 command).\nJoin us! Some of these commands are in their infancy. Want to help make them better? Come join the coding party! We\u0026rsquo;re all hanging out on the SQL Server Community Slack in the #dbatools channel.\n","date":"2016-12-14","summary":"In this release, we gained 4 new contributors to the dbatools master repository for a grand total of of 33! We even added 4 new Major Contributors to the team. Thanks to all who have joined in to make the awesomest toolset for SQL Server DBAs — we\u0026rsquo;re now offering the community over 100 quality commands\nJust a Quick Highlight I\u0026rsquo;m especially excited about every one of the commands in this release.","tags":[],"title":"New Release - Schleem","type":"post","url":"https://dbatools.io/schleem/"},{"categories":["announcements"],"content":"\nToday\u0026rsquo;s blog post is part of T-SQL Tuesday. T-SQL Tuesday is the brainchild of Adam Machanic. It is a monthly blog party on the second Tuesday of each month. Everyone is welcome to participate.\nintro dbatools has been around since 2014. At first, it started with one contributor and was solely dedicated to migrating SQL Server instances, but now it\u0026rsquo;s grown into an awesome open source DBA project with over 30 contributors.\nWe have nearly 100 commands for you to enjoy and about 10 of them revolve around Backup and Restore. Even more are planned, as you can read in Stuart Moore\u0026rsquo;s blog post titled Easier SQL Server Restores using DBATools. Stuart is a long-established SQL/PowerShell powerhouse backup/restore and we\u0026rsquo;re honored to have him on board.\nour backup/restore commands (present) Get-DbaBackupHistory Get-DbaDatabaseSnapshot Get-DbaRestoreHistory Get-DbaLastBackup Read-DbaBackupHeader Remove-DbaBackup Remove-DbaDatabaseSnapshot Restore-SqlBackupFromDirectory* Test-DbaLastBackup Test-DbaFullRecoveryModel Want to know more about our snapshot commands? Check out team member Constantine Kokkinos\u0026rsquo; blog post \u0026ldquo;T-SQL Tuesday 85: Managing database snapshots with dbatools\u0026rdquo;. A snapshot may not exactly be a backup/restore but its spirit is, fa sho.\nRestore-SqlBackupFromDirectory is super useful in a pinch, too, but it\u0026rsquo;s not quite fleshed out to our standards, so it doesn\u0026rsquo;t have a corresponding webpage. We expect this will be renamed by the next release.\nour backup/restore commands (soon) Restore-DbaBackup Restore-DbaSnapshot New-DbaSnapshot Test-DbaBackup ??? Coming up, we\u0026rsquo;re going to have a fully featured Restore-DbaBackup command that can easily restore a single file, to a point in time, from a Ola Hallengren styled directory structure or a formatted hashtable (like the one I\u0026rsquo;ll pass to process my Test-DbaLastBackup command).\nWe\u0026rsquo;re eager to keep going. Have any ideas? Let us know by filing an issue or joining our Slack Channel on the SQL Community Slack and telling us what you need.\nmy favorite backup/restore command I love this entire toolset but damn, I\u0026rsquo;ve been needing a command like Test-DbaLastBackup for a long time. Testing backups can be such a pain, but PowerShell can make it easy for your entire estate. Not just one SQL instance where you\u0026rsquo;ve got some specific stored procedure installed, but all of your SQL servers \u0026ndash; from one workstation!\nI created Test-DbaLastBackup because I wanted to test all of my backups and using PowerShell was the easiest way to do it. It parses Get-DbaBackupHistory for the last full backup, restores it, runs a DBCC CHECKTABLE and then drops the test database.\nHere\u0026rsquo;s a test I did on my SQL Server 2016 instance. I ran Ola Hallengren\u0026rsquo;s Full backups for both system and user, then executed Test-DbaLastBackup -SqlServer sql2016. Simple AF!\nThe command\u0026rsquo;s webpage is at dbatools.io/Test-DbaLastBackup. Pretty easy, eh? That goes for every command we have, too. Just dbatools.io + /The-CommandName.\nBack to the command, Test-DbaLastBackup. It:\nRestores the test databases (named dbatools-testrestore-$dbname by default) to the specified -SqlServer unless you specify a -Destination. Then it\u0026rsquo;ll restore to the Destination (if remote, so long as the backups are on a shared directory \u0026ndash; which mine always are). You can even specify a MaxMB if you don\u0026rsquo;t have space for super large database restores (in that case, the -VerifyOnly switch could come in handy). Want your Data and Log files to go somewhere other than default? Use the -DataDirectory and -LogDirectory params. This command is only in its infancy, too! Next up, team member Christian Solje will be adding additional features like Point in Time restore.\nget-help Need to know more about our commands? In every release, we require some basic docs so just run Get-Help Test-DbaLastBackup -Detailed and you\u0026rsquo;ll be greeted with Examples, docs for each parameter, a synopsis a description and other useful stuff.\ndownload Intrigued and haven\u0026rsquo;t installed dbatools yet? Hit up our Downloads page to see how to install it on your system.\nyoutube and community We have a YouTube channel if you want to watch some videos. That\u0026rsquo;s the YouTube channel for the SQL Community Collaborative where you can watch videos about open source, (mostly) SQL PowerShell projects like dbareports and, of course, dbatools.io.\nWe are also on Bluesky as @dbatools.io.\none more thing If you think we\u0026rsquo;ve done something that sucks, let us know, either on GitHub or Slack. We welcome and even enjoy alternative approaches and civilized debate about processes. Or hey, if you love something we\u0026rsquo;ve done, feel free to drop by the Slack channel too.\nWe like to release early, release often which means that we\u0026rsquo;re nimble and responsive to changes and requests. (It also means that, while we are at v0.8.69, version 1.0 which is due in Summer 2017 will likely introduce breaking - but beautiful - changes. This is thanks to our Style Shepherd Klaas Vandenberghe.)\nin conclusion We\u0026rsquo;re a bunch of DBA\u0026rsquo;s who, like you, want to have an even easier time managing SQL Server. dbatools uses PowerShell to help do exactly that. Want to join the fun? We\u0026rsquo;re an inclusive group \u0026ndash; even if you don\u0026rsquo;t know PowerShell, we\u0026rsquo;ll help you. Even if you don\u0026rsquo;t know Git, we\u0026rsquo;ve got you covered. Come with your experience, your scholarly background or your enthusiasm and passion. We\u0026rsquo;d love to hear from you.\nThanks for reading. I\u0026rsquo;m looking forward to the next T-SQL Tuesday!\n","date":"2016-12-13","summary":"Today\u0026rsquo;s blog post is part of T-SQL Tuesday. T-SQL Tuesday is the brainchild of Adam Machanic. It is a monthly blog party on the second Tuesday of each month. Everyone is welcome to participate.\nintro dbatools has been around since 2014. At first, it started with one contributor and was solely dedicated to migrating SQL Server instances, but now it\u0026rsquo;s grown into an awesome open source DBA project with over 30 contributors.","tags":["backup","restore"],"title":"dbatools to the backup/restore rescue","type":"post","url":"https://dbatools.io/backup-restore-rescue/"},{"categories":["announcements"],"content":"Recently, I presented to the Philadelphia PowerShell User Group about Contributing to Open Source PowerShell projects using GitHub Desktop. I chose this topic because a number of people have asked for step-by-step instructions on how to work with GitHub.\nI love the command line, but with Git? I think it\u0026rsquo;s important to get the concepts down first and the Desktop version makes that a lot easier to contribute to projects like dbatools, dbareports and even PowerShell itself.\nIn the presentation, I pretty much follow along with the tutorial on our wiki called Your First Pull Request. But! I also included some information about working with PowerShell, PowerShell modules and PowerShell-centric GitHub repositories that was not in the tutorial, so there\u0026rsquo;s still some good information to gain even if you already know how to make a Pull Request.\nSo if you\u0026rsquo;ve wanted to get involved in the project but were a bit hesitant because you aren\u0026rsquo;t comfortable with git, check out this informative and fun video and Get-Contributing ;)\n","date":"2016-12-03","summary":"Recently, I presented to the Philadelphia PowerShell User Group about Contributing to Open Source PowerShell projects using GitHub Desktop. I chose this topic because a number of people have asked for step-by-step instructions on how to work with GitHub.\nI love the command line, but with Git? I think it\u0026rsquo;s important to get the concepts down first and the Desktop version makes that a lot easier to contribute to projects like dbatools, dbareports and even PowerShell itself.","tags":["community"],"title":"Contributing to dbatools \u0026 dbareports using GitHub Desktop","type":"post","url":"https://dbatools.io/github-desktop-contributing/"},{"categories":["announcements"],"content":"Recently, I presented to the Philadelphia PowerShell User Group about Contributing to Open Source PowerShell projects using GitHub Desktop. I chose this topic because a number of people have asked for step-by-step instructions on how to work with GitHub.\nI love the command line, but with Git? I think it\u0026rsquo;s important to get the concepts down first and the Desktop version makes that a lot easier to contribute to projects like dbatools, dbareports and even PowerShell itself.\nIn the presentation, I pretty much follow along with the tutorial on our wiki called Your First Pull Request. But! I also included some information about working with PowerShell, PowerShell modules and PowerShell-centric GitHub repositories that was not in the tutorial, so there\u0026rsquo;s still some good information to gain even if you already know how to make a Pull Request.\nSo if you\u0026rsquo;ve wanted to get involved in the project but were a bit hesitant because you aren\u0026rsquo;t comfortable with git, check out this informative and fun video and Get-Contributing 😊\n","date":"2016-12-02","summary":"Recently, I presented to the Philadelphia PowerShell User Group about Contributing to Open Source PowerShell projects using GitHub Desktop. I chose this topic because a number of people have asked for step-by-step instructions on how to work with GitHub.\nI love the command line, but with Git? I think it\u0026rsquo;s important to get the concepts down first and the Desktop version makes that a lot easier to contribute to projects like dbatools, dbareports and even PowerShell itself.","tags":["party"],"title":"Video: Contributing to dbatools \u0026 dbareports Using GitHub Desktop","type":"post","url":"https://dbatools.io/video-contributing-to-dbatools-dbareports-using-github-desktop/"},{"categories":["announcements"],"content":"In this release (two in one month, woo!), we gained 3 new contributors to the dbatools master repository for a grand total of of 29!\nCommands We fixed about 10 bugs, made two commands more efficient and added 5 new commands.\nConnect-DbaSqlServer Creates an SMO SQL Server object. Supports both Windows and SQL Authentication. I imagine mostly SMO programmers will like this one, but check it out anyway. It has a ton of useful parameters.\nGet-DbaLastBackup Retrieves and compares the date/time for the last known backups, as well as the creation date/time for the database.\nDefault output includes columns Server, Database, RecoveryModel, LastFullBackup, LastDiffBackup, LastLogBackup, SinceFull, SinceDiff, SinceLog, Status, DatabaseCreated, DaysSinceDbCreated.\nGet-DbaPermission Get a list of Server and Database level permissions\nGet-DbaStartupParameter Displays values for a detailed list of SQL Server Startup Parameters including Master Data Path, Master Log path, Error Log, Trace Flags, Parameter String and much more.\nRemove-DbaBackup T-SQL based maintenance plans can\u0026rsquo;t safely access Windows file system to determine if a file has been properly archived. PowerShell makes it easy.\nThis command will make it easier to clean up old, archived (and unarchived) backups.\nWant to see more or work on a command yourself? Check out the dbatools GitHub repository to see what we\u0026rsquo;re working on and to contribute your own improvements.\nNotable Bug Fixes Copy-DbaCredential and Copy-DbaLinkedServer Both commands worked properly but made an attempt to connect to the destination that was unnecessary and sometimes generated errors.\nFind-DbaOrphanedFile Fixed bug that reported some valid directories and files as orphaned.\nGet-DbaTcpPort Fixed a bug that hid a real exception message behind one that basically said \u0026ldquo;Something didn\u0026rsquo;t work right.\u0026rdquo;\nTest-DbaNetworkLatency Fixed a logic bug that produced inaccurate results.\nTest-DbaPath Now works in all languages!\nJoin Us! Some of these commands are in their infancy. Want to help make them better? Come join the coding party! We\u0026rsquo;re all hanging out on the SQL Server Community Slack in the #dbatools channel.\n","date":"2016-11-22","summary":"In this release (two in one month, woo!), we gained 3 new contributors to the dbatools master repository for a grand total of of 29!\nCommands We fixed about 10 bugs, made two commands more efficient and added 5 new commands.\nConnect-DbaSqlServer Creates an SMO SQL Server object. Supports both Windows and SQL Authentication. I imagine mostly SMO programmers will like this one, but check it out anyway. It has a ton of useful parameters.","tags":[],"title":"New Release - Ants in My Eyes Johnson","type":"post","url":"https://dbatools.io/antsinmyeyesjohnson/"},{"categories":["announcements"],"content":"In this month\u0026rsquo;s release, we gained 6 new contributors to the dbatools master repository for a grand total of of 26! This was likely the result of moving the repository to the new organization on GitHub called the SQL Server Community Collaborative, which makes it easier to participate in the dbatools project.\nWe also added a few pages to the dbatools GitHub Wiki including: Your First Pull Request, Style Guide and Testing and Q\u0026amp;A.\nCommands We fixed 15 bugs and added 9 new commands including one that migrates SQL Server Integration Services!\nCopy-DbaSsisCatalog\nThis command migrates Folders, SSIS projects, and environments from one SQL Server to another.\nBy default, all folders, projects, and environments are copied. The Project parameter can be specified to copy only one project, if desired.\nThe parameters get more granular from the Folder level i.e. specifying folder will only deploy projects/environments from within that folder.\nWe\u0026rsquo;re working towards this command being a wrapper for other new commands including Copy-SqlSsisFolder, Copy-SqlSsisProject and Copy-SqlSsisEnvironment.\nFind-DbaOrphanedFile\nThis command searches all directories associated with SQL database files for database files that are not currently in use by the SQL Server instance.\nBy default, it looks for orphaned .mdf, .ldf and .ndf files in the root\\data directory, the default data path, the default log path, the system paths and any directory in use by any attached directory.\nGet-DbaAvailabilityGroup\nBy default outputs a small set of information around the Availability Group found on the server.\nGet-DbaLastGoodCheckDb\nThis command retrieves and compares the date/time for the last known good DBCC CHECKDB, as well as the creation date/time for the database.\nGet-DbaProcess\nThis command displays processes associated with a spid, login, host, program or database.\nGet-DbaRunningJob\nThis function returns agent jobs that active on the SQL Server intance when calling the command. The information is gathered the SMO JobServer.jobs and be returned either in detailed or standard format.\nSet-DbaMaxDop\nThis command will help you set MaxDop configuration according to Microsoft recommendations.\nTest-DbaDbRecoveryModel\nWhen you switch a database into FULL recovery model, it will behave like a SIMPLE recovery model until a full backup is taken in order to begin a log backup chain. This command, inspired by Paul Randal\u0026rsquo;s post, will let you easily see if a database is in the \u0026lsquo;pseudo-Simple\u0026rsquo; recovery model.\nTest-DbaMaxDop\nInspired by Sakthivel Chidambaram\u0026rsquo;s post about SQL Server MAXDOP Calculator, this command displays a SQL Server\u0026rsquo;s current configuration and calculated recommendation.\nThese are just general recommendations for SQL Server and are a good starting point for setting the \u0026ldquo;max degree of parallelism\u0026rdquo; option.\nNext Batch Some commands almost made it to this release, but didn\u0026rsquo;t.\nRename-DbaDatabase\nRenames not just the database but the underlying files.\nGet-DbaBackupThroughput\nGets the minimum, maximum and average throughput in Mb/sec for all or one database on a server for all time or filter by month, day or year.\nCopy-SqlMaintenancePlan\nThis is already a pull request in the development repository! Just a bit more development is needed.\nMove-DbaDatabaseFile\nSo close!\nRemove-SqlBackupFromDisk\nT-SQL based maintenance plans can\u0026rsquo;t safely access Windows file system to determine if a file has been properly archived. PowerShell makes it easy. This command will make it easier to clean up old, archived (and unarchived) backups.\nWant to see more or work on a command yourself? We have approved command ideas on the dbatools Trello board. This board shows you what we\u0026rsquo;re working on and what we\u0026rsquo;re talking about. We\u0026rsquo;d love if you\u0026rsquo;d join us.\nJoin Us! Some of these commands are in their infancy. Want to help make them better? Come join the coding party! We\u0026rsquo;re all hanging out on the SQL Server Community Slack in the #dbatools channel.\n","date":"2016-11-02","summary":"In this month\u0026rsquo;s release, we gained 6 new contributors to the dbatools master repository for a grand total of of 26! This was likely the result of moving the repository to the new organization on GitHub called the SQL Server Community Collaborative, which makes it easier to participate in the dbatools project.\nWe also added a few pages to the dbatools GitHub Wiki including: Your First Pull Request, Style Guide and Testing and Q\u0026amp;A.","tags":[],"title":"New Release - Mr. Meeseeks","type":"post","url":"https://dbatools.io/new-release-mrmeeseeks/"},{"categories":["announcements"],"content":"Hey, Chrissy here. Recently, I had great success with scheduling a database migration and wanted to let you know how I did it in case you have a similar requirement.\nMy requirement comprised of copying two databases that were 30 GB in size, from one server to another, during a time that I wouldn\u0026rsquo;t be at the office. Remote work was not possible.\nThe Script Here\u0026rsquo;s the scheduled-migration.ps1 script that ultimately worked for me.\nStart-Transcript C:\\logs\\db-migration-9-1-2016.txt Import-Module C:\\scripts\\dbatools\\dbatools.psd1 Copy-DbaDatabase -Source sql01 -Destination sql02 -Databases WSS_Content, WSS_Content2 -BackupRestore -SharedPath \\nas\\sql\\migration Stop-Transcript What It Does First, I did not need to migrate an entire instance, so I did not use Start-DbaMigration. Instead, I used Copy-DbaDatabase which doesn\u0026rsquo;t transcribe automatically like Start-DbaMigration. Because of this, I explicitly requested a transcript.\nAlso note that I already copied over all of the logins, jobs, etc that I needed. If you have any dependencies, make sure those are copied over as well.\nNext, I imported the module to ensure that the Copy-DbaDatabase command would be available to the Scheduled Task. Potentially, I could put this in my path and hope for the best, but I\u0026rsquo;d rather be explicit.\nFinally, I stopped the transcript.\nTesting and -WhatIf Because Copy-DbaDatabase runs so many checks and supports -WhatIf, I then tested by doing the following:\nAdded -WhatIf to the Copy-DbaDatabase command Ran scheduled-migration.ps1 from the command line, and it worked Setup a scheduled task to run once, that night at 9pm, ensuring that the migration occurred no matter if I was logged in or not. Then I executed the scheduled task manually, waited until it finished, then checked the transcript All the tests passed! I then removed the -WhatIf from Copy-DbaDatabase inside scheduled-migration.ps1 and went home for the night 😊 The next morning, I excitedly checked my transcript and boom, both databases had migrated as planned! In Conclusion You don\u0026rsquo;t need to be at the office to migrate your data. So schedule that migration. Go home to your family, your cats, and/or your video console. Or drink a craft beer and watch some Rick and Morty. You deserve it.\n","date":"2016-09-20","summary":"Hey, Chrissy here. Recently, I had great success with scheduling a database migration and wanted to let you know how I did it in case you have a similar requirement.\nMy requirement comprised of copying two databases that were 30 GB in size, from one server to another, during a time that I wouldn\u0026rsquo;t be at the office. Remote work was not possible.\nThe Script Here\u0026rsquo;s the scheduled-migration.ps1 script that ultimately worked for me.","tags":["migration","party"],"title":"Scheduling a Migration","type":"post","url":"https://dbatools.io/scheduling-a-migration/"},{"categories":["announcements"],"content":"dbatools is not only intended to be a great migration tool, but also a toolset to help DBAs follow best practices. Check out all the new commands in this batch, courtesy of Mike Fal, Constantine Kokkinos and Chrissy LeMaire.\nBest Practices Commands Ever read a really great article about how to do something properly but then kinda forgot and you have to revisit each time? Well, we\u0026rsquo;ve codified some of those practices for you, making them easy to both follow and remember.\nTest-DbaDbOwner and Set-DbaDbOwner Database ownership is complicated, but many SQL Server experts suggest using one specific account, be it sa or an alternative account that your organization has decided on. These commands, created by Mike Fal, validate or set ownership on all databases on an instance to a SQL login you specify, or the default of sa.\nTest-DbaDiskAlignment This command, created by Constantine Kokkinos, evaluates a servers disk setup to see if it aligns with the Disk Partition Alignment Best Practices recommended by Microsoft. Disk Alignment is a very complicated subject, but we did our best to make it easy to evaluate your environment.\nTest-DbaDiskAllocation This command helps DBAs check all disks on a computer to see if they are formatted to 64k. It also reports if a disk has SQL Server data on it or not.\nTest-DbaAgentJobOwner and Set-DbaAgentJobOwner These commands, created by Mike Fal, will check and set all SQL Agent Job on an instance against a SQL login to validate if that login owns those SQL Agent Jobs or not. By default, the function will check against \u0026lsquo;sa\u0026rsquo; for ownership, but the user can pass a specific login if they use something else. For the Test command, only jobs that fail the test will be returned.\nTest-DbaPowerPlan and Set-DbaPowerPlan These commands Test and Set the SQL Server OS\u0026rsquo;s Power Plan. It defaults to High Performance which is Best Practice.\nMeasure-DbaDbVirtualLogFile This command returns database virtual log file information for database files on a SQL instance. As you may already know, having a TLog file with too many VLFs can hurt database performance. This command helps you easily see the VLF counts for all your databases, or just specific ones.\nCommands That Make Your Life Easier Get-DbaClusterActiveNode Returns the active node(s) of a SQL Cluster\nGet-DbaDbSpace These commands, created by Mike Fal, get information about space available inside the database.\nInstall-SqlSpWhoIsActive and Update-SqlSpWhoIsActive Install and update Adam Machanic\u0026rsquo;s sp_whoisactive with ease using these commands. The latest version of sp_whoisactive is automatically downloaded from Adam\u0026rsquo;s site and installed. Update-SqlSpWhoIsActive is actually an alias for Install-SqlSpWhoIsActive since Adam\u0026rsquo;s install routine handles updates.\nCommands That Are Coming Soon And we\u0026rsquo;ve got more planned!\nCopy-SqlMaintenancePlan Maintenance plan support isn\u0026rsquo;t provided by dbatools at this time, but that\u0026rsquo;s soon going to change once this command is complete.\nDisable-DbaLogonTrigger Like Reset-DbaAdmin, this is a command that won\u0026rsquo;t be used often, but when it is, its a lifesaver.\nFind-DbaSqlInstance This one\u0026rsquo;s gonna be fun. Scan your subnet, AD or specific servers for SQL Server instances.\nMove-DbaDatabaseFile We wanted to ensure this command is as fail-proof and useful as possible. It\u0026rsquo;s been tough getting progress bars to work, but we\u0026rsquo;re getting there! This command should be available in our next batch.\nRestore-DbaBackupFromDirectory Routine to restore databases from directories (think the way that Ola Hallengren\u0026rsquo;s outputs his by default)\nRemove-DbaBackupFromDisk Routine to remove SQL backups from disk. If you copy your backups to tape or use a third-party solution, this command will ensure that no backups are deleted until they\u0026rsquo;ve been marked as archived.\nTest-DbaBackup Routine to test your backups\nWrite-SqlSpWhoIsActive Write the results of Show-SqlSpWhoIsActive to table!\nJoin Us! Some of these commands are in their infancy. Want to help make them better? Come join the coding party! We\u0026rsquo;re all hanging out on the SQL Server Community Slack in the #dbatools channel.\n","date":"2016-08-17","summary":"dbatools is not only intended to be a great migration tool, but also a toolset to help DBAs follow best practices. Check out all the new commands in this batch, courtesy of Mike Fal, Constantine Kokkinos and Chrissy LeMaire.\nBest Practices Commands Ever read a really great article about how to do something properly but then kinda forgot and you have to revisit each time? Well, we\u0026rsquo;ve codified some of those practices for you, making them easy to both follow and remember.","tags":["migration"],"title":"Another Batch of New Commands Now Available!","type":"post","url":"https://dbatools.io/new-batch-of-commands/"},{"categories":["announcements"],"content":"When I first began working on dbatools, I was aware of the suggestion to use a distinct prefix in PowerShell, but chose to use Sql for its universal recognition. That will soon change.\nPowerShell Prefixes Prefixes are the things that start the noun. SQL Server uses Sql, Active Directory uses AD, SharePoint uses SP, PowerShell uses PS and Lync uses Cs. You can see, even with two letter prefixes, that there is no true case consistency.\nI chose to use Sql even though it was in use by Microsoft both because there had been minimal development on SQLPS and because I wanted the intention of the commands I was writing to be obvious. Start-DBAMigration and Copy-DBALogins makes it sound like I\u0026rsquo;m just migrating DBA-related stuff, and not performing a DBA task.\nConsidering the following, I think now is the right time to move away from the Sql prefix for some commands.\nMicrosoft is now investing a lot into the SqlServer module dbatools is becoming more recognized so the intention is becoming more obvious dbatools is approaching v1.0 All Sql commands have been renamed to Dba. Old Sql commands within dbatools will become aliases so there will still be backwards compatibility.\nNew Naming So now for the part I\u0026rsquo;m terrible at — naming things. dbatools, the module, is spelled in all lower case, probably because of the Linux influence and I wanted this to be an open source product. But Test-dbaDiskAllocation was ugly. I noticed that some people were spelling the module\u0026rsquo;s name DBAtools and dbatools, which is understandable but kind of made my eyes bleed.\nI was curious and put it up for a vote.\nWhen it became obvious yesterday that the winner was going to be DBA, I submitted the first two commands (Test-DBAPowerPlan and Set-DBAPowerPlan) the DBA prefix in this commit.\nAnnouncing the Winner You guys, I really wanted to adhere the will of the people. The lower-case prefix \u0026ldquo;dba\u0026rdquo;, with its 10% of all votes, was no longer considered. And I submitted a total of three commands with the all capped \u0026ldquo;DBA\u0026rdquo;.\nUnfortunately, my OCD is preventing me from making this a permanent change. The PowerSheller in me overruled the DBA, and I\u0026rsquo;ve decided to go with second place. The new naming convention will be Dba.\nAhhh, I feel so much better already.\nComing Soon Thank you all for voting! The changes will be coming soon, and again, it won\u0026rsquo;t be all commands, and the ones that do change will have an alias so you can continue to use them with the Sql prefix. That will go away, however, by the 1.0 version.\nWe are currently at 0.8.5. I believe dbatools will be cool enough for the v1.0 release once we get mirroring, log shipping and AG support in the Copy-Sql* commands. And once we\u0026rsquo;ve finalized the naming of each command.\n","date":"2016-08-02","summary":"When I first began working on dbatools, I was aware of the suggestion to use a distinct prefix in PowerShell, but chose to use Sql for its universal recognition. That will soon change.\nPowerShell Prefixes Prefixes are the things that start the noun. SQL Server uses Sql, Active Directory uses AD, SharePoint uses SP, PowerShell uses PS and Lync uses Cs. You can see, even with two letter prefixes, that there is no true case consistency.","tags":["party"],"title":"New Prefix for Many dbatools Commands","type":"post","url":"https://dbatools.io/new-prefix-for-many-dbatools-commands/"},{"categories":["announcements"],"content":"When I first began working on dbatools, I was aware of the suggestion to use a distinct prefix in PowerShell, but chose to use Sql for its universal recognition. That will soon change.\nPowerShell Prefixes Prefixes are the things that start the noun. SQL Server uses Sql, Active Directory uses AD, SharePoint uses SP, PowerShell uses PS and Lync uses Cs. You can see, even with two letter prefixes, that there is no true case consistency.\nI chose to use Sql even though it was in use by Microsoft both because there had been minimal development on SQLPS and because I wanted the intention of the commands I was writing to be obvious. Start-DBAMigration and Copy-DBALogins makes it sound like I\u0026rsquo;m just migrating DBA-related stuff, and not performing a DBA task.\nConsidering the following, I think now is the right time to move away from the Sql prefix for some commands.\nMicrosoft is now investing a lot into the SqlServer module dbatools is becoming more recognized so the intention is becoming more obvious dbatools is approaching v1.0 All Sql commands have been renamed to Dba. Old Sql commands within dbatools will become aliases so there will still be backwards compatibility.\nNew Naming So now for the part I\u0026rsquo;m terrible at — naming things. dbatools, the module, is spelled in all lower case, probably because of the Linux influence and I wanted this to be an open source product. But Test-dbaDiskAllocation was ugly. I noticed that some people were spelling the module\u0026rsquo;s name DBAtools and dbatools, which is understandable but kind of made my eyes bleed.\nI was curious and put it up for a Twitter vote.\nWhen it became obvious yesterday that the winner was going to be DBA, I submitted the first two commands (Test-DBAPowerPlan and Set-DBAPowerPlan) the DBA prefix in this commit.\nAnnouncing the Winner You guys, I really wanted to adhere the will of the people. The lower-case prefix \u0026ldquo;dba\u0026rdquo;, with its 10% of all votes, was no longer considered. And I submitted a total of three commands with the all capped \u0026ldquo;DBA\u0026rdquo;.\nUnfortunately, my OCD is preventing me from making this a permanent change. The PowerSheller in me overruled the DBA, and I\u0026rsquo;ve decided to go with second place. The new naming convention will be Dba.\nAhhh, I feel so much better already.\nComing Soon Thank you all for voting! The changes will be coming soon, and again, it won\u0026rsquo;t be all commands, and the ones that do change will have an alias so you can continue to use them with the Sql prefix. That will go away, however, by the 1.0 version.\nWe are currently at 0.8.5. I believe dbatools will be cool enough for the v1.0 release once we get mirroring, log shipping and AG support in the Copy-Sql* commands. And once we\u0026rsquo;ve finalized the naming of each command.\n","date":"2016-08-02","summary":"When I first began working on dbatools, I was aware of the suggestion to use a distinct prefix in PowerShell, but chose to use Sql for its universal recognition. That will soon change.\nPowerShell Prefixes Prefixes are the things that start the noun. SQL Server uses Sql, Active Directory uses AD, SharePoint uses SP, PowerShell uses PS and Lync uses Cs. You can see, even with two letter prefixes, that there is no true case consistency.","tags":["party"],"title":"New Prefix for Many dbatools Commands","type":"post","url":"https://dbatools.io/prefix/"},{"categories":["announcements"],"content":"So many SQL Server and PowerShell pros have joined the dbatools team and we\u0026rsquo;re producing well designed PowerShell commands like mad!\ndbatools is not only intended to be a great migration tool, but also a toolset to help DBAs follow best practices. We like to think of these commands as fully automated Wizards that are executed from the command line instead of the GUI.\nBest Practices Commands Ever read a really great article about how to do something properly but then kinda forgot and you have to revisit each time? Well, we\u0026rsquo;ve codified some those practices for you, making them easy to both follow and remember.\nExpand-DbaDbLogFile This command, created by Cláudio Silva helps DBAs automate Virtual Log File (VLF) management.\nFind-DbaDbDuplicateIndex This command, also created by Cláudio Silva helps DBAs find duplicate indexes which may be slowing your queries down and taking up unnecessary disk space.\nRemove-DbaDatabaseSafely This command, created by Rob Sewell, safely removes a SQL Database and creates an Agent Job to restore it. By default it:\nPerforms a DBCC CHECKDB Backs up the database WITH CHECKSUM Restores with VERIFY ONLY on the source Creates and Agent job to easily restore from that backup Drops the database The Agent Job restores the database Performs a DBCC CHECKDB and drops the database for a final time Simply amazing!\nSet-DbaTempdbConfig These commands, created by Mike Fal, sets tempdb data and log files according to best practice calcluations. Mike writes more about this function on his blog.\nFind-DbaDbUnusedIndex This command, created by Aaron Nelson, will help you to find unused indexes on a database or a list of databases. It also tells how much space you can save by dropping the index. For now only supported for CLUSTERED and NONCLUSTERED indexes.\nCommands That Make Your Life Easier Invoke-DbaWhoIsActive We wrote a PowerShell command to output results of Adam Machanic\u0026rsquo;s beloved sp_WhoIsActive to a GridView (default) or DataTable. If sp_WhoIsActive is not installed in the system, it will be downloaded and installed to a database you specify with either -Database or a database you select from Show-DbaDbList.\nThis is v0.1 of Invoke-DbaWhoIsActive. We\u0026rsquo;ll be working on formatting options and auto-population soon.\nRepair-DbaDbOrphanUser This command, created by Cláudio Silva, helps DBAs find and repairs orphaned users in one, multiple or all databases.\nRemove-DbaDbOrphanUser Another homerun written by Cláudio Silva, which removes orphaned database users with no matching logins.\nGet-DbaDiskSpace Displays Disk information for all local drives on one or more servers. Returns server name, name of disk, label of disk, total size, free size and percent free. Considering a new column in the future that designates if any SQL data/log files are stored on the returned disks. What do you think?\nGet-DbaRegServer Gets list of SQL Server names stored in SQL Server Central Management Server. Filtering by one or more server groups supported.\nShow-SqlServerFileSystem Similar to the remote file system popup you see when browsing a remote SQL Server in SQL Server Management Studio, this command allows you to traverse the remote SQL Server\u0026rsquo;s file structure.\nShow-SqlServerFileSystem uses SQL Management Objects to browse the directories and what you see is limited to the permissions of the account running the command. This will complement the upcoming Move-SqlDatabaseFile command.\nShow-DbaDbList Shows a list of databases in a GUI. Returns a simple string. Hitting cancel returns null. Test Commands Test-DbaTempdbConfig Test Your TempDb Configuration\nTest-DbaNetworkLatency This function is intended to help measure SQL Server network latency by establishing a connection and making a simple query. This is a better alternative than ping because it actually creates the connection to the SQL Server, and times not only the entire routine, but also how long the actual queries take vs how long it takes to get the results.\nTest-DbaPath Use this command to determine whether the SQL Server service account can \u0026ldquo;see\u0026rdquo; a directory. This command uses master.dbo.xp_fileexist under the hood and returns $true or $false.\nTest-DbaMigrationConstraint Shows if you can migrate the database(s) between the servers. When you want to migrate from a higher edition to a lower one there are some features that can\u0026rsquo;t be used. This function will validate if you have any of this features in use and will report to you. The validation will be made ONLY on on SQL Server 2008 or higher using the \u0026lsquo;sys.dm_db_persisted_sku_features\u0026rsquo; DMV.\nJoin Us! Some of these commands are in their infancy. Want to help make them better? Come join the coding party! We\u0026rsquo;re all hanging out on the SQL Server Community Slack in the #dbatools channel.\n","date":"2016-07-20","summary":"So many SQL Server and PowerShell pros have joined the dbatools team and we\u0026rsquo;re producing well designed PowerShell commands like mad!\ndbatools is not only intended to be a great migration tool, but also a toolset to help DBAs follow best practices. We like to think of these commands as fully automated Wizards that are executed from the command line instead of the GUI.\nBest Practices Commands Ever read a really great article about how to do something properly but then kinda forgot and you have to revisit each time?","tags":["migration"],"title":"New Best Practices Commands Now Available","type":"post","url":"https://dbatools.io/new-best-practices-commands-now-available/"},{"categories":[],"content":"Here are a few things to keep in mind when programming for dbatools.\nMinimum Requirements One source of pride for this project is that it works on most systems. We at least try to make it work on SQL Server 2000, though sometimes it\u0026rsquo;s not possible. SQL Server 2005 and above usually works well.\nAlso, remember that this module is intended for migrations and hence older systems, so PowerShell v3 is the base that we\u0026rsquo;ll be using to program. Some modern methods and cmdlets won\u0026rsquo;t be available to you, but it\u0026rsquo;s a really solid version.\nOften times, clusters have to be handled differently. Try to test your command against a cluster if you\u0026rsquo;ve got access. If not, we\u0026rsquo;re working on things with Jenkins to help automate testing.\nProgram Thoroughly and Optimistically Does the user need a table to be created? Create it for them and populate the database name (dbatools) and table names with defaults.\nProgram as if there is a solution. Locked out of your SQL Server because of a bad logon trigger? Program as though you can somehow populate a list of logon triggers, because we can probably find a way 😄 Let\u0026rsquo;s work together to find a way.\nIs there something you always forget as a DBA like Trace Flags? Perhaps your command can have a dictionary or your command could be the dictionary.\nUse T-SQL Only When Appropriate I can\u0026rsquo;t emphasize this enough. SMO takes care of all the SQL commands for you, so use SMO by default. That way, the module will be compatible with all the different versions of SQL Server.\nSMO can slow down on servers with thousands of databases, but we\u0026rsquo;re optimistic we can get it to work quickly. Just give us a few weeks 😁\nDon\u0026rsquo;t know which SMO object you need? Look up the T-SQL syntax first; that\u0026rsquo;s what I do. I needed to change the password for a credential, saw that it\u0026rsquo;s ALTER CREDENTIAL in T-SQL and guessed that the issue could be resolved with $credential.alter() and sure enough that was it.\nWhen is it appropriate to use T-SQL? When SMO can\u0026rsquo;t be used. Like to find out supported features for a particular edition, in use right now by the database (stored in sys.dm_db_persisted_sku_features), if you need info from sys.key_encryptions or actually, if you want to detach a database but not modify the $databases collection. It happens, but it\u0026rsquo;s rare.\nDon\u0026rsquo;t Rely on SQLPS Do not require the user to load SQLPS or the new awesome version of SQLPS, SqlServer. This is for a number of reasons, but here\u0026rsquo;s three. Remember, we program for the lowest common denominator and expect that the user is running old versions of things.\nUse These Templates The GitHub repo, dbatools-templates is dedicated to templates for commands. You can also look to similar commands for templates.\nGet Familiar with the Current Code The code structure is as follows:\n[dbatools](https://github.com/ctrlbold/dbatools/) functions\\ Copy-SqlDatabase.ps1 Copy-SqlLogin.ps1 DynamicParams.ps1 SharedFunctions.ps1 … tests\\ InModule.Help.Tests.ps1 dbatools.psd1 dbatools.psm1 LICENSE.txt README.md DynamicParams.ps1 stores all of the DynamicParameters. These are all of the functions that provide tab completion. Tab completion/dynamic parameters look like this:\nSharedFunctions.ps1 are functions that are shared between the commands like Copy-SqlDatabase, etc.\nI suggest examining both of these files to see what\u0026rsquo;s available to you. Also, recall there\u0026rsquo;s TONS of code for you to copy/paste from, and you\u0026rsquo;re encouraged to do so. If you\u0026rsquo;re duplicating any functionality, just look at similar functions and copy/paste away.\nThis Is Important In order to get your function to access the shared environment that dbatools creates, you must do the following.\nCreate your .ps1 file from the template mentioned above and place it in the functions directory Add the function to dbatools.psd1 with the rest of the functions in FunctionsToExport=@() Reload the module (Import-Module .\\dbatools.psd1 -Force) This will allow your function to access all the other functions in SharedFunctions.ps1 that are not exported such as Connect-SqlServer.\nNote that the .psd1 should not be included in your pull request because it causes conflicts. We will take care of adding your function to the psd1.\nGot Questions? We\u0026rsquo;re available in the Slack channel #dbatools and via email (clemaire@gmail.com)\n","date":"2016-07-06","summary":"Here are a few things to keep in mind when programming for dbatools.\nMinimum Requirements One source of pride for this project is that it works on most systems. We at least try to make it work on SQL Server 2000, though sometimes it\u0026rsquo;s not possible. SQL Server 2005 and above usually works well.\nAlso, remember that this module is intended for migrations and hence older systems, so PowerShell v3 is the base that we\u0026rsquo;ll be using to program.","tags":[],"title":"Guidelines","type":"page","url":"https://dbatools.io/guidelines/"},{"categories":["announcements"],"content":"The SQL Server community is now on Slack! And we are too. Just join the #dbatools channel by signing up, signing in, clicking CHANNELS then #dbatools.\n","date":"2016-07-01","summary":"The SQL Server community is now on Slack! And we are too. Just join the #dbatools channel by signing up, signing in, clicking CHANNELS then #dbatools.","tags":["party"],"title":"Join Us on the SQL Server Community's Slack","type":"post","url":"https://dbatools.io/dbatools-is-now-on-the-sql-server-communitys-slack/"},{"categories":[],"content":"First thing is first, if you contribute a major amount, you\u0026rsquo;ll be added to the Major Contributors on the Team page 😀\nHelp Us Build an Amazing Toolset The types of commands we are looking for simplify whole tasks. As Microsoft continues its work on the PowerShell module for SQL Server, we\u0026rsquo;ll be here building commands for DBA Best Practices and common painful tasks.\nBenefits Help your fellow DBAs and yourself Build your resume Be an all-star DBA Ready to Join? If you\u0026rsquo;re ready to join, that\u0026rsquo;s awesome! First email me (clemaire@gmail.com) or join the Slack channel to see if your proposed command is a good fit for the toolset.\nWe\u0026rsquo;ll be working closely together and the team will help you with style and technique if you\u0026rsquo;re newer to PowerShell.\nFinally Finally, read the style guidelines and setup git. Don\u0026rsquo;t worry, we\u0026rsquo;re still learning, too 😉\n","date":"2016-06-30","summary":"First thing is first, if you contribute a major amount, you\u0026rsquo;ll be added to the Major Contributors on the Team page 😀\nHelp Us Build an Amazing Toolset The types of commands we are looking for simplify whole tasks. As Microsoft continues its work on the PowerShell module for SQL Server, we\u0026rsquo;ll be here building commands for DBA Best Practices and common painful tasks.\nBenefits Help your fellow DBAs and yourself Build your resume Be an all-star DBA Ready to Join?","tags":[],"title":"Developing for dbatools","type":"page","url":"https://dbatools.io/join-us/"},{"categories":[],"content":"First thing is first, if you contribute a major amount, you\u0026rsquo;ll be added to the Major Contributors on the Team page 😄\nHelp Us Build an Amazing Toolset The types of commands we are looking for simplify whole tasks. As Microsoft continues its work on the PowerShell module for SQL Server, we\u0026rsquo;ll be here building commands for DBA Best Practices and common painful tasks.\nBenefits Help your fellow DBAs and yourself Build your resume Be an all-star DBA Ready to Join? If you\u0026rsquo;re ready to join, that\u0026rsquo;s awesome! First email me (clemaire@gmail.com) or join the Slack channel to see if your proposed command is a good fit for the toolset.\nWe\u0026rsquo;ll be working closely together and the team will help you with style and technique if you\u0026rsquo;re newer to PowerShell.\nFinally Finally, read the style guidelines and setup git. Don\u0026rsquo;t worry, we\u0026rsquo;re still learning, too 😉\n","date":"2016-06-30","summary":"First thing is first, if you contribute a major amount, you\u0026rsquo;ll be added to the Major Contributors on the Team page 😄\nHelp Us Build an Amazing Toolset The types of commands we are looking for simplify whole tasks. As Microsoft continues its work on the PowerShell module for SQL Server, we\u0026rsquo;ll be here building commands for DBA Best Practices and common painful tasks.\nBenefits Help your fellow DBAs and yourself Build your resume Be an all-star DBA Ready to Join?","tags":[],"title":"Developing for dbatools","type":"page","url":"https://dbatools.io/join/"},{"categories":[],"content":"Slack is a collaboration platform (okay, it\u0026rsquo;s kinda just an enhanced IRC ;)) It requires an invite, but you\u0026rsquo;re invited! Just enter in your email and this page will send you an email with the link.\nUltimately, you\u0026rsquo;ll be joining us at sqlcommunity.slack.com in the #dbatools channel. To hang out, you can use the website itself, a desktop client or the mobile app.\nOnce you have arrived, click CHANNELS then #dbatools\n","date":"2016-06-29","summary":"Slack is a collaboration platform (okay, it\u0026rsquo;s kinda just an enhanced IRC ;)) It requires an invite, but you\u0026rsquo;re invited! Just enter in your email and this page will send you an email with the link.\nUltimately, you\u0026rsquo;ll be joining us at sqlcommunity.slack.com in the #dbatools channel. To hang out, you can use the website itself, a desktop client or the mobile app.\nOnce you have arrived, click CHANNELS then #dbatools","tags":[],"title":"#dbatools on Sqlcommunity.slack.com","type":"page","url":"https://dbatools.io/slack/"},{"categories":[],"content":"Presentation Materials Slide Deck (Filled With Comments) From \u0026ldquo;Simplifying SQL Server Migrations Using PowerShell\u0026rdquo; Slides Demo code Videos Migrate an Entire Instance In this video (sound coming later), I migrate a fully stocked instance to a rather empty one. Migration includes databases, logins, SQL Server agent, agent categories, alerts, audits, audit specifications, backup devices, central management servers, credentials, custom errors, database assemblies, database mail, data collector sets, endpoints, extended events, jobs, linked servers, operators, policy managements, proxy accounts, resource governor, server triggers, shared schedules, sp_configure and user objects in system databases.\nCopy-SqlDatabase With GridView This is one of my favorite demos. Migrate two databases by selecting them visually using PowerShell\u0026rsquo;s GridView.\nCreate Login With a Ton of Properties, Migrate Migrate a login with SID, password, server/database roles, server/database permission sets \u0026amp; securables, default database and login attributes. Updates job ownership. Works on SQL Server 2000 and above.\nReset-SqlAdmin Another favorite demo. Ever inherited a SQL Server but not admin credentials? If you have Windows administrator access, you can add a Windows or SQL Login user as sysadmin.\n","date":"2016-05-21","summary":"Presentation Materials Slide Deck (Filled With Comments) From \u0026ldquo;Simplifying SQL Server Migrations Using PowerShell\u0026rdquo; Slides Demo code Videos Migrate an Entire Instance In this video (sound coming later), I migrate a fully stocked instance to a rather empty one. Migration includes databases, logins, SQL Server agent, agent categories, alerts, audits, audit specifications, backup devices, central management servers, credentials, custom errors, database assemblies, database mail, data collector sets, endpoints, extended events, jobs, linked servers, operators, policy managements, proxy accounts, resource governor, server triggers, shared schedules, sp_configure and user objects in system databases.","tags":[],"title":"Slides / Videos","type":"page","url":"https://dbatools.io/slides-videos/"},{"categories":[],"content":"dbatools is a free PowerShell module with nearly 700 commands that replace manual SQL Server administration with powerful and fun automation.\nWhy dbatools? Traditional Methods dbatools SSMS: Click through 50 servers manually PowerShell: Query all 50 servers in one command Migration: Days of planning and execution Migration: Minutes with automated best practices Backup Testing: Manual restores, hope for the best Backup Testing: Automated verification of all backups Documentation: Hours of manual collection Documentation: Instant HTML/Excel reports Scripting: Complex T-SQL across versions Scripting: Consistent commands for SQL 2000-2022 Your First 5 Minutes Let\u0026rsquo;s get you up and running with dbatools. These commands are read-only and safe to explore.\n# 0. Check your PowerShell version (v3+ required for Windows, Core 7.4+ for Linux/macOS) $PSVersionTable.PSVersion # 1. Install dbatools (takes about 30 seconds) Install-Module dbatools -Scope CurrentUser # 2. See all databases on your local SQL Server # Replace \u0026#39;sql01\u0026#39; with your SQL Server name if needed Get-DbaDatabase -SqlInstance sql01 # 3. Check when your databases were last backed up Get-DbaLastBackup -SqlInstance sql01 | Format-Table # 4. Run any T-SQL query you want Invoke-DbaQuery -SqlInstance sql01, sql02, sql03 -Query \u0026#34;SELECT @@VERSION\u0026#34; What just happened?\nGet-DbaDatabase shows all your databases - no clicking through SSMS Get-DbaLastBackup checks backup history - instantly spot backup problems Invoke-DbaQuery runs any T-SQL you want - your most versatile command These commands are read-only - they won\u0026rsquo;t change anything on your server Note: Replace sql01 with your SQL Server instance name (like sql01, server\\instance, or server:port).\nInstallation Where Should You Install dbatools? Install dbatools on your workstation or jump box - NOT on your SQL Servers.\nThink of it like SSMS: you install it on your local machine and connect remotely to SQL Server instances. dbatools is a PowerShell module that runs on your computer and manages SQL Servers over the network.\nGood places to install:\nYour Windows workstation (where you run SSMS) A dedicated management/jump server Your laptop for demos and dev work Don\u0026rsquo;t install on:\nProduction SQL Servers (unnecessary and adds risk) Every SQL Server in your estate (wasteful) Quick Install (Recommended) # One-time setup: Allow PowerShell to run scripts Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser # Install dbatools for current user (no admin rights needed) Install-Module dbatools -Scope CurrentUser That\u0026rsquo;s it! dbatools is now installed on your workstation and ready to manage remote SQL Servers.\nFirst Time Using PowerShell Gallery? If you get a prompt about trusting PSGallery, type Y for Yes. You only need to do this once:\nSet-PSRepository -Name PSGallery -InstallationPolicy Trusted Certificate Change (v2.5.5+ Users) If you\u0026rsquo;re upgrading from an older version, you may need to use:\nInstall-Module dbatools -Force -SkipPublisherCheck Learn more about our certificate change →\nOther Installation Methods (Click to expand) Install for All Users (Requires Admin) Install-Module dbatools Offline Installation # On internet-connected machine: Save-Module -Name dbatools -Path C:\\temp # Copy to target machine and place in: # - All users: C:\\Program Files\\WindowsPowerShell\\Modules # - Current user: $HOME\\Documents\\WindowsPowerShell\\Modules # Import the module after copying Import-Module dbatools Chocolatey choco install dbatools Learning Approach dbatools has over 700 commands - don\u0026rsquo;t let that overwhelm you! Think of it like learning SQL Server: start with the basics, then expand your knowledge over time.\nMost Popular Commands Here are the commands people use most - the ones that solve real problems:\nInvoke-DbaQuery - Run T-SQL against any instance. Your Swiss Army knife. Copy-DbaLogin - Copy logins between servers (with passwords and permissions!) Test-DbaLastBackup - Actually restores your backups, verifies they work, then cleans up Start-DbaMigration / Export-DbaInstance - Migrate entire instances or export everything for DR Backup-DbaDatabase \u0026amp; Restore-DbaDatabase - Do the fundamental stuff at scale Essential Discovery \u0026amp; Troubleshooting Before you can automate, you need to explore:\nFind-DbaInstance - Discover SQL instances on your network Test-DbaConnection - Verify connectivity and permissions Get-DbaDiskSpace - Check disk space before things go wrong Find-DbaAgentJob - Find failed jobs across all servers Find-DbaStoredProcedure - Search for code patterns across databases Once you\u0026rsquo;re comfortable with these, branch out to whatever you work with most: migrations, security, monitoring, or configuration management.\nCommon Use Cases Now that you\u0026rsquo;ve seen the basics, here are some powerful real-world examples.\nRunning Queries at Scale # Run a query against multiple servers at once Invoke-DbaQuery -SqlInstance sql01, sql02, sql03 -Query \u0026#34;SELECT @@VERSION\u0026#34; # Export query results to CSV Invoke-DbaQuery -SqlInstance sql01 -Database master -Query \u0026#34;SELECT * FROM sys.databases\u0026#34; | Export-Csv -Path C:\\temp\\databases.csv -NoTypeInformation # Run a script file against all your servers Get-Content C:\\Scripts\\CheckStatus.sql | Invoke-DbaQuery -SqlInstance (Get-Content C:\\servers.txt) Backups \u0026amp; Restores # Backup all user databases with compression Backup-DbaDatabase -SqlInstance sql01 -ExcludeSystem -Compress # Simple restore Restore-DbaDatabase -SqlInstance sql01 -Path \u0026#34;C:\\temp\\mydb.bak\u0026#34; # Test ALL your backups on a different server # This actually restores them, verifies integrity, then drops them Test-DbaLastBackup -SqlInstance sql01 -Destination sql02 | Out-GridView Finding Things Fast # Find a database across multiple servers Find-DbaDatabase -SqlInstance sql01, sql02, sql03 -Pattern \u0026#34;Production\u0026#34; # Find stored procedures containing specific text Find-DbaStoredProcedure -SqlInstance sql01 -Pattern \u0026#34;INSERT INTO Audit\u0026#34; # Discover SQL instances on your network Find-DbaInstance -ComputerName server01, server02 Monitoring \u0026amp; Health # Check disk space before problems happen Get-DbaDiskSpace -ComputerName sql01, sql02 | Out-GridView # Find databases without recent backups Get-DbaLastBackup -SqlInstance sql01 | Where-Object LastFullBackup -lt (Get-Date).AddDays(-7) # Check for corruption Get-DbaLastGoodCheckDb -SqlInstance sql01 | Out-GridView # Find failed jobs across all servers Find-DbaAgentJob -SqlInstance sql01, sql02 -Failed | Get-DbaAgentJobHistory # See who\u0026#39;s running what and blocking whom Get-DbaProcess -SqlInstance sql01 | Out-GridView # Monitor currently running queries with sp_WhoIsActive Install-DbaWhoIsActive -SqlInstance sql01 -Database master Invoke-DbaWhoIsActive -SqlInstance sql01 Data Import \u0026amp; Export # Import CSV files into SQL Server (auto-creates tables!) Import-DbaCsv -Path C:\\data\\sales.csv -SqlInstance sql01 -Database tempdb -AutoCreateTable # Copy data between tables, even across servers Copy-DbaDbTableData -SqlInstance sql01 -Database source -Table Customers ` -DestinationSqlInstance sql02 -DestinationDatabase target -DestinationTable Customers # Write PowerShell objects directly to SQL Server Get-Process | Write-DbaDbTableData -SqlInstance sql01 -Database tempdb -Table ProcessList -AutoCreateTable Migrations \u0026amp; DR # Migrate entire SQL instance with one command $params = @{ Source = \u0026#39;sql01\u0026#39; Destination = \u0026#39;sql02\u0026#39; BackupRestore = $true SharedPath = \u0026#39;\\\\nas\\temp\u0026#39; } Start-DbaMigration @params # Export everything for disaster recovery # Creates scripts for logins, jobs, databases, configs, everything Export-DbaInstance -SqlInstance sql01 -Path C:\\temp\\dr # Copy just the jobs between servers Copy-DbaAgentJob -Source sql01 -Destination sql02 # Migrate a database with logins Copy-DbaDatabase -Source sql01 -Destination sql02 -Database MyApp -BackupRestore -SharedPath \\\\nas\\migration Copy-DbaLogin -Source sql01 -Destination sql02 -Login ad\\appuser Quick Wins Lost sysadmin access? Use Reset-DbaAdmin Need to test your backups? Use Test-DbaLastBackup SPN management got you down? Use our suite of SPN commands Got so many databases you can\u0026rsquo;t keep track? Use Find-DbaDatabase Getting Help # Detailed help for any command Get-Help Test-DbaLastBackup -Full # See examples Get-Help Test-DbaLastBackup -Examples # Find commands by keyword Get-Command -Module dbatools *backup* Find-DbaCommand -Tag Migration # Open online help in browser Get-Help Test-DbaLastBackup -Online Resources:\nDocumentation Command Reference Blog Slack Community - Friendly help from the community Advanced Topics Authentication By default, dbatools uses Windows Authentication (your current login). To use SQL logins or different Windows credentials:\nSQL Authentication $cred = Get-Credential sqladmin Get-DbaDatabase -SqlInstance sql01 -SqlCredential $cred Alternative Windows Credentials For commands that access Windows (like Get-DbaDiskSpace):\n$cred = Get-Credential ad\\winadmin Get-DbaDiskSpace -ComputerName sql01 -Credential $cred Storing Credentials Securely PowerShell\u0026rsquo;s Export-CliXml provides a fast and secure way to store credentials to disk. The credentials are encrypted using Windows Data Protection API (DPAPI) and can only be decrypted by the same user on the same machine.\n# Save credentials to disk (one-time setup) Get-Credential | Export-CliXml -Path \u0026#34;$HOME\\sql-credentials.xml\u0026#34; # Reuse saved credentials in scripts $cred = Import-CliXml -Path \u0026#34;$HOME\\sql-credentials.xml\u0026#34; Get-DbaDatabase -SqlInstance sql01 -SqlCredential $cred For more advanced credential management approaches including the Secrets Management module, see Rob Sewell\u0026rsquo;s guide.\nCustom Ports If you use non-default ports and SQL Browser is disabled, use a colon or comma:\n# Using colon or comma for non-default ports Get-DbaDatabase -SqlInstance \u0026#39;sql01:55559\u0026#39; Get-DbaDatabase -SqlInstance \u0026#39;sql01,55559\u0026#39; # Note: quotes required with comma PowerShell treats commas as array separators, so you must use quotes.\nPowerShell Transcript Logging # Import module before starting transcript (PS 5.1 requirement) Import-Module dbatools Start-Transcript Get-DbaDatabase -SqlInstance sql01 Stop-Transcript Troubleshooting Common Issues Issue: \u0026ldquo;Could not connect to SqlInstance\u0026rdquo;\n# Test connectivity Test-DbaConnection -SqlInstance sql01 # Check if SQL Browser service is running (for named instances) Get-DbaService -ComputerName sql01 -Type Browser Issue: \u0026ldquo;Access denied\u0026rdquo; errors\n# Ensure you have proper SQL permissions Get-DbaLogin -SqlInstance sql01 -Login $env:USERNAME # For Windows authentication issues, verify domain connectivity Test-ComputerSecureChannel Issue: Module won\u0026rsquo;t import\n# Check execution policy Get-ExecutionPolicy # Force reimport if needed Remove-Module dbatools -Force -ErrorAction SilentlyContinue Import-Module dbatools -Force For more help, visit our troubleshooting guide or ask in Slack.\nMore Learning Resources 📖 Learn dbatools in a Month of Lunches Want structured, in-depth training? Check out our official book Learn dbatools in a Month of Lunches by dbatools creator Chrissy LeMaire and core contributors Rob Sewell, Jess Pomfret, and Cláudio Silva (Manning Publications, 2022).\nIn 28 bite-sized lessons, learn automation techniques directly from the experts who built dbatools. Perfect for DBAs and systems engineers who want to master SQL Server automation.\nBlog Articles Our blog has great articles for diving deeper:\nGetting complex with Restore-DbaDatabase Scheduling PowerShell Tasks with SQL Server Agent Building a dedicated backup test server Scheduling a migration Dealing with SPNs Installing modules from the PowerShell Gallery Offline installs of dbatools Talking to your security team about PowerShell and dbatools Community \u0026amp; Support Get Involved:\n⭐ Star us on GitHub 🐛 Report issues 💡 Request features 🤝 Contribute code Community Channels:\n#dbatools on SQL Community Slack Bluesky Stats:\n📦 7+ million downloads on PowerShell Gallery 👥 250+ contributors 🎯 700+ commands 🚀 10+ years of active development System Requirements SQL Server Compatibility Version Commands Supported SQL Server 2000 75% SQL Server 2005 90% SQL Server 2008/R2 93% SQL Server 2012+ 100% Azure SQL VM As per version above Azure SQL Database 40% Azure SQL Managed Instance 60% Containers/Kubernetes 75% Operating System Compatibility OS Commands Supported PowerShell Required Windows 7/8/10/11 100% v3+ Windows Server 2008 R2+ 100% v3+ Linux (Intel/ARM64) 78% Core 7.4.0+ macOS (Intel/M1) 78% Core 7.4.0+ 💡 Note: Commands requiring SQL WMI or -ComputerName parameter typically don\u0026rsquo;t work on Linux/macOS.\nNetwork Requirements For remote SQL Server management, ensure these ports are accessible:\nProtocol Default Port Used By Required For Firewall Note SQL Database Engine 1433 Get-DbaDatabase 62% of commands Allow inbound on SQL Server WS-Management 5985/5986 New-DbaClientAlias 25% of commands Windows Remote Management SQL WMI 135 Enable-DbaAgHadr 4% of commands DCOM/RPC endpoint mapper SMB 445 Backup-DbaDatabase 4% of commands File sharing for backups Firewall Tip: Create a dedicated Windows Firewall rule group for dbatools management traffic.\n","date":"2016-05-06","summary":"dbatools is a free PowerShell module with nearly 700 commands that replace manual SQL Server administration with powerful and fun automation.\nWhy dbatools? Traditional Methods dbatools SSMS: Click through 50 servers manually PowerShell: Query all 50 servers in one command Migration: Days of planning and execution Migration: Minutes with automated best practices Backup Testing: Manual restores, hope for the best Backup Testing: Automated verification of all backups Documentation: Hours of manual collection Documentation: Instant HTML/Excel reports Scripting: Complex T-SQL across versions Scripting: Consistent commands for SQL 2000-2022 Your First 5 Minutes Let\u0026rsquo;s get you up and running with dbatools.","tags":[],"title":"Getting Started","type":"page","url":"https://dbatools.io/getting-started/"},{"categories":[],"content":"Where Should You Install dbatools? Install dbatools on your workstation, just like SSMS.\ndbatools is a management tool that runs on your local machine and connects remotely to SQL Server instances. You don\u0026rsquo;t need to install anything on your SQL Servers themselves - it manages them over the network.\nWhere people typically install it:\nYour Windows workstation (where you run SSMS) A dedicated management/jump server Your laptop for demos and dev work No need to install on SQL Servers - it\u0026rsquo;s designed to manage them remotely, keeping your servers clean and your deployment simple.\nInstall from the PowerShell Gallery Security Note: dbatools is digitally signed with Azure Trusted Signing, ensuring code integrity and security. Learn more about our signing process →\nInstall-Module dbatools -Scope CurrentUser This is the recommended method - no admin rights needed, installs just for you.\nNeed to install for all users? Use admin PowerShell:\nInstall-Module dbatools Note: dbatools has dependent libraries that will be installed automatically.\nThe PowerShell Gallery and Install-Module are available in Windows 10+, Windows Server 2016+, and PowerShell 7.\nFor Windows 7, 8, Server 2012, first install WMF5 from https://aka.ms/wmf5download then reboot.\nFirst Time Using PowerShell Gallery? If you get a prompt about trusting PSGallery, type Y for Yes. You only need to do this once:\nSet-PSRepository -Name PSGallery -InstallationPolicy Trusted Install-PSResource (PowerShell 7.4+) For PowerShell 7.4 and above, you can also use Install-PSResource:\nInstall-PSResource dbatools To install for all users (requires Run As Administrator):\nInstall-PSResource dbatools -Scope AllUsers Upgrading from Older Versions (v2.5.4 or earlier) Starting with v2.5.5, we switched to Azure Trusted Signing. If you\u0026rsquo;re upgrading from an older version, you may need:\nInstall-Module dbatools -Force -SkipPublisherCheck This is a one-time requirement due to the certificate change.\nOther Installation Methods Chocolatey choco install dbatools More info at chocolatey.org/packages/dbatools\nOffline Install Don\u0026rsquo;t have Internet access on your DBA workstation? Check out our offline install guide.\nSystem Requirements dbatools values backward compatibility. We still deliver for people running PowerShell v3 and SQL Server 2000.\nSQL Server Support SQL Server 2000 through SQL Server 2025 Azure SQL Database (40% of commands) Azure SQL Managed Instance (60% of commands) No PowerShell needed on the SQL Server host for database commands Workstation Requirements Windows: Windows 7+ with PowerShell 3+ Linux/macOS: PowerShell 7+ Remote Windows Commands: PowerShell remoting enabled on target servers Network Requirements For remote SQL Server management, ensure these ports are accessible:\nProtocol Default Port Used By Required For Firewall Note SQL Database Engine 1433 Get-DbaDatabase 62% of commands Allow inbound on SQL Server WS-Management 5985/5986 New-DbaClientAlias 25% of commands Windows Remote Management SQL WMI 135 Enable-DbaAgHadr 4% of commands DCOM/RPC endpoint mapper SMB 445 Backup-DbaDatabase 4% of commands File sharing for backups Firewall Tip: Use New-DbaFirewallRule to automatically configure Windows Firewall rules for SQL Server.\nNew to PowerShell? If you\u0026rsquo;re new to PowerShell and would like in-depth walk-thrus and more:\nWalk-thru: Installing modules from the PowerShell Gallery Getting started with PowerShell Offline installs of dbatools Talking to your security team about PowerShell and dbatools What\u0026rsquo;s Next? Installing the module makes hundreds of commands available to you.\nReady to start?\nGetting Started Guide - Learn the basics with code samples Popular Commands - See what everyone uses most Our Book - Learn dbatools in a Month of Lunches Like what you see? Give us a star on GitHub!\n","date":"2016-05-06","summary":"Where Should You Install dbatools? Install dbatools on your workstation, just like SSMS.\ndbatools is a management tool that runs on your local machine and connects remotely to SQL Server instances. You don\u0026rsquo;t need to install anything on your SQL Servers themselves - it manages them over the network.\nWhere people typically install it:\nYour Windows workstation (where you run SSMS) A dedicated management/jump server Your laptop for demos and dev work No need to install on SQL Servers - it\u0026rsquo;s designed to manage them remotely, keeping your servers clean and your deployment simple.","tags":[],"title":"Install","type":"page","url":"https://dbatools.io/install/"},{"categories":[],"content":"","date":"","summary":"","tags":[],"title":"Search","type":"page","url":"https://dbatools.io/search/"},{"categories":[],"content":" We encourage pull requests and development participation. There's also a #dbatools channel on the SQL Server Slack if you'd like to discuss the module or just hang out.\nCore Maintainers Chrissy Creator\nJess Maintainer\nAndreas Maintainer\nSimone Maintainer\nRob Maintainer\nShawn Maintainer\nTop Contributors #1 Chrissy LeMaire @potatoqualitee 8,919 Commits #2 Shawn Melton @wsmelton 1,583 Commits #3 Stuart Moore @Stuart-Moore 828 Commits #4 Simone Bizzotto @niphlod 662 Commits #5 Andreas Jordan @andreasjordan 462 Commits #6 Jess Pomfret @jpomfret 333 Commits #7 Sander Stad @sanderstad 315 Commits #8 Claudio Silva @ClaudioESSilva 309 Commits #9 Andy Levy @alevyinroc 204 Commits #10 Mikey Bronowski @MikeyBronowski 181 Commits #11 Adam Lancaster @lancasteradam 175 Commits #12 Kirill Kravtsov @nvarscar 163 Commits #13 Friedrich Weinmann @FriedrichWeinmann 142 Commits #14 Rob Sewell @SQLDBAWithABeard 121 Commits #15 Josh Corrick @joshcorr 115 Commits #16 Patrick Flynn @sqllensman 104 Commits #17 Klaas Vandenberghe @PowerDBAKlaas 91 Commits #18 Justin Dearing @zippy1981 84 Commits #19 Mötz Jensen @Splaxi 77 Commits #20 Viorel Ciucu @cviorel 76 Commits And many more amazing contributors who make dbatools better every day! 💙 Chrissy LeMaire, dbatools creator SQL Server \u0026 PowerShell MVP GitHub Bluesky Blog LinkedIn Reddit Hey, I'm Chrissy. I'm a Cajun living in Europe and a SQL Server DBA with over 20 years of experience.\nI've been a fan of Linux and Open Source since I was first introduced back in the 90's, right around the time I moved to California to work in tech. I've loved SQL Server for nearly as long. And of course, PowerShell, which I've worked with since 2005.\n","date":"","summary":"We encourage pull requests and development participation. There's also a #dbatools channel on the SQL Server Slack if you'd like to discuss the module or just hang out.\nCore Maintainers Chrissy Creator\nJess Maintainer\nAndreas Maintainer\nSimone Maintainer\nRob Maintainer\nShawn Maintainer\nTop Contributors #1 Chrissy LeMaire @potatoqualitee 8,919 Commits #2 Shawn Melton @wsmelton 1,583 Commits #3 Stuart Moore @Stuart-Moore 828 Commits #4 Simone Bizzotto @niphlod 662 Commits #5 Andreas Jordan @andreasjordan 462 Commits #6 Jess Pomfret @jpomfret 333 Commits #7 Sander Stad @sanderstad 315 Commits #8 Claudio Silva @ClaudioESSilva 309 Commits #9 Andy Levy @alevyinroc 204 Commits #10 Mikey Bronowski @MikeyBronowski 181 Commits #11 Adam Lancaster @lancasteradam 175 Commits #12 Kirill Kravtsov @nvarscar 163 Commits #13 Friedrich Weinmann @FriedrichWeinmann 142 Commits #14 Rob Sewell @SQLDBAWithABeard 121 Commits #15 Josh Corrick @joshcorr 115 Commits #16 Patrick Flynn @sqllensman 104 Commits #17 Klaas Vandenberghe @PowerDBAKlaas 91 Commits #18 Justin Dearing @zippy1981 84 Commits #19 Mötz Jensen @Splaxi 77 Commits #20 Viorel Ciucu @cviorel 76 Commits And many more amazing contributors who make dbatools better every day!","tags":[],"title":"Team","type":"page","url":"https://dbatools.io/team/"}]