Permalink
Browse files

Fixes for Update-DbaInstance: parallelism, exceptions (#5053)

* Changing error handling in internal functions + minor fixes

* Removing $EnableException param
  • Loading branch information...
nvarscar authored and potatoqualitee committed Feb 6, 2019
1 parent d18fe23 commit 30cda659f27cb23a803ea3c72ec5105d2824c501
@@ -157,7 +157,7 @@ function Update-DbaInstance {
[string[]]$KB,
[Alias("Instance")]
[string]$InstanceName,
[string[]]$Path,
[string[]]$Path = (Get-DbatoolsConfigValue -Name 'Path.SQLServerUpdates'),
[switch]$Restart,
[switch]$Continue,
[ValidateNotNull()]
@@ -286,7 +286,11 @@ function Update-DbaInstance {
$activity = "Preparing to update SQL Server on $resolvedName"
## Find the current version on the computer
Write-ProgressHelper -ExcludePercent -Activity $activity -StepNumber 0 -Message "Gathering all SQL Server instance versions"
$components = Get-SQLInstanceComponent -ComputerName $resolvedName -Credential $Credential
try {
$components = Get-SQLInstanceComponent -ComputerName $resolvedName -Credential $Credential
} catch {
Stop-Function -Message "Error while looking for SQL Server installations on $resolvedName" -Continue -ErrorRecord $_
}
if (!$components) {
Stop-Function -Message "No SQL Server installations found on $resolvedName" -Continue
}
@@ -295,13 +299,17 @@ function Update-DbaInstance {
if ($InstanceName) {
$components = $components | Where-Object {$_.InstanceName -eq $InstanceName }
}
try {
$restartNeeded = Test-PendingReboot -ComputerName $resolvedName -Credential $Credential
} catch {
Stop-Function -Message "Failed to get reboot status from $resolvedName" -Continue -ErrorRecord $_
}
if ($restartNeeded -and (-not $Restart -or ([DbaInstanceParameter]$resolvedName).IsLocalHost)) {
#Exit the actions loop altogether - nothing can be installed here anyways
Stop-Function -Message "$resolvedName is pending a reboot. Reboot the computer before proceeding." -Continue
}
$upgrades = @()
:actions foreach ($currentAction in $actions) {
$restartNeeded = Test-PendingReboot -ComputerName $resolvedName
if ($restartNeeded -and (-not $Restart -or ([DbaInstanceParameter]$resolvedName).IsLocalHost)) {
#Exit the actions loop altogether - nothing can be installed here anyways
Stop-Function -Message "$resolvedName is pending a reboot. Reboot the computer before proceeding." -Continue -ContinueLabel computers
}
# Attempt to configure CredSSP for the remote host when credentials are defined
if ($Credential -and -not ([DbaInstanceParameter]$resolvedName).IsLocalHost -and $Authentication -eq 'Credssp') {
Write-Message -Level Verbose -Message "Attempting to configure CredSSP for remote connections"
@@ -350,7 +358,11 @@ function Update-DbaInstance {
Path = $Path
KB = $detail.KB
}
$installer = Find-SqlServerUpdate @kbLookupParams
try {
$installer = Find-SqlServerUpdate @kbLookupParams
} catch {
Stop-Function -Message "Failed to enumerate files in -Path" -ErrorRecord $_ -Continue
}
if ($installer) {
$detail.Installer = $installer.FullName
} else {
@@ -455,6 +467,7 @@ function Update-DbaInstance {
Write-ProgressHelper -ExcludePercent -Activity $activity -Message "Now installing update SQL$($currentAction.MajorVersion)$($currentAction.TargetLevel) from $spExtractPath"
Write-Message -Level Verbose -Message "Starting installation from $spExtractPath" -FunctionName Update-DbaInstance
$updateResult = Invoke-Program @execParams -Path "$spExtractPath\setup.exe" -ArgumentList @('/quiet', $instanceClause, '/IAcceptSQLServerLicenseTerms') -WorkingDirectory $spExtractPath -Fallback
$output.ExitCode = $updateResult.ExitCode
if ($updateResult.Successful) {
$output.Successful = $true
} else {
@@ -486,7 +499,13 @@ function Update-DbaInstance {
}
}
#double check if restart is needed
if ($updateResult.ExitCode -eq 3010 -or (Test-PendingReboot -ComputerName $resolvedName)) {
try {
$restartNeeded = Test-PendingReboot -ComputerName $resolvedName -Credential $Credential
} catch {
$restartNeeded = $false
Stop-Function -Message "Failed to get reboot status from $resolvedName" -ErrorRecord $_ -FunctionName Update-DbaInstance
}
if ($updateResult.ExitCode -eq 3010 -or $restartNeeded) {
if ($Restart) {
# Restart the computer
Write-ProgressHelper -ExcludePercent -Activity $activity -Message "Restarting computer $($computer) and waiting for it to come back online"
@@ -510,7 +529,7 @@ function Update-DbaInstance {
if ($installActions.Count -eq 1) {
$installActions | ForEach-Object -Process $installScript | ForEach-Object -Process $outputHandler
} elseif ($installActions.Count -ge 2) {
$installActions | Invoke-Parallel -ImportModules -ImportVariables -ScriptBlock $installScript -Throttle $Throttle | ForEach-Object -Process $outputHandler
$installActions | Invoke-Parallel -ImportModules -ImportVariables -ImportFunctions -ScriptBlock $installScript -Throttle $Throttle | ForEach-Object -Process $outputHandler
}
}
}
@@ -27,16 +27,14 @@ function Find-SqlServerUpdate {
[string]$KB,
[ValidateSet('x86', 'x64')]
[string]$Architecture = 'x64',
[string[]]$Path = (Get-DbatoolsConfigValue -Name 'Path.SQLServerUpdates'),
[bool]$EnableException = $EnableException
[string[]]$Path = (Get-DbatoolsConfigValue -Name 'Path.SQLServerUpdates')

)
begin {
}
process {
if (!$Path) {
Stop-Function -Message "Path to SQL Server updates folder is not set. Consider running Set-DbatoolsConfig -Name Path.SQLServerUpdates -Value '\\path\to\updates' or specify the path in the original command"
return
throw "Path to SQL Server updates folder is not set. Consider running Set-DbatoolsConfig -Name Path.SQLServerUpdates -Value '\\path\to\updates' or specify the path in the original command"
}
$filter = "SQLServer$MajorVersion*-KB$KB-*$Architecture*.exe"
Write-Message -Level Verbose -Message "Using filter [$filter] to check for updates in $Path"
@@ -61,11 +59,6 @@ function Find-SqlServerUpdate {
ErrorAction = 'Stop'
Raw = $true
}
try {
Invoke-CommandWithFallback @params
} catch {
Stop-Function -Message "Failed to enumerate files in $Path" -ErrorRecord $_
return
}
Invoke-CommandWithFallback @params
}
}
@@ -69,8 +69,7 @@ function Get-SQLInstanceComponent {
[DbaInstanceParameter[]]$ComputerName = $Env:COMPUTERNAME,
[ValidateSet('SSDS', 'SSAS', 'SSRS')]
[string[]]$Component = @('SSDS', 'SSAS', 'SSRS'),
[pscredential]$Credential,
[bool]$EnableException = $EnableException
[pscredential]$Credential
)

begin {
@@ -297,11 +296,8 @@ function Get-SQLInstanceComponent {
}
process {
foreach ($computer in $ComputerName) {
try {
$results = Invoke-Command2 -ComputerName $computer -ScriptBlock $regScript -Credential $Credential -ErrorAction Stop -Raw -ArgumentList @($Component) -RequiredPSVersion 3.0
} catch {
Stop-Function -Message "Failed to get instance components from $computer" -ErrorRecord $_ -Continue
}
$results = Invoke-Command2 -ComputerName $computer -ScriptBlock $regScript -Credential $Credential -ErrorAction Stop -Raw -ArgumentList @($Component) -RequiredPSVersion 3.0

# Log is stored in the log property, pile it all into the debug log
foreach ($logEntry in $results.Log) {
Write-Message -Level Debug -Message $logEntry
@@ -314,7 +310,7 @@ function Get-SQLInstanceComponent {
$newVersion = New-Object -TypeName System.Version -ArgumentList ($newVersion.Major , ($newVersion.Minor - $newVersion.Minor % 10), $newVersion.Build)
Write-Message -Level Debug -Message "Converted version $($result.Version) to $newVersion"
#Find a proper build reference and replace Version property
$result.Version = Get-DbaBuildReference -Build $newVersion
$result.Version = Get-DbaBuildReference -Build $newVersion -EnableException
$result | Select-Object -ExcludeProperty Log
}
}
@@ -17,47 +17,42 @@ function Test-PendingReboot {
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[DbaInstanceParameter]$ComputerName,
[ValidateNotNullOrEmpty()]
[pscredential]$Credential,
[bool]$EnableException = $EnableException
[pscredential]$Credential
)
process {
try {
$icmParams = @{
ComputerName = $ComputerName.ComputerName
Raw = $true
}
if ($PSBoundParameters.ContainsKey('Credential')) {
$icmParams.Credential = $Credential
}

$OperatingSystem = Get-DbaCmObject -ComputerName $ComputerName.ComputerName -ClassName Win32_OperatingSystem
$icmParams = @{
ComputerName = $ComputerName.ComputerName
Raw = $true
ErrorAction = 'Stop'
}
if (Test-Bound -ParameterName Credential) {
$icmParams.Credential = $Credential
}

# If Vista/2008 & Above query the CBS Reg Key
If ($OperatingSystem.BuildNumber -ge 6001) {
$PendingReboot = Invoke-Command2 @icmParams -ScriptBlock { Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing' -Name 'RebootPending' -ErrorAction SilentlyContinue }
if ($PendingReboot) {
Write-Message -Level Verbose -Message 'Reboot pending detected in the Component Based Servicing registry key'
return $true
}
}
$OperatingSystem = Get-DbaCmObject -ComputerName $ComputerName.ComputerName -ClassName Win32_OperatingSystem -EnableException

# Query WUAU from the registry
$PendingReboot = Invoke-Command2 @icmParams -ScriptBlock { Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update' -Name 'RebootRequired' -ErrorAction SilentlyContinue }
# If Vista/2008 & Above query the CBS Reg Key
If ($OperatingSystem.BuildNumber -ge 6001) {
$PendingReboot = Invoke-Command2 @icmParams -ScriptBlock { Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing' -Name 'RebootPending' -ErrorAction SilentlyContinue }
if ($PendingReboot) {
Write-Message -Level Verbose -Message 'WUAU has a reboot pending'
Write-Message -Level Verbose -Message 'Reboot pending detected in the Component Based Servicing registry key'
return $true
}
}

# Query PendingFileRenameOperations from the registry
$PendingReboot = Invoke-Command2 @icmParams -ScriptBlock { Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name 'PendingFileRenameOperations' -ErrorAction SilentlyContinue }
if ($PendingReboot -and $PendingReboot.PendingFileRenameOperations) {
Write-Message -Level Verbose -Message 'Reboot pending in the PendingFileRenameOperations registry value'
return $true
}
return $false
} catch {
Stop-Function -Message "Failed to obtain any intormation from remote registry on $ComputerName" -ErrorRecord $_
# Query WUAU from the registry
$PendingReboot = Invoke-Command2 @icmParams -ScriptBlock { Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update' -Name 'RebootRequired' -ErrorAction SilentlyContinue }
if ($PendingReboot) {
Write-Message -Level Verbose -Message 'WUAU has a reboot pending'
return $true
}

# Query PendingFileRenameOperations from the registry
$PendingReboot = Invoke-Command2 @icmParams -ScriptBlock { Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name 'PendingFileRenameOperations' -ErrorAction SilentlyContinue }
if ($PendingReboot -and $PendingReboot.PendingFileRenameOperations) {
Write-Message -Level Verbose -Message 'Reboot pending in the PendingFileRenameOperations registry value'
return $true
}
return $false
}
}

0 comments on commit 30cda65

Please sign in to comment.