-
-
Notifications
You must be signed in to change notification settings - Fork 839
dbatools SNI.dll Access Denied when Remoting
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.
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.
PowerShell Edition | Version | Windows Auth + SqlCredential | SQL Auth + SqlCredential | Module Loading |
---|---|---|---|---|
Desktop (5.1) | 5.1 | ✅ Works | ✅ Loads | |
Core (pwsh) | < 7.4.0 | ❌ Module load fails | ❌ Module load fails | ❌ Fails |
Core (pwsh) | ≥ 7.4.0 | ✅ Works reliably | ✅ Works | ✅ Loads |
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
Solution: Upgrade PowerShell Core
- Download PowerShell 7.4+ from: https://github.com/PowerShell/PowerShell/releases
- Install alongside existing versions
- Use
pwsh.exe
instead of older PowerShell Core versions
PSSession failures occur due to different execution contexts (wsmprovhost.exe vs powershell.exe) combined with the permission/version issues above.
Solutions:
- Grant permissions to the credential user for PowerShell Modules directory
- Use PowerShell 7.4+ for more reliable PSSession credential handling
- Use SQL Authentication to bypass Windows credential impersonation
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
❌ 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.
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.
The SNI.dll "Access Denied" error has two distinct causes:
- PowerShell Core < 7.4.0: Hard module loading failure (clear error message)
- PowerShell 5.1 + Windows Auth + SqlCredential: File system permissions issue (confusing error message)
Recommended solutions by priority:
- Upgrade to PowerShell 7.4+ for the most reliable experience
- Grant file system permissions if staying on PowerShell 5.1
- Use SQL Authentication as a workaround for credential scenarios
- 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.