Skip to content
Open
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Versions

## [Unreleased]
* Upgrade SqlServerDsc from 15.1.1 to 17.1.0 [#1476](https://github.com/microsoft/PowerStig/issues/1476)


## [4.27.0] - 2025-09-05
Expand Down
25 changes: 25 additions & 0 deletions Tests/Unit/Module/SqlScriptQueryRule.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ try
Extended Events. If Extended Events are in use, and cover all the required audit events listed above, this is not a finding.'
FixText = 'This will not be used for this type of rule.'
EventId = '(14),(15),(18),(20),(102),(103),(104),(105),(106),(107),(108),(109),(110),(111),(112),(113),(115),(116),(117),(118),(128),(129),(130),(131),(132),(133),(134),(135),(152),(153),(170),(171),(172),(173),(175),(176),(177),(178)'
QueryId = '2'
}
Permission = @{
GetScript = "SELECT who.name AS [Principal Name], who.type_desc AS [Principal Type], who.is_disabled AS [Principal Is Disabled], what.state_desc AS [Permission State], what.permission_name AS [Permission Name] FROM sys.server_permissions what INNER JOIN sys.server_principals who ON who.principal_id = what.grantee_principal_id WHERE what.permission_name = 'Alter any endpoint' AND who.name NOT LIKE '##MS%##' AND who.type_desc <> 'SERVER_ROLE' ORDER BY who.name;"
Expand Down Expand Up @@ -121,6 +122,7 @@ try
USE master
REVOKE ALTER ANY ENDPOINT TO <'account name'>
GO"
QueryId = '2'
}
SysAdminAccount = @{
GetScript = "USE [master] SELECT name, is_disabled FROM sys.sql_logins WHERE principal_id = 1 AND is_disabled <> 1;"
Expand All @@ -137,6 +139,7 @@ try
USE master;
GO
ALTER LOGIN [sa] WITH NAME = <new name> GO"
QueryId = '2'
}
Audit = @{
GetScript = "IF Not Exists (SELECT name AS 'Audit Name', status_desc AS 'Audit Status', audit_file_path AS 'Current Audit File' FROM sys.dm_server_audit_status WHERE status_desc = 'STARTED') Select 'Doest exist'"
Expand Down Expand Up @@ -201,6 +204,7 @@ try
SERVER_STATE_CHANGE_GROUP
TRACE_CHANGE_GROUP
See the supplemental file `"SQL 2016 Audit.sql`". "
QueryId = '1'
}
PlainSQL = @{
GetScript = "SELECT name from sysdatabases where name like 'AdventureWorks%';"
Expand All @@ -211,6 +215,7 @@ try
If the `"AdventureWorks`" database is present, this is a finding."
FixText = "Remove the publicly available `"AdventureWorks`" database from SQL Server by running the following query:
DROP DATABASE AdventureWorks"
QueryId = '2'
}
SaAccountRename = @{
GetScript = "SELECT name FROM sys.server_principals WHERE TYPE = 'S' and name not like '%##%'"
Expand All @@ -222,6 +227,7 @@ try
FixText = "Navigate to SQL Server Management Studio &gt;&gt; Object Explorer &gt;&gt; &lt;'SQL Server name'&gt; &gt;&gt; Security &gt;&gt; Logins &gt;&gt; click 'sa' account name.
Hit &lt;F2&gt; while the name is highlighted in order to edit the name.
Rename the 'sa' account."
QueryId = '2'
}
TraceFileLimit = @{
GetScript = "SELECT * FROM ::fn_trace_getinfo(NULL)"
Expand All @@ -233,6 +239,7 @@ try
If auditing will outgrow the space reserved for logging before being overwritten, this is a finding."
FixText = "Configure the maximum number of audit log files that are to be generated, staying within the number of logs the system was sized to support.
Update the max_files parameter of the audits to ensure the correct number of files is defined."
QueryId = '2'
}
ShutdownOnError = @{
GetScript = "SELECT * FROM ::fn_trace_getinfo(NULL)"
Expand Down Expand Up @@ -262,6 +269,7 @@ try
FixText = "If a trace does not exist, create a trace specification that complies with requirements.
If a trace exists, but is not set to SHUTDOWN_ON_ERROR, modify the SQL Server audit setting to immediately shutdown the database in the event of an audit failure by setting property 1 to a value of 4 or 6 for the audit.
(See the SQL Server Help page for sys.sp_trace_create for implementation details.)"
QueryId = '2'
}
ViewAnyDatabase = @{
GetScript = "SELECT who.name AS [Principal Name], who.type_desc AS [Principal Type], who.is_disabled AS [Principal Is Disabled], what.state_desc AS [Permission State], what.permission_name AS [Permission Name] FROM sys.server_permissions what INNER JOIN sys.server_principals who ON who.principal_id = what.grantee_principal_id WHERE what.permission_name = 'View any database' AND who.type_desc = 'SERVER_ROLE' ORDER BY who.name"
Expand Down Expand Up @@ -340,6 +348,7 @@ try
"
FixText = "Remove the `"View any database`" permission access from the role that is not authorized by executing the following query:
REVOKE View any database TO &lt;'role name'&gt;"
QueryId = '2'
}
ChangeDatabaseOwner= @{
GetScript = "select suser_sname(owner_sid) AS 'Owner' from sys.databases where name = `$(Database)"
Expand All @@ -358,6 +367,7 @@ try
Navigate to SQL Server Management Studio &gt;&gt; Object Explorer &gt;&gt; &lt;'SQL Server name'&gt; &gt;&gt; Databases &gt;&gt; right click &lt;'database name'&gt; &gt;&gt; Properties &gt;&gt; Files.
Select new database `"Owner`":
Navigate to click on […] &gt;&gt; Select new Database Owner &gt;&gt; Browse… &gt;&gt; click on box to indicate account &gt;&gt; &lt;'OK'&gt; &gt;&gt; &lt;'OK'&gt; &gt;&gt; &lt;'OK'&gt;"
QueryId = '2'
}
AuditShutDownOnError = @{
GetScript = 'SELECT on_failure_desc FROM sys.server_audits'
Expand Down Expand Up @@ -393,6 +403,7 @@ try
GO
ALTER SERVER AUDIT [AuditNameHere] WITH (STATE = ON);
GO '
QueryId = '2'
}
AuditFileSize = @{
GetScript = 'CREATE TABLE #AuditFileSize (Name nvarchar (30),Type_Desc nvarchar (30),Max_RollOver_Files int) INSERT INTO #AuditFileSize (Name, Type_Desc) SELECT Name, type_desc FROM sys.server_audits WHERE is_state_enabled = 1 IF (SELECT Type_Desc FROM #AuditFileSize) = ''FILE'' BEGIN UPDATE #AuditFileSize SET Max_RollOver_Files = (SELECT max_rollover_files FROM sys.server_file_audits) WHERE Name IS NOT NULL END SELECT * FROM #AuditFileSize DROP TABLE #AuditFileSize'
Expand Down Expand Up @@ -424,6 +435,7 @@ try
GO
ALTER SERVER AUDIT [AuditName] WITH (STATE = ON);
GO '
QueryId = '2'
}
}
#endregion
Expand Down Expand Up @@ -468,6 +480,19 @@ try
$result | Should be $setScript
}
}

Context 'Sql Query Id' {
It 'Should return a query id'{
$result = Get-SqlScriptQueryId -CheckContent $sqlScriptQueryRule.$($ruleType).CheckContent
if ($rule -eq 'Audit') {
$queryId = '1'
$queryId | Should be '1'
}
else {
$result | Should not be '1'
}
}
}
}

Context 'Get-Query' {
Expand Down
6 changes: 6 additions & 0 deletions source/DSCResources/Resources/SqlServer.ScriptQuery.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ foreach ($instance in $ServerInstance)
TestQuery = $rule.TestScript
SetQuery = $rule.SetScript
Variable = Format-SqlScriptVariable -Database $db -Variable $($rule.Variable) -VariableValue $($rule.VariableValue)
Encrypt = $encrypt
Id = $rule.QueryId
}
}
}
Expand All @@ -51,6 +53,8 @@ foreach ($instance in $ServerInstance)
TestQuery = $rule.TestScript
SetQuery = $rule.SetScript
Variable = Format-SqlScriptVariable -Variable $($rule.Variable) -VariableValue $($rule.VariableValue)
Encrypt = $encrypt
Id = $rule.QueryId
}
continue
}
Expand All @@ -62,6 +66,8 @@ foreach ($instance in $ServerInstance)
GetQuery = $rule.GetScript
TestQuery = $rule.TestScript
SetQuery = $rule.SetScript
Encrypt = $encrypt
Id = $rule.QueryId
}
}
}
Expand Down
12 changes: 11 additions & 1 deletion source/DSCResources/SqlServer/SqlServer.schema.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ using module ..\..\PowerStig.psm1
.PARAMETER Database
The Name of the database that you would like to be applied to. This parameter is only used
for the SQL Database STIG.
.PARAMETER Encrypt
The Encrypt parameter is used to specify if the connection to the SQL instance should be encrypted.
.PARAMETER Exception
A hashtable of StigId=Value key pairs that are injected into the STIG data and applied to
the target node. The title of STIG settings are tagged with the text 'Exception' to identify
Expand All @@ -37,6 +39,9 @@ using module ..\..\PowerStig.psm1
.PARAMETER SkipRuleType
All STIG rule IDs of the specified type are collected in an array and passed to the Skip-Rule
function. Each rule follows the same process as the SkipRule parameter.
.NOTES
Encrypt parameter does not fully support strict mode yet. This is due to a limitation in the SqlServerDsc module
as of version 17.1.0.
#>
configuration SqlServer
{
Expand Down Expand Up @@ -66,6 +71,11 @@ configuration SqlServer
[string[]]
$Database,

[Parameter()]
[ValidateSet('Strict', 'Optional', 'Mandatory')]
[string]
$Encrypt = 'Optional',

[Parameter()]
[ValidateNotNullOrEmpty()]
[hashtable]
Expand Down Expand Up @@ -97,7 +107,7 @@ configuration SqlServer
$stig.LoadRules($OrgSettings, $Exception, $SkipRule, $SkipRuleType, $SkipRuleSeverity)
##### END DO NOT MODIFY #####

Import-DscResource -ModuleName SqlServerDsc -ModuleVersion 15.1.1
Import-DscResource -ModuleName SqlServerDsc -ModuleVersion 17.1.0
. "$resourcePath\SqlServer.ScriptQuery.ps1"
. "$resourcePath\SqlServer.SqlLogin.ps1"
. "$resourcePath\SqlServer.SqlProtocol.ps1"
Expand Down
31 changes: 31 additions & 0 deletions source/Module/Rule.SqlScriptQuery/Convert/Methods.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2225,4 +2225,35 @@ function Get-SqlScriptQueryOrganizationValueTestString
}
}

<#
.SYNOPSIS
Creates a unique ID for the SqlScriptQuery resource.
.Notes
Required as of version SqlServerDsc 17.0.0.
#>
function Get-SqlScriptQueryId
{
[CmdletBinding()]
[OutputType([string])]
param
(
[Parameter(Mandatory = $true)]
[AllowEmptyString()]
[string[]]
$CheckContent
)

$collection = Get-AuditEvents -CheckContent $CheckContent
if ($collection)
{
$queryId = '1'
}
else
{
$queryId = New-Guid
}

return $queryId
}

#endregion Helper Functions
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class SqlScriptQueryRuleConvert : SqlScriptQueryRule
$this.SetTestScript($ruleType)
$this.SetSetScript($ruleType, $fixText)
$this.SetVariable($ruleType)
$this.SetQueryId($ruleType)
if ($null -ne $this.Variable)
{
$this.SetOrganizationValueTestString($ruleType)
Expand Down Expand Up @@ -141,6 +142,24 @@ class SqlScriptQueryRuleConvert : SqlScriptQueryRule
}
}

<#
.SYNOPSIS
Creates a unique ID for the SqlScriptQuery resource.
.DESCRIPTION
Gets the id string to be used in the SqlScriptQuery resource
.PARAMETER RuleType
The type of rule to get the variable string for.
#>
[void] SetQueryId ([string] $RuleType)
{
$thisId = Get-SqlScriptQueryId -CheckContent $this.SplitCheckContent

if (-not $this.SetStatus($thisId))
{
$this.set_QueryId($thisId)
}
}

<#
.SYNOPSIS
Extracts the rule type from the check-content and sets the value
Expand Down
1 change: 1 addition & 0 deletions source/Module/Rule.SqlScriptQuery/SqlScriptQueryRule.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class SqlScriptQueryRule : Rule
[string] $SetScript <#(ExceptionValue)#>
[string[]] $Variable
[String[]] $VariableValue
[string] $QueryId

<#
.SYNOPSIS
Expand Down
2 changes: 1 addition & 1 deletion source/PowerStig.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
@{ModuleName = 'GPRegistryPolicyDsc'; ModuleVersion = '1.3.1' },
@{ModuleName = 'PSDscResources'; ModuleVersion = '2.12.0.0' },
@{ModuleName = 'SecurityPolicyDsc'; ModuleVersion = '2.10.0.0' },
@{ModuleName = 'SqlServerDsc'; ModuleVersion = '15.1.1' },
@{ModuleName = 'SqlServerDsc'; ModuleVersion = '17.1.0' },
@{ModuleName = 'WindowsDefenderDsc'; ModuleVersion = '2.2.0' },
@{ModuleName = 'xDnsServer'; ModuleVersion = '1.16.0.0' },
@{ModuleName = 'xWebAdministration'; ModuleVersion = '3.2.0' },
Expand Down
4 changes: 3 additions & 1 deletion source/StigData/Processed/SqlServer-2012-Database-1.19.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<DISASTIG version="1" classification="UNCLASSIFIED" customname="" stigid="MS_SQL_Server_2012_STIG" description="The Microsoft SQL Server 2012 Security Technical Implementation Guide (STIG) is published as a tool to improve the security of Department of Defense (DoD) information systems. Comments or proposed revisions to this document should be sent via e-mail to the following address: [email protected]." filename="U_MS_SQL_Server_2012_Database_STIG_V1R19_Manual-xccdf.xml" releaseinfo="Release: 19 Benchmark Date: 26 Jul 2019" title="Microsoft SQL Server 2012 Security Technical Implementation Guide" notice="terms-of-use" source="STIG.DOD.MIL" fullversion="1.19" created="8/12/2021">
<DISASTIG version="1" classification="UNCLASSIFIED" customname="" stigid="MS_SQL_Server_2012_STIG" description="The Microsoft SQL Server 2012 Security Technical Implementation Guide (STIG) is published as a tool to improve the security of Department of Defense (DoD) information systems. Comments or proposed revisions to this document should be sent via e-mail to the following address: [email protected]." filename="U_MS_SQL_Server_2012_Database_STIG_V1R19_Manual-xccdf.xml" releaseinfo="Release: 19 Benchmark Date: 26 Jul 2019" title="Microsoft SQL Server 2012 Security Technical Implementation Guide" notice="terms-of-use" source="STIG.DOD.MIL" fullversion="1.19" created="9/26/2025">
<DocumentRule dscresourcemodule="None">
<Rule id="V-41389" severity="medium" conversionstatus="pass" title="SRG-APP-000006-DB-000183" dscresource="None">
<Description>&lt;VulnDiscussion&gt;Security attributes are abstractions representing the basic properties or characteristics of an entity (e.g., subjects and objects) with respect to safeguarding information.
Expand Down Expand Up @@ -795,6 +795,7 @@ The DBMS must provide auditing for the list of events defined by the organizatio
</LegacyId>
<OrganizationValueRequired>False</OrganizationValueRequired>
<OrganizationValueTestString />
<QueryId>6b1826e1-ee86-41a2-8464-9af9cd730b96</QueryId>
<RawString>Check to see that all required events are being audited.
From the query prompt:
SELECT DISTINCT traceid FROM sys.fn_trace_getinfo(0);
Expand Down Expand Up @@ -839,6 +840,7 @@ Within the database, object ownership implies full privileges to the owned objec
</LegacyId>
<OrganizationValueRequired>True</OrganizationValueRequired>
<OrganizationValueTestString>{0} is a database owner</OrganizationValueTestString>
<QueryId>baf9f4fc-49bb-40ef-8c1f-5d0b403531f9</QueryId>
<RawString>Review system documentation to identify SQL Server accounts authorized to own database objects.

If the SQL Server database ownership list does not exist or needs to be updated, this is a finding.
Expand Down
4 changes: 3 additions & 1 deletion source/StigData/Processed/SqlServer-2012-Database-1.20.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<DISASTIG version="1" classification="UNCLASSIFIED" customname="" stigid="MS_SQL_Server_Database_2012" description="The Microsoft SQL Server 2012 Security Technical Implementation Guide (STIG) is published as a tool to improve the security of Department of Defense (DoD) information systems. Comments or proposed revisions to this document should be sent via e-mail to the following address: [email protected]." filename="U_MS_SQL_Server_2012_Database_STIG_V1R20_Manual-xccdf.xml" releaseinfo="Release: 20 Benchmark Date: 16 Jan 2020" title="Microsoft SQL Server Database 2012 Security Technical Implementation Guide" notice="terms-of-use" source="STIG.DOD.MIL" fullversion="1.20" created="8/12/2021">
<DISASTIG version="1" classification="UNCLASSIFIED" customname="" stigid="MS_SQL_Server_Database_2012" description="The Microsoft SQL Server 2012 Security Technical Implementation Guide (STIG) is published as a tool to improve the security of Department of Defense (DoD) information systems. Comments or proposed revisions to this document should be sent via e-mail to the following address: [email protected]." filename="U_MS_SQL_Server_2012_Database_STIG_V1R20_Manual-xccdf.xml" releaseinfo="Release: 20 Benchmark Date: 16 Jan 2020" title="Microsoft SQL Server Database 2012 Security Technical Implementation Guide" notice="terms-of-use" source="STIG.DOD.MIL" fullversion="1.20" created="9/26/2025">
<DocumentRule dscresourcemodule="None">
<Rule id="V-41389" severity="medium" conversionstatus="pass" title="SRG-APP-000006-DB-000183" dscresource="None">
<Description>&lt;VulnDiscussion&gt;Security attributes are abstractions representing the basic properties or characteristics of an entity (e.g., subjects and objects) with respect to safeguarding information.
Expand Down Expand Up @@ -795,6 +795,7 @@ The DBMS must provide auditing for the list of events defined by the organizatio
</LegacyId>
<OrganizationValueRequired>False</OrganizationValueRequired>
<OrganizationValueTestString />
<QueryId>6084df45-dac2-4467-b3c4-85ed0d8bea28</QueryId>
<RawString>Check to see that all required events are being audited.
From the query prompt:
SELECT DISTINCT traceid FROM sys.fn_trace_getinfo(0);
Expand Down Expand Up @@ -839,6 +840,7 @@ Within the database, object ownership implies full privileges to the owned objec
</LegacyId>
<OrganizationValueRequired>True</OrganizationValueRequired>
<OrganizationValueTestString>{0} is a database owner</OrganizationValueTestString>
<QueryId>93580376-9eec-4fdd-bf60-bf09ab50f9e9</QueryId>
<RawString>Review system documentation to identify SQL Server accounts authorized to own database objects.

If the SQL Server database ownership list does not exist or needs to be updated, this is a finding.
Expand Down
Loading
Loading