Skip to content
Merged
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
39 changes: 29 additions & 10 deletions functions/Update-DbaInstance.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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()]
Expand Down Expand Up @@ -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
}
Expand All @@ -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"
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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"
Expand All @@ -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
}
}
}
13 changes: 3 additions & 10 deletions internal/functions/Find-SqlServerUpdate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
}
}
12 changes: 4 additions & 8 deletions internal/functions/Get-SqlInstanceComponent.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand All @@ -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
}
}
Expand Down
61 changes: 28 additions & 33 deletions internal/functions/Test-PendingReboot.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}