Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BREAKING CHANGE: SqlServerNetwork: Add the possibility to use ListenAll and custom IPs #1045

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
SqlRS as the parameter UseSsl. The UseSsl parameter is of type boolean. This
change was made because from SQL Server 2008 R2 this value is made an on/off
switch. Read more in the article [ConfigurationSetting Method - SetSecureConnectionLevel](https://docs.microsoft.com/en-us/sql/reporting-services/wmi-provider-library-reference/configurationsetting-method-setsecureconnectionlevel).
- BREAKING CHANGE: Added new key parameter to SqlServerNetwork resource
Added IPAddress parameter to configure IP adresses. Must be a key property
to configure multiple IP adresses including the IPAll.
- Updated so that named parameters are used for New-Object cmdlet. This was
done to follow the style guideline.
- Updated manifest and license to reflect the new year
Expand Down Expand Up @@ -128,6 +131,7 @@
- Style cleanup in tests.
- Changes to SqlServerNetwork
- Added sysadmin account parameter usage to the examples.
- Added ListenAll parameter to configure if it should listen on all IP adresses.
- Changes to SqlServerReplication
- Fix Script Analyzer warning ([issue #263](https://github.com/PowerShell/SqlServerDsc/issues/263)).
- Changes to SqlServerRole
Expand Down
155 changes: 138 additions & 17 deletions DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ $script:localizedData = Get-LocalizedData -ResourceName 'MSFT_SqlServerNetwork'

.PARAMETER ProtocolName
The name of network protocol to be configured. Only tcp is currently supported.

.PARAMETER IPAddress
Specify the IP address to configure. Use IPAll for all ip adresses (listen on all).
#>
function Get-TargetResource
{
Expand All @@ -30,7 +33,11 @@ function Get-TargetResource
[Parameter(Mandatory = $true)]
[ValidateSet('Tcp')]
[System.String]
$ProtocolName
$ProtocolName,

[Parameter(Mandatory = $true)]
[System.String]
$IPAddress
)

try
Expand All @@ -42,13 +49,17 @@ function Get-TargetResource
Write-Verbose -Message ($script:localizedData.GetNetworkProtocol -f $ProtocolName, $InstanceName)
$tcp = $managedComputerObject.ServerInstances[$InstanceName].ServerProtocols[$ProtocolName]

$ipAddressKey = Resolve-SqlProtocolIPAddress -Protocol $tcp -IPAddress $IPAddress

Write-Verbose -Message $script:localizedData.ReadingNetworkProperties
$returnValue = @{
InstanceName = $InstanceName
ProtocolName = $ProtocolName
IsEnabled = $tcp.IsEnabled
TcpDynamicPort = ($tcp.IPAddresses['IPAll'].IPAddressProperties['TcpDynamicPorts'].Value -ge 0)
TcpPort = $tcp.IPAddresses['IPAll'].IPAddressProperties['TcpPort'].Value
InstanceName = $InstanceName
ProtocolName = $ProtocolName
IPAddress = $IPAddress
IsEnabled = $(if($ipAddressKey -eq 'IPAll') { $tcp.IsEnabled } else { $tcp.IPAddresses[$ipAddressKey].IPAddressProperties['Enabled'].Value })
ListenAll = $(if($ipAddressKey -eq 'IPAll') { $tcp.ProtocolProperties['ListenOnAllIPs'].Value } else { $null })
TcpDynamicPort = ($tcp.IPAddresses[$ipAddressKey].IPAddressProperties['TcpDynamicPorts'].Value -ge 0)
TcpPort = $tcp.IPAddresses[$ipAddressKey].IPAddressProperties['TcpPort'].Value
}

$returnValue.Keys | ForEach-Object {
Expand Down Expand Up @@ -76,9 +87,16 @@ function Get-TargetResource
.PARAMETER ProtocolName
The name of network protocol to be configured. Only tcp is currently supported.

.PARAMETER IPAddress
Specify the IP address to configure. Use IPAll for all ip adresses (listen on all).

.PARAMETER IsEnabled
Enables or disables the network protocol.

.PARAMETER ListenAll
Enables or disables to listen on all IP adresses. Will be ignored if IPAddress is
not set to 'IPAll'.

.PARAMETER TcpDynamicPort
Specifies whether the SQL Server instance should use a dynamic port.
Value cannot be set to $true if TcpPort is set to a non-empty string.
Expand Down Expand Up @@ -116,10 +134,18 @@ function Set-TargetResource
[System.String]
$ProtocolName,

[Parameter(Mandatory = $true)]
[System.String]
$IPAddress,

[Parameter()]
[System.Boolean]
$IsEnabled,

[Parameter()]
[System.Boolean]
$ListenAll,

[Parameter()]
[System.Boolean]
$TcpDynamicPort,
Expand All @@ -143,18 +169,20 @@ function Set-TargetResource
New-InvalidOperationException -Message $errorMessage
}

$getTargetResourceResult = Get-TargetResource -InstanceName $InstanceName -ProtocolName $ProtocolName
$getTargetResourceResult = Get-TargetResource -InstanceName $InstanceName -ProtocolName $ProtocolName -IPAddress $IPAddress

try
{
$applicationDomainObject = Register-SqlWmiManagement -SQLInstanceName $InstanceName

$desiredState = @{
InstanceName = $InstanceName
ProtocolName = $ProtocolName
IsEnabled = $IsEnabled
TcpDynamicPort = $TcpDynamicPort
TcpPort = $TcpPort
InstanceName = $InstanceName
ProtocolName = $ProtocolName
IPAddress = $IPAddress
ListenAll = $ListenAll
IsEnabled = $IsEnabled
TcpDynamicPort = $TcpDynamicPort
TcpPort = $TcpPort
}

$isRestartNeeded = $false
Expand All @@ -164,13 +192,31 @@ function Set-TargetResource
Write-Verbose -Message ($script:localizedData.GetNetworkProtocol -f $ProtocolName, $InstanceName)
$tcp = $managedComputerObject.ServerInstances[$InstanceName].ServerProtocols[$ProtocolName]

$ipAddressKey = Resolve-SqlProtocolIPAddress -Protocol $tcp -IPAddress $IPAddress

Write-Verbose -Message ($script:localizedData.CheckingProperty -f 'IsEnabled')
if ($desiredState.IsEnabled -ine $getTargetResourceResult.IsEnabled)
{
Write-Verbose -Message ($script:localizedData.UpdatingProperty -f 'IsEnabled', $getTargetResourceResult.IsEnabled, $desiredState.IsEnabled)
$tcp.IsEnabled = $desiredState.IsEnabled
$tcp.Alter()
if ($ipAddressKey -eq 'IPAll')
{
$tcp.IsEnabled = $desiredState.IsEnabled
$tcp.Alter()
}
else
{
$tcp.IPAddresses[$ipAddressKey].IPAddressProperties['Enabled'].Value = $desiredState.IsEnabled
$tcp.Alter()
}
$isRestartNeeded = $true
}

Write-Verbose -Message ($script:localizedData.CheckingProperty -f 'ListenAll')
if ($desiredState.ListenAll -ine $getTargetResourceResult.ListenAll -and $ipAddressKey -eq 'IPAll')
{
Write-Verbose -Message ($script:localizedData.UpdatingProperty -f 'ListenAll', $getTargetResourceResult.ListenAll, $desiredState.ListenAll)
$tcp.ProtocolProperties['ListenOnAllIPs'].Value = $desiredState.ListenAll
$tcp.Alter()
$isRestartNeeded = $true
}

Expand All @@ -193,7 +239,7 @@ function Set-TargetResource
$toTcpDynamicPortDisplayValue = $dynamicPortDisplayValueTable[$desiredState.TcpDynamicPort]

Write-Verbose -Message ($script:localizedData.UpdatingProperty -f 'TcpDynamicPorts', $fromTcpDynamicPortDisplayValue, $toTcpDynamicPortDisplayValue)
$tcp.IPAddresses['IPAll'].IPAddressProperties['TcpDynamicPorts'].Value = $desiredDynamicPortValue[$desiredState.TcpDynamicPort]
$tcp.IPAddresses[$ipAddressKey].IPAddressProperties['TcpDynamicPorts'].Value = $desiredDynamicPortValue[$desiredState.TcpDynamicPort]
$tcp.Alter()

$isRestartNeeded = $true
Expand All @@ -215,7 +261,7 @@ function Set-TargetResource
}

Write-Verbose -Message ($script:localizedData.UpdatingProperty -f 'TcpPort', $fromTcpPort, $toTcpPort)
$tcp.IPAddresses['IPAll'].IPAddressProperties['TcpPort'].Value = $desiredState.TcpPort
$tcp.IPAddresses[$ipAddressKey].IPAddressProperties['TcpPort'].Value = $desiredState.TcpPort
$tcp.Alter()

$isRestartNeeded = $true
Expand Down Expand Up @@ -247,9 +293,16 @@ function Set-TargetResource
.PARAMETER ProtocolName
The name of network protocol to be configured. Only tcp is currently supported.

.PARAMETER IPAddress
Specify the IP address to configure. Use IPAll for all ip adresses (listen on all).

.PARAMETER IsEnabled
Enables or disables the network protocol.

.PARAMETER ListenAll
Enables or disables to listen on all IP adresses. Will be ignored if IPAddress is
not set to 'IPAll'.

.PARAMETER TcpDynamicPort
Specifies whether the SQL Server instance should use a dynamic port.
Value cannot be set to $true if TcpPort is set to a non-empty string.
Expand Down Expand Up @@ -291,10 +344,18 @@ function Test-TargetResource
[System.String]
$ProtocolName,

[Parameter(Mandatory = $true)]
[System.String]
$IPAddress,

[Parameter()]
[System.Boolean]
$IsEnabled,

[Parameter()]
[System.Boolean]
$ListenAll,

[Parameter()]
[System.Boolean]
$TcpDynamicPort,
Expand All @@ -318,7 +379,7 @@ function Test-TargetResource
New-InvalidOperationException -Message $errorMessage
}

$getTargetResourceResult = Get-TargetResource -InstanceName $InstanceName -ProtocolName $ProtocolName
$getTargetResourceResult = Get-TargetResource -InstanceName $InstanceName -ProtocolName $ProtocolName -IPAddress $IPAddress

Write-Verbose -Message $script:localizedData.CompareStates

Expand Down Expand Up @@ -346,6 +407,21 @@ function Test-TargetResource
}
}

if ($PSBoundParameters.ContainsKey('ListenAll') -and $IPAddress -eq 'IPAll')
{
if ($ListenAll -ne $getTargetResourceResult.ListenAll)
{
$evaluateEnableOrDisable = @{
$true = 'enabled'
$false = 'disabled'
}

Write-Verbose -Message ($script:localizedData.ExpectedPropertyValue -f 'ListenAll', $evaluateEnableOrDisable[$ListenAll], $evaluateEnableOrDisable[$getTargetResourceResult.ListenAll])

$isInDesiredState = $false
}
}

if ($PSBoundParameters.ContainsKey('TcpDynamicPort'))
{
if ($TcpDynamicPort -and $getTargetResourceResult.TcpDynamicPort -eq $false)
Expand Down Expand Up @@ -380,4 +456,49 @@ function Test-TargetResource
return $isInDesiredState
}

<#
.SYNOPSIS
Resolve the IP Adress to the SQL Server protocol key.

.PARAMETER Protocol
SQL Server protocol object.

.PARAMETER IPAddress
The IP address to resolve.
#>
function Resolve-SqlProtocolIPAddress
{
[CmdletBinding()]
[OutputType([System.String])]
param
(
[Parameter(Mandatory = $true)]
$Protocol,

[Parameter(Mandatory = $true)]
[System.String]
$IPAddress
)

Write-Verbose ($script:localizedData.GetSQLProtocolIPAddressKey -f $IPAddress)

if ($IPAddress -eq 'IPAll')
{
return $IPAddress
}
else
{
$ipAddressObject = $Protocol.IPAddresses.Where({$_.IPAddress.IPAddressToString -eq $IPAddress})[0]

if ($null -eq $ipAddressObject)
{
throw ($script:localizedData.IPAddressNotFoundError -f $IPAddress)
}
else
{
return $ipAddressObject.Name
}
}
}

Export-ModuleMember -Function *-TargetResource
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ class MSFT_SqlServerNetwork : OMI_BaseResource
[Key, Description("The name of the SQL instance to be configured.")] String InstanceName;
[Required, Description("The name of network protocol to be configured. Only tcp is currently supported."), ValueMap{"Tcp"}, Values{"Tcp"}] String ProtocolName;
[Write, Description("The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME.")] String ServerName;
[Key, Description("Specify the IP address to configure. Use IPAll for all ip adresses (listen on all).")] String IPAddress;
[Write, Description("Enables or disables the network protocol.")] Boolean IsEnabled;
[Write, Description("Enables or disables to listen on all IP adresses. Will be ignored if IPAddress is not set to 'IPAll'.")] Boolean ListenAll;
[Write, Description("Specifies whether the SQL Server instance should use a dynamic port. Value cannot be set to 'True' if TcpPort is set to a non-empty string.")] Boolean TcpDynamicPort;
[Write, Description("The TCP port(s) that SQL Server should be listening on. If the IP address should listen on more than one port, list all ports separated with a comma ('1433,1500,1501'). To use this parameter set TcpDynamicPorts to 'False'.")] String TcpPort;
[Write, Description("If set to $true then SQL Server and dependent services will be restarted if a change to the configuration is made. The default value is $false.")] Boolean RestartService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ ConvertFrom-StringData @'
CompareStates = Comparing desired state with current state.
InDesiredState = System is in the desired state.
ErrorDynamicAndStaticPortSpecified = Unable to set both tcp dynamic port and tcp static port. Only one can be set.
GetSQLProtocolIPAddressKey = Get the SQL protocol key for IP address [{0}].
IPAddressNotFoundError = Specified IP address [{0}] not found.
'@
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Configuration Example
{
InstanceName = 'MSSQLSERVER'
ProtocolName = 'Tcp'
IPAddress = 'IPAll'
IsEnabled = $true
TCPDynamicPort = $false
TCPPort = 4509
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Configuration Example
{
InstanceName = 'MSSQLSERVER'
ProtocolName = 'Tcp'
IPAddress = 'IPAll'
IsEnabled = $true
TCPDynamicPort = $true
RestartService = $true
Expand Down
30 changes: 30 additions & 0 deletions Examples/Resources/SqlServerNetwork/3-EnableTcpIpOnCustomIP.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<#
.EXAMPLE
This example will enable TCP/IP protocol and set the custom static port to 1433
on the IP address 192.168.1.10.
#>
Configuration Example
{
param
(
[Parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$SystemAdministratorAccount
)

Import-DscResource -ModuleName SqlServerDsc

node localhost
{
SqlServerNetwork 'ChangeTcpIpOnDefaultInstance'
{
InstanceName = 'MSSQLSERVER'
ProtocolName = 'Tcp'
IPAddress = '192.168.1.10'
IsEnabled = $true
TCPDynamicPort = $false
TCPPort = 1433
PsDscRunAsCredential = $SystemAdministratorAccount
}
}
}
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1243,7 +1243,11 @@ Read more about the network settings in the article
Only tcp is currently supported. { tcp }.
* **`[String]` ServerName** _(Write)_: The host name of the SQL Server to be configured.
Default value is $env:COMPUTERNAME.
* **`[String]` IPAddress** _(Key)_: Specify the IP address to configure. Use
IPAll for all ip adresses (listen on all).
* **`[Boolean]` IsEnabled** _(Write)_: Enables or disables the network protocol.
* **`[Boolean]` ListenAll** _(Write)_: Enables or disables to listen on all
IP adresses. Will be ignored if IPAddress is not set to 'IPAll'.
* **`[Boolean]` TcpDynamicPort** _(Write)_: Specifies whether the SQL Server
instance should use a dynamic port. Value cannot be set to $true if TcpPort
is set to a non-empty string.
Expand All @@ -1261,6 +1265,7 @@ Read more about the network settings in the article

* [Enable TCP/IP with static port and restart SQL Server](/Examples/Resources/SqlServerNetwork/1-EnableTcpIpWithStaticPort.ps1)
* [Enable TCP/IP with dynamic port](/Examples/Resources/SqlServerNetwork/2-EnableTcpIpWithDynamicPort.ps1)
* [Enable TCP/IP on custom IP](/Examples/Resources/SqlServerNetwork/3-EnableTcpIpOnCustomIP.ps1)

#### Known issues

Expand Down
Loading