Windows Server 2016下SQL Server备份到DropBox报Access Denied错误求助
问题根因
该Access Denied报错和Dropbox本身无关,是SQL Server服务的运行权限问题:
你运行netsh命令时使用的是当前登录的个人用户身份,该账号本身拥有个人目录下Dropbox文件夹的读写权限,所以防火墙规则导出正常。但SQL Server的备份操作是由SQL Server服务进程执行的,默认配置下该服务的运行账号没有你的个人用户目录(C:\Users\xyxAbc)的写入权限,因此无法直接写入Dropbox文件夹;而C:\DatabaseBackup目录的默认权限更宽松,或你提前给SQL服务账号配置了对应权限,因此备份可以成功。
解决方案
方案1:给SQL服务账号配置Dropbox备份目录权限(操作最简单)
- 打开Windows服务管理器(按下
Win+R输入services.msc回车),找到对应SQL Server实例的服务,查看「登录身份」列的运行账号,默认实例一般为NT SERVICE\MSSQLSERVER,命名实例格式为NT SERVICE\MSSQL$你的实例名 - 找到
C:\Users\xyxAbc\Dropbox\VPSBACKUP文件夹,右键点击「属性」→「安全」→「编辑」→「添加」,输入刚才查到的SQL服务运行账号,点击检查名称确认无误后,给该账号授予「修改」、「写入」等完全读写权限,保存配置后重新运行脚本A即可正常备份。
方案2:先备份到本地目录再移动到Dropbox(权限更安全)
无需修改文件夹权限,调整脚本逻辑即可:先把数据库备份到本地有权限的目录,再用当前脚本运行用户的权限把备份文件移动到Dropbox目录,参考代码如下:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null $s = new-object ("Microsoft.SqlServer.Management.Smo.Server") $instance # 本地备份目录(SQL服务有写入权限) $localBkdir = "C:\DatabaseBackup" # Dropbox目标目录(当前用户有写入权限) $dropboxBkdir = "C:\Users\xyxAbc\Dropbox\VPSBACKUP" $dbs = $s.Databases foreach ($db in $dbs) { # 注意:原判断逻辑使用-or存在错误,永远会返回真,需改为-and才能正确过滤系统库 if($db.Name -ne "tempdb" -and $db.Name -ne "master" -and $db.Name -ne 'model' -and $db.Name -ne'msdb') { $dbname = $db.Name $bakFileName = $dbname + "_db_.bak" $localBakPath = Join-Path $localBkdir $bakFileName $dropboxBakPath = Join-Path $dropboxBkdir $bakFileName $dbBackup = new-object ("Microsoft.SqlServer.Management.Smo.Backup") $dbBackup.Action = "Database" $dbBackup.Database = $dbname $dbBackup.Devices.AddDevice($localBakPath, "File") $dbBackup.SqlBackup($s) # 备份完成后移动到Dropbox目录 Move-Item -Path $localBakPath -Destination $dropboxBakPath -Force } }
额外注意
你原脚本中过滤系统库的判断条件存在逻辑错误:使用-or连接多个不等于判断时,只要满足其中一个条件就会返回真,相当于不会过滤任何系统库,需要把所有-or替换为-and才能实现过滤系统库的预期效果。
内容的提问来源于stack exchange,提问作者Johnny
相关产品推荐
相关产品推荐

