AMSoftware.Dataverse.PowerShell.AccessManagement.psm1
# PowerShell Module for Power Platform Dataverse # Copyright(C) 2024 AMSoftwareNL # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. # .EXTERNALHELP AMSoftware.Dataverse.PowerShell.AccessManagement.psm1-help.xml function Get-DataverseUser { [CmdletBinding(DefaultParameterSetName = 'GetAllUsers')] [OutputType([Microsoft.Xrm.Sdk.Entity])] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'GetUserById')] [ValidateNotNullOrEmpty()] [Guid]$Id, [Parameter(ParameterSetName = 'GetAllUsers')] [Alias('Include')] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [string]$Name, [Parameter(ParameterSetName = 'GetAllUsers')] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [string]$Exclude, [Parameter(ParameterSetName = 'GetAllUsers')] [switch]$Disabled, [Parameter(ParameterSetName = 'GetAllUsers')] [switch]$Licensed, [Parameter(ParameterSetName = 'GetAllUsers')] [switch]$Application ) process { switch ($PSCmdlet.ParameterSetName) { 'GetAllUsers' { $nameFilterAttributes = @('fullname', 'domainname', 'internalemailaddress') if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('Name')) { if ([WildcardPattern]::ContainsWildcardCharacters($Name)) { $pattern = [WildcardPattern]::new($Name); $filterOperator = 'like' $filterValue = $pattern.ToWql() } else { $filterOperator = 'eq' $filterValue = $Name } $includeFilter += '<filter type="or">' $includeFilter += $nameFilterAttributes | ForEach-Object { '<condition attribute="{0}" operator="{1}" value="{2}" />' -f $_, $filterOperator, $filterValue } | Join-String $includeFilter += '</filter>' } if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('Exclude')) { if ([WildcardPattern]::ContainsWildcardCharacters($Exclude)) { $pattern = [WildcardPattern]::new($Exclude); $filterValue = $pattern.ToWql() $filterOperator = 'not-like' } else { $filterValue = $Exclude $filterOperator = 'ne' } $excludeFilter += '<filter type="and">' $excludeFilter += $nameFilterAttributes | ForEach-Object { '<condition attribute="{0}" operator="{1}" value="{2}" />' -f $_, $filterOperator, $filterValue } | Join-String $excludeFilter += '</filter>' } if ($Application) { $mainConditions += '<condition attribute="applicationid" operator="not-null" value="" />' } else { $mainConditions += '<condition attribute="applicationid" operator="null" value="" />' } if ($Disabled) { $mainConditions += '<condition attribute="isdisabled" operator="eq" value="1" />' } else { $mainConditions += '<condition attribute="isdisabled" operator="eq" value="0" />' } if ($Licensed) { $mainConditions += '<condition attribute="islicensed" operator="eq" value="1" />' } [xml]$fetchxml = @" <fetch> <entity name="systemuser"> <all-attributes /> <filter type="and"> $($mainConditions) $($includeFilter) $($excludeFilter) </filter> <order attribute="domainname" /> </entity> </fetch> "@ Get-DataverseRows -FetchXml $fetchxml } 'GetUserById' { Get-DataverseRow -Table 'systemuser' -Id $Id } Default {} } } } enum RoleInheritance { TeamOnly = 0; DirectAndTeam = 1; } # .EXTERNALHELP AMSoftware.Dataverse.PowerShell.AccessManagement.psm1-help.xml function Get-DataverseRole { [CmdletBinding(DefaultParameterSetName = 'GetAllRoles')] [OutputType([Microsoft.Xrm.Sdk.Entity])] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'GetRoleById')] [ValidateNotNullOrEmpty()] [Guid]$Id, [Parameter(ParameterSetName = 'GetAllRoles')] [Alias('Include')] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [string]$Name, [Parameter(ParameterSetName = 'GetAllRoles')] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [string]$Exclude, [Parameter(ParameterSetName = 'GetAllRoles')] [RoleInheritance]$Inheritance ) process { switch ($PSCmdlet.ParameterSetName) { 'GetAllRoles' { if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('Name')) { if ([WildcardPattern]::ContainsWildcardCharacters($Name)) { $pattern = [WildcardPattern]::new($Name); $filterOperator = 'like' $filterValue = $pattern.ToWql() } else { $filterOperator = 'eq' $filterValue = $Name } $includeFilter += '<condition attribute="name" operator="{1}" value="{2}" />' -f $filterOperator, $filterValue } if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('Exclude')) { if ([WildcardPattern]::ContainsWildcardCharacters($Exclude)) { $pattern = [WildcardPattern]::new($Exclude); $filterValue = $pattern.ToWql() $filterOperator = 'not-like' } else { $filterValue = $Exclude $filterOperator = 'ne' } $excludeFilter += '<condition attribute="name" operator="{1}" value="{2}" />' -f $filterOperator, $filterValue } if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('Inheritance')) { $mainConditions += "<condition attribute=""isinherited"" operator=""eq"" value=""$($Inheritance)"" />" } [xml]$fetchxml = @" <fetch> <entity name="role"> <all-attributes /> <filter type="and"> $($mainConditions) $($includeFilter) $($excludeFilter) </filter> <order attribute="name" /> </entity> </fetch> "@ Get-DataverseRows -FetchXml $fetchxml } 'GetRoleById' { Get-DataverseRow -Table 'role' -Id $Id } Default {} } } } enum TeamType { Owner = 0; Access = 1; AADSecurityGroup = 2; AADOfficeGroup = 3; } # .EXTERNALHELP AMSoftware.Dataverse.PowerShell.AccessManagement.psm1-help.xml function Get-DataverseTeam { [CmdletBinding(DefaultParameterSetName = 'GetAllTeams')] [OutputType([Microsoft.Xrm.Sdk.Entity])] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'GetTeamById')] [ValidateNotNullOrEmpty()] [Guid]$Id, [Parameter(ParameterSetName = 'GetAllTeams')] [Alias('Include')] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [string]$Name, [Parameter(ParameterSetName = 'GetAllTeams')] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [string]$Exclude, [Parameter(ParameterSetName = 'GetAllTeams')] [TeamType]$TeamType, [Parameter(ParameterSetName = 'GetAllTeams')] [ValidateNotNullOrEmpty()] [guid]$BusinessUnit, [Parameter(ParameterSetName = 'GetAllTeams')] [ValidateNotNullOrEmpty()] [guid]$Administrator ) process { switch ($PSCmdlet.ParameterSetName) { 'GetAllTeams' { if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('Name')) { if ([WildcardPattern]::ContainsWildcardCharacters($Name)) { $pattern = [WildcardPattern]::new($Name); $filterOperator = 'like' $filterValue = $pattern.ToWql() } else { $filterOperator = 'eq' $filterValue = $Name } $includeFilter += '<condition attribute="name" operator="{1}" value="{2}" />' -f $filterOperator, $filterValue } if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('Exclude')) { if ([WildcardPattern]::ContainsWildcardCharacters($Exclude)) { $pattern = [WildcardPattern]::new($Exclude); $filterValue = $pattern.ToWql() $filterOperator = 'not-like' } else { $filterValue = $Exclude $filterOperator = 'ne' } $excludeFilter += '<condition attribute="name" operator="{1}" value="{2}" />' -f $filterOperator, $filterValue } if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('TeamType')) { $mainConditions += "<condition attribute=""teamtype"" operator=""eq"" value=""$([int]$TeamType)"" />" } if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('BusinessUnit')) { $mainConditions += "<condition attribute=""businessunitid"" operator=""eq"" value=""$($BusinessUnit)"" />" } if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('Administrator')) { $mainConditions += "<condition attribute=""administratorid"" operator=""eq"" value=""$($Administrator)"" />" } [xml]$fetchxml = @" <fetch> <entity name="team"> <all-attributes /> <filter type="and"> $($mainConditions) $($includeFilter) $($excludeFilter) </filter> <order attribute="name" /> </entity> </fetch> "@ Get-DataverseRows -FetchXml $fetchxml } 'GetTeamById' { Get-DataverseRow -Table 'team' -Id $Id } Default {} } } } # .EXTERNALHELP AMSoftware.Dataverse.PowerShell.AccessManagement.psm1-help.xml function Get-DataverseRowAccess { [CmdletBinding()] [OutputType([Microsoft.Crm.Sdk.Messages.RetrieveSharedPrincipalsAndAccessResponse])] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('LogicalName', 'EntityLogicalName', 'Entity')] [ArgumentCompleter([AMSoftware.Dataverse.PowerShell.ArgumentCompleters.TableNameArgumentCompleter])] [string]$Table, [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('Row', 'RowId')] [guid]$Id ) process { Send-DataverseRequest -Name 'RetrieveSharedPrincipalsAndAccess' -TargetTable $Table -TargetRow $Id } } # .EXTERNALHELP AMSoftware.Dataverse.PowerShell.AccessManagement.psm1-help.xml function Set-DataverseRowOwner { [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')] [OutputType([Microsoft.Crm.Sdk.Messages.AssignResponse])] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('LogicalName', 'EntityLogicalName', 'Entity')] [ValidateNotNullOrEmpty()] [ArgumentCompleter([AMSoftware.Dataverse.PowerShell.ArgumentCompleters.TableNameArgumentCompleter])] [string]$Table, [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('Row', 'RowId')] [ValidateNotNullOrEmpty()] [guid]$Id, [Parameter(Mandatory = $true)] [ValidateNotNull()] [Microsoft.Xrm.Sdk.EntityReference]$Owner, [Parameter()] [switch]$Force ) process { if ($Force -and -not $PSBoundParameters.ContainsKey('Confirm')) { $ConfirmPreference = 'None' } if ($PSCmdlet.ShouldProcess("Assign $($Owner.LogicalName) $($Owner.Id)", "$Table $Id")) { Send-DataverseRequest -Name 'Assign' -TargetTable $Table -TargetRow $Id -Parameters @{'Assignee' = $Owner } } } } |