How To Know When Microsoft Releases Patches For SQL Server 1732038323
How To Know When Microsoft Releases Patches For SQL Server 1732038323
Keeping SQL Server up-to-date with the latest patches is crucial for ensuring optimal performance, security, and stability. For those who
manage SQL Server patching manually, staying informed about new releases is essential. Here’s how you can effectively track patch
releases and even automate notifications to your team:
o Visit trusted sources like sqlbuilds or the official Microsoft websites to stay updated on the latest SQL Server builds
and patches.
o Microsoft typically releases patches on a predictable schedule, but staying vigilant for emergency patches is crucial
to ensure your systems are always secure.
o To streamline the process, consider automating an email alert to your team whenever there’s a new release. Here’s
how:
▪ Create a scheduled script (using PowerShell or a similar tool) that checks for updates on official sources
like sqlbuilds or Microsoft's website.
▪ When a new patch is detected, trigger an automated email notification to your team to ensure they are
aware of the update.
▪ This approach is especially beneficial if your team handles patching manually, allowing for quick action
without the need to constantly monitor for updates.
• For automation, you can use PowerShell scripts, which can check the RSS feed or web content for updates and send emails
via SMTP.
• Third-party patch management tools often handle this process automatically, but for teams that prefer manual patching, the
above approach ensures they are always up-to-date without extra effort.
By leveraging these methods, you can simplify your SQL Server maintenance process and reduce the risk of missing critical updates.
Sample email:
I follow Method 2.
Steps involving
Step 1. Download the Microsoft SQL Server Version and Build history excel file
Step 2. Insert into a table in your DBA database and send an email when there is a new record.
Complete script for your reference as below. Configure a SQL agent job and add 2 steps below.
#Step1:
#import-module dbatools
$location = "T:\sql_versions"
$myDownloadUrl = "https://aka.ms/sqlserverbuilds"
$sqlinstance = "YOURSERVER"
$query_alter = "alter table [DBA].[dbo].[MsftBuildHistory_Source] add Namelevel varchar(10);"
$query_update = "update [DBA].[dbo].[MsftBuildHistory_Source] set Namelevel =
case
when [Build Number]
like '9%' then '2005'
when [Build Number]
like '10.0%' then '2008'
when [Build Number]
like '10.5%' then '2008R2'
when [Build Number]
like '11%' then '2012'
when [Build Number]
like '12%' then '2014'
when [Build Number]
like '13%' then '2016'
when [Build Number]
like '14%' then '2017'
when [Build Number]
like '15%' then '2019'
when [Build Number]
like '16%' then '2022'
else
'Unkown'
end"
set-location $location
Get-ChildItem -Path $location -Include * -File -Recurse | foreach { $_.Delete()}
#Download spreadsheet from sql server build
Invoke-WebRequest $myDownloadUrl -OutFile $location\SQLServerBuilds.xlsx
try {
Invoke-Sqlcmd -Query "SELECT 1 as one" -ServerInstance $sqlinstance -Database dba -ErrorAction Stop | out-null
Write-Host "Connection successful!"
} catch {
Write-Host "Connection failed: $($_.Exception.Message)"
exit 1
}
#Convert downloaded spreadsheet to .csv and import them to MsftBuildHistory_Source table
Invoke-sqlcmd -ServerInstance $sqlinstance -Database dba -query "truncate table dbo.MsftBuildHistory_Source"
(Import-Excel $location\SQLServerBuilds.xlsx *).GetEnumerator() |ForEach-Object { $_.Value | Export-Csv ($_.key + '.csv') -
NoTypeInformation }
gci $location -Exclude *e*.csv, *.xlsx | ForEach-Object {
#Import-DbaCsv -SqlInstance $sqlinstance -Database dba -Path $_ -Table MsftBuildHistory_Source -AutoCreateTable
Import-CSV $_ | ForEach-Object {Invoke-Sqlcmd -Database dba -ServerInstance $sqlinstance -Query "insert into
dbo.MsftBuildHistory_Source VALUES ('$($_.'Build Number')','$($_.'KB Number')','$($_.'KB URL')','$($_.'Release Date')','$($_.'Service
Pack Level')','$($_.'Cumulative Update or Security ID' )','$($_.'Servicing Model')','$($_.'Notes')','$($_.'Namelevel')')"}
}
#Create and update namelevel in MsftBuildHistory_Source table
#invoke-sqlcmd -ServerInstance $sqlinstance -Database dba -query $query_alter
#sleep 1
invoke-sqlcmd -ServerInstance $sqlinstance -Database dba -query $query_update
#Convert Release date to date format
invoke-sqlcmd -ServerInstance $sqlinstance -Database dba -query $dateconvert
#update refresh date in MsftBuildHistory_refreshdate table
invoke-sqlcmd -ServerInstance $sqlinstance -Database dba -query "update [dbo].[msftbuildhistory_refreshdate] set refresh_date =
SYSDATETIME()"
#Step2:
BEGIN TRY
-- Step 1: Create a temporary table to hold new records for the email content
CREATE TABLE #NewRecords (
[Build Number] NVARCHAR(50),
[KB Number] NVARCHAR(50),
[KB URL] NVARCHAR(255),
[Release Date] DATE,
[Service Pack Level] NVARCHAR(50),
[Cumulative Update or Security ID] NVARCHAR(50),
[Servicing Model] NVARCHAR(100),
[Notes] NVARCHAR(255),
[Namelevel] NVARCHAR(50)
);
-- Step 2: Use MERGE to insert new records into the target table
MERGE INTO dbo.MsftBuildHistory AS Target
USING dbo.MsftBuildHistory_Source AS Source
ON Target.[Build Number] = Source.[Build Number]
WHEN NOT MATCHED BY Target THEN
INSERT ([Build Number], [KB Number], [KB URL], [Release Date], [Service Pack Level],
[Cumulative Update or Security ID], [Servicing Model], Notes, NameLevel)
VALUES (Source.[Build Number], Source.[KB Number], Source.[KB URL], Source.[Release Date],
Source.[Service Pack Level], Source.[Cumulative Update or Security ID],
Source.[Servicing Model], Source.Notes, Source.NameLevel)
OUTPUT inserted.[Build Number], inserted.[KB Number], inserted.[KB URL],
inserted.[Release Date], inserted.[Service Pack Level],
inserted.[Cumulative Update or Security ID], inserted.[Servicing Model],
inserted.Notes, inserted.NameLevel
INTO #NewRecords; -- Store the new records into the temporary table
IF @recordCount > 0
BEGIN
DECLARE @body NVARCHAR(MAX) = '<html><body><p>The following new records have been added to MsftBuildHistory:</p>';
SET @body += '<table border="1" style="border-collapse:collapse;">';
SET @body += '<tr><th>Build Number</th><th>KB Number</th><th>KB URL</th><th>Release Date</th>'
+ '<th>Service Pack Level</th><th>Cumulative Update or Security ID</th>'
+ '<th>Servicing Model</th><th>Notes</th><th>Name Level</th></tr>';
-- Append each new record's details to the email body as rows in the HTML table
DECLARE @BuildNumber NVARCHAR(50);
DECLARE @KBNumber NVARCHAR(50);
DECLARE @KBURL NVARCHAR(255);
DECLARE @ReleaseDate DATE;
DECLARE @ServicePackLevel NVARCHAR(50);
DECLARE @CumulativeUpdateOrSecurityID NVARCHAR(50);
DECLARE @ServicingModel NVARCHAR(100);
DECLARE @Notes NVARCHAR(255);
DECLARE @NameLevel NVARCHAR(50);
OPEN record_cursor;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @body += '<tr><td>' + ISNULL(@BuildNumber, '') + '</td>'
+ '<td>' + ISNULL(@KBNumber, '') + '</td>'
+ '<td><a href="' + ISNULL(@KBURL, '') + '">' + ISNULL(@KBURL, '') + '</a></td>'
+ '<td>' + ISNULL(CAST(@ReleaseDate AS NVARCHAR(10)), '') + '</td>'
+ '<td>' + ISNULL(@ServicePackLevel, '') + '</td>'
+ '<td>' + ISNULL(@CumulativeUpdateOrSecurityID, '') + '</td>'
+ '<td>' + ISNULL(@ServicingModel, '') + '</td>'
+ '<td>' + ISNULL(@Notes, '') + '</td>'
+ '<td>' + ISNULL(@NameLevel, '') + '</td></tr>';
CLOSE record_cursor;
DEALLOCATE record_cursor;