@@ -13,7 +13,7 @@ function Export-DbaDacPackage {
1313 For help with the extract action parameters and properties, refer to https://learn.microsoft.com/en-us/sql/tools/sqlpackage/sqlpackage-extract
1414
1515 . PARAMETER SqlInstance
16- The target SQL Server instance or instances.
16+ The target SQL Server instance or instances. Must be SQL Server 2008 R2 or higher (DAC Framework minimum version 10.50).
1717
1818 . PARAMETER SqlCredential
1919 Login to the target instance using alternative credentials. Accepts PowerShell credentials (Get-Credential).
@@ -73,6 +73,8 @@ function Export-DbaDacPackage {
7373 Copyright: (c) 2018 by dbatools, licensed under MIT
7474 License: MIT https://opensource.org/licenses/MIT
7575
76+ Minimum SQL Server Version: SQL Server 2008 R2 (10.50) - DAC Framework requirement
77+
7678 . LINK
7779 https://dbatools.io/Export-DbaDacPackage
7880
@@ -199,16 +201,52 @@ function Export-DbaDacPackage {
199201 } catch {
200202 Stop-Function - Message " Failure" - Category ConnectionError - ErrorRecord $_ - Target $instance - Continue
201203 }
204+
205+ # Check SQL Server version - DAC Framework requires SQL Server 2008 R2+ (Version 10.50+)
206+ if ($server.VersionMajor -lt 10 -or ($server.VersionMajor -eq 10 -and $server.VersionMinor -lt 50 )) {
207+ Stop-Function - Message " Export-DbaDacPackage requires SQL Server 2008 R2 or higher (DAC Framework minimum version 10.50). Server $instance is version $ ( $server.VersionString ) ." - Target $instance - Continue
208+ }
209+
210+ # ============================================================
211+ # THREAD-SAFE DATABASE ENUMERATION
212+ # Use Invoke-DbaQuery instead of Get-DbaDatabase to avoid SMO thread-safety issues
213+ # Get-DbaDatabase uses $server.Databases enumeration which is NOT thread-safe in parallel runspaces
214+ # Note: Export-DbaDacPackage requires SQL Server 2008 R2+ (DAC Framework minimum version)
215+ # ============================================================
216+
217+ # Build query to enumerate databases (equivalent to Get-DbaDatabase -OnlyAccessible -ExcludeSystem)
218+ $query = @"
219+ SELECT name
220+ FROM sys.databases
221+ WHERE database_id > 4 -- Exclude system databases (master=1, tempdb=2, model=3, msdb=4)
222+ AND state = 0 -- Only ONLINE databases (OnlyAccessible equivalent)
223+ "@
224+
225+ # Add ExcludeDatabase filter if specified
226+ if ($ExcludeDatabase ) {
227+ $excludedDatabaseList = $ExcludeDatabase | ForEach-Object { " '$_ '" }
228+ $query += " `n AND name NOT IN ($ ( $excludedDatabaseList -join " ," ) )"
229+ }
230+
231+ $query += " `n ORDER BY name"
232+
233+ Write-Message - Level Verbose - Message " Executing query: $query "
234+ $dbNames = Invoke-DbaQuery - SqlInstance $server - Query $query - EnableException | Select-Object - ExpandProperty name
235+
236+ # Apply Database filter if specified
202237 if ($Database ) {
203- $dbs = Get-DbaDatabase - SqlInstance $server - OnlyAccessible - Database $Database - ExcludeDatabase $ExcludeDatabase
204- } else {
205- # all user databases by default
206- $dbs = Get-DbaDatabase - SqlInstance $server - OnlyAccessible - ExcludeSystem - ExcludeDatabase $ExcludeDatabase
238+ $dbNames = $dbNames | Where-Object { $_ -in $Database }
207239 }
208- if (-not $dbs ) {
209- Stop-Function - Message " Databases not found on $instance " - Target $instance - Continue
240+
241+ if (-not $dbNames ) {
242+ Stop-Function - Message " Databases not found on $instance " - Target $instance - Continue
210243 }
211244
245+ Write-Message - Level Verbose - Message " Found $ ( $dbNames.Count ) databases: $ ( $dbNames -join " , " ) "
246+
247+ # Convert database names to objects for compatibility with rest of function
248+ $dbs = $dbNames | ForEach-Object { [PSCustomObject ]@ { name = $_ } }
249+
212250 foreach ($db in $dbs ) {
213251 $resultstime = [diagnostics.stopwatch ]::StartNew()
214252 $dbName = $db.name
0 commit comments