使用SqlPackage.exe发布DACPAC时防止用户丢失

时间:2013-07-01 11:01:39

标签: sql-server-data-tools

使用SqlPackage.exe发布DACPAC时是否有任何阻止用户被删除的方法,除了更改下面的设置,如果不在DACPAC中,则会阻止所有对象被删除。

<DropObjectsNotInSource>True</DropObjectsNotInSource>

我们部署到多个环境,每个环境都有不同的用户。目前的解决方法是:

  1. 为每个环境编写脚本,以便在部署
  2. 后重新创建它们
  3. 使用/Action:Script并手动更改部署脚本。
  4. 这些都不是理想的......

4 个答案:

答案 0 :(得分:9)

使用SqlPackage.exe参数(自2015年2月发布:New Advanced Publish Options to Specify Object Types to Exclude or Not Drop):

这是我们在部署中使用的实际参数:

/p:DropObjectsNotInSource=True 
/p:ExcludeObjectTypes=Users;Logins;RoleMembership;Permissions

第一行清除所有,但下一行进一步细化了不会掉落的东西。事实证明,这种组合最有效的方法是删除所有不必要的对象,同时保留登录映射。

可以在MSDN - SqlPackage.exe

中找到所有参数及其可能值的详细文档

答案 1 :(得分:8)

答案 2 :(得分:3)

我遇到了同样的问题并使用了Pre / Post部署脚本来重新插入用户,权限,角色等,如建议的博客文章。但是从长远来看,这变得无法维护(用户在部署期间无法进行身份验证,如果部署失败,则不会恢复权限,安全更改需要通过源代码控制和重新部署)。

最近,我在迁移部署平台时重新评估了这个问题。随着DacFx API(和bug fixes)的发布,我能够通过创建DeploymentPlanModifier来扩展SSDT中的部署过程。它们提供example for filtering objects on creation,通过简单的修改,我可以过滤任何基于权限的对象类型(使用/p:AdditionalDeploymentContributors参数)。

[ExportDeploymentPlanModifier( UserMappingFilter.PlanFiltererContributorId, "1.0.0.0" )]
public class UserMappingFilter : DeploymentPlanModifier
{
    public const string PlanFiltererContributorId = "Dac.UserMappingFilter";

    protected override void OnExecute( DeploymentPlanContributorContext context )
    {
        DeploymentStep next = context.PlanHandle.Head;
        while( next != null )
        {
            DeploymentStep current = next;
            next = current.Next;

            DropElementStep dropStep = current as DropElementStep;
            if( dropStep != null && ShouldFilter( dropStep ) )
            {
                base.Remove( context.PlanHandle, dropStep );
            }
        }
    }

    private bool ShouldFilter( DropElementStep createStep )
    {
        TSqlObject target = createStep.TargetElement;


        if( target.ObjectType.Name == "RoleMembership" || target.ObjectType.Name == "User" || target.ObjectType.Name == "Role" )
        {
            return true;
        }


        return false;
    }
}

答案 3 :(得分:2)

我们在部署后脚本中处理此问题。设置起来有点困难,但一旦设置允许您为每个环境配置略有不同的脚本。我们将此与发布配置文件结合使用,每个环境具有不同的配置文件。基本上,您使用Powershell为用户和权限生成一堆脚本,将这些脚本添加到项目中,然后将文件包含在项目中。将博客文章中引用的内容添加为“SecurityAdditionsWrapper.sql”到您的部署后脚本,您应该做得很好。只需从项目中删除其他安全性,以确保其设置正确。

http://schottsql.blogspot.com/2013/05/ssdt-setting-different-permissions-per.html

SSDT中还有以下选项: “删除权限不在源头” - 错误 “删除未在源中定义的角色成员” - 错误 “忽略权限” - 是的 “忽略角色成员身份” - 真实

我们使用这些,但如果您需要通过环境更好地控制您的用户/权限,我强烈建议您查看该博文。 (感谢Jamie Thomson的最初想法。)