Powershell to get site permissions (Unique Permission) for the SharePoint Users

<# The below PowerShell script enumerates through all sites with unique permissions and fetches users with Full Control Permission granted directly to the site
or through group membership.
#>
#Load SharePoint PowerShell Snapin
if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
    Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}
#Collection of user permission objects
$SiteOwners =@();
#Define all the properties for the user permission object
$Properties = @{Title='';SiteID='';WebID='';WebSiteUrl='';AccessRequestEmail='';Scope='';Login='';UserID='';User='';Email='';LastItemModified='';};
#Site Url
$WebUrl ="";
#Web Application URL
$WebApplicationURL = "<WebAppUrl>";
#Enumerate through all Site Collections and Sites
Get-SPWebApplication -Identity $WebApplicationURL | Get-SPSite -limit all |%{
$siteID=$_.ID;
#Enumerate through all sites within the site collection
Get-SPWeb -limit all -Site $_|%{
$web = $_;
#Check if the site has unique permissions
if(($web.HasUniqueRoleAssignments -eq "True" -or $web.IsRootWeb -eq "True")){
$WebUrl = $web.Url;
#Full Control Role Definition
$FullControl = $web.RoleDefinitions["Full Control"];
#Collection of Groups with Full Control permissions
$OwnerGroups=@();
#Get all Owner groups with Full Control permission
$web.Groups|?{$_.Name -match "Owners"}|%{
$IsGroupFullControl = $_.Roles|?{$_.Name -eq $FullControl.Name;}
$OwnerGroups += $_;
}
try{
<#
SPWeb.Users:
This represents the collection of users or user objects who have been explicitly assigned permissions in the Web site . This does not return users who have access through a group.
SPWeb.AllUsers:
This gives us the collection of user objects who are either members of the site collection or who have atleast navigated to the site as authenticated members of a domain group in the site.
#>
#Enumerate through all Users in the Web
$web.AllUsers|?{$_.LoginName -ne "SHAREPOINT\System" -and $_.Email.Length -gt 0}|%{
#Check User Effective Permissions
if($web.DoesUserHavePermissions($_.LoginName,[Microsoft.SharePoint.SPBasePermissions]::FullMask)){
$user=$_;
#Full Control Permission could have been granted directly or through group membership. Scope will represent these details.
$Scopes=@();
try{
$UserRoleAssignments = $web.RoleAssignments.GetAssignmentByPrincipal($user);
}
catch{}
#Check if user has Full Control Permissions
if($UserRoleAssignments.RoleDefinitionBindings.Contains($FullControl)){
  
$Scopes += "Site";
  
#Check for group membership of user in Owners group i.e. groups with Full Control permission
$user.Groups|%{
$Group=$_;
$IsOwnerGroup = $OwnerGroups|?{$_.Name -eq $Group.Name};
if($IsOwnerGroup){
$Scopes += $Group.Name;
}
}
  
#Create an object for the user permission record
$Owner = New-Object PSObject -Property $Properties;
$Owner.Title = $web.Title;
$Owner.WebID = $web.ID;
$Owner.SiteID = $siteID;
$Owner.WebSiteURL = $web.URL;
$Owner.AccessRequestEmail=$web.RequestAccessEmail;
$Owner.Scope = ($Scopes -join ",");
$Owner.UserID=$user.LoginName.Split("\")[1];
$Owner.Login=$user.LoginName;
$Owner.User=$user.Name;
$Owner.Email=$user.Email;
$Owner.LastItemModified=$web.LastItemModifiedDate.ToString("MM/dd/yyyy");
  
$SiteOwners +=$Owner;
}
}
}
$web.Dispose();
$_.Dispose();
}
catch [System.Exception]{
Write-Host ($WebUrl + ":" + $_.Exception.Message + ":" + $_.Exception.StackTrace);
}
}
}
#Dispose SPSite
$_.Dispose();
}
$SiteOwners|Export-CSV "D:\SharePoint Administration\SiteOwners.csv" -NoTypeInformation;

Courtesy: https://social.technet.microsoft.com/wiki/contents/articles/5884.sharepoint-2010-get-site-users-with-full-controlowners-permissions-with-powershell-script.aspx

Collect the log from SharePoint environment Using Power-Shell Script



How to  collect the log from SharePoint environment Using PowerShell Script

Getting SharePoint Log . Using timing and Correlation ids


Save email as .eml file in sharepoint online document libarary using Mocrosoft Flow


Flow:
Please take a look at this article, I think it will help us save the email as a msg or eml file to the document library.

 Give needed permission to the SharePoint library (Contribute 

Create needed folder in you email box.  should be save as .eml file




SharePoint Online Get all user Permissions. Permission Matrix.


SharePoint Online Permission Matrix

Hi After migration you may like to compare the existing user permissions(On-Prem and current user permission (Online)

Note : NTAuthenitcated users need to be replaced with Every one . 

Please use the below two Powers-hell script to get the result

Pre requisites : 
1. Sharepoint online management shell
2.Download the Sharepoint SDK , It will install all the SharePoint client related Dll
3. Have admin permission

Paths to SDK. Please verify location on your computer.
# On farm it would be available at c:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"


 Two set power shell required to get the result
1.
please the name it as powershellUserpermission.ps1 (as per u r wish)
--- Begin 


Import-Module Microsoft.Online.SharePoint.PowerShell
$admin = "your email id "
$pass = ConvertTo-SecureString "Pwad" -AsPlainText -Force

$OutputFile = "C:\Temp\Company_AllSitePermissions.csv"
Set-Content $OutputFile "Site,HasUniquePerm?,Group Name,Group Owner,Login Name,Roles"

Function Get-SPOAllSitePermissions ($url)
{
    $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($url)
    $ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($admin, $pass)
    $web = $ctx.Web   
    Load-CSOMProperties -Object $web -PropertyNames @("HasUniqueRoleAssignments", "Url", "Title")
    $ctx.Load($ctx.Web.Webs)   
    $ctx.Load($ctx.Web.RoleAssignments)   
    $ctx.ExecuteQuery()
    Write-Host $web.Url
    $webUrl = $web.Url   
    $record = "`"$webUrl`",$($web.HasUniqueRoleAssignments),"   
    if($web.HasUniqueRoleAssignments -eq $true) {
        $firstIteration = $true #helps when to append commas
        foreach($roleAssignment in $ctx.Web.RoleAssignments) {
            Load-CSOMProperties -Object $roleAssignment -PropertyNames @("Member","RoleDefinitionBindings")
            $ctx.ExecuteQuery()
            $roles = ($roleAssignment.RoleDefinitionBindings | Select -ExpandProperty Name) -join ", ";
            $loginName = if($roleAssignment.Member.PrincipalType -eq "User") { $($roleAssignment.Member.LoginName) } else { "" }
            $record += if($firstIteration) { "" } else { ",," }
            $record += "`"$($roleAssignment.Member.Title)`",`"$($roleAssignment.Member.OwnerTitle)`","
            $record += "`"$loginName`",`"$roles`""           
            Add-Content $OutputFile $record
            $firstIteration = $false
            $record = ""
        }     
    }
    else {
        Add-Content $OutputFile $record #you can refer the permissions from its parent web.
    }
    if($web.Webs.Count -eq 0)
    {
 
    }
    else {
        foreach ($web in $web.Webs) {
            Get-SPOAllSitePermissions -Url $web.Url
        }
    }
}

# Paths to SDK. Please verify location on your computer.
# On farm it would be available at c:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

.\Load-CSOMProperties.ps1

Get-SPOAllSitePermissions "https://Tenant/site-collection" ///--- Url.. Subsite or site-collection


------ End

2. Second Powershell

please the name it as Load-CSOMProperties.ps1 (don't change the name)
-- Begin


<#
.Synopsis
    Facilitates the loading of specific properties of a Microsoft.SharePoint.Client.ClientObject object or Microsoft.SharePoint.Client.ClientObjectCollection object.
.DESCRIPTION
    Replicates what you would do with a lambda expression in C#. 
    For example, "ctx.Load(list, l => list.Title, l => list.Id)" becomes
    "Load-CSOMProperties -object $list -propertyNames @('Title', 'Id')".
.EXAMPLE
    Load-CSOMProperties -parentObject $web -collectionObject $web.Fields -propertyNames @("InternalName", "Id") -parentPropertyName "Fields" -executeQuery
    $web.Fields | select InternalName, Id
.EXAMPLE
   Load-CSOMProperties -object $web -propertyNames @("Title", "Url", "AllProperties") -executeQuery
   $web | select Title, Url, AllProperties
#>
function global:Load-CSOMProperties {
    [CmdletBinding(DefaultParameterSetName='ClientObject')]
    param (
        # The Microsoft.SharePoint.Client.ClientObject to populate.
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0, ParameterSetName = "ClientObject")]
        [Microsoft.SharePoint.Client.ClientObject]
        $object,

        # The Microsoft.SharePoint.Client.ClientObject that contains the collection object.
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0, ParameterSetName = "ClientObjectCollection")]
        [Microsoft.SharePoint.Client.ClientObject]
        $parentObject,

        # The Microsoft.SharePoint.Client.ClientObjectCollection to populate.
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 1, ParameterSetName = "ClientObjectCollection")]
        [Microsoft.SharePoint.Client.ClientObjectCollection]
        $collectionObject,

        # The object properties to populate
        [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "ClientObject")]
        [Parameter(Mandatory = $true, Position = 2, ParameterSetName = "ClientObjectCollection")]
        [string[]]
        $propertyNames,

        # The parent object's property name corresponding to the collection object to retrieve (this is required to build the correct lamda expression).
        [Parameter(Mandatory = $true, Position = 3, ParameterSetName = "ClientObjectCollection")]
        [string]
        $parentPropertyName,

        # If specified, execute the ClientContext.ExecuteQuery() method.
        [Parameter(Mandatory = $false, Position = 4)]
        [switch]
        $executeQuery
    )

    begin { }
    process {
        if ($PsCmdlet.ParameterSetName -eq "ClientObject") {
            $type = $object.GetType()
        } else {
            $type = $collectionObject.GetType() 
            if ($collectionObject -is [Microsoft.SharePoint.Client.ClientObjectCollection]) {
                $type = $collectionObject.GetType().BaseType.GenericTypeArguments[0]
            }
        }

        $exprType = [System.Linq.Expressions.Expression]
        $parameterExprType = [System.Linq.Expressions.ParameterExpression].MakeArrayType()
        $lambdaMethod = $exprType.GetMethods() | ? { $_.Name -eq "Lambda" -and $_.IsGenericMethod -and $_.GetParameters().Length -eq 2 -and $_.GetParameters()[1].ParameterType -eq $parameterExprType }
        $lambdaMethodGeneric = Invoke-Expression "`$lambdaMethod.MakeGenericMethod([System.Func``2[$($type.FullName),System.Object]])"
        $expressions = @()

        foreach ($propertyName in $propertyNames) {
            $param1 = [System.Linq.Expressions.Expression]::Parameter($type, "p")
            try {
                $name1 = [System.Linq.Expressions.Expression]::Property($param1, $propertyName)
            } catch {
                Write-Error "Instance property '$propertyName' is not defined for type $type"
                return
            }
            $body1 = [System.Linq.Expressions.Expression]::Convert($name1, [System.Object])
            $expression1 = $lambdaMethodGeneric.Invoke($null, [System.Object[]] @($body1, [System.Linq.Expressions.ParameterExpression[]] @($param1)))

            if ($collectionObject -ne $null) {
                $expression1 = [System.Linq.Expressions.Expression]::Quote($expression1)
            }
            $expressions += @($expression1)
        }


        if ($PsCmdlet.ParameterSetName -eq "ClientObject") {
            $object.Context.Load($object, $expressions)
            if ($executeQuery) { $object.Context.ExecuteQuery() }
        } else {
            $newArrayInitParam1 = Invoke-Expression "[System.Linq.Expressions.Expression``1[System.Func````2[$($type.FullName),System.Object]]]"
            $newArrayInit = [System.Linq.Expressions.Expression]::NewArrayInit($newArrayInitParam1, $expressions)

            $collectionParam = [System.Linq.Expressions.Expression]::Parameter($parentObject.GetType(), "cp")
            $collectionProperty = [System.Linq.Expressions.Expression]::Property($collectionParam, $parentPropertyName)

            $expressionArray = @($collectionProperty, $newArrayInit)
            $includeMethod = [Microsoft.SharePoint.Client.ClientObjectQueryableExtension].GetMethod("Include")
            $includeMethodGeneric = Invoke-Expression "`$includeMethod.MakeGenericMethod([$($type.FullName)])"

            $lambdaMethodGeneric2 = Invoke-Expression "`$lambdaMethod.MakeGenericMethod([System.Func``2[$($parentObject.GetType().FullName),System.Object]])"
            $callMethod = [System.Linq.Expressions.Expression]::Call($null, $includeMethodGeneric, $expressionArray)
            
            $expression2 = $lambdaMethodGeneric2.Invoke($null, @($callMethod, [System.Linq.Expressions.ParameterExpression[]] @($collectionParam)))

            $parentObject.Context.Load($parentObject, $expression2)
            if ($executeQuery) { $parentObject.Context.ExecuteQuery() }
        }
    }
    end { }
}


---End

SPFX - HTTPClient - Curd Operations - SharePoint list.

  Create solution in the name of SpfxCrud. ISpfxCrudProps.ts export interface ISpfxCrudProps {   description : string ;     context : an...