DSCResources/MSFT_SPUserProfileServiceAppPermissions/MSFT_SPUserProfileServiceAppPermissions.psm1
$script:SPDscUtilModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\SharePointDsc.Util' Import-Module -Name $script:SPDscUtilModulePath function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory = $true)] [System.String] $ProxyName, [Parameter()] [System.String[]] $CreatePersonalSite, [Parameter()] [System.String[]] $FollowAndEditProfile, [Parameter()] [System.String[]] $UseTagsAndNotes, [Parameter()] [System.Management.Automation.PSCredential] $InstallAccount ) Write-Verbose -Message "Getting permissions for user profile service proxy '$ProxyName" Confirm-SPDscUpaPermissionsConfig -Parameters $PSBoundParameters $result = Invoke-SPDscCommand -Credential $InstallAccount -Arguments $PSBoundParameters -ScriptBlock { $params = $args[0] $proxy = Get-SPServiceApplicationProxy | Where-Object { $_.DisplayName -eq $params.ProxyName } if ($null -eq $proxy) { return @{ ProxyName = $params.ProxyName CreatePersonalSite = $null FollowAndEditProfile = $null UseTagsAndNotes = $null } } $security = Get-SPProfileServiceApplicationSecurity -ProfileServiceApplicationProxy $proxy $createPersonalSite = @() $followAndEditProfile = @() $useTagsAndNotes = @() foreach ($securityEntry in $security.AccessRules) { $user = $securityEntry.Name if ($user -like "i:*|*" -or $user -like "c:*|*") { # Only claims users can be processed by the PowerShell cmdlets, so only # report on and manage the claims identities if ($user -eq "c:0(.s|true") { $user = "Everyone" } else { $user = (New-SPClaimsPrincipal -Identity $user -IdentityType EncodedClaim).Value } } if ($securityEntry.AllowedRights.ToString() -eq "All") { $createPersonalSite += $user $followAndEditProfile += $user $useTagsAndNotes += $user } if ($securityEntry.AllowedRights.ToString() -like "*UsePersonalFeatures*") { $followAndEditProfile += $user } if ($securityEntry.AllowedRights.ToString() -like "*UseSocialFeatures*") { $useTagsAndNotes += $user } if (($securityEntry.AllowedRights.ToString() -like "*CreatePersonalSite*") ` -and ($securityEntry.AllowedRights.ToString() -like "*UseMicrobloggingAndFollowing*")) { $createPersonalSite += $user } } if (!$createPersonalSite) { $createPersonalSite += "None" } if (!$followAndEditProfile) { $followAndEditProfile += "None" } if (!$useTagsAndNotes) { $useTagsAndNotes += "None" } return @{ ProxyName = $params.ProxyName CreatePersonalSite = $createPersonalSite FollowAndEditProfile = $followAndEditProfile UseTagsAndNotes = $useTagsAndNotes } } return $result } function Set-TargetResource { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [System.String] $ProxyName, [Parameter()] [System.String[]] $CreatePersonalSite, [Parameter()] [System.String[]] $FollowAndEditProfile, [Parameter()] [System.String[]] $UseTagsAndNotes, [Parameter()] [System.Management.Automation.PSCredential] $InstallAccount ) Write-Verbose -Message "Setting permissions for user profile service proxy '$ProxyName" Confirm-SPDscUpaPermissionsConfig -Parameters $PSBoundParameters $CurrentValues = Get-TargetResource @PSBoundParameters if ($CurrentValues.CreatePersonalSite -contains "NT AUTHORITY\Authenticated Users" ` -or $CurrentValues.FollowAndEditProfile -contains "NT AUTHORITY\Authenticated Users" ` -or $CurrentValues.UseTagsAndNotes -contains "NT AUTHORITY\Authenticated Users") { Write-Warning -Message ("Permissions were found for the non-claims identity " + ` "'NT AUTHORITY\Authenticated Users'. This will be removed as " + ` "identies on service app proxy permissions should be claims based.") Invoke-SPDscCommand -Credential $InstallAccount -Arguments $PSBoundParameters -ScriptBlock { $params = $args[0] $proxy = Get-SPServiceApplicationProxy | Where-Object { $_.DisplayName -eq $params.ProxyName } $security = Get-SPProfileServiceApplicationSecurity -ProfileServiceApplicationProxy $proxy Revoke-SPObjectSecurity -Identity $security -All Set-SPProfileServiceApplicationSecurity -Identity $security -ProfileServiceApplicationProxy $proxy -Confirm:$false Write-Verbose -Message "Successfully cleared all permissions on the service app proxy" } Write-Verbose -Message "Waiting 2 minutes for proxy permissions to be applied fully before continuing" Start-Sleep -Seconds 120 Write-Verbose -Message "Continuing configuration by getting the new current values." $CurrentValues = Get-TargetResource @PSBoundParameters } Invoke-SPDscCommand -Credential $InstallAccount ` -Arguments @($PSBoundParameters, $MyInvocation.MyCommand.Source, $CurrentValues) ` -ScriptBlock { $params = $args[0] $eventSource = $args[1] $CurrentValues = $args[2] $proxy = Get-SPServiceApplicationProxy | Where-Object { $_.DisplayName -eq $params.ProxyName } if ($null -eq $proxy) { $message = "Unable to find service application proxy called '$($params.ProxyName)'" Add-SPDscEvent -Message $message ` -EntryType 'Error' ` -EventID 100 ` -Source $eventSource throw $message } $security = Get-SPProfileServiceApplicationSecurity -ProfileServiceApplicationProxy $proxy $permissionsToUpdate = @{ "CreatePersonalSite" = "Create Personal Site" "FollowAndEditProfile" = "Use Personal Features" "UseTagsAndNotes" = "Use Social Features" } foreach ($permission in $permissionsToUpdate.Keys) { $permissionsDiff = Compare-Object -ReferenceObject $CurrentValues.$permission ` -DifferenceObject $params.$permission $everyoneDiff = $permissionsDiff | Where-Object -FilterScript { $_.InputObject -eq "Everyone" } $noneDiff = $permissionsDiff | Where-Object -FilterScript { $_.InputObject -eq "None" } if (($null -ne $noneDiff) -and ($noneDiff.SideIndicator -eq "=>")) { # Need to remove everyone foreach ($user in $CurrentValues.$permission) { if ($user -ne "Everyone" -and $user -ne "None" -and $user) { $isUser = Test-SPDscIsADUser -IdentityName $user if ($isUser -eq $true) { $claim = New-SPClaimsPrincipal -Identity $user ` -IdentityType WindowsSamAccountName } else { $claim = New-SPClaimsPrincipal -Identity $user ` -IdentityType WindowsSecurityGroupName } Revoke-SPObjectSecurity -Identity $security ` -Principal $claim ` -Rights $permissionsToUpdate.$permission } elseif ($user -eq "Everyone") { # Revoke the all user permissions $allClaimsUsersClaim = New-SPClaimsPrincipal -Identity "c:0(.s|true" ` -IdentityType EncodedClaim Revoke-SPObjectSecurity -Identity $security ` -Principal $allClaimsUsersClaim ` -Rights $permissionsToUpdate.$permission } } } elseif (($null -ne $everyoneDiff) -and ($everyoneDiff.SideIndicator -eq "=>")) { # Need to add everyone, so remove all the permissions that exist currently of this type # and then add the everyone permissions foreach ($user in $CurrentValues.$permission) { if ($user -ne "Everyone" -and $user -ne "None" -and $user) { $isUser = Test-SPDscIsADUser -IdentityName $user if ($isUser -eq $true) { $claim = New-SPClaimsPrincipal -Identity $user ` -IdentityType WindowsSamAccountName } else { $claim = New-SPClaimsPrincipal -Identity $user ` -IdentityType WindowsSecurityGroupName } Revoke-SPObjectSecurity -Identity $security ` -Principal $claim ` -Rights $permissionsToUpdate.$permission } } $allClaimsUsersClaim = New-SPClaimsPrincipal -Identity "c:0(.s|true" ` -IdentityType EncodedClaim Grant-SPObjectSecurity -Identity $security ` -Principal $allClaimsUsersClaim ` -Rights $permissionsToUpdate.$permission } else { # permission changes aren't to everyone or none, process each change foreach ($permissionChange in $permissionsDiff) { if ($permissionChange.InputObject -ne "Everyone" -and ` $permissionChange.InputObject -ne "None") { $isUser = Test-SPDscIsADUser -IdentityName $permissionChange.InputObject if ($isUser -eq $true) { $claim = New-SPClaimsPrincipal -Identity $permissionChange.InputObject ` -IdentityType WindowsSamAccountName } else { $claim = New-SPClaimsPrincipal -Identity $permissionChange.InputObject ` -IdentityType WindowsSecurityGroupName } if ($permissionChange.SideIndicator -eq "=>") { # Grant permission to the identity Grant-SPObjectSecurity -Identity $security ` -Principal $claim ` -Rights $permissionsToUpdate.$permission } if ($permissionChange.SideIndicator -eq "<=") { # Revoke permission for the identity Revoke-SPObjectSecurity -Identity $security ` -Principal $claim ` -Rights $permissionsToUpdate.$permission } } } } } Set-SPProfileServiceApplicationSecurity -Identity $security ` -ProfileServiceApplicationProxy $proxy ` -Confirm:$false } } function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [System.String] $ProxyName, [Parameter()] [System.String[]] $CreatePersonalSite, [Parameter()] [System.String[]] $FollowAndEditProfile, [Parameter()] [System.String[]] $UseTagsAndNotes, [Parameter()] [System.Management.Automation.PSCredential] $InstallAccount ) Write-Verbose -Message "Testing permissions for user profile service proxy '$ProxyName" Confirm-SPDscUpaPermissionsConfig -Parameters $PSBoundParameters $CurrentValues = Get-TargetResource @PSBoundParameters Write-Verbose -Message "Current Values: $(Convert-SPDscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-SPDscHashtableToString -Hashtable $PSBoundParameters)" $result = Test-SPDscParameterState -CurrentValues $CurrentValues ` -Source $($MyInvocation.MyCommand.Source) ` -DesiredValues $PSBoundParameters ` -ValuesToCheck @("CreatePersonalSite", ` "FollowAndEditProfile", ` "UseTagsAndNotes") Write-Verbose -Message "Test-TargetResource returned $result" return $result } function Confirm-SPDscUpaPermissionsConfig() { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [Object] $Parameters ) @( "CreatePersonalSite", "FollowAndEditProfile", "UseTagsAndNotes" ) | ForEach-Object -Process { if (($Parameters.$_ -contains "Everyone") -and ($Parameters.$_ -contains "None")) { $message = ("You can not specify 'Everyone' and 'None' in the same property. " + ` "Check the value for the '$_' property on this resource.") Add-SPDscEvent -Message $message ` -EntryType 'Error' ` -EventID 100 ` -Source $MyInvocation.MyCommand.Source throw $message } } } function Export-TargetResource { $VerbosePreference = "SilentlyContinue" $ParentModuleBase = Get-Module "SharePointDsc" -ListAvailable | Select-Object -ExpandProperty Modulebase $module = Join-Path -Path $ParentModuleBase -ChildPath "\DSCResources\MSFT_SPUserProfileServiceAppPermissions\MSFT_SPUserProfileServiceAppPermissions.psm1" -Resolve $Content = '' $params = Get-DSCFakeParameters -ModulePath $module $proxies = Get-SPServiceApplicationProxy | Where-Object { $_.GetType().Name -eq "UserProfileApplicationProxy" } foreach ($proxy in $proxies) { try { $params.ProxyName = $proxy.Name $PartialContent = " SPUserProfileServiceAppPermissions " + [System.Guid]::NewGuid().ToString() + "`r`n" $PartialContent += " {`r`n" $results = Get-TargetResource @params $results = Repair-Credentials -results $results $currentBlock = Get-DSCBlock -Params $results -ModulePath $module $currentBlock = Convert-DSCStringParamToVariable -DSCBlock $currentBlock -ParameterName "PsDscRunAsCredential" $PartialContent += $currentBlock $PartialContent += " }`r`n" $Content += $PartialContent } catch { $Global:ErrorLog += "[User Profile Service Application Permissions]" + $proxy.Name + "`r`n" $Global:ErrorLog += "$_`r`n`r`n" } } return $Content } Export-ModuleMember -Function *-TargetResource |