Upload
others
View
30
Download
0
Embed Size (px)
Citation preview
Richmond SQL Server Users Group
http://rva.sqlpass.org/
Second Thursday at Markel Plaza (Glen Allen)
Agenda• SQL Server (setup)
• PowerShellSyntax & Commandlets
• JSON
• Creating PowerShell Scripts
• Automation ExamplesClustering (WSFC)Managed Service AccountsConfigurationFile.ini
Automation
Why automate your SQL Server deployment?
• Time savings
• Server build standardization
• Documentation
• Setup.exe has over 70 parameters
• SQL Server has 100’s of configuration options
SQL Server Setup
What should go into all of your SQL installs?
Question:
Answer:Umm….
Let me go find that Checklist.
SQL Setup Checklist
• .NET 4.6 feature ←Automatic install for Win2016/SQL2016+• SQL configuration file (for unattended installs)
• C:\Program Files\Microsoft SQL Server\...\ConfigurationFile.ini• Service Accounts (MSA SQL2012) ← gMSA supported in SQL2016• Firewall exceptions
Requirements for SQL installs
Port UseTCP 1433 Database Engine default installUDP 1434 SQL Server Browser ServiceTCP 1434 Dedicated Admin Connection (DAC)TCP 80 & 443 HTTP/HTTPS for SSRSTCP 139 & 445 SQL Filestream & FiletablesTCP 2383 Analysis ServicesTCP 135 MS Distributed Transaction Coordinator
SQL Setup Checklist cont.
Post Install Configurations• Add Admin Users/Groups ←• Enable the SQL Agent service ←• Instant File Initialization (IFI) ←• Add TempDB files ←• Rename/Disable the SA account• Service Provider Name (SPN)• Operators• DBMail• Trace Flags (3226, 4199, 8152)• Import Custom SQL procedures• Filestream & File Tables• Auditing• Management Policies (PBM)• Encryption Certificates← SQL 2016+ ConfigurationFile.ini
Alerts• Severity 19-25• ID 18456 - Login Error• ID 15247 - Permission Error• ID 9002 - Log Full• ID 825 - Disk I/O Error
Maintenance Jobs• Backups• Reindex• CheckDB
FREE Maintenance Solutionshttp://minionware.nethttp://ola.hallengren.com
JSON
• Open standard designed for data interchange
• PowerShell import using ConvertFrom-JSON
• Key:Value pairs
• Objects {}
• Arrays []
JavaScript Object Notation
https://blog.wicktech.net/powershell-json/
PowerShell• Shell and Integrated Scripting Environment (ISE)
• SQL Server module for PowerShellSQLPS
SQL Server (2008-2016)SQLSERVER
SQLServer 20 - SSMS 16.3 – 16.5 (July 2016 release)SQLServer 21
PowerShell IntegrationPS Windows SQL PSv1 2008 SQLPS
mini-shellv2 2008 R2 SQLPS
v3 2012 SQLPS
v4 2012 R2 SQLPSSqlServer 20
v5 2016 SqlServer 21(PS Gallery)
SQL SSMS SQL PS2008 2008 SQLPS
2008 R2 2008 R2 SQLPS
2012 2012 SQLPS
2012 R2 2012 R2 SQLPS2014 2014 SQLPS2016 16.3-16.5 SqlServer 202017 17.0 –
17.3SqlServer 21(PS Gallery)Core OS SQL PS
v6 WindowsMacOSLinux
SqlServer 21(PS Gallery)
EOL July 2019
Powershell Basics:Syntax:
$xxxxxxx – variable name
[string]$xxxx - variable with string data type
“ (double quote) - string expands/replaces variables
‘ (single quote) - literal string (does not expand variables)
@” - here string (multi-line string w/ variable replacement)
# - comment out remainder of line
` (back tick) - escape character
{} - script block
$_ - current object (iterative loops, ForEach)
Powershell Basics: (cont.)
Commandlets: (Verb-noun naming convention)
Set-ExecutionPolicy [Restricted, AllSigned, RemoteSigned, Unrestricted, Bypass]
Enable-PSRemoting –forceImport-Module [ServerManager, SQLPS, SQLSERVER]
Invoke-Command -Computername -ScriptBlock {}Invoke-Sqlcmd -ServerInstance [-Query or -InputFile]
Invoke-Expression [$variable]
Start-Process [path\file.exe]
Write-Output
Powershell Comparators:
SQL PowerShell= or <> -eq or -ne> or < -gt or -lt
>= or <= -ge or -leLIKE -like
NOT LIKE -notlikeIS NULL !$variable
-contains
SQLIF (@variable = 15)
BEGINDo this
END
PowerShellIF ($variable -eq 15) {
Do this}
Powershell Scripts:
• .ps1 (script) • .psm1 (script module), .psd1 (manifest file), .ps1xml (formatting file)
• Double-click <> Execute.\script.ps1 -ServerName “SQL01” -Path “C:\temp”
• Set-ExecutionPolicy to allow unsigned scripts to be run• Parameters
Param ([string]$ServerName = “.”,[string]$Path = “C:\”)
Creating PowerShell Scripts:Design ConsiderationsExecute script(s) locally or remote?
• Locally – copy script(s) to server• Remote – run script(s) from a single repository
Single Script or Script Set?• Single - 1 big script containing all configuration items• Set - 1 primary script that calls sub scripts
Script Users• Internal use – doesn’t have to be PERFECT, document for usability• External use – better documentation, allow for env variability
Installing SQL Server:Install .NET Feature
Note: Install media location option -Source D:\Sources\SxS\
Import-Module ServerManager;# Get Windows Server Version$WindowsVersion = [environment]::OSVersion.Version
# Add .NET 3.5 to Windows Server 2008R2 and earlierIf (($WindowsVersion.Major -eq 6) -And ($WindowsVersion.Minor -lt 2)) {
Add-WindowsFeature AS-Net-Framework;}
# Add .NET 3.5 to Windows Server 2012 and 2012R2If (($WindowsVersion.Major -eq 6) -And ($WindowsVersion.Minor -ge 2)) {
Add-WindowsFeature Net-Framework-Core;}
# Add .NET 4.6 to Windows Server 2016If ($WindowsVersion.Major -eq 10) {
Add-WindowsFeature Net-Framework-45-Core;}
Create Directories
Open Firewall Ports
Installing SQL Server:
Run SQL install as administrator, specifying config file
New-Item -ItemType directory -Path E:\SQL
netsh advfirewall firewall add rule name="SQL Instances"dir=in action=allow protocol=TCP localport=1433;
$install = 'Start-Process -verb runas -FilePath "' +$SQLInstaller + '" -ArgumentList /ConfigurationFile="' +$ScriptPath + '\Config_Scripts\ConfigurationFile.ini" -Wait';Invoke-Expression $install;
Enable-NetFirewallRule -DisplayName "Remote Desktop -User Mode (TCP-In)”
New-NetFirewallRule -DisplayName "SQL" -Profile "Domain"-Direction Inbound -Action Allow -Protocol TCP -LocalPort"1433" –RemoteAddress @(10.3.20.0/24",“10.1.1.100");
Configuring SQL Server:
Import SQL PowerShell Module
Set Script Parameters
SQL Server 2012-2014
SQL Server 2016 & 2017*
Import-Module SQLPS -DisableNameChecking;
Import-Module Sqlserver -DisableNameChecking;
Param ([string]$SQLServer = ".",[string]$SQLInstaller = "D:\setup.exe",[switch]$CreateMSA = $True,[string]$ScriptPath = $PSScriptRoot
)
* SSMS & PowerShell modules separated as of 2017.
Configuring SQL Server: (cont.)
Execute SQL Query (single line)
Invoke-Sqlcmd -ServerInstance $SQLServer-Query "CREATE DATABASE [Mgmt];";
Execute SQL Query (multi-line ‘here’ string)
$query = @"EXEC sys.sp_configure N'contained database authentication', N'1'GORECONFIGURE WITH OVERRIDE;"@;
Invoke-Sqlcmd -ServerInstance $SQLServer-Query $query;
Configuring SQL Server: (cont.)
Invoke-Sqlcmd -ServerInstance $SQLServer -InputFile"$ScriptPath\Alerts_Triggers.sql";
Execute SQL Script File
Execute Multiple SQL Script Files In Order$ScriptList = Get-Content InstallOrder.txt;$ScriptList | %{ $currScript = $_;Invoke-Sqlcmd -ServerInstance $SQLServer-InputFile $currScript;}
Execute PowerShell Script File./PowerShellScript.ps1 -Parameter1 "Value"-Parameter2 $variable;
Variables & JSON:
$Config = ConvertFrom-Json -InputObject (Get-Content -Path “FileName” -Raw);
[array]$gMSANames = ((($Config).Accounts).Services).Where{$_.AccountType -eq“gMSA”};
ForEach ($Server in $ServerList) {$IP = ((($Config).Servers) | Where-Object {$_.ServerName -eq $Server}).IP; }
[array]$ServerList = (($Config).Servers).ServerName
Group Managed Service Accounts:
$gMSANames = ((($Config).Accounts).Services).Where{$_.AccountType -eq“gMSA”};
ForEach ($Name in $gMSANames) {$Acct = $Name.Username;$AcctDNS = “$Acct.$DomainName”$gMSA_HostNames = $ServerList | ForEach-Object { Get-ADComputer -Identity $_ };
New-ADServiceAccount -Name $Acct -DNSHostName $AcctDNS -PrincipalsAllowedToRetrieveManagedPassword $gMSA_HostNames;
Set-ADServiceAccount -Identity $Acct -TrustedForDelegation$true;
}
https://blog.wicktech.net/powershell-install-gmsa/
Create AD Objects
Group Managed Service Accounts:
$pscred = Get-Credential;
ForEach ($Server in $ServerList) {
ForEach ($Name in $gMSANames) {$Acct = ($Name).Username;
$MSAblock = @”Add-WindowsFeature RSAT-AD-Powershell;Import-Module ActiveDirectory; Install-ADServiceAccount $Acct;“@;
Invoke-Command -ComputerName $Server -ScriptBlock{$MSAblock} -Credential $pscred;
}}
https://blog.wicktech.net/powershell-install-gmsa/
Install Accounts On Servers
WSFC - Clusters & Availability Groups:
ForEach ($Server in $Nodes) {Invoke-Command -ComputerName $Server -ScriptBlock {Import-Module ServerManager;Add-WindowsFeature Failover-Clustering -
IncludeManagementTools;}}
• Cluster Name• Cluster IP Address• Cluster Nodes • Subnets To Ignore • Quorum Mode
• Remote Server Administration Tools (RSAT)https://docs.microsoft.com/en-us/windows-server/remote/remote-server-administration-tools
More Info - https://blog.wicktech.net/powershell-wsfc/
WSFC - Clusters & Availability Groups:Test-Cluster -Node $ClusterList;
New-Cluster -Name $ClusterName -Node $ClusterList -NoStorage -StaticAddress $ClusterIPAddress -IgnoreNetwork$IgnoreIPRange”;
Set-ClusterQuorum -Cluster “$ClusterFQDN”• -NodeMajority;• -NodeAndDiskMajority;• -FileShareWitness $FileShareWitness;• -DiskOnly “Cluster Disk 1”;
Start-Cluster -Name “$ClusterFQDN”;
More Info - https://blog.wicktech.net/powershell-wsfc/
Unattended Setup.exe:
Setup.exe /Q /IACCEPTSQLSERVERLICENSETERMS /FEATURES=AS,RS,IS /INSTANCENAME=“MSSQLSERVER” /INSTANCEDIR=“E:\Path” /INSTALLSHAREDDIR=“F:\Path” /AGTSVCACCOUNT=“Domain\AgentSvc” /AGTSVCPASSWORD=“P@ssW0rd”/SQLSVCACCOUNT=“Domain\SQLSvc”/SQLSVCPASSWORD=“P@ssW0rd”
… (over 70 possible parameters)
• Runtime Parameters • ConfigurationFile.ini
More Info - https://docs.microsoft.com/en-us/sql/database-engine/install-windows/install-sql-server-from-the-command-promp
Runtime Parameters
Unattended Setup.exe:
$ConfigFilename = (($Config).SQLMedia).ConfigFile;$BaseConfigFilename = (($Config).SQLMedia).ConfigFileTemplate;
(Get-Content $BaseConfigFilename) | ForEach-Object {switch -regex($_) {
('INSTANCEDIR=') {$InstanceDir = ((($Config).Folders).Where{$_.Use -eq
"Instance"}).Path;'INSTANCEDIR="' + $InstanceDir + '"'}
('SQLUSERDBDIR=') {…}('SQLUSERDBLOGDIR=') {…}
# Keep unaltered linesDefault {$_};}
} | Set-Content -Path "$ConfigFilename" -Force;
Create ConfigurationFile.ini
Setup.exe – Local or Remote:
$install = 'Start-Process -verb runas -FilePath "' + $SQLInstaller + '" -ArgumentList /ConfigurationFile="' + $ScriptPath + '\ConfigurationFile.ini" -Wait';
Invoke-Expression $install;
$SQLInstaller = (($Config).SQLMedia).Installer;
Copy-Item $ConfigFilename "\\$Server\c$\Temp\" -Force;
$Install = '"' + $SQLInstaller + '“ /ConfigurationFile="C:\Temp\' + (Split-Path $ConfigFilename -Leaf) + '"‘
# Invoke-Command to remote server doesn't work with setup.exe (DCOM error). Using WMI instead.
([WMICLASS]"\\$Server\ROOT\CIMV2:Win32_Process").Create($Install)
Local
Remote
Additional Resources:
SQL Server PowerShell Modulehttps://docs.microsoft.com/en-us/sql/ssms/download-sql-server-
ps-module
PowerShell Galleryhttps://www.powershellgallery.com/
http://powershell.sqlpass.org/
Presentation Scriptshttps://blog.wicktech.net/sql-ps-install-scripts/