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: xSQLServerNetwork: Support for configuring SQL Server to use a static port #887

Merged
merged 8 commits into from
Oct 17, 2017
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
- Added the CommonTestHelper.psm1 to store common testing functions.
- Added the Import-SQLModuleStub function to ensure the correct version of the
module stubs are loaded ([issue #784](https://github.com/PowerShell/xSQLServer/issues/784)).
- Changes to xSQLServerNetwork
- BREAKING CHANGE: Renamed parameter TcpDynamicPorts to TcpDynamicPort and
changed type to Boolean.
- Resolved issue when switching from dynamic to static port.
configuration ([issue #534](https://github.com/PowerShell/xSQLServer/issues/534)).
- Added localization (en-US) for all strings in resource and unit tests
([issue #618](https://github.com/PowerShell/xSQLServer/issues/618)).
- Updated examples to reflect new parameters.

## 8.2.0.0

Expand Down
122 changes: 64 additions & 58 deletions DSCResources/MSFT_xSQLServerNetwork/MSFT_xSQLServerNetwork.psm1
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) `
-ChildPath 'xSQLServerHelper.psm1') `
-Force
-ChildPath 'xSQLServerHelper.psm1') -Force
Import-Module -Name (Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) `
-ChildPath 'CommonResourceHelper.psm1')

# Load localized string data
$script:localizedData = Get-LocalizedData -ResourceName 'MSFT_xSQLServerNetwork'

<#
.SYNOPSIS
Returns the current state of the SQL Server network properties.
Expand All @@ -11,7 +16,7 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Pare
.PARAMETER ProtocolName
The name of network protocol to be configured. Only tcp is currently supported.
#>
Function Get-TargetResource
function Get-TargetResource
{
[CmdletBinding()]
[OutputType([System.Collections.Hashtable])]
Expand All @@ -34,20 +39,20 @@ Function Get-TargetResource

$managedComputerObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer

Write-Verbose "Getting network protocol [$ProtocolName] for SQL instance [$InstanceName]."
Write-Verbose -Message ($script:localizedData.GetNetworkProtocol -f $ProtocolName, $InstanceName)
$tcp = $managedComputerObject.ServerInstances[$InstanceName].ServerProtocols[$ProtocolName]

Write-Verbose "Reading current network properties."
Write-Verbose -Message $script:localizedData.ReadingNetworkProperties
$returnValue = @{
InstanceName = $InstanceName
InstanceName = $InstanceName
ProtocolName = $ProtocolName
IsEnabled = $tcp.IsEnabled
TcpDynamicPorts = $tcp.IPAddresses['IPAll'].IPAddressProperties['TcpDynamicPorts'].Value
TcpDynamicPort = ($tcp.IPAddresses['IPAll'].IPAddressProperties['TcpDynamicPorts'].Value -ge 0)
TcpPort = $tcp.IPAddresses['IPAll'].IPAddressProperties['TcpPort'].Value
}

$returnValue.Keys | ForEach-Object {
Write-Verbose "$_ = $($returnValue[$_])"
Write-Verbose -Message "$_ = $($returnValue[$_])"
}
}
finally
Expand All @@ -74,16 +79,15 @@ Function Get-TargetResource
.PARAMETER IsEnabled
Enables or disables the network protocol.

.PARAMETER TcpDynamicPorts
Set the value to '0' if dynamic ports should be used.
If static port should be used set this to a empty string value.
Value can not be set to '0' if TcpPort is also set to a value.
.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.

.PARAMETER TcpPort
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 the value '' (empty string).
TcpDynamicPort to 'False'.

.PARAMETER RestartService
If set to $true then SQL Server and dependent services will be restarted
Expand All @@ -93,7 +97,7 @@ Function Get-TargetResource
Timeout value for restarting the SQL Server services. The default value
is 120 seconds.
#>
Function Set-TargetResource
function Set-TargetResource
{
[CmdletBinding()]
param
Expand All @@ -117,9 +121,8 @@ Function Set-TargetResource
$IsEnabled,

[Parameter()]
[ValidateSet('0', '')]
[System.String]
$TcpDynamicPorts,
[System.Boolean]
$TcpDynamicPort,

[Parameter()]
[System.String]
Expand All @@ -134,9 +137,10 @@ Function Set-TargetResource
$RestartTimeout = 120
)

if ($TcpDynamicPorts -eq '0' -and $TcpPort)
if ($TcpDynamicPort -and $TcpPort)
{
throw New-TerminatingError -ErrorType UnableToUseBothDynamicAndStaticPort -ErrorCategory InvalidOperation
$errorMessage = $script:localizedData.ErrorDynamicAndStaticPortSpecified
New-InvalidOperationException -Message $errorMessage
}

$getTargetResourceResult = Get-TargetResource -InstanceName $InstanceName -ProtocolName $ProtocolName
Expand All @@ -146,53 +150,56 @@ Function Set-TargetResource
$applicationDomainObject = Register-SqlWmiManagement -SQLInstanceName $InstanceName

$desiredState = @{
InstanceName = $InstanceName
InstanceName = $InstanceName
ProtocolName = $ProtocolName
IsEnabled = $IsEnabled
TcpDynamicPorts = $TcpDynamicPorts
TcpDynamicPort = $TcpDynamicPort
TcpPort = $TcpPort
}

$isRestartNeeded = $false

$managedComputerObject = New-Object Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer

Write-Verbose "Getting [$ProtocolName] network protocol for [$InstanceName] SQL instance"
Write-Verbose -Message ($script:localizedData.GetNetworkProtocol -f $ProtocolName, $InstanceName)
$tcp = $managedComputerObject.ServerInstances[$InstanceName].ServerProtocols[$ProtocolName]

Write-Verbose 'Checking [IsEnabled] property.'
Write-Verbose -Message ($script:localizedData.CheckingProperty -f 'IsEnabled')
if ($desiredState.IsEnabled -ine $getTargetResourceResult.IsEnabled)
{
Write-Verbose "Updating [IsEnabled] from $($getTargetResourceResult.IsEnabled) to $($desiredState.IsEnabled)."
Write-Verbose -Message ($script:localizedData.UpdatingProperty -f 'IsEnabled', $getTargetResourceResult.IsEnabled, $desiredState.IsEnabled)
$tcp.IsEnabled = $desiredState.IsEnabled
$tcp.Alter()

$isRestartNeeded = $true
}

Write-Verbose 'Checking [TcpDynamicPorts] property.'
if ($desiredState.TcpDynamicPorts -ine $getTargetResourceResult.TcpDynamicPorts)
Write-Verbose -Message ($script:localizedData.CheckingProperty -f 'TcpDynamicPort')
if ($desiredState.TcpDynamicPort -ne $getTargetResourceResult.TcpDynamicPort)
{
$fromTcpDynamicPortsValue = $getTargetResourceResult.TcpDynamicPorts
if ($fromTcpDynamicPortsValue -eq '')
{
$fromTcpDynamicPortsValue = 'none'
# Translates the current and desired state to a string for display
$dynamicPortDisplayValueTable = @{
$true = 'enabled'
$false = 'disabled'
}

$toTcpDynamicPortsValue = $desiredState.TcpDynamicPorts
if ($toTcpDynamicPortsValue -eq '')
{
$toTcpDynamicPortsValue = 'none'
# Translates the desired state to a valid value
$desiredDynamicPortValue = @{
$true = '0'
$false = ''
}

Write-Verbose "Updating [TcpDynamicPorts] from $($fromTcpDynamicPortsValue) to $($toTcpDynamicPortsValue)."
$tcp.IPAddresses['IPAll'].IPAddressProperties['TcpDynamicPorts'].Value = $desiredState.TcpDynamicPorts
$fromTcpDynamicPortDisplayValue = $dynamicPortDisplayValueTable[$getTargetResourceResult.TcpDynamicPort]
$toTcpDynamicPortDisplayValue = $dynamicPortDisplayValueTable[$desiredState.TcpDynamicPort]

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

$isRestartNeeded = $true
}

Write-Verbose 'Checking [TcpPort property].'
Write-Verbose -Message ($script:localizedData.CheckingProperty -f 'TcpPort')
if ($desiredState.TcpPort -ine $getTargetResourceResult.TcpPort)
{
$fromTcpPort = $getTargetResourceResult.TcpPort
Expand All @@ -207,7 +214,7 @@ Function Set-TargetResource
$toTcpPort = 'none'
}

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

Expand Down Expand Up @@ -243,16 +250,15 @@ Function Set-TargetResource
.PARAMETER IsEnabled
Enables or disables the network protocol.

.PARAMETER TcpDynamicPorts
Set the value to '0' if dynamic ports should be used.
If static port should be used set this to a empty string value.
Value can not be set to '0' if TcpPort is also set to a value.
.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.

.PARAMETER TcpPort
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 the value '' (empty string).
TcpDynamicPort to 'False'.

.PARAMETER RestartService
If set to $true then SQL Server and dependent services will be restarted
Expand All @@ -266,7 +272,7 @@ Function Set-TargetResource

Not used in Test-TargetResource.
#>
Function Test-TargetResource
function Test-TargetResource
{
[CmdletBinding()]
[OutputType([System.Boolean])]
Expand All @@ -290,9 +296,8 @@ Function Test-TargetResource
$IsEnabled,

[Parameter()]
[ValidateSet('0', '')]
[System.String]
$TcpDynamicPorts,
[System.Boolean]
$TcpDynamicPort,

[Parameter()]
[System.String]
Expand All @@ -307,20 +312,21 @@ Function Test-TargetResource
$RestartTimeout = 120
)

if ($TcpDynamicPorts -eq '0' -and $TcpPort)
if ($TcpDynamicPort -and $TcpPort)
{
throw New-TerminatingError -ErrorType UnableToUseBothDynamicAndStaticPort -ErrorCategory InvalidOperation
$errorMessage = $script:localizedData.ErrorDynamicAndStaticPortSpecified
New-InvalidOperationException -Message $errorMessage
}

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

Write-Verbose "Comparing desired state with current state."
Write-Verbose -Message $script:localizedData.CompareStates

$isInDesiredState = $true

if ($ProtocolName -ne $getTargetResourceResult.ProtocolName)
{
Write-Verbose ('Expected protocol to be ''{0}'', but was ''{1}''.' -f $ProtocolName, $getTargetResourceResult.ProtocolName)
Write-Verbose -Message ($script:localizedData.ExpectedPropertyValue -f 'ProtocolName', $ProtocolName, $getTargetResourceResult.ProtocolName)

$isInDesiredState = $false
}
Expand All @@ -334,17 +340,17 @@ Function Test-TargetResource
$false = 'disabled'
}

Write-Verbose ('Expected protocol to be {0}, but was {1}.' -f $evaluateEnableOrDisable[$IsEnabled], $evaluateEnableOrDisable[$getTargetResourceResult.IsEnabled])
Write-Verbose -Message ($script:localizedData.ExpectedPropertyValue -f 'IsEnabled', $evaluateEnableOrDisable[$IsEnabled], $evaluateEnableOrDisable[$getTargetResourceResult.IsEnabled])

$isInDesiredState = $false
}
}

if ($PSBoundParameters.ContainsKey('TcpDynamicPorts'))
if ($PSBoundParameters.ContainsKey('TcpDynamicPort'))
{
if ($TcpDynamicPorts -eq '0' -and $getTargetResourceResult.TcpDynamicPorts -eq '')
if ($TcpDynamicPort -and $getTargetResourceResult.TcpDynamicPort -eq $false)
{
Write-Verbose 'Expected tcp dynamic port to be used, but it was not.'
Write-Verbose -Message ($script:localizedData.ExpectedPropertyValue -f 'TcpDynamicPort', $TcpDynamicPort, $getTargetResourceResult.TcpDynamicPort)

$isInDesiredState = $false
}
Expand All @@ -354,21 +360,21 @@ Function Test-TargetResource
{
if ($getTargetResourceResult.TcpPort -eq '')
{
Write-Verbose 'Expected tcp static port to be used, but it was not.'
Write-Verbose -Message ($script:localizedData.ExpectedPropertyValue -f 'TcpPort', $TcpPort, $getTargetResourceResult.TcpPort)

$isInDesiredState = $false
}
elseif ($TcpPort -ne $getTargetResourceResult.TcpPort)
{
Write-Verbose ('Expected tcp static port to be ''{0}'', but was ''{1}''.' -f $TcpPort, $getTargetResourceResult.TcpPort)
Write-Verbose -Message ($script:localizedData.ExpectedPropertyValue -f 'TcpPort', $TcpPort, $getTargetResourceResult.TcpPort)

$isInDesiredState = $false
}
}

if ($isInDesiredState)
{
Write-Verbose "In desired state."
Write-Verbose -Message ($script:localizedData.InDesiredState)
}

return $isInDesiredState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ class MSFT_xSQLServerNetwork : OMI_BaseResource
[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 SQLServer;
[Write, Description("Enables or disables the network protocol.")] Boolean IsEnabled;
[Write, Description("Set the value to '0' if dynamic ports should be used. If static port should be used set this to a empty string value. Value can not be set to '0' if TcpPort is also set to a value."), ValueMap{"0",""}, Values{"0",""}] String TcpDynamicPorts;
[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 the value '' (empty string).")] String TcpPort;
[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;
[Write, Description("Timeout value for restarting the SQL Server services. The default value is 120 seconds.")] UInt16 RestartTimeout;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Localized resources for xSQLServerNetwork

ConvertFrom-StringData @'
GetNetworkProtocol = Getting network protocol [{0}] for SQL instance [{1}].
ReadingNetworkProperties = Reading current network properties.
CheckingProperty = Checking [{0}] property.
UpdatingProperty = Updating property [{0}] from [{1}] to [{2}].
ExpectedPropertyValue = Expected property [{0}] value to be [{1}] but was [{2}].
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.
'@
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ Configuration Example
{
xSQLServerNetwork 'ChangeTcpIpOnDefaultInstance'
{
InstanceName = 'MSSQLSERVER'
ProtocolName = 'Tcp'
IsEnabled = $true
TCPDynamicPorts = ''
TCPPort = 4509
RestartService = $true
InstanceName = 'MSSQLSERVER'
ProtocolName = 'Tcp'
IsEnabled = $true
TCPDynamicPort = $false
TCPPort = 4509
RestartService = $true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ Configuration Example
{
xSQLServerNetwork 'ChangeTcpIpOnDefaultInstance'
{
InstanceName = 'MSSQLSERVER'
ProtocolName = 'Tcp'
IsEnabled = $true
TCPDynamicPorts = '0'
RestartService = $true
InstanceName = 'MSSQLSERVER'
ProtocolName = 'Tcp'
IsEnabled = $true
TCPDynamicPort = $true
RestartService = $true
}
}
}
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -976,13 +976,13 @@ Read more about the network settings in the article
* **`[String]` SQLServer** _(Write)_: The host name of the SQL Server to be configured.
Default value is $env:COMPUTERNAME.
* **`[Boolean]` IsEnabled** _(Write)_: Enables or disables the network protocol.
* **`[String]` TcpDynamicPorts** _(Write)_: Set the value to '0' if dynamic ports
should be used. If static port should be used set this to a empty string value.
Value can not be set to '0' if TcpPort is also set to a value. { '0','' }.
* **`[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.
* **`[String]` TcpPort** _(Write)_: 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
the value '' (empty string).
with a comma ('1433,1500,1501'). To use this parameter set TcpDynamicPort to
$false.
* **`[Boolean]` RestartService** _(Write)_: 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.
Expand Down
Loading