functions/MaxMemory.ps1
Function Get-SqlMaxMemory { <# .SYNOPSIS Displays information relating to SQL Server Max Memory configuration settings. Works on SQL Server 2000-2014. .DESCRIPTION Inspired by Jonathan Kehayias's post about SQL Server Max memory (http://bit.ly/sqlmemcalc), this script displays a SQL Server's: total memory, currently configured SQL max memory, and the calculated recommendation. Jonathan notes that the formula used provides a *general recommendation* that doesn't account for everything that may be going on in your specific environment. THIS CODE IS PROVIDED "AS IS", WITH NO WARRANTIES. .PARAMETER SqlServer Allows you to specify a comma separated list of servers to query. .PARAMETER SqlCredential Allows you to login to servers using SQL Logins as opposed to Windows Auth/Integrated/Trusted. To use: $cred = Get-Credential, this pass this $cred to the param. Windows Authentication will be used if DestinationSqlCredential is not specified. To connect as a different Windows user, run PowerShell as that user. .NOTES Author : Chrissy LeMaire (@cl), netnerds.net Requires: sysadmin access on SQL Servers dbatools PowerShell module (https://dbatools.io, clemaire@gmail.com) Copyright (C) 2105 Chrissy LeMaire This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. .LINK https://dbatools.io/Get-SqlMaxMemory .EXAMPLE Get-SqlMaxMemory -SqlServer sqlcluster,sqlserver2012 Get Memory Settings for all servers within the SQL Server Central Management Server "sqlcluster" .EXAMPLE Get-SqlMaxMemory -SqlServer sqlcluster | Where-Object { $_.SqlMaxMB -gt $_.TotalMB } | Set-SqlMaxMemory Find all servers in CMS that have Max SQL memory set to higher than the total memory of the server (think 2147483647) #> [CmdletBinding()] Param ( [parameter(Position = 0, Mandatory=$true)] [Alias("ServerInstance", "SqlInstance", "SqlServers")] [string[]]$SqlServer, [System.Management.Automation.PSCredential]$SqlCredential ) PROCESS { $collection = @() foreach ($servername in $sqlserver) { Write-Verbose "Attempting to connect to $servername" try { $server = Connect-SqlServer -SqlServer $servername -SqlCredential $SqlCredential } catch { Write-Warning "Can't connect to $servername or access denied. Skipping." continue } $maxmem = $server.Configuration.MaxServerMemory.ConfigValue $reserve = 1 $totalMemory = $server.PhysicalMemory # Some servers underreport by 1MB. if (($totalmemory % 1024) -ne 0) { $totalMemory = $totalMemory + 1 } if ($totalMemory -ge 4096) { $currentCount = $totalMemory while ($currentCount/4096 -gt 0) { if ($currentCount -gt 16384) { $reserve += 1 $currentCount += -8192 } else { $reserve += 1 $currentCount += -4096 } } $recommendedMax = [int]($totalMemory - ($reserve * 1024)) } else { $recommendedMax = $totalMemory * .5 } $object = New-Object PSObject -Property @{ Server = $server.name TotalMB = $totalMemory SqlMaxMB = $maxmem RecommendedMB = $recommendedMax } $server.ConnectionContext.Disconnect() $collection += $object } return ($collection | Sort-Object Server | Select Server, TotalMB, SqlMaxMB, RecommendedMB) } } Function Set-SqlMaxMemory { <# .SYNOPSIS Sets SQL Server max memory then displays information relating to SQL Server Max Memory configuration settings. Works on SQL Server 2000-2014. THIS CODE IS PROVIDED "AS IS", WITH NO WARRANTIES. Inspired by Jonathan Kehayias's post about SQL Server Max memory (http://bit.ly/sqlmemcalc), this uses a formula to determine the default optimum RAM to use, then sets the SQL max value to that number. Jonathan notes that the formula used provides a *general recommendation* that doesn't account for everything that may be going on in your specific environment. .PARAMETER SqlServer Allows you to specify a comma separated list of servers to query. .PARAMETER MaxMb Specifies the max megabytes .NOTES Author : Chrissy LeMaire (@cl), netnerds.net Requires: sysadmin access on SQL Servers .LINK https://gallery.technet.microsoft.com/scriptcenter/Get-Set-SQL-Max-Memory-19147057 .EXAMPLE Set-SqlMaxMemory sqlserver1 2048 Set max memory to 2048 MB on just one server, "sqlserver1" .EXAMPLE Get-SqlMaxMemory -SqlServer sqlserver2014 | Where-Object { $_.SqlMaxMB -gt $_.TotalMB } | Set-SqlMaxMemory Find all servers in CMS that have Max SQL memory set to higher than the total memory of the server (think 2147483647), then pipe those to Set-SqlMaxMemory and use the default recommendation .EXAMPLE Set-SqlMaxMemory -SqlCms sqlcluster -SqlCmsGroups Express -MaxMB 512 -Verbose Specifically set memory to 512 MB for all servers within the "Express" server group on CMS "sqlcluster" #> [CmdletBinding()] Param ( [parameter(Position = 0)] [Alias("ServerInstance", "SqlInstance", "SqlServers")] [string[]]$SqlServer, [parameter(Position = 1)] [int]$MaxMb, [Parameter(ValueFromPipeline = $True)] [object]$collection, [System.Management.Automation.PSCredential]$SqlCredential ) PROCESS { if ($SqlServer.length -eq 0 -and $collection -eq $null) { throw "You must specify a server list source using -SqlServer or you can pipe results from Get-SqlMaxMemory" } if ($MaxMB -eq 0) { $UseRecommended = $true } if ($collection -eq $null) { $collection = Get-SqlMaxMemory -SqlServer $SqlServer } $collection | Add-Member -NotePropertyName OldMaxValue -NotePropertyValue 0 foreach ($row in $collection) { Write-Verbose "Attempting to connect to $sqlserver" try { $server = Connect-SqlServer -SqlServer $row.server -SqlCredential $SqlCredential } catch { Write-Warning "Can't connect to $sqlserver or access denied. Skipping." continue } if (!(Test-SqlSa -SqlServer $server)) { Write-Error "Not a sysadmin on $servername. Skipping." $server.ConnectionContext.Disconnect() continue } $row.OldMaxValue = $row.SqlMaxMB try { if ($UseRecommended) { Write-Verbose "Changing $($row.server) SQL Server max from $($row.SqlMaxMB) to $($row.RecommendedMB) MB" $server.Configuration.MaxServerMemory.ConfigValue = $row.RecommendedMB $row.SqlMaxMB = $row.RecommendedMB } else { Write-Verbose "Changing $($row.server) SQL Server max from $($row.SqlMaxMB) to $MaxMB MB" $server.Configuration.MaxServerMemory.ConfigValue = $MaxMB $row.SqlMaxMB = $MaxMB } $server.Configuration.Alter() } catch { Write-Error "Could not modify Max Server Memory for $($row.server)" } $server.ConnectionContext.Disconnect() } return $collection | Select Server, TotalMB, OldMaxValue, @{ name = "CurrentMaxValue"; expression = { $_.SqlMaxMB } } } } |