DSCResources/DSC_SqlEndpoint/DSC_SqlEndpoint.psm1
$script:sqlServerDscHelperModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\SqlServerDsc.Common' $script:resourceHelperModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\DscResource.Common' Import-Module -Name $script:sqlServerDscHelperModulePath Import-Module -Name $script:resourceHelperModulePath $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# .SYNOPSIS Returns the current state of the endpoint. .PARAMETER EndpointName The name of the endpoint. .PARAMETER EndpointType Specifies the type of endpoint. Currently the only type that is supported is the Database Mirror type. .PARAMETER ServerName The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME. .PARAMETER InstanceName The name of the SQL instance to be configured. .NOTES Get-TargetResource throws an error when the endpoint does not match the endpoint type. This is because the endpoint cannot be changed once the endpoint have been created and manual intervention is needed. Also Set-TargetResource and Test-TargetResource depends on that the Get-TargetResource does this check so we don't need to have the same check in those functions as well. #> function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory = $true)] [System.String] $EndpointName, [Parameter(Mandatory = $true)] [ValidateSet('DatabaseMirroring')] [System.String] $EndpointType, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $ServerName = $env:COMPUTERNAME, [Parameter(Mandatory = $true)] [System.String] $InstanceName ) Write-Verbose -Message ( $script:localizedData.GetEndpoint -f $EndpointName, $InstanceName ) $getTargetResourceReturnValues = @{ ServerName = $ServerName InstanceName = $InstanceName EndpointType = $EndpointType Ensure = 'Absent' EndpointName = '' Port = '' IpAddress = '' Owner = '' State = $null } $sqlServerObject = Connect-SQL -ServerName $ServerName -InstanceName $InstanceName if ($sqlServerObject) { Write-Verbose -Message ( $script:localizedData.ConnectedToInstance -f $ServerName, $InstanceName ) $endpointObject = $sqlServerObject.Endpoints[$EndpointName] if ($endpointObject.Name -eq $EndpointName) { if ($endpointObject.EndpointType -ne $EndpointType) { $errorMessage = $script:localizedData.EndpointFoundButWrongType -f $EndpointName, $endpointObject.EndpointType, $EndpointType New-InvalidOperationException -Message $errorMessage } $getTargetResourceReturnValues.Ensure = 'Present' $getTargetResourceReturnValues.EndpointName = $endpointObject.Name $getTargetResourceReturnValues.Port = $endpointObject.Protocol.Tcp.ListenerPort $getTargetResourceReturnValues.IpAddress = $endpointObject.Protocol.Tcp.ListenerIPAddress $getTargetResourceReturnValues.Owner = $endpointObject.Owner $getTargetResourceReturnValues.State = $endpointObject.EndpointState } } else { $errorMessage = $script:localizedData.NotConnectedToInstance -f $ServerName, $InstanceName New-InvalidOperationException -Message $errorMessage } return $getTargetResourceReturnValues } <# .SYNOPSIS Create, changes or drops an endpoint. .PARAMETER EndpointName The name of the endpoint. .PARAMETER EndpointType Specifies the type of endpoint. Currently the only type that is supported is the Database Mirror type. .PARAMETER Ensure If the endpoint should be present or absent. Default values is 'Present'. .PARAMETER Port The network port the endpoint is listening on. Default value is 5022, but default value is only used during endpoint creation, it is not enforce. .PARAMETER ServerName The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME. .PARAMETER InstanceName The name of the SQL instance to be configured. .PARAMETER IpAddress The network IP address the endpoint is listening on. Default value is '0.0.0.0' which means listen on any valid IP address. The default value is only used during endpoint creation, it is not enforce. .PARAMETER Owner The owner of the endpoint. Default is the login used for the creation. .PARAMETER State Specifies the state of the endpoint. Valid states are Started, Stopped, or Disabled. When an endpoint is created and the state is not specified then the endpoint will be started after it is created. The state will not be enforced unless the parameter is specified. #> function Set-TargetResource { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [System.String] $EndpointName, [Parameter(Mandatory = $true)] [ValidateSet('DatabaseMirroring')] [System.String] $EndpointType, [Parameter()] [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', [Parameter()] [System.UInt16] $Port = 5022, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $ServerName = $env:COMPUTERNAME, [Parameter(Mandatory = $true)] [System.String] $InstanceName, [Parameter()] [System.String] $IpAddress = '0.0.0.0', [Parameter()] [System.String] $Owner, [Parameter()] [ValidateSet('Started', 'Stopped', 'Disabled')] [System.String] $State ) $getTargetResourceParameters = @{ EndpointName = $EndpointName EndpointType = $EndpointType ServerName = $ServerName InstanceName = $InstanceName } $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters $sqlServerObject = Connect-SQL -ServerName $ServerName -InstanceName $InstanceName if ($sqlServerObject) { if ($Ensure -eq 'Present') { if ($getTargetResourceResult.Ensure -eq 'Absent') { Write-Verbose -Message ( $script:localizedData.CreateEndpoint -f $EndpointName, $InstanceName ) switch ($EndpointType) { 'DatabaseMirroring' { $endpointObject = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Endpoint' -ArgumentList @($sqlServerObject, $EndpointName) $endpointObject.EndpointType = [Microsoft.SqlServer.Management.Smo.EndpointType]::DatabaseMirroring $endpointObject.ProtocolType = [Microsoft.SqlServer.Management.Smo.ProtocolType]::Tcp $endpointObject.Protocol.Tcp.ListenerPort = $Port $endpointObject.Protocol.Tcp.ListenerIPAddress = $IpAddress if ($PSBoundParameters.ContainsKey('Owner')) { $endpointObject.Owner = $Owner } $endpointObject.Payload.DatabaseMirroring.ServerMirroringRole = [Microsoft.SqlServer.Management.Smo.ServerMirroringRole]::All $endpointObject.Payload.DatabaseMirroring.EndpointEncryption = [Microsoft.SqlServer.Management.Smo.EndpointEncryption]::Required $endpointObject.Payload.DatabaseMirroring.EndpointEncryptionAlgorithm = [Microsoft.SqlServer.Management.Smo.EndpointEncryptionAlgorithm]::Aes $endpointObject.Create() <# If endpoint state is not specified, then default to starting the endpoint. If state is specified then it will be handled later. #> if (-not ($PSBoundParameters.ContainsKey('State'))) { $endpointObject.Start() } } } } else { Write-Verbose -Message ( $script:localizedData.SetEndpoint -f $EndpointName, $InstanceName ) $endpointObject = $sqlServerObject.Endpoints[$EndpointName] if (-not $endpointObject) { $errorMessage = $script:localizedData.EndpointNotFound -f $EndpointName New-ObjectNotFoundException -Message $errorMessage } } <# The endpoint exist or was just created. Verifying supported properties so they are in desired state. #> # Properties regardless of endpoint type. if ($PSBoundParameters.ContainsKey('State')) { if ($endpointObject.EndpointState -ne $State) { Write-Verbose -Message ( $script:localizedData.ChangingEndpointState -f $State ) switch ($State) { 'Started' { $endpointObject.Start() } 'Stopped' { $endpointObject.Stop() } 'Disabled' { $endpointObject.Disable() } } } } # Individual endpoint type properties. switch ($EndpointType) { 'DatabaseMirroring' { if ($PSBoundParameters.ContainsKey('IpAddress')) { if ($endpointObject.Protocol.Tcp.ListenerIPAddress -ne $IpAddress) { Write-Verbose -Message ( $script:localizedData.UpdatingEndpointIPAddress -f $IpAddress ) $endpointObject.Protocol.Tcp.ListenerIPAddress = $IpAddress $endpointObject.Alter() } } if ($PSBoundParameters.ContainsKey('Port')) { if ($endpointObject.Protocol.Tcp.ListenerPort -ne $Port) { Write-Verbose -Message ( $script:localizedData.UpdatingEndpointPort -f $Port ) $endpointObject.Protocol.Tcp.ListenerPort = $Port $endpointObject.Alter() } } if ($PSBoundParameters.ContainsKey('Owner')) { if ($endpointObject.Owner -ne $Owner) { Write-Verbose -Message ( $script:localizedData.UpdatingEndpointOwner -f $Owner ) $endpointObject.Owner = $Owner $endpointObject.Alter() } } } } } if ($Ensure -eq 'Absent' -and $getTargetResourceResult.Ensure -eq 'Present') { $endpointObject = $sqlServerObject.Endpoints[$EndpointName] if ($endpointObject) { Write-Verbose -Message ( $script:localizedData.DropEndpoint -f $EndpointName, $InstanceName ) $endpointObject.Drop() } else { $errorMessage = $script:localizedData.EndpointNotFound -f $EndpointName New-ObjectNotFoundException -Message $errorMessage } } } else { $errorMessage = $script:localizedData.NotConnectedToInstance -f $ServerName, $InstanceName New-InvalidOperationException -Message $errorMessage } } <# .SYNOPSIS Tests if the principal (login) has the desired permissions. .PARAMETER EndpointName The name of the endpoint. .PARAMETER EndpointType Specifies the type of endpoint. Currently the only type that is supported is the Database Mirror type. .PARAMETER Ensure If the endpoint should be present or absent. Default values is 'Present'. .PARAMETER Port The network port the endpoint is listening on. Default value is 5022, but default value is only used during endpoint creation, it is not enforce. .PARAMETER ServerName The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME. .PARAMETER InstanceName The name of the SQL instance to be configured. .PARAMETER IpAddress The network IP address the endpoint is listening on. Default value is '0.0.0.0' which means listen on any valid IP address. The default value is only used during endpoint creation, it is not enforce. .PARAMETER Owner The owner of the endpoint. Default is the login used for the creation. .PARAMETER State Specifies the state of the endpoint. Valid states are Started, Stopped, or Disabled. When an endpoint is created and the state is not specified then the endpoint will be started after it is created. The state will not be enforced unless the parameter is specified. #> function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [System.String] $EndpointName, [Parameter(Mandatory = $true)] [ValidateSet('DatabaseMirroring')] [System.String] $EndpointType, [Parameter()] [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', [Parameter()] [System.UInt16] $Port = 5022, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $ServerName = $env:COMPUTERNAME, [Parameter(Mandatory = $true)] [System.String] $InstanceName, [Parameter()] [System.String] $IpAddress = '0.0.0.0', [Parameter()] [System.String] $Owner, [Parameter()] [ValidateSet('Started', 'Stopped', 'Disabled')] [System.String] $State ) Write-Verbose -Message ( $script:localizedData.TestingConfiguration -f $EndpointName, $InstanceName ) $getTargetResourceParameters = @{ EndpointName = $EndpointName EndpointType = $EndpointType ServerName = $ServerName InstanceName = $InstanceName } $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters if ($getTargetResourceResult.Ensure -eq $Ensure) { $result = $true if ($PSBoundParameters.ContainsKey('Owner')) { if ($getTargetResourceResult.Owner -ne $Owner) { $result = $false } } if ($PSBoundParameters.ContainsKey('State')) { if ($getTargetResourceResult.State -ne $State) { $result = $false } } if ($getTargetResourceResult.Ensure -eq 'Present' ` -and ( $getTargetResourceResult.Port -ne $Port ` -or $getTargetResourceResult.IpAddress -ne $IpAddress ) ) { $result = $false } } else { $result = $false } if ($result) { Write-Verbose -Message ( $script:localizedData.InDesiredState -f $EndpointName ) } else { Write-Verbose -Message ( $script:localizedData.NotInDesiredState -f $EndpointName ) } return $result } Export-ModuleMember -Function *-TargetResource |