Forum Discussion

Zilverflame's avatar
Zilverflame
Copper Contributor
Nov 18, 2016
Solved

SharePoint Online overview of user permissions

Hi group, We have a site collection with several subsites. From the start we have been using security groups to control user permissions. As time has passed the number of subsites have exploded and we need to get an overview of permissions. Is it possible, hopefully through powershell, go get the main site and all subsites links? Even better also list the security groups attached to the sharepoint permission groups for each link. Have a nice weekend. Regards Anders
  • Hi,

     

    Please check the below updated script, this should work with the latest PnP module.

     

    function connect-site($webs,$creds){
    
    Connect-PNPonline -Url $webs -Credentials $cred
    
    }
    
    function get-sitepermission($web,$cred){
    
    $rec=@()
    
    connect-site -webs $web -creds $cred
    
    if($web -eq $parentsitename)
    {
    #Write-Host "Parent site permission" $web
    $Pgroups=Get-PNPGroup
    foreach($Pgroup in $Pgroups)
    {
    $DLGP = "" | Select "SiteUrl","GroupName","Permission"
    $pPerm=Get-PNPGroupPermissions -Identity $Pgroup.loginname -ErrorAction SilentlyContinue |Where-Object {$_.Hidden -like "False"}
    if($pPerm -ne $null)
    {
    $DLGP.SiteUrl=$web
    $DLGP.GroupName=$Pgroup.loginname
    $DLGP.Permission=$pPerm.Name
    $rec+= $DLGP
    }
    }
    }
    $subwebs=Get-PNPSubWebs
    foreach($subweb in $subwebs)
    {
    connect-site -webs $subweb.Url -creds $cred
    #Write-Host $subweb.Url
    $groups=Get-PNPGroup
    foreach($group in $groups)
    {
    $DLGP = "" | Select "SiteUrl","GroupName","Permission"
    $sPerm=Get-PNPGroupPermissions -Identity $group.loginname -ErrorAction SilentlyContinue |Where-Object {$_.Hidden -like "False"}
    if ($sPerm -ne $null)
    {
    $DLGP.SiteUrl=$subweb.Url
    $DLGP.GroupName=$group.loginname
    $DLGP.Permission=$sPerm.Name
    $rec+=$DLGP
    }
    }
    Write-Host $subweb.Url "permission fetched!"
    get-sitepermission -web $subweb.Url -cred $cred
    
    }
    return $rec
    }
    #Input parameter
    $cred=Get-Credential
    $parentsitename="https://<Tenantname>.sharepoint.com/sites/contosobeta"
    $outputPath= "c:\csv\AllSubsitegrouppermission.csv"
    
    $Sitepermission=get-sitepermission -web $parentsitename -cred $cred
    $Sitepermission |Export-Csv -Path $outputPath
    
    
    

9 Replies

  • You can run this script to get the permission details for subsites. This can be run with PnP PowerShell module. 

     

    function connect-site($webs,$creds){
     
    Connect-SPOnline -Url $webs -Credentials $cred
     
    }
     
    function get-sitepermission($web,$cred){
     
    $rec=@()
     
    connect-site -webs $web -creds $cred
     
    if($web -eq $parentsitename)
    {
    #Write-Host "Parent site permission" $web
    $Pgroups=Get-SPOGroup
    foreach($Pgroup in $Pgroups)
    {
    $DLGP = "" | Select "SiteUrl","GroupName","Permission"
    $pPerm=Get-SPOGroupPermissions -Identity $Pgroup.loginname -ErrorAction SilentlyContinue |Where-Object {$_.Hidden -like "False"}
    if($pPerm -ne $null)
    {
    $DLGP.SiteUrl=$web
    $DLGP.GroupName=$Pgroup.loginname
    $DLGP.Permission=$pPerm.Name
    $rec+= $DLGP
    }
    }
    }
    $subwebs=Get-SPOSubWebs
    foreach($subweb in $subwebs)
    {
    connect-site -webs $subweb.Url -creds $cred
    #Write-Host $subweb.Url
    $groups=Get-SPOGroup
    foreach($group in $groups)
    {
    $DLGP = "" | Select "SiteUrl","GroupName","Permission"
    $sPerm=Get-SPOGroupPermissions -Identity $group.loginname -ErrorAction SilentlyContinue |Where-Object {$_.Hidden -like "False"}
    if ($sPerm -ne $null)
    {
    $DLGP.SiteUrl=$subweb.Url
    $DLGP.GroupName=$group.loginname
    $DLGP.Permission=$sPerm.Name
    $rec+=$DLGP
    }
    }
    Write-Host $subweb.Url "permission fetched!"
    get-sitepermission -web $subweb.Url -cred $cred
     
    }
    return $rec
    }
    #Input parameter
    $cred=Get-Credential
    $parentsitename="https://mod.sharepoint.com/sites/contosobeta"
    $outputPath= "c:\csv\AllSubsitegrouppermission.csv"
     
    $Sitepermission=get-sitepermission -web $parentsitename -cred $cred
    $Sitepermission |Export-Csv -Path $outputPath
    • Zilverflame's avatar
      Zilverflame
      Copper Contributor

      NarasimaPerumal Chandramohan wrote:

      You can run this script to get the permission details for subsites. This can be run with PnP PowerShell module. 


      Hmmmm, doesn't work. Many commands are not recognized, even after import SPO module. Also when connecting it's called "Connect-SPOservice".
      • Hi,

         

        Please check the below updated script, this should work with the latest PnP module.

         

        function connect-site($webs,$creds){
        
        Connect-PNPonline -Url $webs -Credentials $cred
        
        }
        
        function get-sitepermission($web,$cred){
        
        $rec=@()
        
        connect-site -webs $web -creds $cred
        
        if($web -eq $parentsitename)
        {
        #Write-Host "Parent site permission" $web
        $Pgroups=Get-PNPGroup
        foreach($Pgroup in $Pgroups)
        {
        $DLGP = "" | Select "SiteUrl","GroupName","Permission"
        $pPerm=Get-PNPGroupPermissions -Identity $Pgroup.loginname -ErrorAction SilentlyContinue |Where-Object {$_.Hidden -like "False"}
        if($pPerm -ne $null)
        {
        $DLGP.SiteUrl=$web
        $DLGP.GroupName=$Pgroup.loginname
        $DLGP.Permission=$pPerm.Name
        $rec+= $DLGP
        }
        }
        }
        $subwebs=Get-PNPSubWebs
        foreach($subweb in $subwebs)
        {
        connect-site -webs $subweb.Url -creds $cred
        #Write-Host $subweb.Url
        $groups=Get-PNPGroup
        foreach($group in $groups)
        {
        $DLGP = "" | Select "SiteUrl","GroupName","Permission"
        $sPerm=Get-PNPGroupPermissions -Identity $group.loginname -ErrorAction SilentlyContinue |Where-Object {$_.Hidden -like "False"}
        if ($sPerm -ne $null)
        {
        $DLGP.SiteUrl=$subweb.Url
        $DLGP.GroupName=$group.loginname
        $DLGP.Permission=$sPerm.Name
        $rec+=$DLGP
        }
        }
        Write-Host $subweb.Url "permission fetched!"
        get-sitepermission -web $subweb.Url -cred $cred
        
        }
        return $rec
        }
        #Input parameter
        $cred=Get-Credential
        $parentsitename="https://<Tenantname>.sharepoint.com/sites/contosobeta"
        $outputPath= "c:\csv\AllSubsitegrouppermission.csv"
        
        $Sitepermission=get-sitepermission -web $parentsitename -cred $cred
        $Sitepermission |Export-Csv -Path $outputPath
        
        
        
  • Here's one I have which will get you started. I can't remember where I found it. And I'm a Powershell newbie so I won't be able to help!

     

    I use Windows Powershell ISE for running scripts which is more user friendly for me.

    https://msdn.microsoft.com/en-us/powershell/scripting/getting-started/fundamental/windows-powershell-integrated-scripting-environment--ise-

     

    Connect to SPO and then run this. It will generate a CSV file with users and permissions for a site collection. However the CSV needs work to make it readable as all the data is in one column but text to columns sorts that.

    Note you have to create a folder called 'exports' on your C drive. Or change the path in the script. Depending on the number of site and users, it will take a few minutes to run.

     

    Otherwise it's 3rd party tools like ShareGate or Clouldkit365.

     


    function Get-SiteCollectionGroups {
    Param(
    [Parameter(Mandatory=$true)]
    [ValidateNotNull()]
    [string]$outputFullFilePath,
    [Parameter(Mandatory=$false)]
    [switch]$selectSites,
    [Parameter(Mandatory=$false)]
    [char]$csvSeparator = ';',
    [Parameter(Mandatory=$false)]
    [char]$internalSeparator = ','
    )
    Write-Host "Collecting site collection groups";
    $SiteCollectionGroups = @();
    $sites = $null;
    if($selectSites)
    {
    $sites = Get-SPOSite -Detailed | Out-GridView -Title "Select site collections to collect groups from" -PassThru;
    }
    else
    {
    $sites = Get-SPOSite -Detailed;
    }
    [int]$counter = 0;
    [int]$total = $sites.Count;
    [string]$counterFormat = "0" * $total.ToString().Length;
    foreach($site in $sites)
    {
    $counter++;
    Write-Host "$($counter.ToString($counterFormat))/$($total.ToString($counterFormat)) [" -ForegroundColor Yellow -NoNewline;
    Write-Host "$($site.Url)" -ForegroundColor Cyan -NoNewline;
    Write-Host "]: " -ForegroundColor Yellow -NoNewline;
    try {
    $groups = Get-SPOSiteGroup -Site $site;
    foreach($group in $groups)
    {
    [string]$groupUsers = "";
    foreach($user in $group.Users)
    {
    $groupUsers += "$user$($internalSeparator)";
    }
    if($groupUsers -match "$($internalSeparator)$")
    {
    $groupUsers = $groupUsers.Substring(0, $groupUsers.Length-1);
    }
    [string]$groupRoles = "";
    foreach($role in $group.Roles)
    {
    $groupRoles += "$role$($internalSeparator)";
    }
    if($groupRoles -match "$($internalSeparator)$")
    {
    $groupRoles = $groupRoles.Substring(0, $groupRoles.Length-1);
    }
    $group | Add-Member -MemberType NoteProperty -Name "SiteCollectionUrl" -Value $site.Url
    $group | Add-Member -MemberType NoteProperty -Name "GroupUsers" -Value $groupUsers
    $group | Add-Member -MemberType NoteProperty -Name "GroupRoles" -Value $groupRoles
    $SiteCollectionGroups += $group;
    }
    Write-Host "$($groups.Count) groups are successfully collected" -ForegroundColor Green;
    }
    catch
    {
    Write-Host "Groups could not be collected" -ForegroundColor Red;
    }
    }
    $SiteCollectionGroups | Select SiteCollectionUrl,LoginName,Title,OwnerLoginName,OwnerTitle,GroupUsers,GroupRoles | Export-Csv -Path $outputFullFilePath -Delimiter $csvSeparator -NoTypeInformation
    Write-Host "Site collection groups are collected and written to $outputFullFilePath" -ForegroundColor Green
    }
    # 2 examples, the first is a minimal call, the second is a call with all optional parameters
    Get-SiteCollectionGroups -outputFullFilePath "C:\exports\AllSiteCollectionGroups$(Get-Date -Format "yyyyMMddhhmmss").csv"
    #Get-SiteCollectionGroups -outputFullFilePath "C:\exports\AllSiteCollectionGroups$(Get-Date -Format "yyyyMMddhhmmss").csv" -csvSeparator ',' -internalSeparator ';' -selectSites

     

     

    • Zilverflame's avatar
      Zilverflame
      Copper Contributor
      Thanks for your answer Andrew. The script collects info about all site collections, but not the subsites... :) Thanks anyway.
      • As an alternative to PowerShell, there are some governance tools that could help you on this

Resources