Skip to content

Commit

Permalink
Changes to xSQLServer
Browse files Browse the repository at this point in the history
BREAKING CHANGE: xSQLServer does no longer try to support WMF 4.0 (PowerShell 4.0) (issue dsccommunity#574). Minimum supported version of WMF is now 5.0 (PowerShell 5.0).
Changes to xSQLServerSetup
BREAKING CHANGE: The parameter SetupCredential has been removed since it is no longer needed. This is because the resource now support the built-in PsDscRunAsCredential.
BREAKING CHANGE: Now the resource supports using built-in PsDscRunAsCredential. If PsDscRunAsCredential is set, that username will be used as the first system administrator.
BREAKING CHANGE: If the parameter PsDscRunAsCredential are not assigned any credentials then the resource will start the setup process as the SYSTEM account. When installing as the SYSTEM account, then parameter SQLSysAdminAccounts and ASSysAdminAccounts must be specified when installing feature Database Engine and Analysis Services respectively.
When setup exits with exit code 3010 a warning message is written to console telling that setup finished successfully, but a reboot is required (partly fixes issue dsccommunity#565).
Added a new parameter SetupProcessTimeout which defaults to 7200 seconds (2 hours). If the setup process has not finished before the timeout value in SetupProcessTimeout an error will be thrown (issue dsccommunity#566).
  • Loading branch information
johlju committed May 27, 2017
1 parent 9880433 commit 834225a
Show file tree
Hide file tree
Showing 5 changed files with 478 additions and 363 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
- Changes to xSQLServerRSConfig
- Replaced sqlcmd.exe usages with Invoke-Sqlcmd calls (issue #567).
- Changes to xSQLServer
- BREAKING CHANGE: xSQLServer does no longer try to support WMF 4.0 (PowerShell 4.0) (issue #574). Minimum supported version of WMF is now 5.0 (PowerShell 5.0).
- BREAKING CHANGE: Removed deprecated resource xSQLAOGroupJoin (issue #457).
- BREAKING CHANGE: Removed deprecated resource xSQLAOGroupEnsure (issue #456).
- BREAKING CHANGE: Removed deprecated resource xSQLServerFailoverClusterSetup (issue #336).
Expand All @@ -72,6 +73,11 @@
- Removed helper function New-ListenerADObject because the deprecated resource that was using it was removed.
- Changes to xSQLServerSetup
- BREAKING CHANGE: Replaced StartWin32Process helper function with the cmdlet Start-Process (issue #41, #93 and #126).
- BREAKING CHANGE: The parameter SetupCredential has been removed since it is no longer needed. This is because the resource now support the built-in PsDscRunAsCredential.
- BREAKING CHANGE: Now the resource supports using built-in PsDscRunAsCredential. If PsDscRunAsCredential is set, that username will be used as the first system administrator.
- BREAKING CHANGE: If the parameter PsDscRunAsCredential are not assigned any credentials then the resource will start the setup process as the SYSTEM account. When installing as the SYSTEM account, then parameter SQLSysAdminAccounts and ASSysAdminAccounts must be specified when installing feature Database Engine and Analysis Services respectively.
- When setup exits with exit code 3010 a warning message is written to console telling that setup finished successfully, but a reboot is required (partly fixes issue #565).
- Added a new parameter SetupProcessTimeout which defaults to 7200 seconds (2 hours). If the setup process has not finished before the timeout value in SetupProcessTimeout an error will be thrown (issue #566).

## 7.0.0.0

Expand Down
190 changes: 128 additions & 62 deletions DSCResources/MSFT_xSQLServerSetup/MSFT_xSQLServerSetup.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $script
.PARAMETER SourcePath
The path to the root of the source files for installation. I.e and UNC path to a shared resource. Environment variables can be used in the path.
.PARAMETER SetupCredential
Credential to be used to perform the installation.
.PARAMETER SourceCredential
Credentials used to access the path set in the parameter `SourcePath`. Using this parameter will trigger a copy
of the installation media to a temp folder on the target node. Setup will then be started from the temp folder on the target node.
Expand Down Expand Up @@ -45,10 +42,6 @@ function Get-TargetResource
[System.String]
$SourcePath,

[Parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$SetupCredential,

[Parameter()]
[System.Management.Automation.PSCredential]
$SourceCredential,
Expand Down Expand Up @@ -459,9 +452,6 @@ function Get-TargetResource
.PARAMETER SourcePath
The path to the root of the source files for installation. I.e and UNC path to a shared resource. Environment variables can be used in the path.
.PARAMETER SetupCredential
Credential to be used to perform the installation.
.PARAMETER SourceCredential
Credentials used to access the path set in the parameter `SourcePath`. Using this parameter will trigger a copy
of the installation media to a temp folder on the target node. Setup will then be started from the temp folder on the target node.
Expand Down Expand Up @@ -590,6 +580,9 @@ function Get-TargetResource
.PARAMETER FailoverClusterNetworkName
Host name to be assigned to the clustered SQL Server instance
.PARAMETER SetupProcessTimeout
The timeout, in seconds, to wait for the setup process to finish. Default value is 7200 seconds (2 hours). If the setup process does not finish before this time, and error will be thrown.
#>
function Set-TargetResource
{
Expand All @@ -607,10 +600,6 @@ function Set-TargetResource
[System.String]
$SourcePath,

[Parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$SetupCredential,

[Parameter()]
[System.Management.Automation.PSCredential]
$SourceCredential,
Expand Down Expand Up @@ -774,13 +763,16 @@ function Set-TargetResource

[Parameter()]
[System.String]
$FailoverClusterNetworkName
$FailoverClusterNetworkName,

[Parameter()]
[System.UInt32]
$SetupProcessTimeout = 7200
)

$getTargetResourceParameters = @{
Action = $Action
SourcePath = $SourcePath
SetupCredential = $SetupCredential
SourceCredential = $SourceCredential
InstanceName = $InstanceName
FailoverClusterNetworkName = $FailoverClusterNetworkName
Expand Down Expand Up @@ -864,8 +856,8 @@ function Set-TargetResource
$sqlVersion = Get-SqlMajorVersion -Path $pathToSetupExecutable

# Determine features to install
$featuresToInstall = ""
foreach ($feature in $Features.Split(","))
$featuresToInstall = ''
foreach ($feature in $Features.Split(','))
{
# Given that all the returned features are uppercase, make sure that the feature to search for is also uppercase
$feature = $feature.ToUpper();
Expand Down Expand Up @@ -1174,7 +1166,16 @@ function Set-TargetResource
# Should not be passed when PrepareFailoverCluster is specified
if ($Action -in @('Install','InstallFailoverCluster','CompleteFailoverCluster'))
{
$setupArguments += @{ SQLSysAdminAccounts = @($SetupCredential.UserName) }
if ($null -ne $PsDscContext.RunAsUser)
{
<#
Add the credentials from the parameter PsDscRunAsCredential, as the first
system administrator. The username is stored in $PsDscContext.RunAsUser.
#>
New-VerboseMessage -Message "Adding user '$($PsDscContext.RunAsUser)' from the parameter 'PsDscRunAsCredential' as the first system administrator account for SQL Server."
$setupArguments += @{ SQLSysAdminAccounts = @($PsDscContext.RunAsUser) }
}

if ($PSBoundParameters.ContainsKey('SQLSysAdminAccounts'))
{
$setupArguments['SQLSysAdminAccounts'] += $SQLSysAdminAccounts
Expand Down Expand Up @@ -1232,7 +1233,15 @@ function Set-TargetResource

if ($Action -in ('Install','InstallFailoverCluster','CompleteFailoverCluster'))
{
$setupArguments += @{ ASSysAdminAccounts = @($SetupCredential.UserName) }
if ($null -ne $PsDscContext.RunAsUser)
{
<#
Add the credentials from the parameter PsDscRunAsCredential, as the first
system administrator. The username is stored in $PsDscContext.RunAsUser.
#>
New-VerboseMessage -Message "Adding user '$($PsDscContext.RunAsUser)' from the parameter 'PsDscRunAsCredential' as the first system administrator account for Analysis Services."
$setupArguments += @{ ASSysAdminAccounts = @($PsDscContext.RunAsUser) }
}

if($PSBoundParameters.ContainsKey("ASSysAdminAccounts"))
{
Expand Down Expand Up @@ -1318,50 +1327,64 @@ function Set-TargetResource
}
}

New-VerboseMessage -Message "Starting setup using arguments: $log"

$arguments = $arguments.Trim()
$processArguments = @{
FilePath = $pathToSetupExecutable
ArgumentList = $arguments
}

if ($Action -in @('InstallFailoverCluster','AddNode'))
try
{
$processArguments.Add('Credential',$SetupCredential)
}
New-VerboseMessage -Message "Starting setup using arguments: $log"

$sqlSetupProcess = Start-Process @processArguments -PassThru -Wait -NoNewWindow
Wait-Process -InputObject $sqlSetupProcess -Timeout 120
<#
This handles when PsDscRunAsCredential is set, or running as the SYSTEM account (when
PsDscRunAsCredential is set).
#>

$processExitCode = $sqlSetupProcess.ExitCode
$setupExitMessage = "Setup exited with code '$processExitCode'."
$startProcessParameters = @{
FilePath = $pathToSetupExecutable
ArgumentList = $arguments
Timeout = $SetupProcessTimeout
}

if ($processExitCode -ne 0) {
$setupExitMessage += ' Please see the ''Summary.txt'' log file in the ''Setup Bootstrap\Log'' folder.'
$processExitCode = Start-SqlSetupProcess @startProcessParameters

throw $setupExitMessage
}
else
{
Write-Verbose $setupExitMessage
}
$setupExitMessage = "Setup exited with code '$processExitCode'."

if ($ForceReboot -or ($null -ne (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name 'PendingFileRenameOperations' -ErrorAction SilentlyContinue)))
{
if (-not ($SuppressReboot))
if ($processExitCode -eq 3010 -and -not $SuppressReboot)
{
$global:DSCMachineStatus = 1
$setupExitMessage = ('{0} {1}' -f $setupExitMessage, 'Setup was installed successfully, but a reboot is required.')

Write-Warning -Message $setupExitMessage
}
elseif ($processExitCode -ne 0)
{
$setupExitMessage = ('{0} {1}' -f $setupExitMessage, 'Please see the ''Summary.txt'' log file in the ''Setup Bootstrap\Log'' folder.')

throw $setupExitMessage
}
else
{
New-VerboseMessage -Message 'Suppressing reboot'
New-VerboseMessage -Message $setupExitMessage
}
}

if (-not (Test-TargetResource @PSBoundParameters))
if ($ForceReboot -or ($null -ne (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name 'PendingFileRenameOperations' -ErrorAction SilentlyContinue)))
{
if (-not ($SuppressReboot))
{
$global:DSCMachineStatus = 1
}
else
{
New-VerboseMessage -Message 'Suppressing reboot'
}
}

if (-not (Test-TargetResource @PSBoundParameters))
{
throw New-TerminatingError -ErrorType TestFailedAfterSet -ErrorCategory InvalidResult
}
}
catch
{
throw New-TerminatingError -ErrorType TestFailedAfterSet -ErrorCategory InvalidResult
throw $_
}
}

Expand All @@ -1376,9 +1399,6 @@ function Set-TargetResource
.PARAMETER SourcePath
The path to the root of the source files for installation. I.e and UNC path to a shared resource. Environment variables can be used in the path.
.PARAMETER SetupCredential
Credential to be used to perform the installation.
.PARAMETER SourceCredential
Credentials used to access the path set in the parameter `SourcePath`. Using this parameter will trigger a copy
of the installation media to a temp folder on the target node. Setup will then be started from the temp folder on the target node.
Expand Down Expand Up @@ -1507,6 +1527,9 @@ function Set-TargetResource
.PARAMETER FailoverClusterNetworkName
Host name to be assigned to the clustered SQL Server instance
.PARAMETER SetupProcessTimeout
The timeout, in seconds, to wait for the setup process to finish. Default value is 7200 seconds (2 hours). If the setup process does not finish before this time, and error will be thrown.
#>
function Test-TargetResource
{
Expand All @@ -1523,10 +1546,6 @@ function Test-TargetResource
[System.String]
$SourcePath,

[Parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$SetupCredential,

[Parameter()]
[System.Management.Automation.PSCredential]
$SourceCredential,
Expand Down Expand Up @@ -1690,13 +1709,16 @@ function Test-TargetResource

[Parameter(ParameterSetName = 'ClusterInstall')]
[System.String]
$FailoverClusterNetworkName
$FailoverClusterNetworkName,

[Parameter()]
[System.UInt32]
$SetupProcessTimeout = 7200
)

$getTargetResourceParameters = @{
Action = $Action
SourcePath = $SourcePath
SetupCredential = $SetupCredential
SourceCredential = $SourceCredential
InstanceName = $InstanceName
FailoverClusterNetworkName = $FailoverClusterNetworkName
Expand Down Expand Up @@ -1797,7 +1819,7 @@ function Get-FirstItemPropertyValue

<#
.SYNOPSIS
Copy folder structure using RoboCopy. Every file and folder, including empty ones are copied.
Copy folder structure using Robocopy. Every file and folder, including empty ones are copied.
.PARAMETER Path
Source path to be copied.
Expand Down Expand Up @@ -1861,12 +1883,12 @@ function Copy-ItemWithRobocopy

{$_ -gt 7 }
{
throw "Robocopy reported that failures occured when copying files. Error code: $_."
throw "Robocopy reported that failures occurred when copying files. Error code: $_."
}

1
{
Write-Verbose 'Robocopy copied files sucessfully'
Write-Verbose 'Robocopy copied files successfully'
}

2
Expand All @@ -1876,7 +1898,7 @@ function Copy-ItemWithRobocopy

3
{
Write-Verbose 'Robocopy copied files to destination sucessfully. Robocopy also found files at the destination path that is not present at the source path, these extra files was remove at the destination path.'
Write-Verbose 'Robocopy copied files to destination successfully. Robocopy also found files at the destination path that is not present at the source path, these extra files was remove at the destination path.'
}

{$_ -eq 0 -or $null -eq $_ }
Expand Down Expand Up @@ -2029,4 +2051,48 @@ function Get-ServiceAccountParameters
return $parameters
}

<#
.SYNOPSIS
Starts the SQL setup process-
.PARAMETER FilePath
String containing the path to setup.exe.
.PARAMETER ArgumentList
The arguments that should be passed to setup.exe.
.PARAMETER Timeout
The timeout in seconds to wait for the process to finish.
#>
function Start-SqlSetupProcess
{
param
(
[Parameter(Mandatory = $true)]
[System.String]
$FilePath,

[Parameter()]
[System.String]
$ArgumentList,

[Parameter(Mandatory = $true)]
[System.UInt32]
$Timeout
)

$startProcessParameters = @{
FilePath = $FilePath
ArgumentList = $ArgumentList
}

$sqlSetupProcess = Start-Process @startProcessParameters -PassThru -NoNewWindow -ErrorAction Stop

New-VerboseMessage -Message ('Started the process with id {0} using the path ''{1}'', and with a timeout value of {2} seconds.' -f $sqlSetupProcess.Id, $startProcessParameters.FilePath, $Timeout)

Wait-Process -InputObject $sqlSetupProcess -Timeout $Timeout -ErrorAction Stop

return $sqlSetupProcess.ExitCode
}

Export-ModuleMember -Function *-TargetResource
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ class MSFT_xSQLServerSetup : OMI_BaseResource
{
[Write, Description("The action to be performed. Default value is 'Install'."), ValueMap{"Install","InstallFailoverCluster","AddNode","PrepareFailoverCluster","CompleteFailoverCluster"}, Values{"Install","InstallFailoverCluster","AddNode","PrepareFailoverCluster","CompleteFailoverCluster"}] String Action;
[Write, Description("The path to the root of the source files for installation. I.e and UNC path to a shared resource. Environment variables can be used in the path.")] String SourcePath;
[Required, EmbeddedInstance("MSFT_Credential"), Description("Credential to be used to perform the installation.")] String SetupCredential;
[Write, EmbeddedInstance("MSFT_Credential"), Description("Credentials used to access the path set in the parameter 'SourcePath'.")] String SourceCredential;
[Write, Description("Suppresses reboot.")] Boolean SuppressReboot;
[Write, Description("Forces reboot.")] Boolean ForceReboot;
Expand Down Expand Up @@ -50,5 +49,6 @@ class MSFT_xSQLServerSetup : OMI_BaseResource
[Write, Description("Specifies the startup mode for SQL Server Browser service."), ValueMap{"Automatic", "Disabled", "Manual"}, Values{"Automatic", "Disabled", "Manual"}] String BrowserSvcStartupType;
[Write, Description("The name of the resource group to create for the clustered SQL Server instance. Default is 'SQL Server (InstanceName)'.")] String FailoverClusterGroupName;
[Write, Description("Array of IP Addresses to be assigned to the clustered SQL Server instance.")] String FailoverClusterIPAddress[];
[Write, Description("Host name to be assigend to the clustered SQL Server instance.")] String FailoverClusterNetworkName;
[Write, Description("Host name to be assigned to the clustered SQL Server instance.")] String FailoverClusterNetworkName;
[Write, Description("The timeout, in seconds, to wait for the setup process to finish. Default value is 7200 seconds (2 hours). If the setup process does not finish before this time, and error will be thrown.")] Uint32 SetupProcessTimeout;
};
Loading

0 comments on commit 834225a

Please sign in to comment.