├── .devcontainer ├── devcontainer.json ├── docker-compose.yml └── dockerfile ├── .github └── workflows │ └── pestering.yml ├── .gitignore ├── advanced └── readme.md ├── bookcode ├── AllTheCode.ps1 ├── chapter02.ps1 ├── chapter03.ps1 ├── chapter04.ps1 ├── chapter05.ps1 ├── chapter06.ps1 ├── chapter07.ps1 ├── chapter08.ps1 ├── chapter09.ps1 ├── chapter10.ps1 ├── chapter11.ps1 ├── chapter12.ps1 ├── chapter13.ps1 ├── chapter14.ps1 ├── chapter15.ps1 ├── chapter16.ps1 ├── chapter17.ps1 ├── chapter18.ps1 ├── chapter19.ps1 ├── chapter20.ps1 ├── chapter21.ps1 ├── chapter22.ps1 ├── chapter23.ps1 ├── chapter24.ps1 ├── chapter25.ps1 ├── chapter26.ps1 ├── chapter27.ps1 └── chapter28.ps1 ├── config └── Config.psd1 ├── csv └── sameplecsvs.zip ├── notebooks ├── DotNet │ ├── 00-CreateContainers.ipynb │ ├── 01-Introduction.ipynb │ ├── 02-BackupsRestores.ipynb │ ├── 03AvailabilityGroups.ipynb │ ├── 04-LoginsAndUsers.ipynb │ ├── 05-ExtendedEvents.ipynb │ ├── 06-AgentJobs.ipynb │ ├── 99-CleanUpContainers.ipynb │ ├── Untitled.ipynb │ ├── docker-compose.yml │ ├── dockercompose.yml │ └── images │ │ ├── ag.png │ │ ├── blockedprocessXE.png │ │ ├── containers.png │ │ ├── dbachecks-logo.png │ │ ├── dbatools.png │ │ ├── dbatoolsdemopermissions.png │ │ ├── documentsdirectorypermissions.png │ │ └── switchtolinuxcontainers.png ├── NotDotNet │ ├── 00-CreateContainers.ipynb │ ├── 01-Introduction.ipynb │ ├── 02-BackupsRestores.ipynb │ ├── 03AvailabilityGroups.ipynb │ ├── 04-LoginsAndUsers.ipynb │ ├── 05-ExtendedEvents.ipynb │ ├── 06-AgentJobs.ipynb │ ├── 99-CleanUpContainers.ipynb │ ├── Update-Ola-Without-Breaking-Jobs.ipynb │ ├── docker-compose.yml │ ├── dockercompose.yml │ └── images │ │ ├── 02-BackupsRestores.ipynb │ │ ├── RefreshPowerBi.gif │ │ ├── ag.png │ │ ├── blockedprocessXE.png │ │ ├── containers.png │ │ ├── dbachecks-logo.png │ │ ├── dbatools.png │ │ ├── dbatoolsdemopermissions.png │ │ ├── documentsdirectorypermissions.png │ │ ├── firstpowerbi.png │ │ ├── switchtolinuxcontainers.png │ │ └── video.png └── readme.md ├── readme.md ├── scripts ├── 00_Install_Prereqs.ps1 ├── 01_Install_Lab.ps1 ├── 02_Configure_Lab.ps1 └── 99_Cleanup_Lab.ps1 └── tests ├── cleanup.tests.ps1 ├── configure.tests.ps1 ├── install.tests.ps1 ├── prereq.tests.ps1 └── setup └── docker-compose.yml /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dbatoolslab", 3 | "workspaceFolder": "/workspace", 4 | "dockerComposeFile": [ 5 | "docker-compose.yml" 6 | ], 7 | "remoteEnv": { 8 | "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}", 9 | "MY_SERVERS": "dbatoolslab,dbatoolslab2", 10 | "MY_SERVER": "dbatoolslab" 11 | }, 12 | "service": "dbatoolslab", 13 | "settings": { 14 | "terminal.integrated.shell.linux": "/usr/bin/pwsh" 15 | }, 16 | // Add the IDs of extensions you want installed when the container is created. 17 | "extensions": [ 18 | "ms-vscode.powershell", 19 | "github.vscode-pull-request-github", 20 | "2gua.rainbow-brackets", 21 | "oderwat.indent-rainbow", 22 | "mhutchie.git-graph", 23 | "usernamehw.errorlens" 24 | ] 25 | // Uncomment the next line if you want to keep your containers running after VS Code shuts down. 26 | // "shutdownAction": "none", 27 | // Uncomment the next line to run commands after the container is created - for example installing curl. 28 | // "postCreateCommand": "apt-get update && apt-get install -y curl", 29 | } -------------------------------------------------------------------------------- /.devcontainer/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | services: 3 | dbatoolslab: 4 | container_name: "dbatoolslab" 5 | build: . 6 | image: dbatools/sqlinstance:latest 7 | environment: 8 | - ACCEPT_EULA=Y 9 | - SA_PASSWORD=dbatools.IO 10 | - MSSQL_AGENT_ENABLED=True 11 | ports: 12 | - "1401:1433" 13 | volumes: 14 | # Update this to wherever you want VS Code to mount the folder of your project 15 | - ..:/workspace:cached 16 | dbatoolslab2: 17 | depends_on: 18 | - dbatoolslab1 19 | container_name: "dbatoolslab2" 20 | image: dbatools/sqlinstance:latest 21 | environment: 22 | - ACCEPT_EULA=Y 23 | - SA_PASSWORD=dbatools.IO 24 | - MSSQL_AGENT_ENABLED=True 25 | ports: 26 | - "1402:1433" -------------------------------------------------------------------------------- /.devcontainer/dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/mssql/server:2019-latest 2 | USER root 3 | # Install PowerShell 4 | RUN apt-get update && apt install -y powershell 5 | # install git 6 | RUN apt install -y git 7 | 8 | # some cleanup 9 | RUN apt-get autoremove -y \ 10 | && apt-get clean -y 11 | 12 | ENV GIT_PROMPT_START='\033[1;36dbatools>\033[0m\033[0;33m\w\a\033[0m' 13 | 14 | # Save command line history 15 | RUN echo "export HISTFILE=/commandhistory/.bash_history" >> "/root/.bashrc" \ 16 | && echo "export PROMPT_COMMAND='history -a'" >> "/root/.bashrc" \ 17 | && mkdir -p /commandhistory \ 18 | && touch /commandhistory/.bash_history \ 19 | && mkdir /workspace 20 | 21 | # Install Pester, has to be 4.4.3 because 4.4.2 has bug in Unix machines 22 | SHELL ["/usr/bin/pwsh", "-c"] 23 | RUN $ErrorActionPreference='Stop'; Install-Module -Name Pester -Force -SkipPublisherCheck -MaximumVersion 4.4.3; 24 | 25 | # Install dbatools 26 | SHELL ["/usr/bin/pwsh", "-c"] 27 | RUN $ErrorActionPreference='Stop'; Install-Module -Name dbatools -Force -SkipPublisherCheck; 28 | -------------------------------------------------------------------------------- /.github/workflows/pestering.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the workflow will run 6 | on: 7 | # Allows you to run this workflow manually from the Actions tab 8 | workflow_dispatch: 9 | 10 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 11 | jobs: 12 | # This workflow contains a single job called "build" 13 | build: 14 | # The type of runner that the job will run on 15 | runs-on: ubuntu-latest 16 | # Steps represent a sequence of tasks that will be executed as part of the job 17 | steps: 18 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 19 | - uses: actions/checkout@v2 20 | 21 | # Runs the docker compose up 22 | - name: Containers Be ready 23 | run: | 24 | cd tests\setup\ 25 | docker-compose up -d 26 | docker ps -a 27 | shell: pwsh 28 | 29 | - name: Test the connection to the container 30 | run: | 31 | Install-Module dbachecks 32 | $secStringPassword = ConvertTo-SecureString -String 'dbatools.IO' -AsPlainText -Force 33 | $sqlcred = New-Object System.Management.Automation.PSCredential ('sqladmin', $secStringPassword) 34 | $PSDefaultParameterValues = @{'*:SqlCredential' = $sqlcred;'*:WarningAction' = 'Stop'} 35 | Set-DbcConfig -Name policy.connection.authscheme -Value SQL 36 | Set-DbcConfig -Name skip.connection.ping -Value $true 37 | Set-DbcConfig -Name skip.connection.remoting -Value $true 38 | Invoke-DbcCheck -Check InstanceConnection -SqlInstance 'localhost,15592' 39 | shell: pwsh -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.bak -------------------------------------------------------------------------------- /advanced/readme.md: -------------------------------------------------------------------------------- 1 | # Advanced 2 | This is the section of the repo that contains some bonus\advanced scripts. 3 | 4 | E.g. Terraform to create an Azure VM for your dbatools lab. -------------------------------------------------------------------------------- /bookcode/chapter02.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 02 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Invoke-Command -ComputerName spsql01 -ScriptBlock { $Env:COMPUTERNAME } 19 | 20 | ########### 21 | 22 | $Env:PSModulePath -Split ";" 23 | 24 | ########### 25 | 26 | Set-PSRepository -Name PSGallery -InstallationPolicy Trusted 27 | 28 | ########### 29 | 30 | Import-Module dbatools 31 | 32 | ########### 33 | 34 | -------------------------------------------------------------------------------- /bookcode/chapter03.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 03 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Install-DbaInstance -Version 2019 -SqlInstance dbatoolslab -Feature Engine -Path Z:\2019 -AuthenticationMode Mixed 19 | 20 | ########### 21 | 22 | Install-DbaInstance -Version 2017 23 | 24 | ########### 25 | 26 | Connect-DbaInstance -SqlInstance dbatoolslab 27 | 28 | ########### 29 | 30 | Find-DbaInstance -ComputerName localhost 31 | 32 | ComputerName InstanceName Port Availability Confidence ScanTypes 33 | 34 | ########### 35 | 36 | Restore-DbaDatabase -SqlInstance dbatoolslab\sql2017 -Path C:\dbatoolslab\Backup\WideWorldImporters-Full.bak 37 | Restore-DbaDatabase -SqlInstance dbatoolslab\sql2017 -Path C:\dbatoolslab\Backup\AdventureWorks2017-Full.bak 38 | 39 | ########### 40 | 41 | $pw = (Get-Credential wejustneedthepassword).Password 42 | New-DbaLogin -SqlInstance dbatoolslab\sql2017 -Password $pw -Login WWI_ReadOnly 43 | New-DbaLogin -SqlInstance dbatoolslab\sql2017 -Password $pw -Login WWI_ReadWrite 44 | New-DbaLogin -SqlInstance dbatoolslab\sql2017 -Password $pw -Login WWI_Owner 45 | 46 | # Create database users 47 | New-DbaDbUser -SqlInstance dbatoolslab\sql2017 -Login WWI_ReadOnly -Database WideWorldImporters -Confirm:$false 48 | New-DbaDbUser -SqlInstance dbatoolslab\sql2017 -Login WWI_ReadWrite -Database WideWorldImporters -Confirm:$false 49 | New-DbaDbUser -SqlInstance dbatoolslab\sql2017 -Login WWI_Owner -Database WideWorldImporters -Confirm:$false 50 | 51 | # Add database role members 52 | Add-DbaDbRoleMember -SqlInstance dbatoolslab\sql2017 -Database WideWorldImporters -User WWI_Readonly -Role db_datareader 53 | Add-DbaDbRoleMember -SqlInstance dbatoolslab\sql2017 -Database WideWorldImporters -User WWI_ReadWrite -Role db_datawriter 54 | Add-DbaDbRoleMember -SqlInstance dbatoolslab\sql2017 -Database WideWorldImporters -User WWI_Owner -Role db_owner 55 | 56 | # Create some SQL Server Agent jobs 57 | $job = New-DbaAgentJob -SqlInstance dbatoolslab\sql2017 -Job 'dbatools lab job' -Description 'Creating a test job for our lab' 58 | New-DbaAgentJobStep -SqlInstance dbatoolslab\sql2017 -Job $Job.Name -StepName 'Step 1: Select statement' -Subsystem TransactSQL -Command 'Select 1' 59 | 60 | # add second job 61 | $job = New-DbaAgentJob -SqlInstance dbatoolslab\sql2017 -Job 'dbatools lab - where am I' -Description 'Creating test2 job for our lab' 62 | New-DbaAgentJobStep -SqlInstance dbatoolslab\sql2017 -Job $Job.Name -StepName 'Step 1: Select servername' -Subsystem TransactSQL -Command 'Select @@ServerName' 63 | 64 | ########### 65 | 66 | Set-DbaSpConfigure -SqlInstance dbatoolslab\sql2017 -Name RemoteDacConnectionsEnabled -Value 1 67 | Set-DbaSpConfigure -SqlInstance dbatoolslab\sql2017 -Name CostThresholdForParallelism -Value 10 68 | 69 | ########### 70 | 71 | # create a shared network 72 | docker network create localnet 73 | 74 | # Expose engines and setup shared path for migrations 75 | docker run -p 1433:1433 --volume shared:/shared:z --name mssql1 --hostname mssql1 --network localnet -d dbatools/sqlinstance 76 | docker run -p 14333:1433 --volume shared:/shared:z --name mssql2 --hostname mssql2 --network localnet -d dbatools/sqlinstance2 77 | 78 | ########### 79 | 80 | docker ps 81 | 82 | ########### 83 | 84 | Connect-DbaInstance -SqlInstance localhost -SqlCredential sqladmin 85 | 86 | # Connect to SQL Server in a container listening on non standard port 87 | $cred = Get-Credential sqladmin 88 | Connect-DbaInstance -SqlInstance localhost:14333 -SqlCredential $cred 89 | 90 | ########### 91 | 92 | New-DbaClientAlias -ServerName localhost -Alias mssql1 93 | Connect-DbaInstance -SqlInstance mssql1 -SqlCredential sqladmin 94 | 95 | 96 | ########### 97 | 98 | -------------------------------------------------------------------------------- /bookcode/chapter04.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 04 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Get-Help Test-DbaConnection -Detailed 19 | 20 | ########### 21 | 22 | Test-DbaConnection -SqlInstance $Env:ComputerName 23 | 24 | ########### 25 | 26 | Get-DbaDatabase -SqlInstance SQLDEV01 27 | 28 | ########### 29 | 30 | Connect-DbaInstance -SqlInstance PRODSQL01\SHAREPOINT 31 | 32 | ########### 33 | 34 | Connect-DbaInstance -SqlInstance PRODSQL01, PRODSQL02, PRODSQL03\ShoeFactory 35 | 36 | ########### 37 | 38 | "PRODSQL01", "PRODSQL02", "PRODSQL03\ShoeFactory" | Connect-DbaInstance 39 | 40 | ########### 41 | 42 | $instances = "PRODSQL01", "PRODSQL02", "PRODSQL03\ShoeFactory" 43 | Connect-DbaInstance -SqlInstance $instances 44 | 45 | ########### 46 | 47 | $instances = "PRODSQL01", "PRODSQL02", "PRODSQL03\ShoeFactory" 48 | $instances | Connect-DbaInstance 49 | 50 | ########### 51 | 52 | $instances = (Invoke-DbaQuery -SqlInstance ConfigInstance -Database DbaConfig -Query "SELECT InstanceName FROM Config.Instances C JOIN Project.People P ON C.InstanceID = P.InstanceID WHERE P.Name = 'Shawn Melton'").InstanceName 53 | $instances | Connect-DbaInstance 54 | 55 | ########### 56 | 57 | $instances = Invoke-DbaQuery -SqlInstance ConfigInstance -Database DbaConfig -Query "SELECT InstanceName FROM Config.Instances C JOIN Project.People P ON C.InstanceID = P.InstanceID WHERE P.Name = 'Shawn Melton'" | Select-Object -ExpandProperty InstanceName 58 | $instances | Connect-DbaInstance 59 | 60 | ########### 61 | 62 | Connect-DbaInstance -SqlInstance "sqldev04,57689" 63 | 64 | ########### 65 | 66 | Connect-DbaInstance -SqlInstance sqldev04:57689 67 | 68 | ########### 69 | 70 | Connect-DbaInstance -SqlInstance CORPSQL01 -SqlCredential devadmin 71 | 72 | ########### 73 | 74 | Connect-DbaInstance -SqlInstance CORPSQL01 -SqlCredential devadmin 75 | 76 | 77 | ########### 78 | 79 | $cred = Get-Credential 80 | # Connect to the local machine using the credential 81 | Connect-DbaInstance -SqlInstance $Env:ComputerName -SqlCredential $cred 82 | 83 | ########### 84 | 85 | $cred = Get-Credential 86 | 87 | 88 | ########### 89 | 90 | Connect-DbaInstance -SqlInstance $Env:ComputerName -SqlCredential $cred 91 | 92 | Name Product Version Platform IsAzure IsClustered ConnectedAs 93 | 94 | ########### 95 | 96 | $query = "EXEC GetPasswordFromPasswordStore @UserName='AD\dbatools'" 97 | $securepassword = ConvertTo-SecureString (Invoke-DbaQuery -SqlInstance VerySecure -Database NoPasswordsHere -Query $query) -AsPlainText -Force 98 | $cred = New-Object System.Management.Automation.PSCredential ( "AD\dbatools", $securepassword) 99 | Test-DbaConnection -SqlInstance $Env:ComputerName -SqlCredential $cred 100 | 101 | ########### 102 | 103 | Connect-DbaInstance -SqlInstance SQLDEV01 -SqlCredential ad\sander.stad 104 | 105 | ########### 106 | 107 | $server = Connect-DbaInstance -SqlInstance dbatools.database.windows .net -SqlCredential dbatools@mycorp.onmicrosoft.com -Database inventory 108 | # Use server connection to query the database using our query command, Invoke-DbaQuery 109 | Invoke-DbaQuery -SqlInstance $server -Database inventory -Query "select name from instances" 110 | 111 | ########### 112 | 113 | Connect-DbaInstance -SqlInstance dbatools.database.windows.net -SqlCredential 52c1fbca-24ed-4353-bbf1-6dd52f535027 -Tenant ec46e088-2707-4b0a-ab0d-dee0b52fc5c8 -Database inventory 114 | 115 | Name Product Version Platform IsAzure IsClustered ConnectedAs 116 | 117 | ########### 118 | 119 | $appcred = Get-Credential 52c1fbca-24ed-4353-bbf1-6dd52f535027 120 | 121 | # Establish a connection 122 | $server = Connect-DbaInstance -SqlInstance dbatools.database.windows .net -Database inventory -SqlCredential $appcred -Tenant 6b73c0ef-114d-43ad-94c9-85a4a82cde8b 123 | 124 | # Now that the connection is established, use it to perform a query 125 | Invoke-DbaQuery -SqlInstance $server -Database dbatools -Query "SELECT Name FROM sys.objects" 126 | 127 | Name 128 | 129 | ########### 130 | 131 | Get-Help Get-DbaService 132 | 133 | Synopsis 134 | Gets the SQL Server related services on a computer. 135 | 136 | Description 137 | Gets the SQL Server related services on one or more computers. 138 | 139 | Requires Local Admin rights on destination computer(s). 140 | 141 | Syntax 142 | Get-DbaService [[-ComputerName] ] [-InstanceName ] [-Credential ] [-Type ] [-AdvancedProperties] [-EnableException] [] 143 | Get-DbaService [[-ComputerName] ] [-Credential ] [-ServiceName ] [-AdvancedProperties] [-EnableException] [] 144 | 145 | ########### 146 | 147 | Get-DbaService -ComputerName CORPSQL 148 | 149 | ComputerName : CORPSQL 150 | ServiceName : MsDtsServer140 151 | ServiceType : SSIS 152 | InstanceName : 153 | DisplayName : SQL Server Integration Services 14.0 154 | StartName : NT Service\MsDtsServer140 155 | State : Stopped 156 | StartMode : Manual 157 | 158 | ComputerName : CORPSQL 159 | ServiceName : MSSQLSERVER 160 | ServiceType : Engine 161 | InstanceName : MSSQLSERVER 162 | DisplayName : SQL Server (MSSQLSERVER) 163 | StartName : NT Service\MSSQLSERVER 164 | State : Stopped 165 | StartMode : Manual 166 | 167 | ComputerName : CORPSQL 168 | ServiceName : SQLBrowser 169 | ServiceType : Browser 170 | InstanceName : 171 | DisplayName : SQL Server Browser 172 | StartName : NT AUTHORITY\LOCALSERVICE 173 | State : Stopped 174 | StartMode : Manual 175 | 176 | ComputerName : CORPSQL 177 | ServiceName : SQLSERVERAGENT 178 | ServiceType : Agent 179 | InstanceName : MSSQLSERVER 180 | DisplayName : SQL Server Agent (MSSQLSERVER) 181 | StartName : NT Service\SQLSERVERAGENT 182 | State : Stopped 183 | StartMode : Manual 184 | 185 | ########### 186 | 187 | Get-DbaService -ComputerName SQL01, SQL02 188 | 189 | # Computer Names piped to a command 190 | "SQL01", "SQL02" | Get-DbaService 191 | 192 | # Computer Names stored in a variable 193 | $servers = "SQL01", "SQL02" 194 | Get-DbaService -ComputerName $servers 195 | 196 | # Computer Names stored in a variable and piped to a command 197 | $servers = "SQL01", "SQL02" 198 | $servers | Get-DbaService 199 | 200 | ########### 201 | 202 | Get-DbaService -ComputerName CORPSQL -Credential AD\wdurkin 203 | 204 | 205 | ########### 206 | 207 | $cred = Get-Credential 208 | 209 | 210 | ########### 211 | 212 | Get-DbaService -ComputerName CORPSQL -Credential $cred 213 | 214 | ########### 215 | 216 | Get-DbaService -ComputerName CORPSQL -Type Engine 217 | 218 | ########### 219 | 220 | Get-DbaService -ComputerName CORPSQL -InstanceName BOLTON 221 | 222 | ########### 223 | 224 | -------------------------------------------------------------------------------- /bookcode/chapter05.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 05 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Get-DbaDatabase -SqlInstance SQLDEV01 -ExcludeSystem 19 | 20 | 21 | ########### 22 | 23 | Get-DbaDatabase -SqlInstance SQLDEV01 -ExcludeSystem | 24 | Select Name, Size, LastFullBackup 25 | 26 | 27 | ########### 28 | 29 | Get-DbaDatabase -SqlInstance SQLDEV01 -ExcludeSystem | 30 | Select Name, Size, LastFullBackup | clip 31 | 32 | ########### 33 | 34 | Get-DbaDatabase -SqlInstance SQLDEV01 -ExcludeSystem | 35 | Select Name, Size, LastFullBackup | 36 | Export-Csv -Path Databaseinfo.csv -NoTypeInformation 37 | 38 | Get-Content DatabaseInfo.csv 39 | 40 | ########### 41 | 42 | Get-ChildItem -Path E:\csvs\top.csv | 43 | Import-DbaCsv -SqlInstance SQLDEV01 -Database tempdb -Table top 44 | 45 | 46 | ########### 47 | 48 | Get-ChildItem E:\csv\top*.csv | 49 | Import-DbaCsv -SqlInstance SQLDEV01 -Database tempdb -AutoCreateTable 50 | 51 | 52 | ########### 53 | 54 | Import-Csv -Path E:\csv\top-tracks.csv | 55 | Select Rank, Plays, Artist, Title 56 | 57 | 58 | ########### 59 | 60 | Import-Csv -Path .\Databaseinfo.csv | 61 | Write-DbaDataTable -SqlInstance SQLDEV01 -Database tempdb -Table Databases -AutoCreateTable 62 | 63 | ########### 64 | 65 | $csv = Import-Csv \\server\bigdataset.csv 66 | Write-DbaDataTable -SqlInstance sql2014 -InputObject $csv -Database mydb 67 | 68 | ########### 69 | 70 | $query = "Select * from Databases" 71 | Invoke-DbaQuery -SqlInstance SQLDEV01 -Database tempdb -Query $query 72 | 73 | ########### 74 | 75 | Remove-DbaDbTable SqlInstance SQL01 -Database tempdb -Table databases 76 | 77 | ########### 78 | 79 | Get-DbaDatabase -SqlInstance SQLDEV01 -ExcludeSystem | 80 | Select Name, Size, LastFullBackUp | 81 | Write-DbaDataTable -SqlInstance SQLDEV01 -Database tempdb -Table Databases -AutoCreateTable 82 | 83 | ########### 84 | 85 | $query = "Select * from Databases" 86 | Invoke-DbaQuery -SqlInstance SQLDEV01 -Query $query -Database tempdb 87 | 88 | ########### 89 | 90 | (Get-DbaDbTable -SqlInstance SQLDEV01 -Database tempdb -Table Databases).Columns | 91 | Select-Object Parent,Name, Datatype 92 | 93 | 94 | ########### 95 | 96 | Import-Csv -Path .\Databaseinfo.csv | Get-Member 97 | Get-DbaDatabase -SqlInstance SQLDEV01 -ExcludeSystem | 98 | Select Name, Size, LastFullBackup | Get-Member 99 | 100 | ########### 101 | 102 | Import-Csv -Path .\Databaseinfo.csv | 103 | Write-DbaDataTable -SqlInstance SQLDEV01 -Database tempdb -Table Databases 104 | 105 | ########### 106 | 107 | Import-Csv -Path .\Databaseinfo.csv | 108 | Write-DbaDataTable -SqlInstance SQLDEV01 -Database tempdb -Table Databases 109 | Invoke-DbaQuery -SqlInstance SQLDEV01 -Query "select * from Databases" -Database tempdb 110 | 111 | 112 | ########### 113 | 114 | Get-Process | Select -Last 10 | 115 | Write-DbaDataTable -SqlInstance SQLDEV01 -Database tempdb -Table processes -AutoCreateTable 116 | 117 | ########### 118 | 119 | (Get-DbaDbTable -SqlInstance SQLDEV01 -Database tempdb -Table processes).Columns | Select-Object Parent,Name, Datatype 120 | 121 | 122 | ########### 123 | 124 | Connect-AzAccount 125 | 126 | 127 | ########### 128 | 129 | Get-AzVM -Status | Write-DbaDataTable -SqlInstance SQLDEV01 -Database tempdb -Table AzureVMs -AutoCreateTable 130 | 131 | ########### 132 | 133 | $query = "SELECT [Name] 134 | ,[Location] 135 | ,[PowerState] 136 | ,[StatusCode] 137 | FROM [AzureVMs]" 138 | Invoke-DbaQuery -SqlInstance SQLDEV01 -Query $query -Database tempdb 139 | 140 | 141 | ########### 142 | 143 | $copyDbaDbTableDataSplat = @{ 144 | SqlInstance = "SQLDEV01" 145 | Database = "WideWorldImporters" 146 | Table = '[Purchasing].[PurchaseOrders]' 147 | Destination = "SQLDEV02,15591" 148 | DestinationDatabase = 'WIP' 149 | DestinationTable = 'dbo.PurchaseOrders' 150 | AutoCreateTable = $true 151 | } 152 | Copy-DbaDbTableData @copyDbaDbTableDataSplat 153 | 154 | SourceInstance : SQLDEV01 155 | SourceDatabase : WideWorldImporters 156 | SourceSchema : Purchasing 157 | SourceTable : PurchaseOrders 158 | DestinationInstance : SQLDEV02,15591 159 | DestinationDatabase : WIP 160 | DestinationSchema : dbo 161 | DestinationTable : PurchaseOrders 162 | RowsCopied : 2074 163 | Elapsed : 77.01 ms 164 | 165 | ########### 166 | 167 | -------------------------------------------------------------------------------- /bookcode/chapter06.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 06 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Find-DbaInstance -ComputerName dbatoolslab 19 | 20 | ########### 21 | 22 | Get-Content -Path C:\temp\serverlist.txt | Find-DbaInstance 23 | 24 | # Pipe in computers from Active Directory 25 | Get-ADComputer -Filter "*" | Find-DbaInstance 26 | 27 | ########### 28 | 29 | Find-DbaInstance -DiscoveryType DataSourceEnumeration -ScanType Browser 30 | 31 | ComputerName InstanceName Port Availability Confidence ScanTypes 32 | 33 | ########### 34 | 35 | [System.Data.Sql.SqlDataSourceEnumerator]::Instance.GetDataSources() 36 | 37 | ########### 38 | 39 | Find-DbaInstance -DiscoveryType Domain 40 | 41 | ########### 42 | 43 | $splatFindInstance = @{ 44 | DiscoveryType = "Domain" 45 | DomainController = "dc.devad.local" 46 | Credential = "devad\admin" 47 | } 48 | Find-DbaInstance @splatFindInstance 49 | 50 | ########### 51 | 52 | Find-DbaInstance -DiscoveryType IPRange 53 | 54 | ########### 55 | 56 | Find-DbaInstance -DiscoveryType IPRange -IpAddress 172.20.0.77 57 | 58 | # Specify a range 59 | Find-DbaInstance -DiscoveryType IPRange -IpAddress 172.20.0.1/24 60 | 61 | ########### 62 | 63 | Find-DbaInstance -ComputerName SQLDEV01 | Select * 64 | 65 | 66 | ########### 67 | 68 | Find-DbaInstance -ComputerName SQLDEV01 | 69 | Select -ExpandProperty DnsResolution 70 | 71 | 72 | ########### 73 | 74 | Find-DbaInstance -ComputerName SQLDEV01 | 75 | Select -ExpandProperty Services 76 | 77 | 78 | ########### 79 | 80 | -------------------------------------------------------------------------------- /bookcode/chapter07.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 07 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | cd "C:\Program Files\Microsoft SQL Server\140\Setup Bootstrap\SQL2017" 19 | .\setup.exe /Action=RunDiscovery 20 | 21 | ########### 22 | 23 | Get-DbaFeature -ComputerName $sqlinstances 24 | 25 | ########### 26 | 27 | Get-DbaBuildReference -SqlInstance SQLDEV01 28 | 29 | 30 | ########### 31 | 32 | Get-DbaBuildReference -Update 33 | 34 | ########### 35 | 36 | Test-DbaBuild -SqlInstance SQLDEV01 -Latest 37 | 38 | ########### 39 | 40 | Get-DbaComputerSystem -ComputerName SQLDEV01 41 | 42 | 43 | ########### 44 | 45 | Get-DbaOperatingSystem -ComputerName SQL2016N1.ad.local 46 | 47 | 48 | ########### 49 | 50 | Get-DbaDatabase -SqlInstance SQLDEV01 51 | 52 | ########### 53 | 54 | $splatDatabase = @{ 55 | SqlInstance = "SQLDEV01" 56 | Database = "WideWorldImporters", "AdventureWorks" 57 | } 58 | Get-DbaDatabase @splatDatabase 59 | 60 | ########### 61 | 62 | Get-DbaDatabase -SqlInstance SQLDEV01 -NoFullBackup 63 | 64 | ########### 65 | 66 | $date = (Get-Date).AddDays(-30) 67 | Get-DbaDatabase -SqlInstance SQLDEV01 -NoFullBackupSince $date 68 | 69 | ########### 70 | 71 | $splatInvokeQuery = @{ 72 | SqlInstance = "ConfigInstance" 73 | Database = "Instances" 74 | Query = "SELECT InstanceName FROM Config" 75 | } 76 | $SqlInstances = (Invoke-DbaQuery @splatInvokeQuery).InstanceName 77 | # Find databases owned by the user 78 | Get-DbaDatabase -SqlInstance $instances -User ad\g.sartori 79 | 80 | ########### 81 | 82 | Find-DbaUserObject -SqlInstance sql2017, sql2005 83 | 84 | 85 | 86 | ########### 87 | 88 | $sqlconfiginstance = "ConfigInstance" 89 | 90 | # A comma delimited list of Host names 91 | $sqlhosts = "SQLDEV01", "sql1" 92 | 93 | # A comma-delimted list of SQL Server instances 94 | $sqlinstances = "SQLDEV01","sql1","SQLDEV01\SHAREPOINT", "sql1\DW" 95 | 96 | # Create DBAEstate database if not existing 97 | New-DbaDatabase -SqlInstance $sqlconfiginstance -Name DBAEstate 98 | 99 | # Put information about the SQL hosts into the DBAEstate database 100 | $splatWriteDataTable = @{ 101 | SqlInstance = $sqlconfiginstance 102 | Database = "DBAEstate" 103 | AutoCreateTable = $true 104 | } 105 | Get-DbaFeature -ComputerName $sqlhosts | 106 | Write-DbaDataTable @splatWriteDataTable -Table Features 107 | 108 | Get-DbaBuildReference -SqlInstance $sqlinstances | 109 | Write-DbaDataTable @splatWriteDataTable -Table SQLBuilds 110 | 111 | Get-DbaComputerSystem -ComputerName $sqlhosts | 112 | Write-DbaDataTable @splatWriteDataTable -Table ComputerSystem 113 | 114 | Get-DbaOperatingSystem -ComputerName $sqlhosts | 115 | Write-DbaDataTable @splatWriteDataTable -Table OperatingSystem 116 | 117 | Get-DbaDatabase -SqlInstance $sqlinstances | 118 | Write-DbaDataTable @splatWriteDataTable -Table Database 119 | 120 | Find-DbaUserObject -SqlInstance $sqlinstances | 121 | Write-DbaDataTable @splatWriteDataTable -Table UserObject 122 | 123 | ########### 124 | 125 | -------------------------------------------------------------------------------- /bookcode/chapter08.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 08 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Get-DbaRegServer | Invoke-DbaQuery -Query "SELECT @@VERSION" 19 | 20 | ########### 21 | 22 | Get-DbaRegServer 23 | 24 | 25 | ########### 26 | 27 | Get-DbaRegServer -Name sql01 | Get-DbaDatabase | 28 | Backup-DbaDatabase 29 | 30 | 31 | ########### 32 | 33 | $cred = Get-Credential sqladmin 34 | Get-DbaRegserver -SqlInstance dbainstance | 35 | Backup-DbaDatabase -SqlCredential $cred 36 | 37 | ########### 38 | 39 | Get-DbaRegServer -SqlInstance dbainstance 40 | 41 | 42 | ########### 43 | 44 | Import-Csv -Path C:\temp\regservers.csv 45 | 46 | ServerName Name Description Group 47 | 48 | ########### 49 | 50 | Import-Csv -Path C:\temp\regservers.csv | 51 | Import-DbaRegServer -SqlInstance sql2016 52 | 53 | 54 | ########### 55 | 56 | Get-DbaRegServer -SqlInstance sql2016 -Group Test\Dev 57 | 58 | 59 | ########### 60 | 61 | Get-DbaRegServer -SqlInstance sql2016 -ExcludeGroup Test\Dev 62 | 63 | 64 | ########### 65 | 66 | Get-DbaRegServer -SqlInstance dbainstance -IncludeLocal 67 | 68 | ########### 69 | 70 | Add-DbaRegServer -ServerName sql2017 71 | 72 | ########### 73 | 74 | $splatRegServer = @{ 75 | SqlInstance = "sqldb01" 76 | Group = "OnPrem" 77 | ServerName = "sql01" 78 | } 79 | Add-DbaRegServer @splatRegServer 80 | 81 | ########### 82 | 83 | $splatRegServer = @{ 84 | SqlInstance = "sqldb01" 85 | Group = "OnPrem\Accounting" 86 | ServerName = "sql01" 87 | } 88 | Add-DbaRegServer @splatRegServer 89 | 90 | ########### 91 | 92 | $splatConnect = @{ 93 | SqlInstance = "dockersql1,14333" 94 | SqlCredential = "sqladmin" 95 | } 96 | Connect-DbaInstance @splatConnect | Add-DbaRegServer -Description = "Container for AG tests" 97 | 98 | ########### 99 | 100 | Copy-DbaRegServer -Source sql2008 -Destination sql01 101 | 102 | # Export CMS list to an XML file 103 | $splatExportRegServer = @{ 104 | SqlInstance = "sql2008" 105 | Path = "C:\temp" 106 | OutVariable = file 107 | } 108 | Export-DbaRegServer @splatExportRegServer 109 | 110 | # Import CMS list from an XML file 111 | Import-DbaRegServer -SqlInstance sql01 -Path $file 112 | 113 | ########### 114 | 115 | Move-DbaRegServer -Name 'Web SQL Cluster' -Group HR\Prod 116 | 117 | ########### 118 | 119 | Get-DbaRegServer | Where Name -match HR | 120 | Move-DbaRegServer -Group HR\Prod 121 | 122 | ########### 123 | 124 | Remove-DbaRegServer -ServerName sql01 125 | 126 | ########### 127 | 128 | Get-DbaRegServer -ServerName sql2016, sql01 | 129 | Remove-DbaRegServer -Confirm:$false 130 | 131 | ########### 132 | 133 | -------------------------------------------------------------------------------- /bookcode/chapter09.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 09 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | $splatGetErrorLog = @{ 19 | SqlInstance = "SQL01" 20 | After = (Get-Date).AddMinutes(-5) 21 | } 22 | Get-DbaErrorLog @splatGetErrorLog | Select LogDate, Source, Text 23 | 24 | ########### 25 | 26 | New-DbaLogin -SqlInstance SQL01 -Login Factory 27 | 28 | ########### 29 | 30 | $servers = Get-DbaRegisteredServer 31 | New-DbaLogin -SqlInstance $servers -Login ad\factoryauditors 32 | 33 | ########### 34 | 35 | $servers = Get-DbaRegisteredServer 36 | $cred = Get-Credential factoryuser1 37 | $splatNewLogin = @{ 38 | SqlInstance = $servers 39 | Login = $cred.UserName 40 | SecurePassword = $cred.Password 41 | } 42 | New-DbaLogin @splatNewLogin 43 | 44 | ########### 45 | 46 | Get-DbaDbUser -SqlInstance SQL01 -Database WideWorldImporters | Select Name 47 | 48 | ########### 49 | 50 | Get-DbaDbUser -SqlInstance SQL01 -Database WideWorldImporters | Select Name 51 | 52 | ########### 53 | 54 | Repair-DbaDbOrphanUser -SqlInstance SQL01" 55 | 56 | ########### 57 | 58 | try { 59 | # Since this is running as an Agent job, use $ENV:ComputerName 60 | # to get the hostname of the server the job runs on 61 | $splatGetAgReplica = @{ 62 | SqlInstance = $ENV:ComputerName 63 | EnableException = $true 64 | } 65 | $replicas = (Get-DbaAgReplica $splatGetAgReplica).Name 66 | 67 | } 68 | catch { 69 | # Ensure SQL Agent shows a failed job 70 | Write-Error -Message $_ -ErrorAction Stop 71 | } 72 | 73 | foreach ($replica in $replicas) { 74 | Write-Output "For this replica $replica" 75 | $replicastocopy = $replicas | Where-Object { $_ -ne $replica } 76 | foreach ($replicatocopy in $replicastocopy) { 77 | Write-Output "We will copy logins from $replica to $replicatocopy" 78 | 79 | $splatCopyLogin = @{ 80 | Source = $replica 81 | Destination = $replicatocopy 82 | ExcludeSystemLogins = $true 83 | EnableException = $true 84 | } 85 | 86 | try { 87 | $output = Copy-DbaLogin @splatCopyLogin 88 | } catch { 89 | $error[0..5] | Format-List -Force | Out-String 90 | # Ensure SQL Agent shows a failed job 91 | Write-Error -Message $_ -ErrorAction Stop 92 | } 93 | if ($output.Status -contains 'Failed') { 94 | $error[0..5] | Format-List -Force | Out-String 95 | # Ensure SQL Agent shows a failed job 96 | Write-Error -Message "At least one login failed. 97 | [CA]See log for details." -ErrorAction Stop 98 | } 99 | } 100 | } 101 | 102 | ########### 103 | 104 | Export-DbaLogin -SqlInstance SQL01" 105 | 106 | ########### 107 | 108 | git init 109 | 110 | 111 | 112 | ########### 113 | 114 | $date = Get-Date 115 | $path = "$home\sourcerepo\SqlPermission" 116 | $file = "Factory.sql" 117 | Export-DbaLogin -SqlInstance SQL01" 118 | 119 | ########### 120 | 121 | Set-Location $path 122 | git add $file 123 | git commit -m "The Factory users update for $date" 124 | 125 | ########### 126 | 127 | Get-DbaUserPermission -SqlInstance SQL01 -Database WideWorldImporters | 128 | Select SqlInstance, Object, Type, Member, RoleSecurableClass | Format-Table" 129 | 130 | ########### 131 | 132 | $splatExportExcel = @{ 133 | Path = "C:\temp\FactoryPermissions.xlsx" 134 | WorksheetName = "User Permissions" 135 | AutoSize = $true 136 | FreezeTopRow = $true 137 | AutoFilter = $true 138 | PassThru = $true 139 | } 140 | 141 | $excel = Get-DbaUserPermission -SqlInstance SQL01 -Database WideWorldImporters | Export-Excel @splatExportExcel 142 | 143 | $rulesparam = @{ 144 | Address = $excel.Workbook.Worksheets["User Permissions"].Dimension.Address 145 | WorkSheet = $excel.Workbook.Worksheets["User Permissions"] 146 | RuleType = "Expression" 147 | } 148 | 149 | Add-ConditionalFormatting @rulesparam -ConditionValue 'NOT(ISERROR(FIND("sysadmin",$G1)))' -BackgroundColor Yellow -StopIfTrue 150 | 151 | Add-ConditionalFormatting @rulesparam -ConditionValue 'NOT(ISERROR(FIND("db_owner",$G1)))' -BackgroundColor Yellow -StopIfTrue 152 | 153 | Add-ConditionalFormatting @rulesparam -ConditionValue 'NOT(ISERROR(FIND("SERVER LOGINS",$E1)))' -BackgroundColor PaleGreen 154 | 155 | Add-ConditionalFormatting @rulesparam -ConditionValue 'NOT(ISERROR(FIND("SERVER SECURABLES",$E1)))' -BackgroundColor PowderBlue 156 | 157 | Add-ConditionalFormatting @rulesparam -ConditionValue 'NOT(ISERROR(FIND("DB ROLE MEMBERS",$E1)))' -BackgroundColor GoldenRod 158 | 159 | Add-ConditionalFormatting @rulesparam -ConditionValue 'NOT(ISERROR(FIND("DB SECURABLES",$E1)))' -BackgroundColor BurlyWood 160 | 161 | Close-ExcelPackage $excel 162 | 163 | ########### 164 | 165 | Find-DbaLoginInGroup -SqlInstance SQL01 -Login "ad\bmiller" 166 | 167 | ########### 168 | 169 | -------------------------------------------------------------------------------- /bookcode/chapter10.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 10 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Backup-DbaDatabase -SqlInstance sql01 19 | 20 | ########### 21 | 22 | Backup-DbaDatabase -SqlInstance sql01 -Path \\nas\sqlbackups 23 | 24 | 25 | ########### 26 | 27 | Backup-DbaDatabase -SqlInstance sql01 -Database pubs -BackupFileName NUL 28 | 29 | ########### 30 | 31 | $bigdbs = Get-DbaDatabase -SqlInstance sql01 | Where Name -match factory 32 | $bigdbs | Backup-DbaDatabase -Path \\nas\sqlbackups -OutputScriptOnly 33 | 34 | ########### 35 | 36 | $splatCredential = @{ 37 | SqlInstance = "sql01" 38 | Name = "https://acmecorp.blob.core.windows.net/backups" 39 | Identity = "SHARED ACCESS SIGNATURE" 40 | SecurePassword = (Get-Credential).Password 41 | } 42 | New-DbaCredential @splatCredential 43 | 44 | $splatBackup = @{ 45 | SqlInstance = "sql01" 46 | AzureBaseUrl = "https://acmecorp.blob.core.windows.net/backups/" 47 | Database = "mydb" 48 | BackupFileName = "mydb.bak" 49 | WithFormat = $true 50 | } 51 | Backup-DbaDatabase @splatBackup 52 | 53 | ########### 54 | 55 | $splatCredential = @{ 56 | SqlInstance = "sql01" 57 | Name = "AzureAccessKey" 58 | Identity = "acmecorp" 59 | SecurePassword = (Get-Credential).Password 60 | } 61 | New-DbaCredential @splatCredential 62 | 63 | $splatBackup = @{ 64 | SqlInstance = "sql01" 65 | AzureCredential = "AzureAccessKey" 66 | AzureBaseUrl = "https://acmecorp.blob.core.windows.net/backups/" 67 | Database = "mydb" 68 | } 69 | Backup-DbaDatabase @splatBackup 70 | 71 | ########### 72 | 73 | Backup-DbaDatabase -SqlInstance localhost:14433 -SqlCredential sqladmin 74 | -BackupDirectory /tmp 75 | 76 | ########### 77 | 78 | Backup-DbaDatabase -SqlInstance localhost:14433 -SqlCredential sqladmin 79 | -BackupDirectory /shared/backups 80 | 81 | ########### 82 | 83 | Read-DbaBackupHeader -SqlInstance sql01 -Path 84 | \\nas\sql\backups\mydb.bak 85 | 86 | ########### 87 | 88 | Get-DbaBackupInformation -SqlInstance sql01 -Path 89 | \\nas\sql\backups\sql01 90 | 91 | ########### 92 | 93 | Get-DbaDbBackupHistory -SqlInstance sql01 -Database pubs 94 | 95 | ########### 96 | 97 | Get-DbaDbBackupHistory -SqlInstance sql01 -Last 98 | 99 | ########### 100 | 101 | Find-DbaBackup -Path \\nas\sql\backups -BackupFileExtension bak 102 | -RetentionPeriod 90d | Remove-Item -Verbose 103 | 104 | ########### 105 | 106 | Find-DbaBackup -Path \\nas\sql\backups -BackupFileExtension trn 107 | -RetentionPeriod 90d | Remove-Item -Verbose 108 | 109 | ########### 110 | 111 | $query = "CREATE TABLE dbo.lastbackuptests ( 112 | SourceServer nvarchar(255), 113 | TestServer nvarchar(255), 114 | [Database] nvarchar(128), 115 | FileExists bit, 116 | Size bigint, 117 | RestoreResult nvarchar(4000), 118 | DbccResult nvarchar(4000), 119 | RestoreStart datetime, 120 | RestoreEnd datetime, 121 | RestoreElapsed nvarchar(128), 122 | DbccStart datetime, 123 | DbccEnd datetime, 124 | DbccElapsed nvarchar(128), 125 | BackupDates nvarchar(4000), 126 | BackupFiles nvarchar(4000))" 127 | Invoke-DbaQuery -SqlInstance sqltest -Database dbatools -Query $query 128 | 129 | $splatTestBackups = @{ 130 | SqlInstance = "sql01", "sql02" 131 | Destination = "sqltest" 132 | DataDirectory = "R:\" 133 | LogDirectory = "L:\" 134 | } 135 | Test-DbaLastBackup @splatTestBackups | Write-DbaDataTable -SqlInstance 136 | sqltest -Table dbatools.dbo.lastbackuptests 137 | 138 | ########### 139 | 140 | -------------------------------------------------------------------------------- /bookcode/chapter11.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 11 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Restore-DbaDatabase -SqlInstance sql01 -Path S:\backups\pubs.bak 19 | 20 | 21 | ########### 22 | 23 | Get-ChildItem \\nas\backups\mydb.bak | 24 | Restore-DbaDatabase -SqlInstance sql01 25 | 26 | ########### 27 | 28 | New-Item -Path 'C:\temp\sql' -Type Directory -Force 29 | $splatGetDatabase = @{ 30 | SqlInstance = "sql01" 31 | ExcludeDatabase = "tempdb", "master", "msdb" 32 | } 33 | $dbs = Get-DbaDatabase @splatGetDatabase 34 | $dbs | Backup-DbaDatabase -Path C:\temp\sql -Type Full 35 | $dbs | Backup-DbaDatabase -Path C:\temp\sql -Type Diff 36 | $dbs | Backup-DbaDatabase -Path C:\temp\sql -Type Log 37 | $dbs | Backup-DbaDatabase -Path C:\temp\sql -Type Log 38 | $dbs | Backup-DbaDatabase -Path C:\temp\sql -Type Log 39 | 40 | # See files, set the variable to $files, restore all files 41 | Get-ChildItem -Path C:\temp\sql -OutVariable files 42 | $files | Restore-DbaDatabase -SqlInstance sql01 -WithReplace 43 | 44 | ########### 45 | 46 | $splatRestoreDatabase = @{ 47 | SqlInstance = "sql01" 48 | Path = "C:\temp\sql\full.bak" 49 | WithReplace = $true 50 | OutputScriptOnly = $true 51 | } 52 | Restore-DbaDatabase @splatRestoreDatabase 53 | 54 | ########### 55 | 56 | $splatRestoreDb = @{ 57 | SqlInstance = "sql01" 58 | Path = "\\nas\sql01\mydb01.bak" 59 | DestinationDataDirectory = "D:\data" 60 | DestinationLogDirectory = "L:\log" 61 | } 62 | Restore-DbaDatabase @splatRestoreDb 63 | 64 | ########### 65 | 66 | $splatRestoreDb = @{ 67 | SqlInstance = "sql01" 68 | NoRecovery = $true 69 | } 70 | Restore-DbaDatabase @splatRestoreDb -Path C:\temp\sql\full.bak 71 | Restore-DbaDatabase @splatRestoreDb -Path C:\temp\sql\diff.bak 72 | 73 | ########### 74 | 75 | $splatRestoreDbFinal = @{ 76 | SqlInstance = "sql01" 77 | Path = "C:\temp\sql\trans.trn" 78 | Continue = $true 79 | } 80 | Restore-DbaDatabase @splatRestoreDbFinal 81 | 82 | ########### 83 | 84 | $splatRestoreDbRename = @{ 85 | SqlInstance = "sql01" 86 | Path = "C:\temp\sql\pubs.bak" 87 | DatabaseName = "Pestering" 88 | ReplaceDbNameInFile = $true 89 | } 90 | Restore-DbaDatabase @splatRestoreDbRename 91 | 92 | ########### 93 | 94 | $splatRestoreDbContinue = @{ 95 | SqlInstance = "sql01" 96 | Path = "\\nas\sql\sql01\mydb" 97 | RestoreTime = (Get-Date "2019-05-02 21:12:27") 98 | } 99 | Restore-DbaDatabase @splatRestoreDbContinue 100 | 101 | ########### 102 | 103 | $splatRestoreDb = @{ 104 | SqlInstance = "sql01" 105 | Database = "pubs" 106 | FilePath = "C:\temp\full.bak" 107 | } 108 | Backup-DbaDatabase @splatRestoreDb 109 | 110 | # Restore to the point right before the delete was executed 111 | $splatRestoreDbMark = @{ 112 | SqlInstance = "sql01" 113 | Path = "C:\temp\full.bak" 114 | StopMark = "DeleteCandidates" 115 | StopBefore = $true 116 | WithReplace = $true 117 | } 118 | Restore-DbaDatabase @splatRestoreDbMark 119 | 120 | ########### 121 | 122 | $corruption = Get-DbaSuspectPage -SqlInstance sql01 -Database pubs 123 | $splatRestoreDbPage = @{ 124 | SqlInstance = "sql01" 125 | Path = "\\nas\backups\sql\pubs.bak" 126 | PageRestore = $corruption 127 | PageRestoreTailFolder = "c:\temp" 128 | } 129 | Restore-DbaDatabase @splatRestoreDbPage 130 | 131 | ########### 132 | 133 | $splatRestoreDbFromAzure = @{ 134 | SqlInstance = "sql01" 135 | Path = "https://acmecorp.blob.core.windows.net/backups/mydb.bak" 136 | } 137 | Restore-DbaDatabase @splatRestoreDbFromAzure 138 | 139 | ########### 140 | 141 | $stripe = "https://acmecorp.blob.core.windows.net/backups/mydb-1.bak", 142 | "https://acmecorp.blob.core.windows.net/backups/mydb-2.bak", 143 | "https://acmecorp.blob.core.windows.net/backups/mydb-3.bak" 144 | $stripe | Restore-DbaDatabase -SqlInstance sql01 145 | 146 | ########### 147 | 148 | $splatRestoreDbFromAzureAK = @{ 149 | SqlInstance = "sql01" 150 | Path = "https://acmecorp.blob.core.windows.net/backups/mydb.bak" 151 | AzureCredential = "AzureAccessKey" 152 | } 153 | Restore-DbaDatabase @splatRestoreDbFromAzureAK 154 | 155 | ########### 156 | 157 | -------------------------------------------------------------------------------- /bookcode/chapter12.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 12 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | New-DbaDbSnapshot -SqlInstance mssql1 -Database AdventureWorks 19 | 20 | ########### 21 | 22 | Get-DbaProcess -SqlInstance mssql1 -Database AdventureWorks | 23 | Stop-DbaProcess 24 | $splatRestoreSnapshot = @{ 25 | SqlInstance = "mssql1" 26 | Snapshot = "AdventureWorks_20210530_071605" 27 | } 28 | Restore-DbaDbSnapshot @splatRestoreSnapshot 29 | 30 | ########### 31 | 32 | Get-DbaDbSnapshot -SqlInstance mssql1 -Database AdventureWorks | 33 | Remove-DbaDbSnapshot 34 | 35 | ########### 36 | 37 | -------------------------------------------------------------------------------- /bookcode/chapter13.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 13 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Install-DbaInstance -Path E:\ -Version 2017 19 | 20 | ########### 21 | 22 | $sqlserver = Get-ADComputer -Identity sql01 23 | $shareserver = Get-ADComputer -Identity fs01 24 | Set-ADComputer -Identity $shareserver -PrincipalsAllowedToDelegateToAccount $sqlserver 25 | # Wait 15 minutes or execute the following, which clears system tickets 26 | Invoke-Command -ComputerName sql01 -ScriptBlock { KLIST PURGE -LI 0x3e7 } 27 | 28 | ########### 29 | 30 | Install-DbaInstance -SqlInstance sql01 -Path \\fs01\share\sqlinstall -Version 2017 31 | 32 | ########### 33 | 34 | $cred = Get-Credential ad\sql01engine 35 | Get-DbaService -ComputerName sql01 | Out-GridView -Passthru | 36 | Update-DbaServiceAccount -ServiceCredential $cred 37 | 38 | ########### 39 | 40 | Get-Help -Name Install-DbaInstance -Detailed | 41 | Select -ExpandProperty Parameters 42 | 43 | ########### 44 | 45 | $config = @{ 46 | SQLSYSADMINACCOUNTS = "AD\SQL Prod Admins" 47 | SQLUSERDBDATADIR = "S:\Mounts\Data\MSSQL14.MSSQLSERVER\MSSQL\Data" 48 | SQLUSERDBLOGDIR = "S:\Mounts\Log\MSSQL14.MSSQLSERVER\MSSQL\Data" 49 | SQLTEMPDBDIR = "S:\Mounts\Tempdb\MSSQL14.MSSQLSERVER\MSSQL\Data" 50 | SQLBACKUPDIR = "\\nas\sqlprod\backups" 51 | TCPENABLED = "1" 52 | NPENABLED = "0" 53 | SQLSVCACCOUNT = "NT AUTHORITY\SYSTEM" 54 | AGTSVCACCOUNT = "NT AUTHORITY\SYSTEM" 55 | UPDATEENABLED = "True" 56 | UPDATESOURCE = "\\nas\sql\2017\update" 57 | } 58 | $splatInstallInst = @{ 59 | SqlInstance = "sql01" 60 | Path = "E:\" 61 | Version = "2017" 62 | Feature = "Engine" 63 | Configuration = $config 64 | } 65 | Install-DbaInstance @splatInstallInst 66 | 67 | ########### 68 | 69 | $config = @{ 70 | SQLSYSADMINACCOUNTS = "ADTEST\SQL Test Admins" 71 | SQLUSERDBDATADIR = "T:\Mounts\Data\MSSQL14.MSSQLSERVER\MSSQL\Data" 72 | SQLUSERDBLOGDIR = "T:\Mounts\Log\MSSQL14.MSSQLSERVER\MSSQL\Data" 73 | SQLTEMPDBDIR = "T:\Mounts\Tempdb\MSSQL14.MSSQLSERVER\MSSQL\Data" 74 | SQLBACKUPDIR = "\\nas\sqltest\backups" 75 | TCPENABLED = "1" 76 | NPENABLED = "0" 77 | } 78 | $splatInstallInst = @{ 79 | SqlInstance = "sqltest01" 80 | Path = "E:\" 81 | Version = "2017" 82 | Feature = "Engine" 83 | Configuration = $config 84 | } 85 | Install-DbaInstance @splatInstallInst 86 | 87 | ########### 88 | 89 | $splatInstallInst = @{ 90 | SqlInstance = "sql01" 91 | Path = "E:\" 92 | Version = "2017" 93 | ConfigurationFile = "\\nas\sqlconfigs\sharepointprod.ini" 94 | } 95 | Install-DbaInstance @splatInstallInst 96 | 97 | ########### 98 | 99 | #Note the dollar sign here on $installparams 100 | $installparams = @{ 101 | Version = 2017 102 | Feature = "Engine" 103 | InstancePath = "T:\Mounts\Data" 104 | DataPath = "T:\Mounts\Data\MSSQL14.MSSQLSERVER\MSSQL\Data" 105 | LogPath = "T:\Mounts\Log\MSSQL14.MSSQLSERVER\MSSQL\Data" 106 | TempPath = "T:\Mounts\Tempdb\MSSQL14.MSSQLSERVER\MSSQL\Data" 107 | BackupPath = "\\nas\sqltest\backups" 108 | AdminAccount = "ADTESTDEV\SQL Test Admins" 109 | PerformVolumeMaintenanceTasks = $true 110 | Verbose = $true 111 | Confirm = $false 112 | } 113 | #Note the at sign here @installparams 114 | Install-DbaInstance @installparams 115 | 116 | ########### 117 | 118 | #Get all computer names from a text file 119 | $servers = Get-Content -Path C:\temp\servers.txt 120 | $splatUpdateInst = @{ 121 | ComputerName = $servers 122 | Path = "\\nas\share\sqlserver2017-kb4498951-x64_b143d28a48204eb6.exe" 123 | } 124 | Update-DbaInstance @splatUpdateInst 125 | 126 | ########### 127 | 128 | $splatUpdateInst = @{ 129 | ComputerName = "sqlcluster" 130 | Version = "2017" 131 | Type = "CumulativeUpdate" 132 | Path = "C:\temp\sqlserver2017-kb4498951-x64_b143d28a48204eb6.exe" 133 | InstanceName = "sqlexpress" 134 | } 135 | Update-DbaInstance @splatUpdateInst 136 | 137 | ########### 138 | 139 | -------------------------------------------------------------------------------- /bookcode/chapter14.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 14 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Export-DbaInstance -SqlInstance sql01 -Path \\nas\backups\sql01 19 | 20 | ########### 21 | 22 | Get-ChildItem .\sql01-11112019080741\ 23 | 24 | 25 | 26 | ########### 27 | 28 | $options = New-DbaScriptingOption 29 | $options | Select * 30 | 31 | ########### 32 | 33 | $options = New-DbaScriptingOption 34 | $options.IncludeIfNotExists = $true 35 | 36 | ########### 37 | 38 | $splatExportInstance = @{ 39 | SqlInstance = "sql01" 40 | Path = "C:\git\ExportInstance" 41 | Exclude = "ResourceGovernor" 42 | } 43 | Export-DbaInstance @splatExportInstance 44 | 45 | ########### 46 | 47 | Get-DbaAgentJob -SqlInstance sql01 | Select-Object -First 1 | 48 | Export-DbaScript 49 | 50 | 51 | ########### 52 | 53 | Get-DbaDbStoredProcedure -SqlInstance sql01 -Database master | 54 | Where-Object Name -eq sp_MScleanupmergepublisher | 55 | Export-DbaScript -Passthru 56 | 57 | ########### 58 | 59 | Get-DbaAgentJob -SqlInstance sql01 | Select-Object -First 1 | 60 | Export-DbaScript | clip 61 | 62 | ########### 63 | 64 | $options = New-DbaScriptingOption 65 | $options.includeifnotexists = $true 66 | $splatExportScript = @{ 67 | FilePath = "C:\git\export\sql01\audit.sql" 68 | ScriptingOptionsObject = $options 69 | } 70 | Get-DbaInstanceAudit -SqlInstance sql01 | 71 | Export-DbaScript @splatExportScript 72 | 73 | 74 | ########### 75 | 76 | $splatExportScript = @{ 77 | FilePath = "C:\git\export\sql01\auditspec.sql" 78 | ScriptingOptionsObject = $options 79 | } 80 | Get-DbaInstanceAuditSpecification -SqlInstance sql01 | 81 | Export-DbaScript @splatExportScript 82 | 83 | 84 | ########### 85 | 86 | Get-DbaAgentJob -SqlInstance sql01 | Get-Member 87 | 88 | 89 | ########### 90 | 91 | Get-DbaSpConfigure -SqlInstance sql01 | Get-Member 92 | 93 | 94 | ########### 95 | 96 | $splatExportSpConf = @{ 97 | SqlInstance = "sql01" 98 | FilePath = "C:\git\ExportInstance\spconfigure.sql" 99 | } 100 | Export-DbaSpConfigure @splatExportSpConf 101 | 102 | ########### 103 | 104 | $splatExportSpConf = @{ 105 | SqlInstance = "sql01,15591" 106 | SqlCredential = "sqladmin" 107 | Path = "C:\git\ExportInstance\spconfigure.sql" 108 | } 109 | Import-DbaSpConfigure @splatExportSpConf 110 | 111 | ########### 112 | 113 | -------------------------------------------------------------------------------- /bookcode/chapter15.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 15 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Start-DbaMigration -Source sql01 -Destination sql02 -BackupRestore -SharedPath \\nas\sql\migration 19 | 20 | ########### 21 | 22 | $copySplat = @{ 23 | Source = "sql01" 24 | Destination = "sql02" 25 | Database = "WideWorldImporters" 26 | SharedPath = "\\nas\sql\migration" 27 | BackupRestore = $true 28 | } 29 | Copy-DbaDatabase @copySplat 30 | 31 | ########### 32 | 33 | $copySplat = @{ 34 | Source = "sql01" 35 | Destination = "sql02" 36 | AllDatabases = $true 37 | SharedPath = "\\nas\sql\migration" 38 | BackupRestore = $true 39 | } 40 | Copy-DbaDatabase @copySplat 41 | 42 | ########### 43 | 44 | $copySplat = @{ 45 | Source = "sql01" 46 | Destination = "sql02" 47 | Database = "WideWorldImporters" 48 | SharedPath = "\\nas\sql\migration" 49 | BackupRestore = $true 50 | SetSourceOffline = $true 51 | } 52 | Copy-DbaDatabase @copySplat 53 | 54 | ########### 55 | 56 | $copySplat = @{ 57 | Source = "sql01" 58 | Destination = "sql02" 59 | Database = "WideWorldImporters" 60 | DetachAttach = $true 61 | } 62 | Copy-DbaDatabase @copySplat 63 | 64 | ########### 65 | 66 | $copySplat = @{ 67 | Source = "sql01" 68 | Destination = "sql02" 69 | Database = "WideWorldImporters" 70 | DetachAttach = $true 71 | Reattach = $true 72 | } 73 | Copy-DbaDatabase @copySplat 74 | 75 | ########### 76 | 77 | $copySplat = @{ 78 | Source = "sql01" 79 | Destination = "sql02" 80 | Database = "WideWorldImporters" 81 | SharedPath = "\\nas\sql\migration" 82 | BackupRestore = $true 83 | NoRecovery = $true 84 | NoCopyOnly = $true 85 | } 86 | Copy-DbaDatabase @copySplat 87 | 88 | ########### 89 | 90 | $diffSplat = @{ 91 | SqlInstance = "sql01" 92 | Database = "WideWorldImporters" 93 | Path = "\\nas\sql\migration" 94 | Type = "Differential" 95 | } 96 | $diff = Backup-DbaDatabase @diffSplat 97 | 98 | # Set the source database offline 99 | $offlineSplat = @{ 100 | SqlInstance = "sql01" 101 | Database = "WideWorldImporters" 102 | Offline = $true 103 | Force = $true 104 | } 105 | Set-DbaDbState @offlineSplat 106 | 107 | # restore the differential and bring the destination online 108 | $restoreSplat = @{ 109 | SqlInstance = "sql02" 110 | Database = "WideWorldImporters" 111 | Path = $diff.Path 112 | Continue = $true 113 | } 114 | Restore-DbaDatabase @restoreSplat 115 | 116 | ########### 117 | 118 | $tableSplat = @{ 119 | SqlInstance = "sql01" 120 | Database = "WideWorldImporters" 121 | Name = "MigrationTestTable" 122 | ColumnMap = @{ 123 | Name = "test" 124 | Type = "varchar" 125 | MaxLength = 20 126 | Nullable = $true 127 | } 128 | } 129 | New-DbaDbTable @tableSplat 130 | 131 | ########### 132 | 133 | $params = @{ 134 | Source = "mssql1" 135 | Destination = "mssql2" 136 | Database = "Northwind" 137 | SharedPath = "\\nas\sql\shipping" 138 | } 139 | Invoke-DbaDbLogShipping @params 140 | 141 | # Then cutover 142 | Invoke-DbaDbLogShipRecovery -SqlInstance mssql2 -Database Northwind 143 | 144 | ########### 145 | 146 | -------------------------------------------------------------------------------- /bookcode/chapter16.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 16 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | $copyLoginSplat = @{ 19 | Source = "sql01" 20 | Destination = "sql02" 21 | Login = "WWI_Owner","WWI_ReadWrite","WWI_ReadOnly", 22 | [CA]"ad\JaneReeves" 23 | } 24 | Copy-DbaLogin @copyLoginSplat 25 | 26 | 27 | ########### 28 | 29 | $dbSplat = @{ 30 | SqlInstance = "sql02" 31 | ExcludeSystem = $true 32 | OutVariable = "databases" 33 | } 34 | Get-DbaDatabase @dbSplat 35 | 36 | $databases 37 | 38 | ########### 39 | 40 | $copyLoginSplat = @{ 41 | Source = "sql01" 42 | Destination = "sql02" 43 | ExcludeSystemLogins = $true 44 | } 45 | Copy-DbaLogin @copyLoginSplat 46 | 47 | 48 | ########### 49 | 50 | $copyLoginSplat = @{ 51 | Source = "sql01" 52 | Destination = "sql02" 53 | ExcludeLogin = "ad\JaneReeves" 54 | } 55 | Copy-DbaLogin @copyLoginSplat 56 | 57 | ########### 58 | 59 | Get-DbaAgentJob -SqlInstance sql01 | select-Object SqlInstance, Name, Category 60 | 61 | 62 | ########### 63 | 64 | $copyJobSplat = @{ 65 | Source = "sql01" 66 | Destination = "sql02" 67 | Job = 'dbatools lab job','dbatools lab job - where am I' 68 | DisableOnSource = $true 69 | } 70 | Copy-DbaAgentJob @copyJobSplat 71 | 72 | 73 | ########### 74 | 75 | $copyJobOperatorSplat = @{ 76 | Source = "sql01" 77 | Destination = "sql02" 78 | Operator = 'dba' 79 | } 80 | Copy-DbaAgentOperator @copyJobOperatorSplat 81 | 82 | 83 | ########### 84 | 85 | $copyJobSplat = @{ 86 | Source = "sql01" 87 | Destination = "sql02" 88 | Job = 'dbatools lab job','dbatools lab job - where am I' 89 | DisableOnSource = $true 90 | } 91 | Copy-DbaAgentJob @copyJobSplat 92 | 93 | 94 | ########### 95 | 96 | $copyMessageSplat = @{ 97 | Source = "sql01" 98 | Destination = "sql02" 99 | CustomError = 50005 100 | } 101 | Copy-DbaCustomError @copyMessageSplat 102 | 103 | 104 | ########### 105 | 106 | $copyAlertSplat = @{ 107 | Source = "sql01" 108 | Destination = "sql02" 109 | Alert = 'FactoryApp - Custom Alert' 110 | } 111 | Copy-DbaAgentAlert @copyAlertSplat 112 | 113 | 114 | ########### 115 | 116 | Get-DbaAgentJob -SqlInstance sql01 | 117 | Out-GridView -Passthru | 118 | Copy-DbaAgentJob -Destination dbatoolslab 119 | 120 | ########### 121 | 122 | $copyLinkedServerSplat = @{ 123 | Source = "sql01" 124 | Destination = "sql02" 125 | } 126 | Copy-DbaLinkedServer @copyLinkedServerSplat 127 | 128 | 129 | ########### 130 | 131 | Get-Command -Module dbatools -Verb Copy 132 | 133 | ########### 134 | 135 | -------------------------------------------------------------------------------- /bookcode/chapter17.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 17 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | $params = @{ 19 | SourceSqlInstance = "dbatoolslab\sql2017" 20 | DestinationSqlInstance = "dbatoolslab" 21 | Database = "AdventureWorks" 22 | SharedPath= "\\dbatoolslab\logship" 23 | } 24 | Invoke-DbaDbLogShipping @params 25 | 26 | 27 | ########### 28 | 29 | $params = @{ 30 | SourceSqlInstance = "dbatoolslab\sql2017" 31 | DestinationSqlInstance = "dbatoolslab" 32 | Database = "AdventureWorks","WideWorldImporters" 33 | SharedPath= "\\dbatoolslab\logship" 34 | } 35 | Invoke-DbaDbLogShipping @params 36 | 37 | ########### 38 | 39 | Get-DbaDbLogShipError -SqlInstance dbatoolslab\sql2017, dbatoolslab | 40 | Select-Object SqlInstance, LogTime, Message 41 | 42 | 43 | 44 | ########### 45 | 46 | $logShipSplat = @{ 47 | SqlInstance = "dbatoolslab" 48 | Database = "AdventureWorks" 49 | } 50 | Invoke-DbaDbLogShipRecovery @logShipSplat 51 | 52 | 53 | ########### 54 | 55 | $logShipSplat = @{ 56 | SqlInstance = "dbatoolslab" 57 | Database = "AdventureWorks","WideWorldImporters" 58 | } 59 | Invoke-DbaDbLogShipRecovery @logShipSplat 60 | 61 | ########### 62 | 63 | Get-Command *wsfc* -Module dbatools 64 | 65 | 66 | ########### 67 | 68 | Get-DbaWsfcNode -ComputerName sql1 69 | 70 | 71 | ########### 72 | 73 | Get-DbaWsfcResource -ComputerName sql1 | 74 | Select-Object ClusterName, Name, State, Type, OwnerGroup, OwnerNode | 75 | Format-Table 76 | 77 | 78 | ########### 79 | 80 | $agSplat = @{ 81 | Primary = "sql1" 82 | Secondary = "sql2" 83 | Name = "agpoc01" 84 | Database = "AdventureWorks" 85 | ClusterType = "Wsfc" 86 | SharedPath = "\\sql1\backup" 87 | } 88 | New-DbaAvailabilityGroup @agsplat 89 | 90 | 91 | ########### 92 | 93 | $sql1 = Connect-DbaInstance -SqlInstance = "sql01,15592" -SqlCredential sa 94 | $sql1 95 | 96 | 97 | ########### 98 | 99 | Get-DbaAvailabilityGroup -SqlInstance $sql1 100 | 101 | 102 | ########### 103 | 104 | Get-DbaAgReplica -SqlInstance $sql1 | Select-Object SqlInstance, 105 | AvailabilityGroup, Name, Role, AvailabilityMode, FailoverMode 106 | 107 | 108 | ########### 109 | 110 | Get-DbaAgDatabase -SqlInstance $sql1 111 | 112 | ########### 113 | 114 | Invoke-DbaAgFailover -SqlInstance $sql2 -AvailabilityGroup ACME_01 115 | 116 | ########### 117 | 118 | Suspend-DbaAgDbDataMovement -SqlInstance $sql1 -AvailabilityGroup ACME_01 119 | 120 | ########### 121 | 122 | Resume-DbaAgDbDataMovement -SqlInstance $sql1 -AvailabilityGroup ACME_01 123 | 124 | ########### 125 | 126 | -------------------------------------------------------------------------------- /bookcode/chapter18.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 18 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | $PSDefaultParameterValues["Get-DbaDatabase:SqlInstance"] = "sql01" 19 | 20 | ########### 21 | 22 | $PSDefaultParameterValues['*-Dba*:EnableException'] = $true 23 | 24 | ########### 25 | 26 | $splatSetAgent = @{ 27 | SqlInstance = "sql1" 28 | MaximumHistoryRows = 10000 29 | MaximumJobHistoryRows = 100 30 | } 31 | Set-DbaAgentServer @splatSetAgent 32 | 33 | ########### 34 | 35 | $date = Get-Date -Format FileDateTime 36 | Start-Transcript -Path "\\loggingserver\sql01\filelist-$date.txt" 37 | Get-ChildItem -Path C:\ 38 | Stop-Transcript 39 | 40 | ########### 41 | 42 | -------------------------------------------------------------------------------- /bookcode/chapter19.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 19 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Get-DbaAgentJob -SqlInstance sql01 19 | 20 | 21 | ########### 22 | 23 | Get-DbaAgentJob -SqlInstance SQL01 -Database dbachecks 24 | 25 | 26 | 27 | ########### 28 | 29 | Get-DbaAgentAlert -SqlInstance SQL01 30 | 31 | 32 | ########### 33 | 34 | $NotRaised = Get-Date -Date '01-01-0001 00:00:00' 35 | Get-DbaAgentAlert -SqlInstance SQL01 | 36 | Where-Object LastRaised -ne $NotRaised 37 | 38 | 39 | ########### 40 | 41 | Get-DbaAgentOperator -SqlInstance SQL01 42 | 43 | 44 | ########### 45 | 46 | $instances = "SQL01","SQL02","SQL03","SQL04","SQL05" 47 | Find-DbaAgentJob -SqlInstance $instances -JobName *FTP* 48 | 49 | 50 | ########### 51 | 52 | $splatFindAgentJob = @{ 53 | SqlInstance = 'SQL01','SQL02','SQL03','SQL04','SQL05' 54 | JobName = "*Integrity*" 55 | IsNotScheduled = $true 56 | } 57 | Find-DbaAgentJob @splatFindAgentJob 58 | 59 | 60 | ########### 61 | 62 | Find-DbaAgentJob -SqlInstance $instances -JobName *ftp* | 63 | Select SqlInstance, JobName, LastRunDate, LastRunOutcome 64 | 65 | 66 | ########### 67 | 68 | $midnight = [datetime]::Today 69 | Find-DbaAgentJob -SqlInstance $instances -JobName *ftp* | 70 | Get-DbaAgentJobHistory -StartDate $midnight 71 | 72 | 73 | ########### 74 | 75 | $threeDaysAgo = [datetime]::Today.AddDays(-3) 76 | Find-DbaAgentJob -SqlInstance sql01 | 77 | Get-DbaAgentJobHistory -StartDate $threeDaysAgo | 78 | ConvertTo-DbaTimeline | 79 | Out-File -FilePath c:\temp\jobs.html -Encoding ASCII 80 | 81 | ########### 82 | 83 | -------------------------------------------------------------------------------- /bookcode/chapter20.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 20 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Get-Command -Module dbatools -Verb New, Set, Remove -Noun *Agent* 19 | 20 | 21 | ########### 22 | 23 | New-DbaAgentJobCategory -SqlInstance SQL01 -Category PastaFactory 24 | 25 | 26 | ########### 27 | 28 | $schedulesplat = @{ 29 | FrequencyType = 'Daily' 30 | SqlInstance = 'SQL01' 31 | Schedule = 'Daily-Midnight' 32 | Force = $true 33 | StartTime = '000327' 34 | FrequencyInterval = 'Everyday' 35 | } 36 | New-DbaAgentSchedule @schedulesplat 37 | 38 | ########### 39 | 40 | $schedulesplat = @{ 41 | FrequencyType = 'Monthly' 42 | SqlInstance = 'SQL01' 43 | Schedule = 'Monthly-1st-Midnight' 44 | Force = $true 45 | StartTime = '000248' 46 | FrequencyInterval = 1 47 | } 48 | New-DbaAgentSchedule @schedulesplat 49 | 50 | ########### 51 | 52 | $schedulesplat = @{ 53 | FrequencyType = 'Weekly' 54 | FrequencyInterval = 'Weekdays' 55 | SqlInstance = 'SQL01' 56 | Schedule = 'WorkingWeek-Every-15-Minute' 57 | Force = $true 58 | StartTime = '070036' 59 | EndTime = '180000' 60 | FrequencySubdayInterval = 15 61 | FrequencySubdayType = 'Minutes' 62 | } 63 | New-DbaAgentSchedule @schedulesplat 64 | 65 | ########### 66 | 67 | $credential = Get-Credential -Message "Enter the Username and 68 | Password for the credential" 69 | # Create a new SQL credential 70 | $credsplat = @{ 71 | SqlInstance = 'SQL01' 72 | SecurePassword = $credential.Password 73 | Name = 'FactoryProcess' 74 | Identity = $credential.UserName 75 | } 76 | New-DbaCredential @credsplat 77 | 78 | # Create a new Proxy 79 | $proxysplat = @{ 80 | SqlInstance = 'SQL01' 81 | ProxyCredential = 'FactoryProcess' 82 | Name = 'FactoryProcess' 83 | Description = 'Proxy account to run the Factory processing using the 84 | ad\FactoryProcesss account' 85 | SubSystem = 'CmdExec' 86 | } 87 | 88 | New-DbaAgentProxy @proxysplat 89 | 90 | ########### 91 | 92 | $operatorSplat = @{ 93 | SqlInstance = 'SQL01' 94 | Operator = 'DBA Team' 95 | EmailAddress = 'operator@dbateam.com' 96 | } 97 | New-DbaAgentOperator @operatorsplat 98 | 99 | 100 | ########### 101 | 102 | $jobsplat = @{ 103 | SqlInstance = 'SQL01' 104 | Description = 'This Job processes all of the Italian factories sales 105 | data in the FactorySales database and creates all of the aggregrations. 106 | Contact G Sartori for questions.' 107 | Category = 'PastaFactory' 108 | EmailOperator = 'DBA Team' 109 | Job = 'Factory Data Processing' 110 | Schedule = 'WorkingWeek-Every-3-Hours' 111 | EventLogLevel = 'OnFailure' 112 | EmailLevel = 'OnFailure' 113 | OwnerLogin = 'ad\FactoryProcesss' 114 | } 115 | New-DbaAgentJob @jobsplat 116 | 117 | 118 | ########### 119 | 120 | $stepcommand = 'EXEC Process_Factory_Sales @Factory="Pasta"' 121 | $stepsplat = @{ 122 | StepId = 1 123 | Subsystem = 'TransactSql' 124 | SqlInstance = 'SQL01' 125 | StepName = ' Process Pasta Factory Data' 126 | OnSuccessAction = 'GoToNextStep' 127 | Job = 'Factory Data Processing' 128 | Command = $stepcommand 129 | OnFailAction = 'QuitWithFailure' 130 | Database = 'FactorySales' 131 | } 132 | New-DbaAgentJobStep @stepsplat 133 | 134 | $stepcommand = 'EXEC Process_Factory_Sales @Factory="Pizza"' 135 | $stepsplat = @{ 136 | StepId = 2 137 | Subsystem = 'TransactSql' 138 | SqlInstance = 'SQL01' 139 | StepName = ' Process Pizza Factory Data' 140 | OnSuccessAction = 'GoToNextStep' 141 | Job = 'Factory Data Processing' 142 | Command = $stepcommand 143 | OnFailAction = 'QuitWithFailure' 144 | Database = 'FactorySales' 145 | } 146 | New-DbaAgentJobStep @stepsplat 147 | 148 | $stepcommand = 'EXEC Process_Factory_Sales @Factory="Sausage"' 149 | $stepsplat = @{ 150 | StepId = 3 151 | Subsystem = 'TransactSql' 152 | SqlInstance = 'SQL01' 153 | StepName = ' Process Sausage Factory Data' 154 | OnSuccessAction = 'GoToNextStep' 155 | Job = 'Factory Data Processing' 156 | Command = $stepcommand 157 | OnFailAction = 'QuitWithFailure' 158 | Database = 'FactorySales' 159 | } 160 | New-DbaAgentJobStep @stepsplat 161 | 162 | $stepcommand = 'EXEC Process_Factory_Sales @Factory="Sauce"' 163 | $stepsplat = @{ 164 | StepId = 4 165 | Subsystem = 'TransactSql' 166 | SqlInstance = 'SQL01' 167 | StepName = ' Process Sauce Factory Data' 168 | OnSuccessAction = 'QuitWithSuccess' 169 | Job = 'Factory Data Processing' 170 | Command = $stepcommand 171 | OnFailAction = 'QuitWithFailure' 172 | Database = 'FactorySales' 173 | } 174 | New-DbaAgentJobStep @stepsplat 175 | 176 | ########### 177 | 178 | $splatGetJobStep = @{ 179 | SqlInstance = "SQL01" 180 | Job = 'Factory Data Processing' 181 | } 182 | Get-DbaAgentJobStep @splatGetJobStep | Format-Table 183 | 184 | 185 | ########### 186 | 187 | $jobname = 'Copy logins from model' 188 | $jobsplat = @{ 189 | SqlInstance = 'SQL02' 190 | Category = 'DBA-Model' 191 | Description = 'Copies logins from the model instance to this instance' 192 | OwnerLogin = 'ad\DBA' 193 | Job = $jobname 194 | EmailOperator = 'DBA Team' 195 | Schedule = 'Daily-Midnight' 196 | EventLogLevel = 'OnFailure' 197 | EmailLevel = 'OnFailure' 198 | Force = $true 199 | } 200 | New-DbaAgentJob @jobsplat 201 | 202 | $command = 'powershell.exe -File C:\AgentScripts\CopyFromModel.ps1' 203 | $stepsplat = @{ 204 | SqlInstance = 'SQL02' 205 | Subsystem = 'CmdExec' 206 | Command = $command 207 | StepName = 'Copy Logins' 208 | Job = $jobname 209 | ProxyName = 'PowerShell Proxy' 210 | Flag = 'AppendAllCmdExecOutputToJobHistory' 211 | } 212 | New-DbaAgentJobStep @stepsplat 213 | 214 | ########### 215 | 216 | $splatGetJob = @{ 217 | SqlInstance = "SQL02", "SQL2017N20" 218 | Job = 'Factory Data Processing' 219 | } 220 | Get-DbaAgentJob @splatGetJob | Start-DbaAgentJob 221 | 222 | 223 | ########### 224 | 225 | Get-DbaRegisteredServer | Get-DbaRunningJob 226 | 227 | 228 | ########### 229 | 230 | Get-DbaRunningJob -SqlInstance SQL02, SQL2017N20 231 | 232 | ########### 233 | 234 | $splatGetJobHist = @{ 235 | SqlInstance = "SQL02" 236 | Job = 'Copy logins from model' 237 | } 238 | Get-DbaAgentJobHistory @splatGetJobHist 239 | 240 | 241 | ########### 242 | 243 | -------------------------------------------------------------------------------- /bookcode/chapter21.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 21 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | # Generate a random datetime value for the year 2021 19 | $splatGetRandValueDT = @{ 20 | Datatype = "datetime" 21 | Min = "2021-01-01" 22 | Max = "2021-12-31 23:59:59" 23 | } 24 | Get-DbaRandomizedValue @splatGetRandValueDT 25 | 26 | # Generate a random IP value 27 | $splatGetRandValueIP = @{ 28 | RandomizerType = "Internet" 29 | RandomizerSubType = "IP" 30 | } 31 | Get-DbaRandomizedValue @splatGetRandValueIP 32 | 33 | ########### 34 | 35 | Invoke-DbaDbPiiScan -SqlInstance mssql1 -Database AdventureWorks 36 | 37 | 38 | ########### 39 | 40 | Invoke-DbaDbPiiScan -SqlInstance mssql1 -Database AdventureWorks 41 | 42 | 43 | ########### 44 | 45 | Invoke-DbaDbPiiScan -SqlInstance mssql1 -Database AdventureWorks -SampleCount 200 46 | 47 | ########### 48 | 49 | New-DbaDbMaskingConfig -SqlInstance mssql1 -Database AdventureWorks -Table Address -Column City, PostalCode -Path D:\temp 50 | 51 | ########### 52 | 53 | Invoke-DbaDbDataMasking -SqlInstance mssql1 -Database dbatools -FilePath "D:\temp\mssql1.AdventureWorks.DataMaskingConfig.json" 54 | 55 | ########### 56 | 57 | -------------------------------------------------------------------------------- /bookcode/chapter22.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 22 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | $splatExportDacPac = @{ 19 | SqlInstance = $ProductionFactoryInstance 20 | Database = "Factory" 21 | FilePath = "C:\temp\ProdFactory_20201230.dacpac" 22 | } 23 | Export-DbaDacPackage @splatExportDacPac 24 | 25 | ########### 26 | 27 | $splatExportDacPac = @{ 28 | SqlInstance = $ProductionFactoryInstance 29 | Database = "Factory" 30 | Path = "C:\temp\ProdFactory_20201230.dacpac" 31 | } 32 | Export-DbaDacPackage @splatExportDacPac 33 | 34 | ########### 35 | 36 | $splatPublishDacPac = @{ 37 | SqlInstance = $developercontainer 38 | Database = "FactoryIssue" 39 | Path = "C:\temp\ProdFactory_20201230.dacpac" 40 | } 41 | Publish-DbaDacPackage @splatPublishDacPac 42 | 43 | ########### 44 | 45 | $dacoptions = New-DbaDacOption -Type DACPAC -Action Publish 46 | $dacoptions.DeployOptions.ExcludeObjectTypes = "Users","RoleMembership" ,"Logins" 47 | $splatPublishDacPacNoUsers = @{ 48 | SqlInstance = $developercontainer 49 | Database = "FactoryIssue" 50 | FilePath = "C:\temp\ProdFactory_20201230.dacpac" 51 | DacOption = $dacoptions 52 | } 53 | Publish-DbaDacPackage @splatPublishDacPacNoUsers 54 | 55 | ########### 56 | 57 | $splatNewDacProfile = @{ 58 | SqlInstance = "sql01" 59 | Database = "Factory" 60 | Path = "c:\temp" 61 | PublishOptions = @{ 62 | IgnoreUserLoginMappings = $true 63 | IgnorePermissions = $true 64 | ExcludeObjectTypes = 'Users;RoleMembership;Logins' 65 | ExcludeLogins = $true 66 | ExcludeUsers = $true 67 | IgnoreUserSettingsObjects = $true 68 | } 69 | } 70 | New-DbaDacProfile @splatNewDacProfile 71 | 72 | ########### 73 | 74 | -------------------------------------------------------------------------------- /bookcode/chapter23.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 23 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Get-DbaTrace -SqlInstance sql01, sql02, sql03 19 | 20 | ########### 21 | 22 | Get-DbaRegisteredServer | Get-DbaTrace 23 | 24 | 25 | ########### 26 | 27 | Get-DbaRegisteredServer | Get-DbaTrace | 28 | Out-GridView -PassThru | Start-DbaTrace 29 | 30 | ########### 31 | 32 | Get-DbaTrace -SqlInstance sql2014 | Where-Object Id -eq 1 | 33 | ConvertTo-DbaXESession -Name 'Converted Default Trace' | 34 | Start-DbaXESession 35 | 36 | 37 | ########### 38 | 39 | Find-DbaCommand -Tag ExtendedEvent 40 | 41 | ########### 42 | 43 | Get-DbaRegServer | Get-DbaXESession 44 | 45 | ########### 46 | 47 | Get-DbaXESession -SqlInstance mssql1 -Session telemetry_xevents 48 | 49 | 50 | ########### 51 | 52 | Get-DbaXESessionTemplate 53 | 54 | 55 | ########### 56 | 57 | Get-DbaXESessionTemplate -Template 'Deprecated Feature Usage' | 58 | Import-DbaXESessionTemplate -SqlInstance mssql1 | 59 | Start-DbaXESession 60 | 61 | 62 | ########### 63 | 64 | Get-ChildItem 'C:\temp\Login Tracker.xml' | 65 | Import-DbaXESessionTemplate -SqlInstance mssql1 66 | 67 | 68 | ########### 69 | 70 | Start-DbaXESession -SqlInstance mssql1 -Session "Query Timeouts" 71 | 72 | 73 | ########### 74 | 75 | Stop-DbaXESession -SqlInstance mssql1 -Session "Query Timeouts" 76 | 77 | 78 | ########### 79 | 80 | Start-DbaXESession -SqlInstance mssql1 -Session 'Query Timeouts' -StopAt (Get-Date).AddMinutes(30) 81 | 82 | ########### 83 | 84 | Watch-DbaXESession -SqlInstance mssql1 -Session QuickSessionStandard | 85 | Where-Object client_app_name -match dbatools 86 | 87 | 88 | ########### 89 | 90 | Read-DbaXEFile -Path C:\temp\deadocks.xel 91 | 92 | ########### 93 | 94 | $splatCopyXESession = @{ 95 | Source = "mssql1" 96 | Destination = "mssql2", "mssql3" 97 | XeSession = "Login Tracker" 98 | } 99 | Copy-DbaXESession @splatCopyXESession 100 | 101 | ########### 102 | 103 | -------------------------------------------------------------------------------- /bookcode/chapter24.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 24 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | $splatCert = @{ 19 | ComputerName = "sql1" 20 | Dns = "sql1.ad.local", "sql1" 21 | } 22 | New-DbaComputerCertificate $splatCert 23 | 24 | 25 | ########### 26 | 27 | $splatCSR = @{ 28 | ComputerName = "sql1" 29 | Dns = "sql1.ad.local", "sql1" 30 | } 31 | New-DbaComputerCertificateSigningRequest $splatCSR 32 | 33 | 34 | ########### 35 | 36 | Get-DbaComputerCertificate -ComputerName sql1 37 | 38 | 39 | ########### 40 | 41 | $splatSetCertificate = @{ 42 | SqlInstance = "sql1" 43 | Thumbprint = "1245FB1ACBCA44D3EE9640F81B6BA14A92F3D6E2" 44 | } 45 | Set-DbaNetworkCertificate @splatSetCertificate 46 | 47 | ########### 48 | 49 | Get-DbaComputerCertificate | Out-GridView -PassThru | 50 | Set-DbaNetworkCertificate -SqlInstance sql1 51 | 52 | ########### 53 | 54 | Enable-DbaForceNetworkEncryption -SqlInstance sql1 55 | 56 | ########### 57 | 58 | Set-DbaExtendedProtection -SqlInstance sql1 -Value Required 59 | 60 | ########### 61 | 62 | Test-DbaSpn -ComputerName sql1 63 | 64 | 65 | ########### 66 | 67 | Test-DbaSpn -ComputerName sql1 | 68 | Where-Object isSet -eq $false | 69 | Set-DbaSpn 70 | 71 | ########### 72 | 73 | Enable-DbaHideInstance -SqlInstance sql1 74 | 75 | ########### 76 | 77 | Connect-DbaInstance -SqlInstance sql01:12345 78 | # This also works but note you must use single or double quotes 79 | Connect-DbaInstance -SqlInstance "sql01,12345" 80 | # Or use a colon without quotes and we'll translate it for you 81 | Connect-DbaInstance -SqlInstance sql01:12345 82 | 83 | ########### 84 | 85 | $masterkeypass = (Get-Credential nobody).Password 86 | $certbackuppass = (Get-Credential nobody).Password 87 | $splatEncrypt = @{ 88 | SqlInstance = "sql1" 89 | MasterKeySecurePassword = $masterkeypass 90 | BackupSecurePassword = $certbackuppass 91 | BackupPath = "/tmp" 92 | AllUserDatabases = $true 93 | } 94 | Start-DbaDbEncryption @splatEncrypt 95 | 96 | ########### 97 | 98 | $masterkeypass = (Get-Credential nobody).Password 99 | $certbackuppass = (Get-Credential nobdody).Password 100 | $splatdbEncrypt = @{ 101 | MasterKeySecurePassword = $masterkeypass 102 | BackupSecurePassword = $certbackuppass 103 | BackupPath = "/tmp" 104 | } 105 | Get-DbaDatabase -SqlInstance sql1 -Database db1, db2, db3 | 106 | Start-DbaDbEncryption @splatdbEncrypt 107 | 108 | ########### 109 | 110 | Stop-DbaDbEncryption -SqlInstance sql1 111 | 112 | ########### 113 | 114 | Disable-DbaDbEncryption -SqlInstance sql1 -Database db1, db2, db3 115 | 116 | ########### 117 | 118 | $securepass = (Get-Credential doesntmatter).Password 119 | $params = @{ 120 | SqlInstance = "sql1" 121 | Database = "master" 122 | SecurePassword = $securepass 123 | } 124 | New-DbaDbMasterKey @params 125 | Backup-DbaDbMasterKey @params 126 | 127 | ########### 128 | 129 | $splatCert = @{ 130 | SqlInstance = "sql1" 131 | Database = "master" 132 | } 133 | New-DbaDbCertificate @splatCert -Name BackupCert 134 | 135 | # Just add to the previous splat! 136 | $splatCert.EncryptionPassword = $securepass 137 | Backup-DbaDbCertificate @splatCert -Certificate BackupCert 138 | 139 | ########### 140 | 141 | $backupparam = @{ 142 | SqlInstance = "sql1" 143 | Database = "master" 144 | FilePath = "c:\backups" 145 | EncryptionAlgorithm = "AES192" 146 | EncryptionCertificate = "BackupCert" 147 | } 148 | 149 | Backup-DbaDatabase @backupparam 150 | 151 | ########### 152 | 153 | $splatReadBackup = @{ 154 | SqlInstance = "sql1" 155 | FilePath = "C:\backups\myEncryptedDatabaseBackup.bak" 156 | } 157 | Test-DbaBackupEncypted @splatReadBackup 158 | 159 | 160 | ########### 161 | 162 | $splatReadBackup = @{ 163 | SqlInstance = "sql1" 164 | FilePath = "S:\backups\myDatabaseBackup.bak" 165 | } 166 | Test-DbaBackupEncypted @splatReadBackup 167 | 168 | 169 | ########### 170 | 171 | -------------------------------------------------------------------------------- /bookcode/chapter25.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 25 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Get-DbaSpConfigure -SqlInstance mssql1 -Name DefaultBackupCompression 19 | 20 | Set-DbaSpConfigure -SqlInstance mssql1 -Name DefaultBackupCompression -Value 1 21 | 22 | ########### 23 | 24 | Get-DbaDbCompression -SqlInstance mssql1 -Database AdventureWorks 25 | 26 | ########### 27 | 28 | Get-DbaDbCompression -SqlInstance mssql1 -Database AdventureWorks 29 | 30 | 31 | ########### 32 | 33 | $splatProperties = @{ 34 | Property = 35 | @{N="Data Compression Type"; E={$_.Name}}, 36 | @{N="Number Of Objects"; E={$_.Count}}, 37 | @{l='SizeMB'; e={'{0:n0}' -f (($_.Group.SizeCurrent | 38 | Measure-Object -Sum).Sum/1MB)}} 39 | } 40 | 41 | Get-DbaDbCompression -SqlInstance mssql1 -Database AdventureWorks | 42 | Group-Object DataCompression | 43 | Select-Object @splatProperties 44 | 45 | ########### 46 | 47 | Get-DbaDbCompression -SqlInstance mssql1 -ExcludeDatabase TestDatabase 48 | 49 | ########### 50 | 51 | Test-DbaDbCompression -SqlInstance mssql1 -Database AdventureWorks 52 | 53 | ########### 54 | 55 | Set-DbaDbCompression -SqlInstance mssql1 -Database AdventureWorks 56 | 57 | ########### 58 | 59 | $splatTestCompression = @{ 60 | SqlInstance = "mssql1" 61 | Database = "AdventureWorks" 62 | } 63 | $compressObjects = Test-DbaDbCompression @splatTestCompression 64 | 65 | ## Review the results in $compressObjects 66 | $splatSetCompression = @{ 67 | SqlInstance = "mssql1" 68 | InputObject = $compressObjects 69 | } 70 | Set-DbaDbCompression @splatSetCompression 71 | 72 | ########### 73 | 74 | $splatSetCompressionPage = @{ 75 | SqlInstance = "mssql1" 76 | Database = "AdventureWorks" 77 | CompressionType = "PAGE" 78 | } 79 | Set-DbaDbCompression @splatSetCompressionPage 80 | 81 | $splatSetCompressionRow = @{ 82 | SqlInstance = "mssql1" 83 | Database = "AdventureWorks" 84 | Table = "Employee" 85 | CompressionType = "ROW" 86 | } 87 | Set-DbaDbCompression @splatSetCompressionRow 88 | 89 | ########### 90 | 91 | $splatSetCompressionPage = @{ 92 | SqlInstance = "mssql1" 93 | Database = "AdventureWorks" 94 | CompressionType = "NONE" 95 | } 96 | Set-DbaDbCompression @splatSetCompressionPage 97 | 98 | ########### 99 | 100 | Set-DbaDbCompression -SqlInstance mssql1 -Database AdventureWorks -MaxRunTime 60 -PercentCompression 25 101 | 102 | ########### 103 | 104 | -------------------------------------------------------------------------------- /bookcode/chapter26.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 26 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Install-Module dbachecks -Scope CurrentUser 19 | 20 | ########### 21 | 22 | Install-Module Pester -RequiredVersion 4.10.1 -Scope CurrentUser 23 | 24 | ########### 25 | 26 | Invoke-DbcCheck -SqlInstance dbatoolslab -Check LastFullBackup 27 | 28 | ########### 29 | 30 | Invoke-DbcCheck -SqlInstance dbatoolslab -Check LastFullBackup 31 | 32 | ########### 33 | 34 | Invoke-DbcCheck -SqlInstance dbatoolslab -Check LastGoodCheckDb, MaxMemory 35 | 36 | ########### 37 | 38 | Get-DbcCheck | Select-Object Group, UniqueTag 39 | 40 | 41 | ########### 42 | 43 | Get-DbcCheck -Tag LastFullBackup | Format-List 44 | 45 | 46 | ########### 47 | 48 | (Get-DbcCheck -Tag LastFullBackup).config.Split(' ') 49 | 50 | ########### 51 | 52 | Get-DbcConfig -Name policy.backup.fullmaxdays 53 | 54 | 55 | ########### 56 | 57 | Set-DbcConfig -Name policy.backup.fullmaxdays -Value 7 58 | 59 | 60 | ########### 61 | 62 | Set-DbcConfig -Name policy.backup.fullmaxdays -Value 7 63 | Set-DbcConfig -Name policy.backup.diffmaxhours -Value 24 64 | Set-DbcConfig -Name policy.backup.logmaxminutes -Value 240 65 | 66 | Invoke-DbcCheck -SqlInstance dbatoolslab -Check LastBackup -Show Fails 67 | 68 | ########### 69 | 70 | Set-DbcConfig -Name policy.backup.fullmaxdays -Value 7 71 | Invoke-DbcCheck -SqlInstance dbatoolslab -Check LastFullBackup 72 | 73 | ########### 74 | 75 | $splatInvokeCheck = @{ 76 | SqlInstance = "dbatoolslab" 77 | Check = "LastBackup" 78 | Passthru = $true 79 | } 80 | Invoke-DbcCheck @splatInvokeCheck | 81 | Convert-DbcResult -Label dbatoolsMol | 82 | Write-DbcTable -SqlInstance dbatoolslab -Database DatabaseAdmin 83 | 84 | ########### 85 | 86 | $splatInvokeCheck = @{ 87 | SqlInstance = "dbatoolslab" 88 | Check = "LastBackup" 89 | Passthru = $true 90 | } 91 | Invoke-DbcCheck @splatInvokeCheck | 92 | Convert-DbcResult -Label dbatoolsMol | 93 | Write-DbcTable -SqlInstance dbatoolslab -Database DatabaseAdmin 94 | 95 | ########### 96 | 97 | Start-DbcPowerBi -FromDatabase 98 | 99 | ########### 100 | 101 | -------------------------------------------------------------------------------- /bookcode/chapter27.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 27 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | $params = @{ 19 | SqlInstance = "myserver.database.windows.net" 20 | Database = "mydb" 21 | SqlCredential = "me@mydomain.onmicrosoft.com" 22 | } 23 | $server = Connect-DbaInstance @params 24 | Invoke-DbaQuery -SqlInstance $server -Query "select 1 as test" 25 | 26 | ########### 27 | 28 | $params = @{ 29 | Type = "RenewableServicePrincipal" 30 | Tenant = "mytenant.onmicrosoft.com" 31 | Credential = "ee590f55-9b2b-55d4-8bca-38ab123db670" 32 | } 33 | $token = New-DbaAzAccessToken @params 34 | $params = @{ 35 | SqlInstance = "myserver.database.windows.net" 36 | Database = "mydb" 37 | AccessToken = $token 38 | } 39 | $server = Connect-DbaInstance @params 40 | Invoke-DbaQuery -SqlInstance $server -Query "select 1 as test" 41 | 42 | ########### 43 | 44 | $azureAccount = Connect-AzAccount 45 | $azureToken = Get-AzAccessToken -ResourceUrl https://database.windows.net 46 | 47 | $params = @{ 48 | SqlInstance = "myserver.database.windows.net" 49 | Database = "mydb" 50 | AccessToken = $azuretoken 51 | } 52 | 53 | $server = Connect-DbaInstance @params 54 | Invoke-DbaQuery -SqlInstance $server -Query "select 1 as test" 55 | 56 | ########### 57 | 58 | $params = @{ 59 | Type = "RenewableServicePrincipal" 60 | Tenant = "mytenant.onmicrosoft.com" 61 | Credential = "ee590f55-9b2b-55d4-8bca-38ab123db670" 62 | } 63 | $token = New-DbaAzAccessToken @params 64 | $params = @{ 65 | SqlInstance = "myserver.database.windows.net" 66 | Database = "mydb" 67 | AccessToken = $token 68 | } 69 | $server = Connect-DbaInstance @params 70 | $params = @{ 71 | SqlInstance = $server 72 | Database = "mydb" 73 | Path = "C:\temp\customers.csv" 74 | AutoCreateTable = $true 75 | } 76 | Import-DbaCsv @params 77 | $params = @{ 78 | SqlInstance = $server 79 | Database = "mydb" 80 | Query = "select * from customers" 81 | } 82 | Invoke-DbaQuery @params 83 | 84 | ########### 85 | 86 | -------------------------------------------------------------------------------- /bookcode/chapter28.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | This is the code from dbatools in a Month of Lunches chapter 28 3 | 4 | You will have to pay attention to the names of instances and databases. 5 | 6 | You running this script/function/code means you will not blame the author(s) if this breaks your stuff. 7 | This script/function is provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties 8 | including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. 9 | The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. 10 | In no event shall author(s) be held liable for any damages whatsoever (including, without limitation, damages 11 | for loss of business profits, business interruption, loss of business information, or other pecuniary loss) 12 | arising out of the use of or inability to use the script or documentation. 13 | 14 | Chrissy Rob Jess Claudio 15 | #> 16 | 17 | 18 | Get-DbatoolsConfig -Module Logging | 19 | Select-Object FullName, Description 20 | 21 | 22 | ########### 23 | 24 | Get-DbatoolsConfig -FullName logging.maxlogfileage 25 | 26 | 27 | 28 | ########### 29 | 30 | Get-DbatoolsConfigValue -FullName sql.connection.timeout 31 | 32 | ########### 33 | 34 | Get-DbatoolsConfig | Reset-DbatoolsConfig 35 | 36 | ########### 37 | 38 | Get-DbatoolsConfigValue -FullName path.dbatoolslogpath -OutVariable dir 39 | Get-ChildItem $dir 40 | 41 | 42 | ########### 43 | 44 | -------------------------------------------------------------------------------- /config/Config.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | # This should be the folder you have extracted the install media to and there should be two folders in here '2017' and '2019' 3 | InstallMediaPath = 'Z:\Install' 4 | 5 | # This will be used to download the WideWorldImporters backup to, and can be used as a backup destination for the labs 6 | BackupPath = 'C:\dbatoolslab\Backup' 7 | 8 | 9 | } -------------------------------------------------------------------------------- /csv/sameplecsvs.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/csv/sameplecsvs.zip -------------------------------------------------------------------------------- /notebooks/DotNet/00-CreateContainers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "kernelspec": { 4 | "name": ".net-powershell", 5 | "display_name": ".NET (PowerShell)", 6 | "language": "PowerShell" 7 | }, 8 | "language_info": { 9 | "name": "PowerShell", 10 | "version": "7.0", 11 | "mimetype": "text/x-powershell", 12 | "file_extension": ".ps1", 13 | "pygments_lexer": "powershell" 14 | } 15 | }, 16 | "nbformat_minor": 2, 17 | "nbformat": 4, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "source": [ 22 | "# Creating the containers for .NET notebooks for exploring dbatools\n", 23 | "\n", 24 | "To run these notebooks, you will first have to have set up Jupyter Notebooks following the information here [https://sqldbawithabeard.com/2020/02/07/new-net-notebooks-are-here-powershell-7-notebooks-are-here/](https://sqldbawithabeard.com/2020/02/07/new-net-notebooks-are-here-powershell-7-notebooks-are-here/)\n", 25 | "\n", 26 | "![dbatools](.\\images\\dbatools.png)\n", 27 | "\n", 28 | "We have written a book which will give you a brilliant introduction to dbatools. It's called dbatools in a Month of Lunches and you can find it at [https://beard.media/book](https://beard.media/book)\n", 29 | "\n", 30 | "# Setting up the containers for the rest of the dbatools notebooks\n", 31 | "\n", 32 | "To be able to follow along with the rest of the notebooks, you will need to set up two containers.\n", 33 | "\n", 34 | "This notebook will enable you to do that.\n", 35 | "\n", 36 | "You will need to have Docker installed [Install Docker Desktop on Windows | Docker Documentation](https://docs.docker.com/docker-for-windows/install/). The image is based on the SQL Server 2019 image so you will need to have docker set to use Linux Containers. Right click on the Docker icon in the notification area and if it says \"Switch to Linux Containers\" click to switch and wait for Docker to restart. \n", 37 | "\n", 38 | "![Switch To Linux Containers](.\\images\\switchtolinuxcontainers.png)\n", 39 | "\n", 40 | "You will be able to run all of the code in the notebooks by creating the folder, credential and containers in this notebook and then you can click on the play button in each code block to run the code. Note - There are a few code blocks with the results already included which should not be run. They are to show you the results of a command that cannot be run against containers (setting up configuration for domain accounts for example)\n", 41 | "\n", 42 | "**You can also navigate through the Notebook using the arrow keys and press SHIFT + ENTER to run a cell**" 43 | ], 44 | "metadata": { 45 | "azdata_cell_guid": "e7503606-32c6-4685-84a5-99cda6387fce" 46 | }, 47 | "attachments": {} 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "source": [ 52 | "## Create the folders and the credential\n", 53 | "\n", 54 | "The code below will create a directory called dbatools-demo in your Documents folder and save a credential file for logging into the containers. You can alter the directory created by altering the `$FolderPath` \n", 55 | "\n", 56 | "The code has been collapsed but you can view it using the view menu in the lab or by clicking the 3 ellipses" 57 | ], 58 | "metadata": { 59 | "azdata_cell_guid": "9a602f20-4924-490a-a025-1aa03bb4f4b4" 60 | } 61 | }, 62 | { 63 | "cell_type": "code", 64 | "source": [ 65 | "$NotebookDir = '' # add the directory that the notebook is in here \n", 66 | "$FolderPath = $Env:USERPROFILE + '\\Documents\\dbatoolsdemo'\n", 67 | "\n", 68 | "########################################################\n", 69 | "Write-Output \"Creating Directory $FolderPath\"\n", 70 | "if (Test-Path $FolderPath) {\n", 71 | " Write-Output \"Path $FolderPath exists already\"\n", 72 | "}\n", 73 | "else {\n", 74 | " $null = New-Item $FolderPath -ItemType Directory\n", 75 | "}\n", 76 | "\n", 77 | "Write-Output \"Creating Directory $FolderPath\\SQL1\"\n", 78 | "if (Test-Path \"$FolderPath\\SQL1\") {\n", 79 | " Write-Output \"Directory SQL1 exists already\"\n", 80 | " Get-ChildItem \"$FolderPath\\SQL1\" -Recurse | Remove-Item -Recurse -Force\n", 81 | "}\n", 82 | "else {\n", 83 | " $null = New-Item \"$FolderPath\\SQL1\"-ItemType Directory\n", 84 | "}\n", 85 | "Write-Output \"Creating File $FolderPath\\SQL1\\dummyfile.txt\"\n", 86 | "if (Test-Path \"$FolderPath\\SQL1\\dummyfile.txt\") {\n", 87 | " Write-Output \"dummyfile.txt exists already\"\n", 88 | "}\n", 89 | "else {\n", 90 | " $null = New-Item \"$FolderPath\\SQL1\\dummyfile.txt\" -ItemType file\n", 91 | "}\n", 92 | "\n", 93 | "Write-Output \"Creating Directory $FolderPath\\SQL2\"\n", 94 | "if (Test-Path \"$FolderPath\\SQL2\") {\n", 95 | " Write-Output \"Directory SQL2 exists already\"\n", 96 | " Get-ChildItem \"$FolderPath\\SQL2\" -Recurse | Remove-Item -Recurse -Force\n", 97 | "}\n", 98 | "else {\n", 99 | " $null = New-Item \"$FolderPath\\SQL2\"-ItemType Directory\n", 100 | "}\n", 101 | "Write-Output \"Creating File $FolderPath\\SQL2\\dummyfile.txt\"\n", 102 | "if (Test-Path \"$FolderPath\\SQL2\\dummyfile.txt\") {\n", 103 | " Write-Output \"dummyfile.txt exists already\"\n", 104 | "}\n", 105 | "else {\n", 106 | " $null = New-Item \"$FolderPath\\SQL2\\dummyfile.txt\" -ItemType file\n", 107 | "}\n", 108 | "\n", 109 | "Write-Output \"Creating a credential file for the containers - Please don't do this in production\"\n", 110 | "\n", 111 | "$sqladminPassword = ConvertTo-SecureString 'dbatools.IO' -AsPlainText -Force \n", 112 | "$cred = New-Object System.Management.Automation.PSCredential ('sqladmin', $sqladminpassword)\n", 113 | "$Cred | Export-Clixml -Path $FolderPath\\sqladmin.cred\n", 114 | "Write-Output \"Credential file created\"\n", 115 | "\n", 116 | "Write-Output \"Setting the docker-compose files values\"\n", 117 | "\n", 118 | "if ($NotebookDir -eq '') {\n", 119 | " try {\n", 120 | " $NotebookDir = Read-Host \"Please enter path to the notebook. Azure Data Studio doesnt know where it is\" -ErrorAction Stop\n", 121 | " }\n", 122 | " catch {\n", 123 | " Write-Warning \"UH-OH - You have not set the `$NotebookDir variable to a directory we can find - Set it in the code please\"\n", 124 | " Break\n", 125 | " }\n", 126 | "}\n", 127 | "if (-not (Test-Path $NotebookDir -ErrorAction SilentlyContinue)) {\n", 128 | " Write-Warning \"UH-OH - You have not set the `$NotebookDir variable to a directory we can find - Set it in the code please\"\n", 129 | " Break\n", 130 | "}\n", 131 | "\n", 132 | "$dockercompose = (Get-Content $NotebookDir\\\\dockercompose.yml -ErrorAction Stop) -replace '__ReplaceME__' , $FolderPath\n", 133 | "# $dockercompose\n", 134 | "$dockercompose | Set-Content $NotebookDir\\\\docker-compose.yml\n", 135 | "Set-Location $NotebookDir\n", 136 | "\n", 137 | "Write-Output \"Finished\"" 138 | ], 139 | "metadata": { 140 | "azdata_cell_guid": "da2a1233-6845-4031-b5dd-fc65263cc832", 141 | "tags": [ 142 | "hide_input" 143 | ] 144 | }, 145 | "outputs": [], 146 | "execution_count": null 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "source": [ 151 | "## Containers\n", 152 | "\n", 153 | "We are going to create two SQL 2019 containers using the sqldbawithabeard\\dbatoolsbeardsql01 [image from the Docker Hub](https://hub.docker.com/repository/docker/sqldbawithabeard/dbatoolsbeardsql01) and sqldbawithabeard\\dbatoolsbeardsql02 [image from the Docker Hub](https://hub.docker.com/repository/docker/sqldbawithabeard/dbatoolsbeardsql02)\n", 154 | "\n", 155 | "The first time it is going to pull the images from the Docker Hub. If you wish to do this first, you can run the cell below\n", 156 | "\n", 157 | "" 158 | ], 159 | "metadata": { 160 | "azdata_cell_guid": "82e68f8a-0aa6-4f70-a781-7e511c1a762f" 161 | } 162 | }, 163 | { 164 | "cell_type": "code", 165 | "source": [ 166 | "docker pull sqldbawithabeard/dbatoolsbeardsql01:v1\r\n", 167 | "docker pull sqldbawithabeard/dbatoolsbeardsql02:v1" 168 | ], 169 | "metadata": { 170 | "azdata_cell_guid": "689caa3f-e974-41ad-a35b-8c2e1f609386" 171 | }, 172 | "outputs": [], 173 | "execution_count": null 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "source": [ 178 | "Now we can start the containers with the code below" 179 | ], 180 | "metadata": { 181 | "azdata_cell_guid": "1771c1c6-4dbb-46e5-b0ad-d66cd66e855e" 182 | } 183 | }, 184 | { 185 | "cell_type": "code", 186 | "source": [ 187 | "docker-compose up -d" 188 | ], 189 | "metadata": { 190 | "azdata_cell_guid": "d05505a2-c39e-4402-93cd-059430df01a3" 191 | }, 192 | "outputs": [], 193 | "execution_count": null 194 | }, 195 | { 196 | "cell_type": "markdown", 197 | "source": [ 198 | "All being well, you wil have something that looks like\n", 199 | "\n", 200 | "\n", 201 | "![DockerCompose](.\\images\\containers.png )\n", 202 | "\n", 203 | "If you get an error you might need to add the user you have shared your drives with Docker modify permissions to the \\Documents\\ directory in your user profile \n", 204 | "More details https://docs.docker.com/docker-for-windows/ or troubleshoot in the normal way\n", 205 | "\n", 206 | "\n", 207 | "Now we can start exploring with dbatools :-)\n", 208 | "\n", 209 | "If you have not installed dbatools, it can be got from the PowerShell Gallery using `Install-Module dbatools` the code below will check for the module and either install it in your user profile or update it and Import it" 210 | ], 211 | "metadata": { 212 | "azdata_cell_guid": "6eeea37c-830b-4a3c-9355-db07601ab47b" 213 | } 214 | }, 215 | { 216 | "cell_type": "code", 217 | "source": [ 218 | "if(Get-Module dbatools -ListAvailable){\n", 219 | "Write-Output \"Updating dbatools\"\n", 220 | "Update-Module dbatools\n", 221 | "}else {\n", 222 | "Write-Output \"Installing dbatools in your user profile\"\n", 223 | "Install-Module dbatools -Scope CurrentUser\n", 224 | "}\n", 225 | "Import-Module dbatools" 226 | ], 227 | "metadata": { 228 | "azdata_cell_guid": "ddff53ab-f6d0-4c74-abc6-f79487d77f19" 229 | }, 230 | "outputs": [], 231 | "execution_count": null 232 | }, 233 | { 234 | "cell_type": "markdown", 235 | "source": [ 236 | "## Check connection\n", 237 | "Now that is done, we can make a connection to our instances and see if we can connect to them.\n", 238 | "\n", 239 | "We are going to use `Connect-DBaInstance` to do this and we will use the containers that we have created and because we need to use SQL Authentication, we will use a credential that we have saved to disk using `Export-CliXML` in one of the celss above.\n", 240 | "\n", 241 | "It is **Important** to state that this is not a production secure solution and should not be used as a means of accessing any secure system." 242 | ], 243 | "metadata": { 244 | "azdata_cell_guid": "c6cfbe4c-5e3b-4312-ab12-91416a3cc02d" 245 | } 246 | }, 247 | { 248 | "cell_type": "code", 249 | "source": [ 250 | "$FolderPath = $Env:USERPROFILE + '\\Documents\\dbatoolsdemo'\n", 251 | "$SqlInstances = 'localhost,15592', 'localhost,15593'\n", 252 | "$SqlCredential = Import-Clixml -Path $FolderPath\\sqladmin.cred\n", 253 | "Write-Output \" Creating connection to the containers\"\n", 254 | "try {\n", 255 | " $SQL1 = Connect-DbaInstance -SqlInstance $SqlInstances[0] -SqlCredential $SqlCredential \n", 256 | " $SQL2 = Connect-DbaInstance -SqlInstance $SqlInstances[1] -SqlCredential $SqlCredential\n", 257 | " Write-Output \"We have a connection to the containers\"\n", 258 | "\n", 259 | "}\n", 260 | "catch {\n", 261 | " Write-Output \"You haven't got a connection to the containers - Either they are still upgrading in which case try again in 30 seconds or the containers have not come up correctly\"\n", 262 | " Write-Output \"Make sure the containers are running - the code is below in a block for you\"\n", 263 | " Write-Output \"docker ps -a\"\n", 264 | " Write-Output \"If they are read the logs - the code is below in a block for you\"\n", 265 | " Write-Output \"docker logs dbatools_SQL2019_1\"\n", 266 | " Write-Output \"docker logs dbatools_SQL2019-1_1\"\n", 267 | "}" 268 | ], 269 | "metadata": { 270 | "azdata_cell_guid": "e8e0f4c0-9328-42f4-b328-6cca11d2ad54", 271 | "jupyter": { 272 | "source_hidden": true 273 | } 274 | }, 275 | "outputs": [], 276 | "execution_count": null 277 | }, 278 | { 279 | "cell_type": "markdown", 280 | "source": [ 281 | "If there are warnings above - Check the containers are running - Look at the status column" 282 | ], 283 | "metadata": { 284 | "azdata_cell_guid": "ec7b3d4b-e1a3-4668-ac40-a89a064d74e2" 285 | } 286 | }, 287 | { 288 | "cell_type": "code", 289 | "source": [ 290 | "docker ps -a" 291 | ], 292 | "metadata": { 293 | "azdata_cell_guid": "6ab5d62d-2069-4206-b555-b3c1a76a7f1d" 294 | }, 295 | "outputs": [], 296 | "execution_count": null 297 | }, 298 | { 299 | "cell_type": "markdown", 300 | "source": [ 301 | "If there are warnings above and the containers are running - check the logs" 302 | ], 303 | "metadata": { 304 | "azdata_cell_guid": "a6ed4b0c-37e0-4a79-a63f-bd35616df3ea" 305 | } 306 | }, 307 | { 308 | "cell_type": "code", 309 | "source": [ 310 | "docker logs dbatools_SQL2019_1" 311 | ], 312 | "metadata": { 313 | "azdata_cell_guid": "67480623-8a3f-4236-8a69-21438c35d90a" 314 | }, 315 | "outputs": [], 316 | "execution_count": null 317 | }, 318 | { 319 | "cell_type": "markdown", 320 | "source": [ 321 | "If there are warnings above and the containers are running - check the logs" 322 | ], 323 | "metadata": { 324 | "azdata_cell_guid": "93044e3d-d9d1-4b03-aab6-0438eb3d9fb9" 325 | } 326 | }, 327 | { 328 | "cell_type": "code", 329 | "source": [ 330 | "docker logs dbatools_SQL2019_1" 331 | ], 332 | "metadata": { 333 | "azdata_cell_guid": "00d631fb-0dc2-421b-bdd3-fb6ec20c1c5b" 334 | }, 335 | "outputs": [], 336 | "execution_count": null 337 | }, 338 | { 339 | "cell_type": "markdown", 340 | "source": [ 341 | "Now you can use these containers to run the rest of the notebooks - Don't forget to run the Clean Up Containers Notebook at the end to clean up" 342 | ], 343 | "metadata": { 344 | "azdata_cell_guid": "51f09646-69f5-46a7-acf0-33d227489314" 345 | } 346 | } 347 | ] 348 | } -------------------------------------------------------------------------------- /notebooks/DotNet/01-Introduction.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "kernelspec": { 4 | "name": ".net-powershell", 5 | "display_name": ".NET (PowerShell)", 6 | "language": "PowerShell" 7 | }, 8 | "language_info": { 9 | "name": "PowerShell", 10 | "version": "7.0", 11 | "mimetype": "text/x-powershell", 12 | "file_extension": ".ps1", 13 | "pygments_lexer": "powershell" 14 | } 15 | }, 16 | "nbformat_minor": 2, 17 | "nbformat": 4, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "source": [ 22 | "# Introduction\n", 23 | "\n", 24 | "How do you start with dbatools?\n", 25 | "\n", 26 | "Lets look at how you can begin and how you can help your self to be able to use dbatools\n", 27 | "\n", 28 | "***You will need to have followed the steps in the 00-CreateContainers notebook to use this notebook***\n", 29 | "\n", 30 | "We have written a book which will give you a brilliant introduction to dbatools. It's called dbatools in a Month of Lunches and you can find it at https://beard.media/book" 31 | ], 32 | "metadata": { 33 | "azdata_cell_guid": "c2e1450c-7c7f-4400-b427-e77c8afbc967" 34 | } 35 | }, 36 | { 37 | "cell_type": "code", 38 | "source": [ 39 | "## Lets look at the commands\n", 40 | "Get-Command -Module dbatools " 41 | ], 42 | "metadata": { 43 | "azdata_cell_guid": "4c5d55a6-203d-4a4f-9f3d-e4c21b4d6070" 44 | }, 45 | "outputs": [], 46 | "execution_count": null 47 | }, 48 | { 49 | "cell_type": "code", 50 | "source": [ 51 | "## How many commands?\n", 52 | "(Get-Command -Module dbatools -CommandType Function ).Count" 53 | ], 54 | "metadata": { 55 | "azdata_cell_guid": "0c674263-5c7d-4ebc-9718-1f18922635a4" 56 | }, 57 | "outputs": [], 58 | "execution_count": null 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "source": [ 63 | "## How do we find commands ?\n", 64 | "\n", 65 | "With that many commands even Chrissy can't remember them all !\n", 66 | "\n", 67 | "So there is a command to find commands" 68 | ], 69 | "metadata": { 70 | "azdata_cell_guid": "9373b8e2-d16b-4e15-b119-f8aa36585f61" 71 | } 72 | }, 73 | { 74 | "cell_type": "code", 75 | "source": [ 76 | "Find-DbaCommand -Tag Backup" 77 | ], 78 | "metadata": { 79 | "azdata_cell_guid": "e80e58a9-2e60-4048-bb32-62dbd60702e7" 80 | }, 81 | "outputs": [], 82 | "execution_count": null 83 | }, 84 | { 85 | "cell_type": "code", 86 | "source": [ 87 | "Find-DbaCommand -Tag Restore" 88 | ], 89 | "metadata": { 90 | "azdata_cell_guid": "983a8d9f-7666-41b2-8255-3e914a9972d3" 91 | }, 92 | "outputs": [], 93 | "execution_count": null 94 | }, 95 | { 96 | "cell_type": "code", 97 | "source": [ 98 | "Find-DbaCommand -Tag Migration" 99 | ], 100 | "metadata": { 101 | "azdata_cell_guid": "352839bb-0f45-44f8-8596-18bf8cbb7f46" 102 | }, 103 | "outputs": [], 104 | "execution_count": null 105 | }, 106 | { 107 | "cell_type": "code", 108 | "source": [ 109 | "Find-DbaCommand -Tag Agent" 110 | ], 111 | "metadata": { 112 | "azdata_cell_guid": "b074e028-7872-4cf6-b89d-0822760a897a" 113 | }, 114 | "outputs": [], 115 | "execution_count": null 116 | }, 117 | { 118 | "cell_type": "code", 119 | "source": [ 120 | "Find-DbaCommand -Pattern User " 121 | ], 122 | "metadata": { 123 | "azdata_cell_guid": "7196cfef-4f9c-4aab-9ae4-45779205f4d1" 124 | }, 125 | "outputs": [], 126 | "execution_count": null 127 | }, 128 | { 129 | "cell_type": "code", 130 | "source": [ 131 | "Find-DbaCommand -Pattern linked" 132 | ], 133 | "metadata": { 134 | "azdata_cell_guid": "c06460e7-12b5-4c19-a26e-f7aab540dd9c" 135 | }, 136 | "outputs": [], 137 | "execution_count": null 138 | }, 139 | { 140 | "cell_type": "markdown", 141 | "source": [ 142 | "## You can also use native PowerShell \n", 143 | "\n", 144 | "This can be used with any module" 145 | ], 146 | "metadata": { 147 | "azdata_cell_guid": "23e63ec8-b5be-4260-a71a-c2c8e23efb9d" 148 | } 149 | }, 150 | { 151 | "cell_type": "code", 152 | "source": [ 153 | "Get-Command -Module dbatools -Name *linked*" 154 | ], 155 | "metadata": { 156 | "azdata_cell_guid": "84d6ffe1-2a6d-47bf-8358-bd52c5cf2a1c" 157 | }, 158 | "outputs": [], 159 | "execution_count": null 160 | }, 161 | { 162 | "cell_type": "markdown", 163 | "source": [ 164 | "# How to use commands ?\n", 165 | "\n", 166 | "**ALWAYS ALWAYS ALWAYS use `Get-Help`**" 167 | ], 168 | "metadata": { 169 | "azdata_cell_guid": "8dc7d4ec-8021-4b19-a58c-8b3b1ee91acc" 170 | } 171 | }, 172 | { 173 | "cell_type": "code", 174 | "source": [ 175 | "Get-Help Test-DbaLinkedServerConnection -Full" 176 | ], 177 | "metadata": { 178 | "azdata_cell_guid": "046a7638-acb4-4d01-a2fc-e051e90f451f" 179 | }, 180 | "outputs": [], 181 | "execution_count": null 182 | }, 183 | { 184 | "cell_type": "code", 185 | "source": [ 186 | "## Here a neat trick which you can use in PowerShell or pwsh but not in a notebook!\n", 187 | "## When PowerShell opens - right click to paste the command\n", 188 | "# Find-DbaCommand -Pattern linked | Out-GridView -PassThru | Get-Help -Full \n", 189 | "\"Find-DbaCommand -Pattern linked | Out-GridView -PassThru | Get-Help -Full \" | clip\n", 190 | "# If you have PowerShell 7\n", 191 | "# Start-Process 'C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe'\n", 192 | "\n", 193 | "# if you dont have PowerShell 7 then you can uncomment (remove the #) from the line below and comment (add a # to the beginning) of the line above\n", 194 | "# Start-Process 'C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe'" 195 | ], 196 | "metadata": { 197 | "azdata_cell_guid": "1112a493-763f-487b-b040-1c9757b03034" 198 | }, 199 | "outputs": [], 200 | "execution_count": null 201 | }, 202 | { 203 | "cell_type": "markdown", 204 | "source": [ 205 | "# Clean Up\n", 206 | "\n", 207 | "The 99-CleanUpContainers notebook will remove the containers, files and directory - it will leave the image so you do not have to download it again!" 208 | ], 209 | "metadata": { 210 | "azdata_cell_guid": "57b0d390-ffdf-4079-8c1d-0f5b96aa501b" 211 | } 212 | } 213 | ] 214 | } -------------------------------------------------------------------------------- /notebooks/DotNet/06-AgentJobs.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "kernelspec": { 4 | "name": ".net-powershell", 5 | "display_name": ".NET (PowerShell)", 6 | "language": "PowerShell" 7 | }, 8 | "language_info": { 9 | "name": "PowerShell", 10 | "mimetype": "text/x-powershell", 11 | "file_extension": ".ps1", 12 | "version": "7.0", 13 | "pygments_lexer": "powershell" 14 | } 15 | }, 16 | "nbformat_minor": 2, 17 | "nbformat": 4, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "source": [ 22 | "# Working with Agent Jobs with dbatools\n", 23 | "\n", 24 | "You can use dbatools to administer your Agent jobs. Make sure that you have first run your create container notebook\n", 25 | "\n", 26 | "We have written a book which will give you a brilliant introduction to dbatools. It's called dbatools in a Month of Lunches and you can find it at https://beard.media/book\n", 27 | "\n", 28 | "The cell block below will create the variables that you will need for the rest of the notebook\n", 29 | "\n", 30 | "You can run the code by using the arrow keys and shift and enter" 31 | ], 32 | "metadata": { 33 | "azdata_cell_guid": "bb22d6b7-3379-462c-99e0-17644cd6535f" 34 | } 35 | }, 36 | { 37 | "cell_type": "code", 38 | "source": [ 39 | "$FolderPath = $Env:USERPROFILE + '\\Documents\\dbatoolsdemo'\n", 40 | "$SqlInstances = 'localhost,15592', 'localhost,15593'\n", 41 | "$SqlCredential = Import-Clixml -Path $FolderPath\\sqladmin.cred\n", 42 | "Write-Output \" Creating connection to the containers\"\n", 43 | "try {\n", 44 | " $SQL1 = Connect-DbaInstance -SqlInstance $SqlInstances[0] -SqlCredential $SqlCredential \n", 45 | " $SQL2 = Connect-DbaInstance -SqlInstance $SqlInstances[1] -SqlCredential $SqlCredential\n", 46 | " Write-Output \"We have a connection to the containers\"\n", 47 | "\n", 48 | "}\n", 49 | "catch {\n", 50 | " Write-Output \"You haven't got a connection to the containers - Either they are still upgrading in which case try again in 30 seconds or the containers have not come up correctly\"\n", 51 | " Write-Output \"Make sure the containers are running - the code is below in a block for you\"\n", 52 | " Write-Output \"docker ps -a\"\n", 53 | " Write-Output \"If they are read the logs - the code is below in a block for you\"\n", 54 | " Write-Output \"docker logs dbatools_SQL2019_1\"\n", 55 | " Write-Output \"docker logs dbatools_SQL2019-1_1\"\n", 56 | "}\n", 57 | "# Run this first to make sure output width does not mess with output - Update output buffer size to prevent clipping in Visual Studio output window.\n", 58 | "if( $Host -and $Host.UI -and $Host.UI.RawUI ) {\n", 59 | " $rawUI = $Host.UI.RawUI\n", 60 | " $oldSize = $rawUI.BufferSize\n", 61 | " $typeName = $oldSize.GetType( ).FullName\n", 62 | " $newSize = New-Object $typeName (500, $oldSize.Height)\n", 63 | " $rawUI.BufferSize = $newSize\n", 64 | " }" 65 | ], 66 | "metadata": { 67 | "jupyter": { 68 | "source_hidden": true 69 | }, 70 | "azdata_cell_guid": "027eb9ed-0cbe-4bc5-95e6-14c04d741d95", 71 | "tags": [ 72 | "hide_input" 73 | ] 74 | }, 75 | "outputs": [], 76 | "execution_count": null 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "source": [ 81 | "## List the Agent jobs on the instance\n", 82 | "\n", 83 | "You can very quickly list all the agent jobs on an instance with dbatools" 84 | ], 85 | "metadata": { 86 | "azdata_cell_guid": "5be1ad92-499e-4040-9f0f-e296b4f11d22" 87 | } 88 | }, 89 | { 90 | "cell_type": "code", 91 | "source": [ 92 | "Get-DbaAgentJob -SqlInstance $sql1 | Format-Table" 93 | ], 94 | "metadata": { 95 | "azdata_cell_guid": "58634944-9a9a-4b70-976d-a77d5a6cf097" 96 | }, 97 | "outputs": [], 98 | "execution_count": null 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "source": [ 103 | "You can get info about a particular job" 104 | ], 105 | "metadata": { 106 | "azdata_cell_guid": "4db1ea57-667c-4d55-ab2a-cf0316c2756b" 107 | } 108 | }, 109 | { 110 | "cell_type": "code", 111 | "source": [ 112 | "Get-DbaAgentJob -SqlInstance $sql1 -Job 'The Beard is Important'" 113 | ], 114 | "metadata": { 115 | "azdata_cell_guid": "a367f38d-edf8-4f57-9e4f-b0c6bf8f5eb3" 116 | }, 117 | "outputs": [], 118 | "execution_count": null 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "source": [ 123 | "Job Steps" 124 | ], 125 | "metadata": { 126 | "azdata_cell_guid": "a2ad4b9c-d335-43f8-847c-c218e0932b9c" 127 | } 128 | }, 129 | { 130 | "cell_type": "code", 131 | "source": [ 132 | "Get-DbaAgentJobStep -SqlInstance $SQL1 -Job 'The Beard is Important'" 133 | ], 134 | "metadata": { 135 | "azdata_cell_guid": "f2a77863-6c58-4f04-afcc-e8dfb5ec17d7" 136 | }, 137 | "outputs": [], 138 | "execution_count": null 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "source": [ 143 | "You can remove jobs \n", 144 | "\n", 145 | "**PLEASE DON'T DO THIS IN PRODUCTION**" 146 | ], 147 | "metadata": { 148 | "azdata_cell_guid": "fb396890-c4b5-4635-8654-06cff6efcfca" 149 | } 150 | }, 151 | { 152 | "cell_type": "code", 153 | "source": [ 154 | "Get-DbaAgentJob -SqlInstance $SQL2 | Remove-DbaAgentJob -Confirm:$false" 155 | ], 156 | "metadata": { 157 | "azdata_cell_guid": "57dc4034-f8c4-44ad-b5be-44988f53dc1e" 158 | }, 159 | "outputs": [], 160 | "execution_count": null 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "source": [ 165 | "We have no jobs on SQL2" 166 | ], 167 | "metadata": { 168 | "azdata_cell_guid": "13d31934-319b-4440-a14d-9d24d535be2f" 169 | } 170 | }, 171 | { 172 | "cell_type": "code", 173 | "source": [ 174 | " $SQL2 = Connect-DbaInstance -SqlInstance $SqlInstances[1] -SqlCredential $SqlCredential\n", 175 | "Get-DbaAgentJob -SqlInstance $SQL2" 176 | ], 177 | "metadata": { 178 | "azdata_cell_guid": "36e7043a-6c66-4d5d-89d4-fb9694cc5cab" 179 | }, 180 | "outputs": [], 181 | "execution_count": null 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "source": [ 186 | "If you have run through the notebooks, you might still have the Availability Group that was created in Notebook 03\n", 187 | "\n", 188 | "You would want your Agent Jobs to be the same on all replicas so that if you failover everything works\n", 189 | "\n", 190 | "dbatools has you covered" 191 | ], 192 | "metadata": { 193 | "azdata_cell_guid": "42cff201-9ce5-4065-987b-2163f172a95e" 194 | } 195 | }, 196 | { 197 | "cell_type": "code", 198 | "source": [ 199 | "Copy-DbaAgentJob -Source $SQL1 -Destination $SQL2" 200 | ], 201 | "metadata": { 202 | "azdata_cell_guid": "7b23de5b-36ea-40c0-acd1-edf0a52eed28" 203 | }, 204 | "outputs": [], 205 | "execution_count": null 206 | }, 207 | { 208 | "cell_type": "markdown", 209 | "source": [ 210 | "and just like that all jobs are on SQL2" 211 | ], 212 | "metadata": { 213 | "azdata_cell_guid": "623f4a38-4363-494a-ab90-625c8a905468" 214 | } 215 | }, 216 | { 217 | "cell_type": "code", 218 | "source": [ 219 | " $SQL2 = Connect-DbaInstance -SqlInstance $SqlInstances[1] -SqlCredential $SqlCredential\n", 220 | "Get-DbaAgentJob -SqlInstance $SQL2|Format-Table" 221 | ], 222 | "metadata": { 223 | "azdata_cell_guid": "3db8ce8d-b269-4965-bdcb-445a06581b1c" 224 | }, 225 | "outputs": [], 226 | "execution_count": null 227 | }, 228 | { 229 | "cell_type": "markdown", 230 | "source": [ 231 | "# Clean Up\n", 232 | "\n", 233 | "The 99-CleanUpContainers notebook will remove the containers, files and directory - it will leave the image so you do not have to download it again!" 234 | ], 235 | "metadata": { 236 | "azdata_cell_guid": "6a216fd0-3bf3-42a4-add8-ec977fb38dec" 237 | } 238 | } 239 | ] 240 | } 241 | -------------------------------------------------------------------------------- /notebooks/DotNet/99-CleanUpContainers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "kernelspec": { 4 | "name": ".net-powershell", 5 | "display_name": ".NET (PowerShell)", 6 | "language": "PowerShell" 7 | }, 8 | "language_info": { 9 | "name": "PowerShell", 10 | "mimetype": "text/x-powershell", 11 | "file_extension": ".ps1", 12 | "version": "7.0", 13 | "pygments_lexer": "powershell" 14 | } 15 | }, 16 | "nbformat_minor": 2, 17 | "nbformat": 4, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "source": [ 22 | "# Cleaning up the containers and directories and files\n", 23 | "\n", 24 | "The code below will clean up the files that have been created and remove the docker containers but not the image so that you can run the notebooks again without having to download the image again" 25 | ], 26 | "metadata": { 27 | "azdata_cell_guid": "bf39922e-c732-4c24-8630-1694d703c50e" 28 | }, 29 | "attachments": {} 30 | }, 31 | { 32 | "cell_type": "code", 33 | "source": [ 34 | "$FolderPath = $Env:USERPROFILE + '\\Documents\\dbatoolsdemo'\n", 35 | "Write-Output \"Removing containers\"\n", 36 | "\n", 37 | " $NotebookDir = Read-Host \"Please enter path to the notebook. Azure Data Studio doesnt know where it is\"\n", 38 | " Set-Location $NotebookDir\n", 39 | " docker-compose down \n", 40 | "\n", 41 | "\n", 42 | "Write-Output \"Removing directories and files\"\n", 43 | "Remove-Item $FolderPath -Recurse -Force\n", 44 | "Write-Output \"Removed everything\"\n", 45 | "" 46 | ], 47 | "metadata": { 48 | "azdata_cell_guid": "45750e3c-b1a5-430f-b79c-d85430564841" 49 | }, 50 | "outputs": [], 51 | "execution_count": null 52 | }, 53 | { 54 | "cell_type": "code", 55 | "source": [ 56 | "docker ps -a" 57 | ], 58 | "metadata": { 59 | "azdata_cell_guid": "06243d1c-1e53-4a2a-9cae-47c6934eb20c" 60 | }, 61 | "outputs": [], 62 | "execution_count": null 63 | } 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /notebooks/DotNet/Untitled.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 48, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "$Stopwatch = [diagnostics.stopwatch]::StartNew()" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 49, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "Number of Files : 10001\n", 22 | "\n" 23 | ] 24 | } 25 | ], 26 | "source": [ 27 | "#!csharp\n", 28 | "using System.IO; \n", 29 | "using System;\n", 30 | "int fileCount = Directory.GetFiles(@\"C:\\Users\\mrrob\\AppData\\Local\\Temp\\pwshplaydir\", \"*\", SearchOption.TopDirectoryOnly).Length;\n", 31 | "Console.WriteLine($\"Number of Files : {fileCount}\\n\");" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 50, 37 | "metadata": {}, 38 | "outputs": [ 39 | { 40 | "name": "stdout", 41 | "output_type": "stream", 42 | "text": [ 43 | "141\n" 44 | ] 45 | } 46 | ], 47 | "source": [ 48 | "$Stopwatch.Stop()\n", 49 | "$Stopwatch.Elapsed.Milliseconds" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 51, 55 | "metadata": {}, 56 | "outputs": [], 57 | "source": [ 58 | "$Stopwatch = [diagnostics.stopwatch]::StartNew()" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 52, 64 | "metadata": {}, 65 | "outputs": [ 66 | { 67 | "name": "stdout", 68 | "output_type": "stream", 69 | "text": [ 70 | "The File Count is 10001\n" 71 | ] 72 | } 73 | ], 74 | "source": [ 75 | "$FileCount = (Get-Childitem C:\\Users\\mrrob\\AppData\\Local\\Temp\\pwshplaydir).Count\n", 76 | "Write-Output \"The File Count is $FileCount\"" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 53, 82 | "metadata": {}, 83 | "outputs": [ 84 | { 85 | "name": "stdout", 86 | "output_type": "stream", 87 | "text": [ 88 | "76\n" 89 | ] 90 | } 91 | ], 92 | "source": [ 93 | "$Stopwatch.Stop()\n", 94 | "$Stopwatch.Elapsed.Milliseconds" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 54, 100 | "metadata": {}, 101 | "outputs": [ 102 | { 103 | "name": "stdout", 104 | "output_type": "stream", 105 | "text": [ 106 | "Number of Files : 10001\n", 107 | "\n", 108 | "Number of Files :10001\n", 109 | "\n", 110 | "Number of Files :10001\n", 111 | "\n" 112 | ] 113 | } 114 | ], 115 | "source": [ 116 | "#!csharp\n", 117 | "using System.IO; \n", 118 | "using System;\n", 119 | "string value;\n", 120 | "string File_Countfromenv;\n", 121 | "int fileCount = Directory.GetFiles(@\"C:\\Users\\mrrob\\AppData\\Local\\Temp\\pwshplaydir\", \"*\", SearchOption.TopDirectoryOnly).Length;\n", 122 | "Console.WriteLine($\"Number of Files : {fileCount}\\n\");\n", 123 | "value = Convert.ToString(fileCount);\n", 124 | "Console.WriteLine($\"Number of Files :{value}\\n\");\n", 125 | "Environment.SetEnvironmentVariable(\"File_Count\", value);\n", 126 | "File_Countfromenv = Environment.GetEnvironmentVariable(\"File_Count\");\n", 127 | "Console.WriteLine($\"Number of Files :{File_Countfromenv}\\n\");" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": 55, 133 | "metadata": {}, 134 | "outputs": [ 135 | { 136 | "name": "stdout", 137 | "output_type": "stream", 138 | "text": [ 139 | "The File Count is 10001\n" 140 | ] 141 | } 142 | ], 143 | "source": [ 144 | "Write-Output \"The File Count is $Env:File_Count\"" 145 | ] 146 | } 147 | ], 148 | "metadata": { 149 | "kernelspec": { 150 | "display_name": ".NET (PowerShell)", 151 | "language": "PowerShell", 152 | "name": ".net-powershell" 153 | }, 154 | "language_info": { 155 | "file_extension": ".ps1", 156 | "mimetype": "text/x-powershell", 157 | "name": "PowerShell", 158 | "version": "7.0", 159 | "pygments_lexer": "powershell" 160 | } 161 | }, 162 | "nbformat": 4, 163 | "nbformat_minor": 4 164 | } 165 | -------------------------------------------------------------------------------- /notebooks/DotNet/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | beardsql01: 4 | image: sqldbawithabeard/dbatoolsbeardsql01:v1 5 | container_name: beardsql01 6 | hostname: f443490967e7 7 | ports: 8 | - "15592:1433" 9 | - "5022:5022" 10 | networks: 11 | - BeardsMagicNetwork 12 | volumes: 13 | - C:\Users\mrrob\Documents\dbatoolsdemo:/var/opt/mssql/backups 14 | environment: 15 | - MSSQL_ENABLE_HADR=1 16 | beardsql02: 17 | image: sqldbawithabeard/dbatoolsbeardsql02:v1 18 | container_name: beardsql02 19 | hostname: f443490967e7 20 | ports: 21 | - "15593:1433" 22 | - "5023:5023" 23 | networks: 24 | - BeardsMagicNetwork 25 | volumes: 26 | - C:\Users\mrrob\Documents\dbatoolsdemo:/var/opt/mssql/backups 27 | environment: 28 | - MSSQL_ENABLE_HADR=1 29 | networks: 30 | BeardsMagicNetwork: 31 | -------------------------------------------------------------------------------- /notebooks/DotNet/dockercompose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | beardsql01: 4 | image: sqldbawithabeard/dbatoolsbeardsql01:v1 5 | container_name: beardsql01 6 | hostname: f443490967e7 7 | ports: 8 | - "15592:1433" 9 | - "5022:5022" 10 | networks: 11 | - BeardsMagicNetwork 12 | volumes: 13 | - __ReplaceMe__:/var/opt/mssql/backups 14 | environment: 15 | - MSSQL_ENABLE_HADR=1 16 | beardsql02: 17 | image: sqldbawithabeard/dbatoolsbeardsql02:v1 18 | container_name: beardsql02 19 | hostname: f443490967e7 20 | ports: 21 | - "15593:1433" 22 | - "5023:5023" 23 | networks: 24 | - BeardsMagicNetwork 25 | volumes: 26 | - __ReplaceMe__:/var/opt/mssql/backups 27 | environment: 28 | - MSSQL_ENABLE_HADR=1 29 | networks: 30 | BeardsMagicNetwork: 31 | -------------------------------------------------------------------------------- /notebooks/DotNet/images/ag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/DotNet/images/ag.png -------------------------------------------------------------------------------- /notebooks/DotNet/images/blockedprocessXE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/DotNet/images/blockedprocessXE.png -------------------------------------------------------------------------------- /notebooks/DotNet/images/containers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/DotNet/images/containers.png -------------------------------------------------------------------------------- /notebooks/DotNet/images/dbachecks-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/DotNet/images/dbachecks-logo.png -------------------------------------------------------------------------------- /notebooks/DotNet/images/dbatools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/DotNet/images/dbatools.png -------------------------------------------------------------------------------- /notebooks/DotNet/images/dbatoolsdemopermissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/DotNet/images/dbatoolsdemopermissions.png -------------------------------------------------------------------------------- /notebooks/DotNet/images/documentsdirectorypermissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/DotNet/images/documentsdirectorypermissions.png -------------------------------------------------------------------------------- /notebooks/DotNet/images/switchtolinuxcontainers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/DotNet/images/switchtolinuxcontainers.png -------------------------------------------------------------------------------- /notebooks/NotDotNet/00-CreateContainers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "kernelspec": { 4 | "name": "powershell", 5 | "display_name": "PowerShell", 6 | "language": "powershell" 7 | }, 8 | "language_info": { 9 | "name": "powershell", 10 | "codemirror_mode": "shell", 11 | "mimetype": "text/x-sh", 12 | "file_extension": ".ps1" 13 | } 14 | }, 15 | "nbformat_minor": 2, 16 | "nbformat": 4, 17 | "cells": [ 18 | { 19 | "cell_type": "markdown", 20 | "source": [ 21 | "# Creating the containers for .NET notebooks for exploring dbatools\n", 22 | "\n", 23 | "![dbatools](.\\images\\dbatools.png)\n", 24 | "\n", 25 | "We have written a book which will give you a brilliant introduction to dbatools. It's called dbatools in a Month of Lunches and you can find it at [https://beard.media/book](https://beard.media/book)\n", 26 | "\n", 27 | "# Setting up the containers for the rest of the dbatools notebooks\n", 28 | "\n", 29 | "To be able to follow along with the rest of the notebooks, you will need to set up two containers.\n", 30 | "\n", 31 | "This notebook will enable you to do that.\n", 32 | "\n", 33 | "You will need to have Docker installed [Install Docker Desktop on Windows | Docker Documentation](https://docs.docker.com/docker-for-windows/install/). The image is based on the SQL Server 2019 image so you will need to have docker set to use Linux Containers. Right click on the Docker icon in the notification area and if it says \"Switch to Linux Containers\" click to switch and wait for Docker to restart. \n", 34 | "\n", 35 | "![Switch To Linux Containers](.\\images\\switchtolinuxcontainers.png)\n", 36 | "\n", 37 | "You will be able to run all of the code in the notebooks by creating the folder, credential and containers in this notebook and then you can click on the play button in each code block to run the code. Note - There are a few code blocks with the results already included which should not be run. They are to show you the results of a command that cannot be run against containers (setting up configuration for domain accounts for example)\n", 38 | "\n", 39 | "**You can also navigate through the Notebook using the arrow keys and press SHIFT + ENTER to run a cell**" 40 | ], 41 | "metadata": { 42 | "azdata_cell_guid": "e7503606-32c6-4685-84a5-99cda6387fce" 43 | }, 44 | "attachments": {} 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "source": [ 49 | "## Create the folders and the credential\n", 50 | "\n", 51 | "The code below will create a directory called dbatools-demo in your Documents folder and save a credential file for logging into the containers. You can alter the directory created by altering the `$FolderPath` \n", 52 | "\n", 53 | "The code has been collapsed but you can view it using the view menu in the lab or by clicking the 3 ellipses" 54 | ], 55 | "metadata": { 56 | "azdata_cell_guid": "9a602f20-4924-490a-a025-1aa03bb4f4b4" 57 | } 58 | }, 59 | { 60 | "cell_type": "code", 61 | "source": [ 62 | "$NotebookDir = '' # add the directory that the notebook is in here \n", 63 | "$FolderPath = $Env:USERPROFILE + '\\Documents\\dbatoolsdemo'\n", 64 | "\n", 65 | "########################################################\n", 66 | "Write-Output \"Creating Directory $FolderPath\"\n", 67 | "if (Test-Path $FolderPath) {\n", 68 | " Write-Output \"Path $FolderPath exists already\"\n", 69 | "}\n", 70 | "else {\n", 71 | " $null = New-Item $FolderPath -ItemType Directory\n", 72 | "}\n", 73 | "\n", 74 | "Write-Output \"Creating Directory $FolderPath\\SQL1\"\n", 75 | "if (Test-Path \"$FolderPath\\SQL1\") {\n", 76 | " Write-Output \"Directory SQL1 exists already\"\n", 77 | " Get-ChildItem \"$FolderPath\\SQL1\" -Recurse | Remove-Item -Recurse -Force\n", 78 | "}\n", 79 | "else {\n", 80 | " $null = New-Item \"$FolderPath\\SQL1\"-ItemType Directory\n", 81 | "}\n", 82 | "Write-Output \"Creating File $FolderPath\\SQL1\\dummyfile.txt\"\n", 83 | "if (Test-Path \"$FolderPath\\SQL1\\dummyfile.txt\") {\n", 84 | " Write-Output \"dummyfile.txt exists already\"\n", 85 | "}\n", 86 | "else {\n", 87 | " $null = New-Item \"$FolderPath\\SQL1\\dummyfile.txt\" -ItemType file\n", 88 | "}\n", 89 | "\n", 90 | "Write-Output \"Creating Directory $FolderPath\\SQL2\"\n", 91 | "if (Test-Path \"$FolderPath\\SQL2\") {\n", 92 | " Write-Output \"Directory SQL2 exists already\"\n", 93 | " Get-ChildItem \"$FolderPath\\SQL2\" -Recurse | Remove-Item -Recurse -Force\n", 94 | "}\n", 95 | "else {\n", 96 | " $null = New-Item \"$FolderPath\\SQL2\"-ItemType Directory\n", 97 | "}\n", 98 | "Write-Output \"Creating File $FolderPath\\SQL2\\dummyfile.txt\"\n", 99 | "if (Test-Path \"$FolderPath\\SQL2\\dummyfile.txt\") {\n", 100 | " Write-Output \"dummyfile.txt exists already\"\n", 101 | "}\n", 102 | "else {\n", 103 | " $null = New-Item \"$FolderPath\\SQL2\\dummyfile.txt\" -ItemType file\n", 104 | "}\n", 105 | "\n", 106 | "Write-Output \"Creating a credential file for the containers - Please don't do this in production\"\n", 107 | "\n", 108 | "$sqladminPassword = ConvertTo-SecureString 'dbatools.IO' -AsPlainText -Force \n", 109 | "$cred = New-Object System.Management.Automation.PSCredential ('sqladmin', $sqladminpassword)\n", 110 | "$Cred | Export-Clixml -Path $FolderPath\\sqladmin.cred\n", 111 | "Write-Output \"Credential file created\"\n", 112 | "\n", 113 | "Write-Output \"Setting the docker-compose files values\"\n", 114 | "\n", 115 | "if ($NotebookDir -eq '') {\n", 116 | " try {\n", 117 | " $NotebookDir = Read-Host \"Please enter path to the notebook. Azure Data Studio doesnt know where it is\" -ErrorAction Stop\n", 118 | " }\n", 119 | " catch {\n", 120 | " Write-Warning \"UH-OH - You have not set the `$NotebookDir variable to a directory we can find - Set it in the code please\"\n", 121 | " Break\n", 122 | " }\n", 123 | "}\n", 124 | "if (-not (Test-Path $NotebookDir -ErrorAction SilentlyContinue)) {\n", 125 | " Write-Warning \"UH-OH - You have not set the `$NotebookDir variable to a directory we can find - Set it in the code please\"\n", 126 | " Break\n", 127 | "}\n", 128 | "\n", 129 | "$dockercompose = (Get-Content $NotebookDir\\\\dockercompose.yml -ErrorAction Stop) -replace '__ReplaceME__' , $FolderPath\n", 130 | "# $dockercompose\n", 131 | "$dockercompose | Set-Content $NotebookDir\\\\docker-compose.yml\n", 132 | "Set-Location $NotebookDir\n", 133 | "\n", 134 | "Write-Output \"Finished\"" 135 | ], 136 | "metadata": { 137 | "azdata_cell_guid": "da2a1233-6845-4031-b5dd-fc65263cc832", 138 | "tags": [ 139 | "hide_input" 140 | ] 141 | }, 142 | "outputs": [], 143 | "execution_count": null 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "source": [ 148 | "## Containers\n", 149 | "\n", 150 | "We are going to create two SQL 2019 containers using the sqldbawithabeard\\dbatoolsbeardsql01 [image from the Docker Hub](https://hub.docker.com/repository/docker/sqldbawithabeard/dbatoolsbeardsql01) and sqldbawithabeard\\dbatoolsbeardsql02 [image from the Docker Hub](https://hub.docker.com/repository/docker/sqldbawithabeard/dbatoolsbeardsql02)\n", 151 | "\n", 152 | "The first time it is going to pull the images from the Docker Hub. If you wish to do this first, you can run the cell below\n", 153 | "\n", 154 | "" 155 | ], 156 | "metadata": { 157 | "azdata_cell_guid": "82e68f8a-0aa6-4f70-a781-7e511c1a762f" 158 | } 159 | }, 160 | { 161 | "cell_type": "code", 162 | "source": [ 163 | "docker pull sqldbawithabeard/dbatoolsbeardsql01:v1\r\n", 164 | "docker pull sqldbawithabeard/dbatoolsbeardsql02:v1" 165 | ], 166 | "metadata": { 167 | "azdata_cell_guid": "689caa3f-e974-41ad-a35b-8c2e1f609386" 168 | }, 169 | "outputs": [], 170 | "execution_count": null 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "source": [ 175 | "Now we can start the containers with the code below" 176 | ], 177 | "metadata": { 178 | "azdata_cell_guid": "1771c1c6-4dbb-46e5-b0ad-d66cd66e855e" 179 | } 180 | }, 181 | { 182 | "cell_type": "code", 183 | "source": [ 184 | "docker-compose up -d" 185 | ], 186 | "metadata": { 187 | "azdata_cell_guid": "d05505a2-c39e-4402-93cd-059430df01a3" 188 | }, 189 | "outputs": [], 190 | "execution_count": null 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "source": [ 195 | "All being well, you wil have something that looks like\n", 196 | "\n", 197 | "\n", 198 | "![DockerCompose](.\\images\\containers.png )\n", 199 | "\n", 200 | "If you get an error you might need to add the user you have shared your drives with Docker modify permissions to the \\Documents\\ directory in your user profile \n", 201 | "More details https://docs.docker.com/docker-for-windows/ or troubleshoot in the normal way\n", 202 | "\n", 203 | "\n", 204 | "Now we can start exploring with dbatools :-)\n", 205 | "\n", 206 | "If you have not installed dbatools, it can be got from the PowerShell Gallery using `Install-Module dbatools` the code below will check for the module and either install it in your user profile or update it and Import it" 207 | ], 208 | "metadata": { 209 | "azdata_cell_guid": "6eeea37c-830b-4a3c-9355-db07601ab47b" 210 | } 211 | }, 212 | { 213 | "cell_type": "code", 214 | "source": [ 215 | "if(Get-Module dbatools -ListAvailable){\n", 216 | "Write-Output \"Updating dbatools\"\n", 217 | "Update-Module dbatools\n", 218 | "}else {\n", 219 | "Write-Output \"Installing dbatools in your user profile\"\n", 220 | "Install-Module dbatools -Scope CurrentUser\n", 221 | "}\n", 222 | "Import-Module dbatools" 223 | ], 224 | "metadata": { 225 | "azdata_cell_guid": "ddff53ab-f6d0-4c74-abc6-f79487d77f19" 226 | }, 227 | "outputs": [], 228 | "execution_count": null 229 | }, 230 | { 231 | "cell_type": "markdown", 232 | "source": [ 233 | "## Check connection\n", 234 | "Now that is done, we can make a connection to our instances and see if we can connect to them.\n", 235 | "\n", 236 | "We are going to use `Connect-DBaInstance` to do this and we will use the containers that we have created and because we need to use SQL Authentication, we will use a credential that we have saved to disk using `Export-CliXML` in one of the celss above.\n", 237 | "\n", 238 | "It is **Important** to state that this is not a production secure solution and should not be used as a means of accessing any secure system." 239 | ], 240 | "metadata": { 241 | "azdata_cell_guid": "c6cfbe4c-5e3b-4312-ab12-91416a3cc02d" 242 | } 243 | }, 244 | { 245 | "cell_type": "code", 246 | "source": [ 247 | "$FolderPath = $Env:USERPROFILE + '\\Documents\\dbatoolsdemo'\n", 248 | "$SqlInstances = 'localhost,15592', 'localhost,15593'\n", 249 | "$SqlCredential = Import-Clixml -Path $FolderPath\\sqladmin.cred\n", 250 | "Write-Output \" Creating connection to the containers\"\n", 251 | "try {\n", 252 | " $SQL1 = Connect-DbaInstance -SqlInstance $SqlInstances[0] -SqlCredential $SqlCredential \n", 253 | " $SQL2 = Connect-DbaInstance -SqlInstance $SqlInstances[1] -SqlCredential $SqlCredential\n", 254 | " Write-Output \"We have a connection to the containers\"\n", 255 | "\n", 256 | "}\n", 257 | "catch {\n", 258 | " Write-Output \"You haven't got a connection to the containers - Either they are still upgrading in which case try again in 30 seconds or the containers have not come up correctly\"\n", 259 | " Write-Output \"Make sure the containers are running - the code is below in a block for you\"\n", 260 | " Write-Output \"docker ps -a\"\n", 261 | " Write-Output \"If they are read the logs - the code is below in a block for you\"\n", 262 | " Write-Output \"docker logs beardsql01\"\n", 263 | " Write-Output \"docker logs beardsql02\"\n", 264 | "}" 265 | ], 266 | "metadata": { 267 | "azdata_cell_guid": "e8e0f4c0-9328-42f4-b328-6cca11d2ad54", 268 | "jupyter": { 269 | "source_hidden": true 270 | } 271 | }, 272 | "outputs": [], 273 | "execution_count": null 274 | }, 275 | { 276 | "cell_type": "markdown", 277 | "source": [ 278 | "If there are warnings above - Check the containers are running - Look at the status column" 279 | ], 280 | "metadata": { 281 | "azdata_cell_guid": "ec7b3d4b-e1a3-4668-ac40-a89a064d74e2" 282 | } 283 | }, 284 | { 285 | "cell_type": "code", 286 | "source": [ 287 | "docker ps -a" 288 | ], 289 | "metadata": { 290 | "azdata_cell_guid": "6ab5d62d-2069-4206-b555-b3c1a76a7f1d" 291 | }, 292 | "outputs": [], 293 | "execution_count": null 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "source": [ 298 | "If there are warnings above and the containers are running - check the logs" 299 | ], 300 | "metadata": { 301 | "azdata_cell_guid": "a6ed4b0c-37e0-4a79-a63f-bd35616df3ea" 302 | } 303 | }, 304 | { 305 | "cell_type": "code", 306 | "source": [ 307 | "docker logs beardsql01" 308 | ], 309 | "metadata": { 310 | "azdata_cell_guid": "67480623-8a3f-4236-8a69-21438c35d90a" 311 | }, 312 | "outputs": [], 313 | "execution_count": null 314 | }, 315 | { 316 | "cell_type": "markdown", 317 | "source": [ 318 | "If there are warnings above and the containers are running - check the logs" 319 | ], 320 | "metadata": { 321 | "azdata_cell_guid": "93044e3d-d9d1-4b03-aab6-0438eb3d9fb9" 322 | } 323 | }, 324 | { 325 | "cell_type": "code", 326 | "source": [ 327 | "docker logs beardsql02" 328 | ], 329 | "metadata": { 330 | "azdata_cell_guid": "00d631fb-0dc2-421b-bdd3-fb6ec20c1c5b" 331 | }, 332 | "outputs": [], 333 | "execution_count": null 334 | }, 335 | { 336 | "cell_type": "markdown", 337 | "source": [ 338 | "Now you can use these containers to run the rest of the notebooks - Don't forget to run the Clean Up Containers Notebook at the end to clean up" 339 | ], 340 | "metadata": { 341 | "azdata_cell_guid": "51f09646-69f5-46a7-acf0-33d227489314" 342 | } 343 | } 344 | ] 345 | } -------------------------------------------------------------------------------- /notebooks/NotDotNet/01-Introduction.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "kernelspec": { 4 | "name": "powershell", 5 | "display_name": "PowerShell", 6 | "language": "powershell" 7 | }, 8 | "language_info": { 9 | "name": "powershell", 10 | "codemirror_mode": "shell", 11 | "mimetype": "text/x-sh", 12 | "file_extension": ".ps1" 13 | } 14 | }, 15 | "nbformat_minor": 2, 16 | "nbformat": 4, 17 | "cells": [ 18 | { 19 | "cell_type": "markdown", 20 | "source": [ 21 | "# Introduction\n", 22 | "\n", 23 | "How do you start with dbatools?\n", 24 | "\n", 25 | "Lets look at how you can begin and how you can help your self to be able to use dbatools\n", 26 | "\n", 27 | "***You will need to have followed the steps in the 00-CreateContainers notebook to use this notebook***\n", 28 | "\n", 29 | "We have written a book which will give you a brilliant introduction to dbatools. It's called dbatools in a Month of Lunches and you can find it at https://beard.media/book" 30 | ], 31 | "metadata": { 32 | "azdata_cell_guid": "c2e1450c-7c7f-4400-b427-e77c8afbc967" 33 | } 34 | }, 35 | { 36 | "cell_type": "code", 37 | "source": [ 38 | "## Lets look at the commands\n", 39 | "Get-Command -Module dbatools " 40 | ], 41 | "metadata": { 42 | "azdata_cell_guid": "4c5d55a6-203d-4a4f-9f3d-e4c21b4d6070" 43 | }, 44 | "outputs": [], 45 | "execution_count": null 46 | }, 47 | { 48 | "cell_type": "code", 49 | "source": [ 50 | "## How many commands?\n", 51 | "(Get-Command -Module dbatools -CommandType Function ).Count" 52 | ], 53 | "metadata": { 54 | "azdata_cell_guid": "0c674263-5c7d-4ebc-9718-1f18922635a4" 55 | }, 56 | "outputs": [], 57 | "execution_count": null 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "source": [ 62 | "## How do we find commands ?\n", 63 | "\n", 64 | "With that many commands even Chrissy can't remember them all !\n", 65 | "\n", 66 | "So there is a command to find commands" 67 | ], 68 | "metadata": { 69 | "azdata_cell_guid": "9373b8e2-d16b-4e15-b119-f8aa36585f61" 70 | } 71 | }, 72 | { 73 | "cell_type": "code", 74 | "source": [ 75 | "Find-DbaCommand -Tag Backup" 76 | ], 77 | "metadata": { 78 | "azdata_cell_guid": "e80e58a9-2e60-4048-bb32-62dbd60702e7" 79 | }, 80 | "outputs": [], 81 | "execution_count": null 82 | }, 83 | { 84 | "cell_type": "code", 85 | "source": [ 86 | "Find-DbaCommand -Tag Restore" 87 | ], 88 | "metadata": { 89 | "azdata_cell_guid": "983a8d9f-7666-41b2-8255-3e914a9972d3" 90 | }, 91 | "outputs": [], 92 | "execution_count": null 93 | }, 94 | { 95 | "cell_type": "code", 96 | "source": [ 97 | "Find-DbaCommand -Tag Migration" 98 | ], 99 | "metadata": { 100 | "azdata_cell_guid": "352839bb-0f45-44f8-8596-18bf8cbb7f46" 101 | }, 102 | "outputs": [], 103 | "execution_count": null 104 | }, 105 | { 106 | "cell_type": "code", 107 | "source": [ 108 | "Find-DbaCommand -Tag Agent" 109 | ], 110 | "metadata": { 111 | "azdata_cell_guid": "b074e028-7872-4cf6-b89d-0822760a897a" 112 | }, 113 | "outputs": [], 114 | "execution_count": null 115 | }, 116 | { 117 | "cell_type": "code", 118 | "source": [ 119 | "Find-DbaCommand -Pattern User " 120 | ], 121 | "metadata": { 122 | "azdata_cell_guid": "7196cfef-4f9c-4aab-9ae4-45779205f4d1" 123 | }, 124 | "outputs": [], 125 | "execution_count": null 126 | }, 127 | { 128 | "cell_type": "code", 129 | "source": [ 130 | "Find-DbaCommand -Pattern linked" 131 | ], 132 | "metadata": { 133 | "azdata_cell_guid": "c06460e7-12b5-4c19-a26e-f7aab540dd9c" 134 | }, 135 | "outputs": [], 136 | "execution_count": null 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "source": [ 141 | "## You can also use native PowerShell \n", 142 | "\n", 143 | "This can be used with any module" 144 | ], 145 | "metadata": { 146 | "azdata_cell_guid": "23e63ec8-b5be-4260-a71a-c2c8e23efb9d" 147 | } 148 | }, 149 | { 150 | "cell_type": "code", 151 | "source": [ 152 | "Get-Command -Module dbatools -Name *linked*" 153 | ], 154 | "metadata": { 155 | "azdata_cell_guid": "84d6ffe1-2a6d-47bf-8358-bd52c5cf2a1c" 156 | }, 157 | "outputs": [], 158 | "execution_count": null 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "source": [ 163 | "# How to use commands ?\n", 164 | "\n", 165 | "**ALWAYS ALWAYS ALWAYS use `Get-Help`**" 166 | ], 167 | "metadata": { 168 | "azdata_cell_guid": "8dc7d4ec-8021-4b19-a58c-8b3b1ee91acc" 169 | } 170 | }, 171 | { 172 | "cell_type": "code", 173 | "source": [ 174 | "Get-Help Test-DbaLinkedServerConnection -Full" 175 | ], 176 | "metadata": { 177 | "azdata_cell_guid": "046a7638-acb4-4d01-a2fc-e051e90f451f" 178 | }, 179 | "outputs": [], 180 | "execution_count": null 181 | }, 182 | { 183 | "cell_type": "code", 184 | "source": [ 185 | "## Here a neat trick which you can use in PowerShell or pwsh but not in a notebook!\n", 186 | "## When PowerShell opens - right click to paste the command\n", 187 | "# Find-DbaCommand -Pattern linked | Out-GridView -PassThru | Get-Help -Full \n", 188 | "\"Find-DbaCommand -Pattern linked | Out-GridView -PassThru | Get-Help -Full \" | clip\n", 189 | "# If you have PowerShell 7\n", 190 | " Start-Process 'C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe'\n", 191 | "\n", 192 | "# if you dont have PowerShell 7 then you can uncomment (remove the #) from the line below and comment (add a # to the beginning) of the line above\n", 193 | "# Start-Process 'C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe'" 194 | ], 195 | "metadata": { 196 | "azdata_cell_guid": "1112a493-763f-487b-b040-1c9757b03034" 197 | }, 198 | "outputs": [], 199 | "execution_count": null 200 | }, 201 | { 202 | "cell_type": "markdown", 203 | "source": [ 204 | "# Clean Up\n", 205 | "\n", 206 | "The 99-CleanUpContainers notebook will remove the containers, files and directory - it will leave the image so you do not have to download it again!" 207 | ], 208 | "metadata": { 209 | "azdata_cell_guid": "57b0d390-ffdf-4079-8c1d-0f5b96aa501b" 210 | } 211 | } 212 | ] 213 | } -------------------------------------------------------------------------------- /notebooks/NotDotNet/06-AgentJobs.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "kernelspec": { 4 | "name": "powershell", 5 | "display_name": "PowerShell", 6 | "language": "powershell" 7 | }, 8 | "language_info": { 9 | "name": "powershell", 10 | "codemirror_mode": "shell", 11 | "mimetype": "text/x-sh", 12 | "file_extension": ".ps1" 13 | } 14 | }, 15 | "nbformat_minor": 2, 16 | "nbformat": 4, 17 | "cells": [ 18 | { 19 | "cell_type": "markdown", 20 | "source": [ 21 | "# Working with Agent Jobs with dbatools\n", 22 | "\n", 23 | "You can use dbatools to administer your Agent jobs. Make sure that you have first run your create container notebook\n", 24 | "\n", 25 | "We have written a book which will give you a brilliant introduction to dbatools. It's called dbatools in a Month of Lunches and you can find it at https://beard.media/book\n", 26 | "\n", 27 | "The cell block below will create the variables that you will need for the rest of the notebook\n", 28 | "\n", 29 | "You can run the code by using the arrow keys and shift and enter" 30 | ], 31 | "metadata": { 32 | "azdata_cell_guid": "bb22d6b7-3379-462c-99e0-17644cd6535f" 33 | } 34 | }, 35 | { 36 | "cell_type": "code", 37 | "source": [ 38 | "$FolderPath = $Env:USERPROFILE + '\\Documents\\dbatoolsdemo'\n", 39 | "$SqlInstances = 'localhost,15592', 'localhost,15593'\n", 40 | "$SqlCredential = Import-Clixml -Path $FolderPath\\sqladmin.cred\n", 41 | "Write-Output \" Creating connection to the containers\"\n", 42 | "try {\n", 43 | " $SQL1 = Connect-DbaInstance -SqlInstance $SqlInstances[0] -SqlCredential $SqlCredential \n", 44 | " $SQL2 = Connect-DbaInstance -SqlInstance $SqlInstances[1] -SqlCredential $SqlCredential\n", 45 | " Write-Output \"We have a connection to the containers\"\n", 46 | "\n", 47 | "}\n", 48 | "catch {\n", 49 | " Write-Output \"You haven't got a connection to the containers - Either they are still upgrading in which case try again in 30 seconds or the containers have not come up correctly\"\n", 50 | " Write-Output \"Make sure the containers are running - the code is below in a block for you\"\n", 51 | " Write-Output \"docker ps -a\"\n", 52 | " Write-Output \"If they are read the logs - the code is below in a block for you\"\n", 53 | " Write-Output \"docker logs dbatools_SQL2019_1\"\n", 54 | " Write-Output \"docker logs dbatools_SQL2019-1_1\"\n", 55 | "}\n", 56 | "# Run this first to make sure output width does not mess with output - Update output buffer size to prevent clipping in Visual Studio output window.\n", 57 | "if( $Host -and $Host.UI -and $Host.UI.RawUI ) {\n", 58 | " $rawUI = $Host.UI.RawUI\n", 59 | " $oldSize = $rawUI.BufferSize\n", 60 | " $typeName = $oldSize.GetType( ).FullName\n", 61 | " $newSize = New-Object $typeName (500, $oldSize.Height)\n", 62 | " $rawUI.BufferSize = $newSize\n", 63 | " }" 64 | ], 65 | "metadata": { 66 | "jupyter": { 67 | "source_hidden": true 68 | }, 69 | "azdata_cell_guid": "027eb9ed-0cbe-4bc5-95e6-14c04d741d95", 70 | "tags": [ 71 | "hide_input" 72 | ] 73 | }, 74 | "outputs": [], 75 | "execution_count": null 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "source": [ 80 | "## List the Agent jobs on the instance\n", 81 | "\n", 82 | "You can very quickly list all the agent jobs on an instance with dbatools" 83 | ], 84 | "metadata": { 85 | "azdata_cell_guid": "5be1ad92-499e-4040-9f0f-e296b4f11d22" 86 | } 87 | }, 88 | { 89 | "cell_type": "code", 90 | "source": [ 91 | "Get-DbaAgentJob -SqlInstance $sql1 | Format-Table" 92 | ], 93 | "metadata": { 94 | "azdata_cell_guid": "58634944-9a9a-4b70-976d-a77d5a6cf097" 95 | }, 96 | "outputs": [], 97 | "execution_count": null 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "source": [ 102 | "You can get info about a particular job" 103 | ], 104 | "metadata": { 105 | "azdata_cell_guid": "4db1ea57-667c-4d55-ab2a-cf0316c2756b" 106 | } 107 | }, 108 | { 109 | "cell_type": "code", 110 | "source": [ 111 | "Get-DbaAgentJob -SqlInstance $sql1 -Job 'The Beard is Important'" 112 | ], 113 | "metadata": { 114 | "azdata_cell_guid": "a367f38d-edf8-4f57-9e4f-b0c6bf8f5eb3" 115 | }, 116 | "outputs": [], 117 | "execution_count": null 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "source": [ 122 | "Job Steps" 123 | ], 124 | "metadata": { 125 | "azdata_cell_guid": "a2ad4b9c-d335-43f8-847c-c218e0932b9c" 126 | } 127 | }, 128 | { 129 | "cell_type": "code", 130 | "source": [ 131 | "Get-DbaAgentJobStep -SqlInstance $SQL1 -Job 'The Beard is Important'" 132 | ], 133 | "metadata": { 134 | "azdata_cell_guid": "f2a77863-6c58-4f04-afcc-e8dfb5ec17d7" 135 | }, 136 | "outputs": [], 137 | "execution_count": null 138 | }, 139 | { 140 | "cell_type": "markdown", 141 | "source": [ 142 | "You can remove jobs \n", 143 | "\n", 144 | "**PLEASE DON'T DO THIS IN PRODUCTION**" 145 | ], 146 | "metadata": { 147 | "azdata_cell_guid": "fb396890-c4b5-4635-8654-06cff6efcfca" 148 | } 149 | }, 150 | { 151 | "cell_type": "code", 152 | "source": [ 153 | "Get-DbaAgentJob -SqlInstance $SQL2 | Remove-DbaAgentJob -Confirm:$false" 154 | ], 155 | "metadata": { 156 | "azdata_cell_guid": "57dc4034-f8c4-44ad-b5be-44988f53dc1e" 157 | }, 158 | "outputs": [], 159 | "execution_count": null 160 | }, 161 | { 162 | "cell_type": "markdown", 163 | "source": [ 164 | "We have no jobs on SQL2" 165 | ], 166 | "metadata": { 167 | "azdata_cell_guid": "13d31934-319b-4440-a14d-9d24d535be2f" 168 | } 169 | }, 170 | { 171 | "cell_type": "code", 172 | "source": [ 173 | " $SQL2 = Connect-DbaInstance -SqlInstance $SqlInstances[1] -SqlCredential $SqlCredential\n", 174 | "Get-DbaAgentJob -SqlInstance $SQL2" 175 | ], 176 | "metadata": { 177 | "azdata_cell_guid": "36e7043a-6c66-4d5d-89d4-fb9694cc5cab" 178 | }, 179 | "outputs": [], 180 | "execution_count": null 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "source": [ 185 | "If you have run through the notebooks, you might still have the Availability Group that was created in Notebook 03\n", 186 | "\n", 187 | "You would want your Agent Jobs to be the same on all replicas so that if you failover everything works\n", 188 | "\n", 189 | "dbatools has you covered" 190 | ], 191 | "metadata": { 192 | "azdata_cell_guid": "42cff201-9ce5-4065-987b-2163f172a95e" 193 | } 194 | }, 195 | { 196 | "cell_type": "code", 197 | "source": [ 198 | "Copy-DbaAgentJob -Source $SQL1 -Destination $SQL2" 199 | ], 200 | "metadata": { 201 | "azdata_cell_guid": "7b23de5b-36ea-40c0-acd1-edf0a52eed28" 202 | }, 203 | "outputs": [], 204 | "execution_count": null 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "source": [ 209 | "and just like that all jobs are on SQL2" 210 | ], 211 | "metadata": { 212 | "azdata_cell_guid": "623f4a38-4363-494a-ab90-625c8a905468" 213 | } 214 | }, 215 | { 216 | "cell_type": "code", 217 | "source": [ 218 | " $SQL2 = Connect-DbaInstance -SqlInstance $SqlInstances[1] -SqlCredential $SqlCredential\n", 219 | "Get-DbaAgentJob -SqlInstance $SQL2|Format-Table" 220 | ], 221 | "metadata": { 222 | "azdata_cell_guid": "3db8ce8d-b269-4965-bdcb-445a06581b1c" 223 | }, 224 | "outputs": [], 225 | "execution_count": null 226 | }, 227 | { 228 | "cell_type": "markdown", 229 | "source": [ 230 | "# Clean Up\n", 231 | "\n", 232 | "The 99-CleanUpContainers notebook will remove the containers, files and directory - it will leave the image so you do not have to download it again!" 233 | ], 234 | "metadata": { 235 | "azdata_cell_guid": "6a216fd0-3bf3-42a4-add8-ec977fb38dec" 236 | } 237 | } 238 | ] 239 | } -------------------------------------------------------------------------------- /notebooks/NotDotNet/99-CleanUpContainers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "kernelspec": { 4 | "name": "powershell", 5 | "display_name": "PowerShell", 6 | "language": "powershell" 7 | }, 8 | "language_info": { 9 | "name": "powershell", 10 | "codemirror_mode": "shell", 11 | "mimetype": "text/x-sh", 12 | "file_extension": ".ps1" 13 | } 14 | }, 15 | "nbformat_minor": 2, 16 | "nbformat": 4, 17 | "cells": [ 18 | { 19 | "cell_type": "markdown", 20 | "source": [ 21 | "# Cleaning up the containers and directories and files\n", 22 | "\n", 23 | "The code below will clean up the files that have been created and remove the docker containers but not the image so that you can run the notebooks again without having to download the image again" 24 | ], 25 | "metadata": { 26 | "azdata_cell_guid": "bf39922e-c732-4c24-8630-1694d703c50e" 27 | }, 28 | "attachments": {} 29 | }, 30 | { 31 | "cell_type": "code", 32 | "source": [ 33 | "$NotebookDir = '' # add the directory that the notebook is in here \n", 34 | "if ($NotebookDir -eq '') {\n", 35 | " try {\n", 36 | " $NotebookDir = Read-Host \"Please enter path to the notebook. Azure Data Studio doesnt know where it is\" -ErrorAction Stop\n", 37 | " }\n", 38 | " catch {\n", 39 | " Write-Warning \"UH-OH - You have not set the `$NotebookDir variable to a directory we can find - Set it in the code please\"\n", 40 | " Break\n", 41 | " }\n", 42 | "}\n", 43 | "if (-not (Test-Path $NotebookDir -ErrorAction SilentlyContinue)) {\n", 44 | " Write-Warning \"UH-OH - You have not set the `$NotebookDir variable to a directory we can find - Set it in the code please\"\n", 45 | " Break\n", 46 | "}\n", 47 | "$FolderPath = $Env:USERPROFILE + '\\Documents\\dbatoolsdemo'\n", 48 | "Write-Output \"Removing containers\"\n", 49 | "\n", 50 | "Set-Location $NotebookDir\n", 51 | "docker-compose down \n", 52 | "\n", 53 | "\n", 54 | "Write-Output \"Removing directories and files\"\n", 55 | "Remove-Item $FolderPath -Recurse -Force\n", 56 | "Write-Output \"Removed everything\"\n", 57 | "" 58 | ], 59 | "metadata": { 60 | "azdata_cell_guid": "45750e3c-b1a5-430f-b79c-d85430564841", 61 | "tags": [ 62 | "hide_input" 63 | ] 64 | }, 65 | "outputs": [ 66 | { 67 | "name": "stdout", 68 | "text": "\u001b[1A\u001b[2KStopping beardsql02 ... \u001b[32mdone\u001b[0m\u001b[1B", 69 | "output_type": "stream" 70 | }, 71 | { 72 | "name": "stdout", 73 | "text": "\u001b[2A\u001b[2KStopping beardsql01 ... \u001b[32mdone\u001b[0m\u001b[2BRemoving beardsql01 ... \nRemoving beardsql02 ... \n", 74 | "output_type": "stream" 75 | }, 76 | { 77 | "name": "stdout", 78 | "text": "\u001b[1A\u001b[2KRemoving beardsql02 ... \u001b[32mdone\u001b[0m\u001b[1B\u001b[2A\u001b[2KRemoving beardsql01 ... \u001b[32mdone\u001b[0m\u001b[2BRemoving network dbatools_BeardsMagicNetwork\n", 79 | "output_type": "stream" 80 | }, 81 | { 82 | "name": "stdout", 83 | "text": "Removing directories and files\nRemoved everything\n", 84 | "output_type": "stream" 85 | } 86 | ], 87 | "execution_count": 1 88 | }, 89 | { 90 | "cell_type": "code", 91 | "source": [ 92 | "docker ps -a" 93 | ], 94 | "metadata": { 95 | "azdata_cell_guid": "06243d1c-1e53-4a2a-9cae-47c6934eb20c" 96 | }, 97 | "outputs": [], 98 | "execution_count": null 99 | } 100 | ] 101 | } -------------------------------------------------------------------------------- /notebooks/NotDotNet/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | beardsql01: 4 | image: sqldbawithabeard/dbatoolsbeardsql01:v1 5 | container_name: beardsql01 6 | hostname: f443490967e7 7 | ports: 8 | - "15592:1433" 9 | - "5022:5022" 10 | networks: 11 | - BeardsMagicNetwork 12 | volumes: 13 | - C:\Users\mrrob\Documents\dbatoolsdemo:/var/opt/mssql/backups 14 | environment: 15 | - MSSQL_ENABLE_HADR=1 16 | beardsql02: 17 | image: sqldbawithabeard/dbatoolsbeardsql02:v1 18 | container_name: beardsql02 19 | hostname: f443490967e7 20 | ports: 21 | - "15593:1433" 22 | - "5023:5023" 23 | networks: 24 | - BeardsMagicNetwork 25 | volumes: 26 | - C:\Users\mrrob\Documents\dbatoolsdemo:/var/opt/mssql/backups 27 | environment: 28 | - MSSQL_ENABLE_HADR=1 29 | networks: 30 | BeardsMagicNetwork: 31 | -------------------------------------------------------------------------------- /notebooks/NotDotNet/dockercompose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | beardsql01: 4 | image: sqldbawithabeard/dbatoolsbeardsql01:v1 5 | container_name: beardsql01 6 | hostname: f443490967e7 7 | ports: 8 | - "15592:1433" 9 | - "5022:5022" 10 | networks: 11 | - BeardsMagicNetwork 12 | volumes: 13 | - __ReplaceMe__:/var/opt/mssql/backups 14 | environment: 15 | - MSSQL_ENABLE_HADR=1 16 | beardsql02: 17 | image: sqldbawithabeard/dbatoolsbeardsql02:v1 18 | container_name: beardsql02 19 | hostname: f443490967e7 20 | ports: 21 | - "15593:1433" 22 | - "5023:5023" 23 | networks: 24 | - BeardsMagicNetwork 25 | volumes: 26 | - __ReplaceMe__:/var/opt/mssql/backups 27 | environment: 28 | - MSSQL_ENABLE_HADR=1 29 | networks: 30 | BeardsMagicNetwork: 31 | -------------------------------------------------------------------------------- /notebooks/NotDotNet/images/RefreshPowerBi.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/NotDotNet/images/RefreshPowerBi.gif -------------------------------------------------------------------------------- /notebooks/NotDotNet/images/ag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/NotDotNet/images/ag.png -------------------------------------------------------------------------------- /notebooks/NotDotNet/images/blockedprocessXE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/NotDotNet/images/blockedprocessXE.png -------------------------------------------------------------------------------- /notebooks/NotDotNet/images/containers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/NotDotNet/images/containers.png -------------------------------------------------------------------------------- /notebooks/NotDotNet/images/dbachecks-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/NotDotNet/images/dbachecks-logo.png -------------------------------------------------------------------------------- /notebooks/NotDotNet/images/dbatools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/NotDotNet/images/dbatools.png -------------------------------------------------------------------------------- /notebooks/NotDotNet/images/dbatoolsdemopermissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/NotDotNet/images/dbatoolsdemopermissions.png -------------------------------------------------------------------------------- /notebooks/NotDotNet/images/documentsdirectorypermissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/NotDotNet/images/documentsdirectorypermissions.png -------------------------------------------------------------------------------- /notebooks/NotDotNet/images/firstpowerbi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/NotDotNet/images/firstpowerbi.png -------------------------------------------------------------------------------- /notebooks/NotDotNet/images/switchtolinuxcontainers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/NotDotNet/images/switchtolinuxcontainers.png -------------------------------------------------------------------------------- /notebooks/NotDotNet/images/video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/notebooks/NotDotNet/images/video.png -------------------------------------------------------------------------------- /notebooks/readme.md: -------------------------------------------------------------------------------- 1 | # Notebooks 2 | 3 | There are two directories here which contain notebooks that can be used in Azure Data Studio to explore dbatools using docker containers, one for DotNet Notebooks and one for NotDotNet Notebooks 4 | 5 | These notebooks are based off of Rob Sewell's Jupyter Notebooks, for more information: 6 | - GitHub Repo: [SQLDBAWithABeard/JupyterNotebooks](https://github.com/SQLDBAWithABeard/JupyterNotebooks) 7 | - Rob's Blog: [Getting PowerShell 7 notebooks setup](https://blog.robsewell.com/blog/jupyter%20notebooks/azure%20data%20studio/powershell/pwsh/dbatools/dbachecks/new-net-notebooks-are-here-powershell-7-notebooks-are-here/) -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # dbatools Lab environment 2 | 3 | This repo contains scripts to help you build a lab suitable for following along with the dbatools MOL labs and exercises. 4 | 5 | ## Config 6 | This folder holds our configuration information that will be used throughout the other scripts. Here you can configure where we'll store backups, where the installation media is, and many more values. 7 | 8 | ## Scripts 9 | This folder holds all the scripts we need to get our lab built: 10 | - 00_Install_Prereqs.ps1 11 | - This script presumes you are connected to the internet, and helps to download all the software you'll need. 12 | - If you are not connected to the internet you will need to manually download a few things and copy them to your lab. 13 | - 01_Install_Lab.ps1 14 | - This will install two instances of SQL Server, if you only have resources for one that is also an option 15 | - 02_Configure_Lab.ps1 16 | - this will create objects for us to explore and can be run against the SQL Server installation we created in step 1 or a test instance you already have kicking around. 17 | - 99_Cleanup_Lab.ps1 18 | - this will clean up all the objects created in the configuration step 19 | - It won't uninstall instances 20 | 21 | ## Tests - Coming Soon! 22 | We love using pester to make sure everything looks like we expect it to. The tests folder contains pester tests that you can run to ensure our dbatools lab is set up perfectly and ready for us to use. 23 | 24 | ## Advanced - Coming Soon! 25 | This folder will contain some more advanced scripts, for example terraform that will setup an Azure VM for the lab. -------------------------------------------------------------------------------- /scripts/00_Install_Prereqs.ps1: -------------------------------------------------------------------------------- 1 | <###################################### 2 | dbatools-lab - 00_Install_Prereqs.ps1 3 | ####################################### 4 | This Install_Prereq file presumes you have internet connectivity. 5 | If not, you'll need to download the following and copy them onto the VM 6 | - dbatools & dbachecks Powershell module 7 | - SQL Server Management Studio 8 | - Azure Data Studio 9 | - PowerBI Desktop 10 | - dbatools-lab repo 11 | - WideWorldImporters backup 12 | #> 13 | 14 | # Read in our configuration file - any values to be changed are in here. 15 | $config = Import-PowerShellDataFile -Path .\Config\Config.psd1 16 | 17 | ## Download software, etc 18 | # Install the latest version of dbatools 19 | Install-Module dbatools 20 | 21 | # Install the latest version of dbachecks 22 | Install-Module dbachecks 23 | 24 | # Install Chocolatey 25 | Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) 26 | 27 | # Install ADS, SSMS 28 | choco install ssms -y 29 | choco install azure-data-studio -y 30 | 31 | # Install VSCode & PowerShell Extension 32 | choco install vscode -y 33 | choco install vscode-powershell -y 34 | 35 | # Install PowerBI Desktop - needed for dbachecks 36 | choco install powerbi -y 37 | 38 | # we'll use git to pull down this repo to the VM 39 | choco install git -y 40 | 41 | # download bak for WideWorldImporters 42 | if(!(Test-Path $config.BackupPath)) { 43 | New-Item -Path $config.BackupPath -Type Directory 44 | } 45 | $wrSplat = @{ 46 | uri = 'https://github.com/Microsoft/sql-server-samples/releases/download/wide-world-importers-v1.0/WideWorldImporters-Full.bak' 47 | OutFile = (Join-Path $config.BackupPath 'WideWorldImporters-Full.bak') 48 | } 49 | Invoke-WebRequest @wrSplat 50 | 51 | # download bak for AdventureWorks 52 | if(!(Test-Path $config.BackupPath)) { 53 | New-Item -Path $config.BackupPath -Type Directory 54 | } 55 | $wrSplat = @{ 56 | uri = 'https://github.com/Microsoft/sql-server-samples/releases/download/adventureworks/AdventureWorks2017.bak' 57 | OutFile = (Join-Path $config.BackupPath 'AdventureWorks2017-Full.bak') 58 | } 59 | Invoke-WebRequest @wrSplat 60 | 61 | # Add permissions for service accounts to backup folder 62 | # Both SQL Server Engine service accounts need to have access to the backup folder 63 | # You can find the service account names with the following once you've installed the instances: 64 | Get-DbaService -ComputerName dbatoolslab -Type Engine -------------------------------------------------------------------------------- /scripts/01_Install_Lab.ps1: -------------------------------------------------------------------------------- 1 | <###################################### 2 | dbatools-lab - 01_Install_Lab.ps1 3 | ####################################### 4 | This script will install two instances of SQL Server: 5 | - Default instance of SQL Server 2019 Developer edition 6 | - Named instance, sql2017l, of SQL Server 2017 Developer edition 7 | #> 8 | 9 | # Read in our configuration file - any values to be changed are in here. 10 | $config = Import-PowerShellDataFile -Path .\Config\Config.psd1 11 | 12 | # Install SQL Server 2019 as the default instance 13 | Install-DbaInstance -Version 2019 -SqlInstance dbatoolslab -Feature Engine -Path (Join-Path $config.InstallMediaPath '2019') -AuthenticationMode Mixed 14 | 15 | # Install SQL Server 2017 as a named instance 16 | Install-DbaInstance -Version 2017 -SqlInstance dbatoolslab\sql2017 -Feature Engine -Path (Join-Path $config.InstallMediaPath '2017') -AuthenticationMode Mixed 17 | 18 | # Add permissions for the engine service accounts to backup directory, you can get the accounts with 19 | Get-DbaService -ComputerName dbatoolslab -Type Engine -------------------------------------------------------------------------------- /scripts/02_Configure_Lab.ps1: -------------------------------------------------------------------------------- 1 | <###################################### 2 | dbatools-lab - 02_Configure_Lab.ps1 3 | ####################################### 4 | This script will configure our SQL Server instances 5 | - Restore the AdventureWorks and WideWorldImporters databases to the 2017 named instance 6 | - Create a few SQL Logins and SQL Agent jobs 7 | - Change a couple of sp_configure settings 8 | #> 9 | 10 | # Read in our configuration file - any values to be changed are in here. 11 | $config = Import-PowerShellDataFile -Path .\Config\Config.psd1 12 | 13 | # Restore WideWorldImporters & AdventureWorks2017 to 2017 instance 14 | Restore-DbaDatabase -SqlInstance dbatoolslab\sql2017 -Path (Join-Path $config.BackupPath 'WideWorldImporters-Full.bak') 15 | Restore-DbaDatabase -SqlInstance dbatoolslab\sql2017 -Path (Join-Path $config.BackupPath 'AdventureWorks2017-Full.bak') 16 | 17 | # Create some SQL Logins 18 | $loginSplat = @{ 19 | SqlInstance = 'dbatoolslab\sql2017' 20 | Password = (ConvertTo-SecureString -String 'N0t@SecureP@ssw0rd!' -Force -AsPlainText) 21 | } 22 | New-DbaLogin @loginSplat -Login WWI_ReadOnly 23 | New-DbaLogin @loginSplat -Login WWI_ReadWrite 24 | New-DbaLogin @loginSplat -Login WWI_Owner 25 | 26 | $userSplat = @{ 27 | SqlInstance = 'dbatoolslab\sql2017' 28 | Database = 'WideWorldImporters' 29 | Confirm = $false 30 | } 31 | New-DbaDbUser @userSplat -Login WWI_ReadOnly 32 | New-DbaDbUser @userSplat -Login WWI_ReadWrite 33 | New-DbaDbUser @userSplat -Login WWI_Owner 34 | 35 | Add-DbaDbRoleMember @userSplat -User WWI_Readonly -Role db_datareader 36 | Add-DbaDbRoleMember @userSplat -User WWI_ReadWrite -Role db_datawriter 37 | Add-DbaDbRoleMember @userSplat -User WWI_Owner -Role db_owner 38 | 39 | # Create a SQL Agent Job Category and some SQL Agent Jobs 40 | New-DbaAgentJobCategory -SqlInstance dbatoolslab\sql2017 -Category dbatoolslab 41 | 42 | $jobSplat = @{ 43 | SqlInstance = 'dbatoolslab\sql2017' 44 | Job = 'dbatools lab job' 45 | } 46 | New-DbaAgentJob @jobSplat -Description 'Creating a test job for our lab' -Category 'dbatoolslab' 47 | New-DbaAgentJobStep @jobSplat -StepName 'Step 1: Select statement' -Subsystem TransactSQL -Command 'Select 1' 48 | 49 | $jobSplat = @{ 50 | SqlInstance = 'dbatoolslab\sql2017' 51 | Job = 'dbatools lab job - where am I' 52 | } 53 | New-DbaAgentJob @jobSplat -Description 'Creating another test job for our lab' -Category 'dbatoolslab' 54 | New-DbaAgentJobStep @jobSplat -StepName 'Step 1: Select servername' -Subsystem TransactSQL -Command 'Select @@ServerName' 55 | 56 | #Install Ola's Maintenance Scripts 57 | Install-DbaMaintenanceSolution -SqlInstance 'dbatoolslab\sql2017' -InstallJobs 58 | 59 | # Change a couple of sp_configure settings 60 | Set-DbaSpConfigure -SqlInstance dbatoolslab\sql2017 -Name RemoteDacConnectionsEnabled -Value 1 61 | Set-DbaSpConfigure -SqlInstance dbatoolslab\sql2017 -Name CostThresholdForParallelism -Value 10 62 | 63 | # add alerts -------------------------------------------------------------------------------- /scripts/99_Cleanup_Lab.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/scripts/99_Cleanup_Lab.ps1 -------------------------------------------------------------------------------- /tests/cleanup.tests.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/tests/cleanup.tests.ps1 -------------------------------------------------------------------------------- /tests/configure.tests.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/tests/configure.tests.ps1 -------------------------------------------------------------------------------- /tests/install.tests.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory)] 3 | [ValidateNotNullOrEmpty] 4 | [string]$serverName, 5 | 6 | [Parameter] 7 | [switch]$OneInstance 8 | ) 9 | 10 | Describe "SQL Install is good" { 11 | Context ('{0} - has the expected sql installs' -f $serverName) { 12 | $instances = Find-DbaInstance -ComputerName $serverName 13 | It "SQL Server 2019 should be installed as a default instance" { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/prereq.tests.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataplat/dbatools-lab/575f2678d5c0a1ae6ba81ddca1cb8395c1b3e087/tests/prereq.tests.ps1 -------------------------------------------------------------------------------- /tests/setup/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | dbatools01: 4 | image: sqldbawithabeard/dbatoolsbeardsql01:v1 5 | container_name: dbatools01 6 | hostname: f443490967e7 7 | ports: 8 | - "15592:1433" 9 | - "5022:5022" 10 | networks: 11 | - dbatoolsnetwork 12 | volumes: 13 | - backups:/var/opt/mssql/backups 14 | environment: 15 | - MSSQL_ENABLE_HADR=1 16 | dbatools02: 17 | image: sqldbawithabeard/dbatoolsbeardsql02:v1 18 | container_name: dbatools02 19 | hostname: f443490967e7 20 | ports: 21 | - "15593:1433" 22 | - "5023:5023" 23 | networks: 24 | - dbatoolsnetwork 25 | volumes: 26 | - backups:/var/opt/mssql/backups 27 | environment: 28 | - MSSQL_ENABLE_HADR=1 29 | networks: 30 | dbatoolsnetwork: 31 | volumes: 32 | backups: 33 | --------------------------------------------------------------------------------