Skip to content

dbatools SNI.dll Access Denied when Remoting

Chrissy LeMaire edited this page Aug 16, 2025 · 1 revision

Solving dbatools SNI.dll Loading Errors: Complete Analysis

The "unable to load DLL 'Microsoft.Data.SqlClient.SNI.dll': Access is denied" error occurs when using Windows Authentication via the -SqlCredential parameter and represents a combination of PowerShell Core version requirements and file system permissions issues.

Root cause analysis

PowerShell Core version enforcement: The dbatools.psm1 module includes this check:

# Core needs to be at least 7.4.0
if ($PSVersionTable.PSEdition -eq 'Core' -and $PSVersionTable.PSVersion -lt [version]"7.4.0") {
    throw "dbatools requires at least PowerShell 7.4.0 when running on Core. Please update your PowerShell."
}

However, this check only applies to PowerShell Core (pwsh.exe), not Windows PowerShell 5.1. This creates the confusing situation where:

  • Windows PowerShell 5.1: Module loads successfully but has credential impersonation issues
  • PowerShell Core < 7.4.0: Module fails to load with clear error message
  • PowerShell Core ≥ 7.4.0: Module loads and credential impersonation works reliably

The credential impersonation issue: When using -SqlCredential with Windows credentials in PowerShell 5.1, the module attempts to access files under the impersonated user's security context. If that user lacks read access to the PowerShell Modules directory, you get "Access Denied" when loading Microsoft.Data.SqlClient.SNI.dll.

Why SQL Authentication works: SQL authentication bypasses Windows impersonation entirely - the connection uses SQL Server's internal authentication, so no Windows credential context switching occurs during DLL loading.

Version compatibility matrix

PowerShell Edition Version Windows Auth + SqlCredential SQL Auth + SqlCredential Module Loading
Desktop (5.1) 5.1 ⚠️ Permissions issues ✅ Works ✅ Loads
Core (pwsh) < 7.4.0 ❌ Module load fails ❌ Module load fails ❌ Fails
Core (pwsh) ≥ 7.4.0 ✅ Works reliably ✅ Works ✅ Loads

Solutions by scenario

Scenario 1: PowerShell 5.1 + Windows Auth + SqlCredential = Access Denied

Solution A: Grant file system permissions (Recommended)

# Find your module path
$modulePath = (Get-Module dbatools -ListAvailable)[0].ModuleBase

# Grant read permissions to your credential user
$acl = Get-Acl -Path $modulePath
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
    "DOMAIN\YourCredentialUser",
    "ReadAndExecute",
    "ContainerInherit,ObjectInherit",
    "None",
    "Allow"
)
$acl.SetAccessRule($accessRule)
Set-Acl -Path $modulePath -AclObject $acl

Solution B: Use SQL Authentication

$sqlCred = Get-Credential -Message "Enter SQL Server login credentials"
Test-DbaConnection -SqlInstance "server\instance" -SqlCredential $sqlCred

Solution C: Use Integrated Security

# Run PowerShell as the target user, then use without credentials
Test-DbaConnection -SqlInstance "server\instance"  # No -SqlCredential needed

Solution D: Upgrade to PowerShell 7.4+

# Install PowerShell 7.4+ and use pwsh.exe instead
pwsh.exe
$cred = Get-Credential
Test-DbaConnection -SqlInstance "server\instance" -SqlCredential $cred

Scenario 2: PowerShell Core < 7.4.0 = Module Load Failure

Solution: Upgrade PowerShell Core

Scenario 3: PSSession/Enter-PSSession failures

PSSession failures occur due to different execution contexts (wsmprovhost.exe vs powershell.exe) combined with the permission/version issues above.

Solutions:

  1. Grant permissions to the credential user for PowerShell Modules directory
  2. Use PowerShell 7.4+ for more reliable PSSession credential handling
  3. Use SQL Authentication to bypass Windows credential impersonation

Verification steps

Check PowerShell edition and version:

$PSVersionTable | Select-Object PSEdition, PSVersion

Test file access with credential:

$cred = Get-Credential
Invoke-Command -Credential $cred -ScriptBlock {
    Get-ChildItem "C:\Program Files\WindowsPowerShell\Modules\dbatools"
} -ComputerName localhost

Test specific SNI.dll access:

$cred = Get-Credential
Invoke-Command -Credential $cred -ScriptBlock {
    $dbatoolsLib = Get-Module dbatools.library -ListAvailable | Select-Object -First 1
    Get-ChildItem "$($dbatoolsLib.ModuleBase)" -Recurse -Filter "*SNI*.dll"
} -ComputerName localhost

What doesn't work and why

❌ Set-DbatoolsInsecureConnection: This command is for encryption/certificate issues, not DLL loading problems. It changes connection string properties like TrustServerCertificate=true and Encrypt=false, which has nothing to do with file system permissions or PowerShell version requirements.

❌ Installation scope changes: Moving between CurrentUser and AllUsers doesn't solve the core permission issue if the credential user still lacks access to the module files.

❌ Module version downgrades: While older dbatools versions might work with older PowerShell versions, the fundamental credential impersonation issue remains the same.

Key insights

Different behavior patterns:

  • Interactive console vs PSSession: Different security contexts affect credential impersonation
  • SQL Auth vs Windows Auth: SQL authentication bypasses the problematic Windows credential impersonation
  • Desktop vs Core PowerShell: Core has explicit version requirements, Desktop allows loading but may have runtime issues

The permission escalation: When you use -SqlCredential with Windows credentials, PowerShell tries to access files under that user's security context. This is correct behavior for credential impersonation, but it means the credential user needs access to system directories.

Why PowerShell 7.4+ works better: Newer PowerShell versions have improved credential impersonation handling, better error reporting, and more robust native library loading under different security contexts.

Conclusion

The SNI.dll "Access Denied" error has two distinct causes:

  1. PowerShell Core < 7.4.0: Hard module loading failure (clear error message)
  2. PowerShell 5.1 + Windows Auth + SqlCredential: File system permissions issue (confusing error message)

Recommended solutions by priority:

  1. Upgrade to PowerShell 7.4+ for the most reliable experience
  2. Grant file system permissions if staying on PowerShell 5.1
  3. Use SQL Authentication as a workaround for credential scenarios
  4. Use Integrated Security when possible to avoid credential impersonation

For production environments: PowerShell 7.4+ provides the most reliable credential handling and is the supported configuration for dbatools when using PowerShell Core.

Clone this wiki locally