Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
252aa99
Add AllowAuditGuidChange parameter to Set-SqlDscAudit for GUID modifi…
johlju Oct 7, 2025
0e0337f
Remove specific error message expectation for AuditGuid modification …
johlju Oct 8, 2025
cfdce01
Refactor MaximumFileSizeUnit conversion for clarity in ConvertTo-SqlD…
johlju Oct 8, 2025
695576f
Align parameter names in Set-SqlDscAudit tests for consistency
johlju Oct 8, 2025
e8f57fa
Add ConvertTo-AuditNewParameterSet function and update related tests
johlju Oct 8, 2025
e53814f
Fix null check for OnFailure parameter in ConvertTo-AuditNewParameter…
johlju Oct 8, 2025
3630617
Enhance documentation for ConvertTo-AuditNewParameterSet with additio…
johlju Oct 8, 2025
d144bc7
Fix comments for clarity in BeforeDiscovery block of ConvertTo-AuditN…
johlju Oct 8, 2025
65a5c0f
Refactor GUID change handling in Set-SqlDscAudit function for clarity…
johlju Oct 8, 2025
bbb1f8a
Add INPUTS section to documentation for ConvertTo-AuditNewParameterSe…
johlju Oct 8, 2025
8030006
Refactor variable names for consistency and improve module loading pa…
johlju Oct 8, 2025
84d9c86
Change Write-Verbose to Write-Debug for improved logging in Set-SqlDs…
johlju Oct 8, 2025
632ab78
Refactor verbose messages to improve clarity in Set-SqlDscAudit function
johlju Oct 8, 2025
3323237
Fix typos and improve clarity in documentation for Set-SqlDscAudit fu…
johlju Oct 8, 2025
821237f
Add test for updating properties with existing AuditGuid in Set-SqlDs…
johlju Oct 8, 2025
f82d21c
Refactor Set-SqlDscAudit tests to set Guid property directly on SMO o…
johlju Oct 8, 2025
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added integration tests for `Add-SqlDscTraceFlag` command to ensure it functions
correctly in real environments
[issue #2214](https://github.com/dsccommunity/SqlServerDsc/issues/2214).
- `Set-SqlDscAudit`
- Added `AllowAuditGuidChange` parameter to enable modifying the audit GUID
by dropping and recreating the audit with the new GUID. This parameter is
required when changing the `AuditGuid` property because SQL Server does not
allow direct modification of the audit GUID ([issue #2287](https://github.com/dsccommunity/SqlServerDsc/issues/2287)).

### Changed

Expand Down
123 changes: 123 additions & 0 deletions source/Private/ConvertTo-AuditNewParameterSet.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<#
.SYNOPSIS
Converts audit object properties to parameters for New-SqlDscAudit.

.DESCRIPTION
This helper function analyzes an existing audit object and returns a hashtable
of parameters that can be splatted to New-SqlDscAudit to recreate the audit
with the same configuration.

.PARAMETER AuditObject
The audit object to analyze.

.PARAMETER AuditGuid
Optional GUID to set on the audit. If not specified, the existing GUID is used.

.OUTPUTS
System.Collections.Hashtable
#>
function ConvertTo-AuditNewParameterSet
{
[CmdletBinding()]
[OutputType([System.Collections.Hashtable])]
param
(
[Parameter(Mandatory = $true)]
[Microsoft.SqlServer.Management.Smo.Audit]
$AuditObject,

[Parameter()]
[System.String]
$AuditGuid
)

$parameters = @{
ServerObject = $AuditObject.Parent
Name = $AuditObject.Name
}

# Determine LogType or Path based on DestinationType
switch ($AuditObject.DestinationType)
{
'ApplicationLog'
{
$parameters['LogType'] = 'ApplicationLog'
}

'SecurityLog'
{
$parameters['LogType'] = 'SecurityLog'
}

'File'
{
$parameters['Path'] = $AuditObject.FilePath

# Add file size parameters if set (not unlimited)
if ($AuditObject.MaximumFileSize -gt 0)
{
$parameters['MaximumFileSize'] = $AuditObject.MaximumFileSize

# Convert SMO unit to parameter value
$parameters['MaximumFileSizeUnit'] = switch ($AuditObject.MaximumFileSizeUnit)
{
'MB'
{
'Megabyte'
}
'GB'
{
'Gigabyte'
}
'TB'
{
'Terabyte'
}
}
}

# Add MaximumFiles or MaximumRolloverFiles (mutually exclusive)
if ($AuditObject.MaximumFiles -gt 0)
{
$parameters['MaximumFiles'] = $AuditObject.MaximumFiles

if ($AuditObject.ReserveDiskSpace)
{
$parameters['ReserveDiskSpace'] = $true
}
}
elseif ($AuditObject.MaximumRolloverFiles -gt 0)
{
$parameters['MaximumRolloverFiles'] = $AuditObject.MaximumRolloverFiles
}
}
}

# Add optional parameters if they have values
if ($null -ne $AuditObject.OnFailure)
{
$parameters['OnFailure'] = $AuditObject.OnFailure
}

if ($AuditObject.QueueDelay -gt 0)
{
$parameters['QueueDelay'] = $AuditObject.QueueDelay
}

if ($AuditObject.Filter)
{
$parameters['AuditFilter'] = $AuditObject.Filter
}

# Use provided GUID or existing GUID
if ($PSBoundParameters.ContainsKey('AuditGuid'))
{
$parameters['AuditGuid'] = $AuditGuid
}
elseif ($AuditObject.Guid -and $AuditObject.Guid -ne '00000000-0000-0000-0000-000000000000')
{
$parameters['AuditGuid'] = $AuditObject.Guid
}

return $parameters
}
177 changes: 123 additions & 54 deletions source/Public/Set-SqlDscAudit.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@
Specifies the GUID found in the mirrored database. To support scenarios such
as database mirroring an audit needs a specific GUID.

.PARAMETER AllowAuditGuidChange
Specifies that the audit GUID can be changed by dropping and recreating the
audit. This parameter is required when modifying the AuditGuid property because
SQL Server does not allow direct modification of the audit GUID. When specified,
the audit will be dropped and recreated with all existing properties plus the
new GUID value. This is a destructive operation that requires explicit opt-in.

.PARAMETER Force
Specifies that the audit should be updated without any confirmation.

Expand Down Expand Up @@ -158,6 +165,10 @@ function Set-SqlDscAudit
[System.String]
$AuditGuid,

[Parameter()]
[System.Management.Automation.SwitchParameter]
$AllowAuditGuidChange,

[Parameter()]
[System.Management.Automation.SwitchParameter]
$Force,
Expand Down Expand Up @@ -250,7 +261,7 @@ function Set-SqlDscAudit
$ConfirmPreference = 'None'
}

if ($PSCmdlet.ParameterSetName -eq 'ServerObject')
if ($PSCmdlet.ParameterSetName -match '^ServerObject')
{
$getSqlDscAuditParameters = @{
ServerObject = $ServerObject
Expand All @@ -277,79 +288,137 @@ function Set-SqlDscAudit

if ($PSCmdlet.ShouldProcess($verboseDescriptionMessage, $verboseWarningMessage, $captionMessage))
{
if ($PSBoundParameters.ContainsKey('Path'))
{
$AuditObject.FilePath = $Path
}

if ($PSCmdlet.ParameterSetName -match 'WithSize')
# Check if GUID change is requested early, before any other modifications
if ($PSBoundParameters.ContainsKey('AuditGuid'))
{
$queryMaximumFileSizeUnit = (
@{
Megabyte = 'MB'
Gigabyte = 'GB'
Terabyte = 'TB'
# Check if the GUID is actually changing
if ($AuditObject.Guid -ne $AuditGuid)
{
# Validate that AllowAuditGuidChange is present
if (-not $AllowAuditGuidChange.IsPresent)
{
$errorMessage = $script:localizedData.Audit_AuditGuidChangeRequiresAllowParameter -f $AuditObject.Name

$PSCmdlet.ThrowTerminatingError(
[System.Management.Automation.ErrorRecord]::new(
$errorMessage,
'SSDA0001', # cspell: disable-line
[System.Management.Automation.ErrorCategory]::InvalidOperation,
$AuditObject.Name
)
)
}
).$MaximumFileSizeUnit

$AuditObject.MaximumFileSize = $MaximumFileSize
$AuditObject.MaximumFileSizeUnit = $queryMaximumFileSizeUnit
}
Write-Verbose -Message ($script:localizedData.Audit_RecreatingAuditForGuidChange -f $AuditObject.Name, $AuditObject.Parent.InstanceName, $AuditGuid)

if ($PSCmdlet.ParameterSetName -match 'MaxFiles')
{
if ($AuditObject.MaximumRolloverFiles)
{
# Switching to MaximumFiles instead of MaximumRolloverFiles.
$AuditObject.MaximumRolloverFiles = 0
# Convert audit properties to parameters for New-SqlDscAudit
$newAuditParameters = ConvertTo-AuditNewParameterSet -AuditObject $AuditObject -AuditGuid $AuditGuid

# Drop the existing audit using Remove-SqlDscAudit
# Use -Confirm:$false since we're already in a confirmed ShouldProcess context
$AuditObject | Remove-SqlDscAudit -Confirm:$false

# Must run method Alter() before setting MaximumFiles.
$AuditObject.Alter()
# Create new audit with the same properties using New-SqlDscAudit
# Use -Confirm:$false and -PassThru since we're already in a confirmed context and need the object
$AuditObject = New-SqlDscAudit @newAuditParameters -Confirm:$false -PassThru

# Remove parameters that should not be passed to recursive call
$null = $PSBoundParameters.Remove('AuditGuid')
$null = $PSBoundParameters.Remove('AllowAuditGuidChange')
$null = $PSBoundParameters.Remove('ServerObject')
$null = $PSBoundParameters.Remove('Name')
$null = $PSBoundParameters.Remove('Force')
$null = $PSBoundParameters.Remove('Refresh')
$null = $PSBoundParameters.Remove('PassThru')

# Remove common parameters and get the resulting hashtable
$remainingParameters = Remove-CommonParameter -Hashtable $PSBoundParameters

# If there are other property-changing parameters to apply, recursively call Set-SqlDscAudit
if ($remainingParameters.Count -gt 0)
{
# Add the new AuditObject parameter
$remainingParameters['AuditObject'] = $AuditObject

# Recursively call to apply remaining changes
$AuditObject = Set-SqlDscAudit @remainingParameters -Confirm:$false -PassThru
}
}
}
else
{
# No GUID change, proceed with normal property updates

$AuditObject.MaximumFiles = $MaximumFiles
# Apply other parameter changes
if ($PSBoundParameters.ContainsKey('Path'))
{
$AuditObject.FilePath = $Path
}

if ($PSBoundParameters.ContainsKey('ReserveDiskSpace'))
if ($PSCmdlet.ParameterSetName -match 'WithSize')
{
$AuditObject.ReserveDiskSpace = $ReserveDiskSpace.IsPresent
$queryMaximumFileSizeUnit = (
@{
Megabyte = 'MB'
Gigabyte = 'GB'
Terabyte = 'TB'
}
).$MaximumFileSizeUnit

$AuditObject.MaximumFileSize = $MaximumFileSize
$AuditObject.MaximumFileSizeUnit = $queryMaximumFileSizeUnit
}
}

if ($PSCmdlet.ParameterSetName -match 'MaxRolloverFiles')
{
if ($AuditObject.MaximumFiles)
if ($PSCmdlet.ParameterSetName -match 'MaxFiles')
{
# Switching to MaximumRolloverFiles instead of MaximumFiles.
$AuditObject.MaximumFiles = 0
if ($AuditObject.MaximumRolloverFiles)
{
# Switching to MaximumFiles instead of MaximumRolloverFiles.
$AuditObject.MaximumRolloverFiles = 0

# Must run method Alter() before setting MaximumRolloverFiles.
$AuditObject.Alter()
# Must run method Alter() before setting MaximumFiles.
$AuditObject.Alter()
}

$AuditObject.MaximumFiles = $MaximumFiles

if ($PSBoundParameters.ContainsKey('ReserveDiskSpace'))
{
$AuditObject.ReserveDiskSpace = $ReserveDiskSpace.IsPresent
}
}

$AuditObject.MaximumRolloverFiles = $MaximumRolloverFiles
}
if ($PSCmdlet.ParameterSetName -match 'MaxRolloverFiles')
{
if ($AuditObject.MaximumFiles)
{
# Switching to MaximumRolloverFiles instead of MaximumFiles.
$AuditObject.MaximumFiles = 0

if ($PSBoundParameters.ContainsKey('OnFailure'))
{
$AuditObject.OnFailure = $OnFailure
}
# Must run method Alter() before setting MaximumRolloverFiles.
$AuditObject.Alter()
}

if ($PSBoundParameters.ContainsKey('QueueDelay'))
{
$AuditObject.QueueDelay = $QueueDelay
}
$AuditObject.MaximumRolloverFiles = $MaximumRolloverFiles
}

if ($PSBoundParameters.ContainsKey('AuditGuid'))
{
$AuditObject.Guid = $AuditGuid
}
if ($PSBoundParameters.ContainsKey('OnFailure'))
{
$AuditObject.OnFailure = $OnFailure
}

if ($PSBoundParameters.ContainsKey('AuditFilter'))
{
$AuditObject.Filter = $AuditFilter
}
if ($PSBoundParameters.ContainsKey('QueueDelay'))
{
$AuditObject.QueueDelay = $QueueDelay
}

if ($PSBoundParameters.ContainsKey('AuditFilter'))
{
$AuditObject.Filter = $AuditFilter
}

$AuditObject.Alter()
$AuditObject.Alter()
}

if ($PassThru.IsPresent)
{
Expand Down
2 changes: 2 additions & 0 deletions source/en-US/SqlServerDsc.strings.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ ConvertFrom-StringData @'
Audit_Update_ShouldProcessCaption = Update audit on instance
Audit_MaximumFileSizeParameterValueInvalid = The maximum file size must be set to a value of 0 or a value between 2 and 2147483647.
Audit_QueueDelayParameterValueInvalid = The queue delay must be set to a value of 0 or a value between 1000 and 2147483647.
Audit_AuditGuidChangeRequiresAllowParameter = Cannot modify the AuditGuid property of the audit '{0}'. SQL Server does not allow direct modification of the audit GUID. Use the parameter AllowAuditGuidChange to permit dropping and recreating the audit with the new GUID.
Audit_RecreatingAuditForGuidChange = Recreating the audit '{0}' on instance '{1}' to change the audit GUID to '{2}'.

## Get-SqlDscAudit
Audit_Missing = There is no audit with the name '{0}'.
Expand Down
Loading
Loading