20

Is there any way of preventing users being dropped when publishing a DACPAC using SqlPackage.exe, other than changing the setting below, which prevents all objects from being dropped if they're not in the DACPAC.

<DropObjectsNotInSource>True</DropObjectsNotInSource>

We deploy to a number of environments, each with different users. Current workarounds are to either:

  1. Script the users for each environment to recreate them after deploying
  2. Use /Action:Script and manually change the deployment script.

Neither of these are ideal though...

4

3 回答 3

20

使用 SqlPackage.exe 参数(自 2015 年 2 月发布:新的高级发布选项以指定要排除或不删除的对象类型):

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

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

第一行清除了所有内容,但下一行进一步细化了不丢弃的内容。事实证明,这种组合对我们来说是最有效的,可以删除所有不必要的对象,同时保留登录映射。

所有参数及其可能值的详细文档可以从MSDN - SqlPackage.exe中找到

于 2017-05-11T12:53:54.053 回答
3

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

最近,我在迁移部署平台时重新评估了这个问题。随着DacFx API(和错误修复)的发布,我能够通过创建 DeploymentPlanModifier 来扩展 SSDT 中的部署过程。它们提供了在创建时过滤对象的示例,通过简单的修改,我过滤了基于权限的对象类型的任何丢弃(使用/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;
    }
}
于 2015-01-01T22:31:47.120 回答
2

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

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

SSDT 中还有以下选项:“丢弃不在源中的权限”-False “丢弃未在源中定义的角色成员”-False “忽略权限”-True “忽略角色成员资格”-True

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

于 2013-07-01T17:37:51.127 回答