处理 Dynamics 365 安全角色的命令

问题描述 投票:0回答:2

是否有可用的 powershell 命令来处理安全角色?

以下是安全角色示例:

Security Role: Sample Standard User
Entity: Contact
Privilege: Read, Append, and Append To

Security Role: Sample Advance User
Entity: Contact
Privilege: Create, Read, Write, Append, and Append to

Security Role: Sample Admin User
Entity: Contact
Privilege: Create, Read, Write, Delete, Append, and Append to

Microsoft Dynamics 中的安全角色配置很繁琐吧? 使用此示例,目标是复制特定的安全角色,然后应用其他权限。

现在使用上面给出的示例,如果我们可以使用 powershell 复制“示例标准用户”来创建“示例高级用户”,然后添加“创建和读取”权限(再次使用 powershell),我们可以跳过配置的繁琐部分并以编程方式创建它们。

powershell dynamics-crm microsoft-dynamics
2个回答
0
投票

如果我理解正确,您可以利用我用于动态角色创建分配和到期的以下代码片段。

Install-Module -Name Microsoft.Xrm.Data.PowerShell -AllowClobber -Scope CurrentUser

Import-Module Microsoft.Xrm.Data.PowerShell

$connection = Get-CrmConnection -InteractiveMode

找回原来的安全角色:

$originalRole = Get-CrmSecurityRole -conn $connection -RoleName "Sample Standard User"

克隆安全角色:

$newRole = New-CrmSecurityRole -conn $connection -OriginalRole $originalRole -NewRoleName "Sample Advance User"

为新角色添加权限:

$entityName = "contact"
$privileges = @("Create", "Write")

foreach ($privilege in $privileges) {
    Set-CrmSecurityRolePrivilege -conn $connection -RoleId $newRole.RoleId -EntityName $entityName -PrivilegeName $privilege -AccessLevel "Organization"
}

验证更改:

$updatedRole = Get-CrmSecurityRole -conn $connection -RoleName "Sample Advance User"

0
投票

此答案基于@Laviza Falak Naz 发布的答案。

代码主要包含以下步骤:

  1. 创建连接

  2. 检索StandardRole的必要信息(如果还需要创建StandardRole,则调用方法Create-Role和Add-Privilege)

  3. 创建新角色。

  4. 将权限从 StandardRole 复制到新角色

  5. 为新角色添加更多权限

    # Install the Microsoft.Xrm.Data.PowerShell module if not installed yet
    if (-not (Get-Module -ListAvailable -Name Microsoft.Xrm.Data.PowerShell)) {
        Install-Module -Name Microsoft.Xrm.Data.PowerShell -Scope CurrentUser
    }
    
    # Import the module
    Import-Module Microsoft.Xrm.Data.PowerShell
    
    # Define privilegeDepthMask enum
    Add-Type -TypeDefinition @"
    public enum PrivilegeDepthMask
    {
        Basic = 1,
        Local = 2,
        Deep = 4,
        Global = 8
    }
    "@
    
    # Define privilegeDepth enum
    Add-Type -TypeDefinition @"
    public enum PrivilegeDepth
    {
        Basic = 0,
        Local = 1,
        Deep = 2,
        Global = 3
    }
    "@
    
    # Define AccessRight enum
    Add-Type -TypeDefinition @"
    public enum AccessRight
    {
        None = 0,
        ReadAccess = 1,
        WriteAccess = 2,
        AppendAccess = 4,
        AppendToAccess = 16,
        CreateAccess = 32,
        DeleteAccess = 65536,
        ShareAccess = 262144,
        AssignAccess = 524288
    }
    "@
    
    # Mapping dictionary for PrivilegeType to AccessRight
    $privilegeTypeToAccessRightMap = @{
        "Read"     = [AccessRight]::ReadAccess
        "Write"    = [AccessRight]::WriteAccess
        "Append"   = [AccessRight]::AppendAccess
        "AppendTo" = [AccessRight]::AppendToAccess
        "Create"   = [AccessRight]::CreateAccess
        "Delete"   = [AccessRight]::DeleteAccess
        "Share"    = [AccessRight]::ShareAccess
        "Assign"   = [AccessRight]::AssignAccess
    }
    
    # Function to get role by name
    function Get-RoleByName {
        param (
            [string]$roleName,
            [Microsoft.Xrm.Tooling.Connector.CrmServiceClient]$conn
        )
        $fetchXML = @"
    <fetch mapping='logical'>
        <entity name='role'>
            <attribute name='roleid' />
            <attribute name='name' />
            <attribute name='businessunitid' />
            <filter type='and'>
                <condition attribute='name' operator='eq' value='$roleName' />
                <condition attribute='parentroleid' operator='null' />
            </filter>
        </entity>
    </fetch>
    "@
        return Get-CrmRecordsByFetch -conn $conn -Fetch $fetchXML
    }
    
    # Function to map PrivilegeDepthMask to PrivilegeDepth
    function Get-PrivilegeDepth {
        param (
            [PrivilegeDepthMask]$privilegeDepthMask,
            [string]$ownershipType
        )
    
        Write-Host "PrivilegeDepthMask value: $privilegeDepthMask"
    
        if ($ownershipType -eq "OrganizationOwned") {
            return [PrivilegeDepth]::Global
        }
    
        if ($privilegeDepthMask -eq [PrivilegeDepthMask]::Basic) {
            return [PrivilegeDepth]::Basic
        }
        elseif ($privilegeDepthMask -eq [PrivilegeDepthMask]::Local) {
            return [PrivilegeDepth]::Local
        }
        elseif ($privilegeDepthMask -eq [PrivilegeDepthMask]::Deep) {
            return [PrivilegeDepth]::Deep
        }
        elseif ($privilegeDepthMask -eq [PrivilegeDepthMask]::Global) {
            return [PrivilegeDepth]::Global
        }
        else {
            throw "Invalid PrivilegeDepthMask value: $privilegeDepthMask"
        }
    }
    
    # Function to create a role if it does not exist
    function Create-Role {
        param (
            [string]$roleName,
            [Guid]$businessUnitId,
            [Microsoft.Xrm.Tooling.Connector.CrmServiceClient]$conn
        )
    
        $role = Get-RoleByName -roleName $roleName -conn $conn
    
        if ($role.CrmRecords.Count -eq 0) {
            # Create the new role
            $newRole = New-CrmRecord -EntityLogicalName role -Fields @{
                name           = $roleName
                businessunitid = New-Object Microsoft.Xrm.Sdk.EntityReference("businessunit", $businessUnitId)
            } -conn $conn
    
            Write-Host "New role '$roleName' created successfully."
            return $newRole
        }
        else {
            # Use the existing role
            $roleId = $role.CrmRecords[0].roleid
            Write-Host "Role '$roleName' already exists. Using the existing role."
            return $roleId
        }
    }
    
    # Function to add a single privilege to a role
    function Add-Privilege {
        param (
            [Guid]$roleId,
            [Guid]$privilegeId,
            [int]$depth,
            [Microsoft.Xrm.Tooling.Connector.CrmServiceClient]$conn
        )
    
        # Create the RolePrivilege object
        $rolePriv = New-Object Microsoft.Crm.Sdk.Messages.RolePrivilege
        $rolePriv.PrivilegeId = $privilegeId
        $rolePriv.Depth = $depth
    
        # Create the AddPrivilegesRoleRequest object
        $addPrivRoleReq = New-Object Microsoft.Crm.Sdk.Messages.AddPrivilegesRoleRequest
        $addPrivRoleReq.RoleId = $roleId
        $addPrivRoleReq.Privileges = @($rolePriv)
    
        # Execute the request
        $response = $conn.ExecuteCrmOrganizationRequest($addPrivRoleReq)
    
        Write-Host "Privilege with ID $privilegeId added to role successfully."
    }
    
    # Function to get privilege ID by entity metadata and access right
    function Get-PrivilegeId {
        param (
            [Microsoft.Xrm.Sdk.Metadata.EntityMetadata]$entityMetadata,
            [AccessRight]$accessRight
        )
    
        foreach ($privilege in $entityMetadata.Privileges) {
            # Map PrivilegeType to AccessRight
            if ($privilegeTypeToAccessRightMap.ContainsKey($privilege.PrivilegeType.ToString()) -and $privilegeTypeToAccessRightMap[$privilege.PrivilegeType.ToString()] -eq $accessRight) {
                return $privilege.PrivilegeId
            }
        }
    
        throw "Privilege with AccessRight $accessRight not found."
    }
    
    # Function to copy privileges from one role to another
    function Copy-Privileges {
        param (
            [Guid]$sourceRoleId,
            [Guid]$targetRoleId,
            [Microsoft.Xrm.Tooling.Connector.CrmServiceClient]$conn,
            [string]$ownershipType
        )
    
        # Retrieve all privileges associated with the source role
        $rolePrivileges = Get-CrmRecords -conn $conn -EntityLogicalName roleprivileges -FilterAttribute roleid -FilterOperator eq -FilterValue $sourceRoleId -Fields privilegeid, privilegedepthmask
    
        foreach ($privilege in $rolePrivileges.CrmRecords) {
            # Log the privilege object to understand its structure
            #Write-Host "Privilege object: $($privilege | Out-String)"
    
            # Extract the integer value from the privilegedepthmask property
            $privilegeDepthMaskValue = [int]$privilege.privilegedepthmask
            Write-Host "Extracted PrivilegeDepthMask value: $privilegeDepthMaskValue"
    
            # Cast the extracted integer value to the PrivilegeDepthMask enum type
            $privilegeDepthMask = [PrivilegeDepthMask]$privilegeDepthMaskValue
            Write-Host "Casted PrivilegeDepthMask enum: $privilegeDepthMask"
            $depth = Get-PrivilegeDepth -privilegeDepthMask $privilegeDepthMask -ownershipType $ownershipType
    
            # Add the privilege to the target role
            Add-Privilege -roleId $targetRoleId -privilegeId ([Guid]::Parse($privilege.privilegeid)) -depth $depth -conn $conn
        }
    }
    
    # Change below values to match your needs
    $username = "[email protected]"
    $password = ConvertTo-SecureString "yourpassword" -AsPlainText -Force
    $credential = New-Object System.Management.Automation.PSCredential($username, $password)
    $standardRoleName = "Sample Standard User"
    $newRoleName = "Sample Advance User"
    $entityName = "contact"
    $addPrivilege = [AccessRight]::AppendAccess
    $addPrivilegeDepth = [PrivilegeDepth]::Local
    $serverUrl = "https://domain.crmX.dynamics.com/"
    $organizationName = "Demo"
    $conn = Get-CrmConnection -serverUrl $serverUrl -credential $credential -organizationName $organizationName
    
    # Check if the connection was successful
    if ($conn -eq $null) {
        Write-Host "Failed to connect to CRM. Exiting script."
        exit
    }
    
    # Retrieve the standard role
    $standardRole = Get-RoleByName -roleName $standardRoleName -conn $conn
    
    # Check if the role was found
    if ($standardRole.CrmRecords.Count -eq 0) {
        Write-Host "$standardRoleName role not found."
        exit
    }
    
    # Retrieve the business unit ID from the standard role
    $businessUnitId = $standardRole.CrmRecords[0].businessunitid_Property.Value.Id
    
    # Create the new role if it does not exist
    $newRoleId = Create-Role -roleName $newRoleName -businessUnitId $businessUnitId -conn $conn
    
    # Retrieve the entity metadata to check the owningtype
    $entityMetadata = Get-CrmEntityMetadata -conn $conn -EntityLogicalName $entityName -EntityFilters "all"
    
    # Copy privileges from the standard role to the new role
    Copy-Privileges -sourceRoleId $standardRole.CrmRecords[0].roleid -targetRoleId $newRoleId -conn $conn -ownershipType $entityMetadata.OwnershipType
    
    # Add the specified privilege to the new role
    $privilegeId = Get-PrivilegeId -entityMetadata $entityMetadata -accessRight $addPrivilege
    Add-Privilege -roleId $newRoleId -privilegeId $privilegeId -depth $addPrivilegeDepth -conn $conn
    

代码中使用的业务单元是最佳实践的根业务单元(Get-RoleByName)。

对于组织拥有的实体,权限深度只有“基本”和“全局”

© www.soinside.com 2019 - 2024. All rights reserved.