From 750c1ea9ebe8107dc2f446a4c47972d38aaf2b54 Mon Sep 17 00:00:00 2001 From: Mikey Bronowski Date: Sun, 4 Aug 2024 07:46:57 +0100 Subject: [PATCH 1/6] Update dbatools-buildref-index.json SQL 2019 CU28 (#9438) --- bin/dbatools-buildref-index.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bin/dbatools-buildref-index.json b/bin/dbatools-buildref-index.json index bf209caf06..b76f8c06e9 100644 --- a/bin/dbatools-buildref-index.json +++ b/bin/dbatools-buildref-index.json @@ -1,5 +1,5 @@ { - "LastUpdated": "2024-07-24T00:00:00", + "LastUpdated": "2024-08-02T00:00:00", "Data": [ { "Version": "8.0.47", @@ -4608,6 +4608,11 @@ "Version": "15.0.4382", "KBList": "5040948" }, + { + "CU": "CU28", + "Version": "15.0.4385", + "KBList": "5039747" + }, { "Version": "16.0.100", "Name": "2022" From a6634ccd5b82b084e0322219476d05bfaa27c4f0 Mon Sep 17 00:00:00 2001 From: mrahman-DBA <176774888+mrahman-DBA@users.noreply.github.com> Date: Sun, 4 Aug 2024 02:48:47 -0400 Subject: [PATCH 2/6] Make Get-DbaPrivilege more efficient (#9436) --- public/Get-DbaPrivilege.ps1 | 155 +++++++++++++++--------------------- 1 file changed, 62 insertions(+), 93 deletions(-) diff --git a/public/Get-DbaPrivilege.ps1 b/public/Get-DbaPrivilege.ps1 index 6b7252c46e..13821107ba 100644 --- a/public/Get-DbaPrivilege.ps1 +++ b/public/Get-DbaPrivilege.ps1 @@ -56,18 +56,18 @@ function Get-DbaPrivilege { ) begin { - $ResolveSID = @' - function Convert-SIDToUserName ([string] $SID ) { - try { - $objSID = New-Object System.Security.Principal.SecurityIdentifier ($SID) - $objUser = $objSID.Translate([System.Security.Principal.NTAccount]) - $objUser.Value - } catch { - $SID - } - } -'@ + function Convert-SIDToUserName ([string] $SID ) { + try { + $objSID = New-Object System.Security.Principal.SecurityIdentifier ($SID) + $objUser = $objSID.Translate([System.Security.Principal.NTAccount]) + $objUser.Value + } catch { + $SID + } + } + $ComputerName = $ComputerName.ComputerName | Select-Object -Unique + } process { foreach ($computer in $ComputerName) { @@ -78,123 +78,96 @@ function Get-DbaPrivilege { } try { - Write-Message -Level Verbose -Message "Exporting Privileges on $computer" - $null = Invoke-Command2 -Raw -ComputerName $computer -Credential $Credential -ScriptBlock { + Write-Message -Level Verbose -Message "Exporting Privileges on $computer and cleaning up temporary files" + $secPol = Invoke-Command2 -Raw -ComputerName $computer -Credential $Credential -ScriptBlock { $temp = ([System.IO.Path]::GetTempPath()).TrimEnd("") secedit /export /cfg $temp\secpolByDbatools.cfg > $null + $CFG = Get-Content $temp\secpolByDbatools.cfg -Force + Remove-Item $temp\secpolByDbatools.cfg -Force + $CFG } Write-Message -Level Verbose -Message "Getting Batch Logon Privileges on $computer" - $bl = Invoke-Command2 -Raw -ComputerName $computer -Credential $Credential -ArgumentList $ResolveSID -ScriptBlock { - param ($ResolveSID) - . ([ScriptBlock]::Create($ResolveSID)) - $temp = ([System.IO.Path]::GetTempPath()).TrimEnd(""); - $blEntries = (Get-Content $temp\secpolByDbatools.cfg | Where-Object { - $_ -like "SeBatchLogonRight*" - }) - - if ($null -ne $blEntries) { - $blEntries.Substring(20).Split(",") | ForEach-Object { - if ($_ -match '^\*S-') { - Convert-SIDToUserName -SID $_.TrimStart('*') - } else { - $_ - } + $blEntries = $secPol | Where-Object { $_ -like "SeBatchLogonRight*" } + + $bl = if ($null -ne $blEntries) { + $blEntries.Substring(20).Split(",") | ForEach-Object { + if ($_ -match '^\*S-') { + Convert-SIDToUserName -SID $_.TrimStart('*') + } else { + $_ } } } + if ($bl.count -eq 0) { Write-Message -Level Verbose -Message "No users with Batch Logon Rights on $computer" } Write-Message -Level Verbose -Message "Getting Instant File Initialization Privileges on $computer" - $ifi = Invoke-Command2 -Raw -ComputerName $computer -Credential $Credential -ArgumentList $ResolveSID -ScriptBlock { - param ($ResolveSID) - . ([ScriptBlock]::Create($ResolveSID)) - $temp = ([System.IO.Path]::GetTempPath()).TrimEnd(""); - $ifiEntries = (Get-Content $temp\secpolByDbatools.cfg | Where-Object { - $_ -like 'SeManageVolumePrivilege*' - }) - - if ($null -ne $ifiEntries) { - $ifiEntries.Substring(26).Split(",") | ForEach-Object { - if ($_ -match '^\*S-') { - Convert-SIDToUserName -SID $_.TrimStart('*') - } else { - $_ - } + $ifiEntries = $secPol | Where-Object { $_ -like 'SeManageVolumePrivilege*' } + + $ifi = if ($null -ne $ifiEntries) { + $ifiEntries.Substring(26).Split(",") | ForEach-Object { + if ($_ -match '^\*S-') { + Convert-SIDToUserName -SID $_.TrimStart('*') + } else { + $_ } } } + if ($ifi.count -eq 0) { Write-Message -Level Verbose -Message "No users with Instant File Initialization Rights on $computer" } Write-Message -Level Verbose -Message "Getting Lock Pages in Memory Privileges on $computer" - $lpim = Invoke-Command2 -Raw -ComputerName $computer -Credential $Credential -ArgumentList $ResolveSID -ScriptBlock { - param ($ResolveSID) - . ([ScriptBlock]::Create($ResolveSID)) - $temp = ([System.IO.Path]::GetTempPath()).TrimEnd(""); - $lpimEntries = (Get-Content $temp\secpolByDbatools.cfg | Where-Object { - $_ -like 'SeLockMemoryPrivilege*' - }) - - if ($null -ne $lpimEntries) { - $lpimEntries.Substring(24).Split(",") | ForEach-Object { - if ($_ -match '^\*S-') { - Convert-SIDToUserName -SID $_.TrimStart('*') - } else { - $_ - } + $lpimEntries = $secPol | Where-Object { $_ -like 'SeLockMemoryPrivilege*' } + + $lpim = if ($null -ne $lpimEntries) { + $lpimEntries.Substring(24).Split(",") | ForEach-Object { + if ($_ -match '^\*S-') { + Convert-SIDToUserName -SID $_.TrimStart('*') + } else { + $_ } } } + if ($lpim.count -eq 0) { Write-Message -Level Verbose -Message "No users with Lock Pages in Memory Rights on $computer" } Write-Message -Level Verbose -Message "Getting Generate Security Audits Privileges on $computer" - $gsa = Invoke-Command2 -Raw -ComputerName $computer -Credential $Credential -ArgumentList $ResolveSID -ScriptBlock { - param ($ResolveSID) - . ([ScriptBlock]::Create($ResolveSID)) - $temp = ([System.IO.Path]::GetTempPath()).TrimEnd(""); - $gsaEntries = (Get-Content $temp\secpolByDbatools.cfg | Where-Object { - $_ -like 'SeAuditPrivilege*' - }) - - if ($null -ne $gsaEntries) { - $gsaEntries.Substring(19).Split(",") | ForEach-Object { - if ($_ -match '^\*S-') { - Convert-SIDToUserName -SID $_.TrimStart('*') - } else { - $_ - } + $gsaEntries = $secPol | Where-Object { $_ -like 'SeAuditPrivilege*' } + + $gsa = if ($null -ne $gsaEntries) { + $gsaEntries.Substring(19).Split(",") | ForEach-Object { + if ($_ -match '^\*S-') { + Convert-SIDToUserName -SID $_.TrimStart('*') + } else { + $_ } } } + if ($gsa.count -eq 0) { Write-Message -Level Verbose -Message "No users with Generate Security Audits Rights on $computer" } Write-Message -Level Verbose -Message "Getting Logon as a service Privileges on $computer" - $los = Invoke-Command2 -Raw -ComputerName $computer -Credential $Credential -ArgumentList $ResolveSID -ScriptBlock { - param ($ResolveSID) - . ([ScriptBlock]::Create($ResolveSID)) - $temp = ([System.IO.Path]::GetTempPath()).TrimEnd(""); - $losEntries = (Get-Content $temp\secpolByDbatools.cfg | Where-Object { - $_ -like "SeServiceLogonRight*" - }) - - if ($null -ne $losEntries) { - $losEntries.Substring(22).split(",") | ForEach-Object { - if ($_ -match '^\*S-') { - Convert-SIDToUserName -SID $_.TrimStart('*') - } else { - $_ - } + $losEntries = $secPol | Where-Object { $_ -like "SeServiceLogonRight*" } + + $los = if ($null -ne $losEntries) { + $losEntries.Substring(22).split(",") | ForEach-Object { + if ($_ -match '^\*S-') { + Convert-SIDToUserName -SID $_.TrimStart('*') + } else { + $_ } } } + if ($los.count -eq 0) { Write-Message -Level Verbose -Message "No users with Logon as a service Rights on $computer" } @@ -211,11 +184,7 @@ function Get-DbaPrivilege { LogonAsAService = $los -contains $_ } } - Write-Message -Level Verbose -Message "Removing secpol file on $computer" - Invoke-Command2 -Raw -ComputerName $computer -Credential $Credential -ScriptBlock { - $temp = ([System.IO.Path]::GetTempPath()).TrimEnd("") - Remove-Item $temp\secpolByDbatools.cfg -Force - } + } catch { Stop-Function -Continue -Message "Failure" -ErrorRecord $_ -Target $computer } From f48273a72044279a8c65977312ce27fb2090215c Mon Sep 17 00:00:00 2001 From: Andreas Jordan <66946165+andreasjordan@users.noreply.github.com> Date: Sun, 4 Aug 2024 08:49:06 +0200 Subject: [PATCH 3/6] Reset-DbaAdmin: Fix parameter name (#9435) --- public/Reset-DbaAdmin.ps1 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/public/Reset-DbaAdmin.ps1 b/public/Reset-DbaAdmin.ps1 index 3479dd97e4..db4bd5f359 100644 --- a/public/Reset-DbaAdmin.ps1 +++ b/public/Reset-DbaAdmin.ps1 @@ -311,7 +311,6 @@ function Reset-DbaAdmin { } } catch { Stop-Service -InputObject $sqlservice -Force -ErrorAction SilentlyContinue - if ($isClustered) { $clusterResource | Where-Object Name -EQ "SQL Server" | ForEach-Object { $_.BringOnline(60) } $clusterResource | Where-Object Name -NE "SQL Server" | ForEach-Object { $_.BringOnline(60) } @@ -332,7 +331,7 @@ function Reset-DbaAdmin { Start-Sleep 3 $null = Invoke-ResetSqlCmd -instance $instance -Sql "SELECT 1" -EnableException } catch { - Stop-Service Input-Object $sqlservice -Force -ErrorAction SilentlyContinue + Stop-Service -InputObject $sqlservice -Force -ErrorAction SilentlyContinue if ($isClustered) { $clusterResource | Where-Object { $_.Name -eq "SQL Server" } | ForEach-Object { $_.BringOnline(60) } $clusterResource | Where-Object { $_.Name -ne "SQL Server" } | ForEach-Object { $_.BringOnline(60) } From 7ad0415c2f8a58d3472c1e85ee431c70f1bb8ae4 Mon Sep 17 00:00:00 2001 From: Chrissy LeMaire Date: Sun, 4 Aug 2024 09:02:23 +0200 Subject: [PATCH 4/6] v2.1.23 --- dbatools.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbatools.psd1 b/dbatools.psd1 index 62d62a356f..3c516bd65d 100644 --- a/dbatools.psd1 +++ b/dbatools.psd1 @@ -11,7 +11,7 @@ RootModule = 'dbatools.psm1' # Version number of this module. - ModuleVersion = '2.1.22' + ModuleVersion = '2.1.23' # ID used to uniquely identify this module GUID = '9d139310-ce45-41ce-8e8b-d76335aa1789' From 03521f78258245284f70ecb5313c5bf18affb08d Mon Sep 17 00:00:00 2001 From: Chrissy LeMaire Date: Sun, 8 Sep 2024 12:51:38 +0200 Subject: [PATCH 5/6] Export-DbaUser - Fix Passthru duplicates (#9463) --- public/Export-DbaUser.ps1 | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/public/Export-DbaUser.ps1 b/public/Export-DbaUser.ps1 index 68da80cdf5..2dc4405b80 100644 --- a/public/Export-DbaUser.ps1 +++ b/public/Export-DbaUser.ps1 @@ -252,6 +252,9 @@ function Export-DbaUser { $stepCounter = 0 foreach ($dbuser in $users) { + # Clear output for each user + $outsql = @() + $sql = "" if ($GenerateFilePerUser) { if ($null -eq $usersProcessed[$dbuser.Name]) { @@ -264,7 +267,12 @@ function Export-DbaUser { } } - Write-ProgressHelper -TotalSteps $users.Count -Activity "Exporting from $($db.Name)" -StepNumber ($stepCounter++) -Message "Generating script ($FilePath) for user $dbuser" + if ($Passthru) { + $progressMessage = "Generating script for user $dbuser" + } else { + $progressMessage = "Generating script ($FilePath) for user $dbuser" + } + Write-ProgressHelper -TotalSteps $users.Count -Activity "Exporting from $($db.Name)" -StepNumber ($stepCounter++) -Message $progressMessage #setting database if (((Test-Bound ScriptingOptionsObject) -and $ScriptingOptionsObject.IncludeDatabaseContext) -or - (Test-Bound ScriptingOptionsObject -Not)) { @@ -366,7 +374,7 @@ function Export-DbaUser { $withGrant = " WITH GRANT OPTION" $grantDatabasePermission = 'GRANT' } else { - $withGrant = " " + $withGrant = "" $grantDatabasePermission = $databasePermission.PermissionState.ToString().ToUpper() } if ($Template) { @@ -526,7 +534,7 @@ function Export-DbaUser { $withGrant = " WITH GRANT OPTION" $grantObjectPermission = 'GRANT' } else { - $withGrant = " " + $withGrant = "" $grantObjectPermission = $objectPermission.PermissionState.ToString().ToUpper() } if ($Template) { @@ -573,9 +581,6 @@ function Export-DbaUser { $sql | Out-File -Encoding:$Encoding -FilePath $FilePath -Append } } - # Clear variables for next user - $outsql = @() - $sql = "" } else { $sql } From a85b606a2944d1db26b4ba7547c4912a0974913c Mon Sep 17 00:00:00 2001 From: Mikey Bronowski Date: Wed, 18 Sep 2024 20:18:48 +0100 Subject: [PATCH 6/6] Security updates for SQL 2022, 2019, 2017, 2016 (#9466) --- bin/dbatools-buildref-index.json | 34 +++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/bin/dbatools-buildref-index.json b/bin/dbatools-buildref-index.json index b76f8c06e9..5b5f873ab5 100644 --- a/bin/dbatools-buildref-index.json +++ b/bin/dbatools-buildref-index.json @@ -1,5 +1,5 @@ { - "LastUpdated": "2024-08-02T00:00:00", + "LastUpdated": "2024-09-11T00:00:00", "Data": [ { "Version": "8.0.47", @@ -4119,6 +4119,10 @@ "Version": "13.0.6441", "KBList": "5040946" }, + { + "Version": "13.0.6445", + "KBList": "5042207" + }, { "Version": "13.0.7000", "KBList": "5014242" @@ -4139,6 +4143,10 @@ "Version": "13.0.7037", "KBList": "5040944" }, + { + "Version": "13.0.7040", + "KBList": "5042209" + }, { "Version": "14.0.1", "Name": "2017" @@ -4204,6 +4212,10 @@ "Version": "14.0.2056", "KBList": "5040942" }, + { + "Version": "14.0.2060", + "KBList": "5042217" + }, { "CU": "CU1", "Version": "14.0.3006", @@ -4399,6 +4411,10 @@ "Version": "14.0.3471", "KBList": "5040940" }, + { + "Version": "14.0.3475", + "KBList": "5042215" + }, { "Version": "15.0.1000", "Name": "2019" @@ -4448,6 +4464,10 @@ "Version": "15.0.2116", "KBList": "5040986" }, + { + "Version": "15.0.2120", + "KBList": "5042214" + }, { "CU": "CU1", "Version": "15.0.4003", @@ -4613,6 +4633,10 @@ "Version": "15.0.4385", "KBList": "5039747" }, + { + "Version": "15.0.4390", + "KBList": "5042749" + }, { "Version": "16.0.100", "Name": "2022" @@ -4650,6 +4674,10 @@ "Version": "16.0.1121", "KBList": "5040936" }, + { + "Version": "16.0.1125", + "KBList": "5042211" + }, { "CU": "CU1", "Version": "16.0.4003", @@ -4735,6 +4763,10 @@ "CU": "CU14", "Version": "16.0.4135", "KBList": "5038325" + }, + { + "Version": "16.0.4140", + "KBList": "5042578" } ] }