How to get all site owners in a sharepoint online site

SR VSP 1,251 Reputation points
2023-12-18T22:03:44.7166667+00:00

Hi Guys - How to get all site owners in a SharePoint online site . I can able to fetch only one site owner but i need all the owners in the Owners group ( I dont need Admins )

# Import-Module -Name Microsoft.Online.SharePoint.PowerShell -WarningAction silentlycontinue
# Load SharePoint CSOM Assemblies
# 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"

# Function to Generate a Report on all documents in a SharePoint Online Site Collection
Function Get-SPODocumentInventory($SiteURL)
{
    Try {
        # Setup the context
        $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
        $Ctx.Credentials = $Credentials

        # Get the web from the given URL and its subsites
        $Web = $Ctx.web
        $Ctx.Load($Web)
        $Ctx.Load($Web.Lists)
        $Ctx.Load($web.Webs)
        $Site = $Ctx.Site
        $Ctx.Load($Site)
        $SiteOwner = $Site.Owner
        $Ctx.Load($SiteOwner)
        $Ctx.executeQuery()
        ###############################################
        # Site Created Date column
        $RootWeb=$Ctx.Web    
        $Ctx.Load($RootWeb)  
        $CreatedDate = $RootWeb.created.toShortDateString()
        ################################################

        # Array to Skip System Lists and Libraries
        $SystemLists = @("Converted Forms", "Master Page Gallery", "Customized Reports", "Form Templates", "List Template Gallery", "Theme Gallery",
            "Reporting Templates", "Solution Gallery", "Style Library", "Web Part Gallery", "Site Assets", "wfpub", "Site Pages", "Images","Pages")

        Write-host -f Yellow "Processing Site: $SiteURL"

        # Get the site creation date
        $SiteCreatedDate = $Site.Createddate

        # Filter Document Libraries to Scan
        $Lists = $Web.Lists | Where { $_.BaseType -eq "DocumentLibrary" -and $_.Hidden -eq $false -and $SystemLists -notcontains $_.Title -and $_.ItemCount -gt 0 }

        # Loop through each document library
        Foreach ($List in $Lists)
        {
            
            Start-Sleep -Seconds 1 # Pause for 1 minute for each document lib

            # Define CAML Query to Get List Items in batches
            $Query = New-Object Microsoft.SharePoint.Client.CamlQuery
            $Query.ViewXml = "
                <View Scope='RecursiveAll'>
                   <Query>
                      <OrderBy><FieldRef Name='ID' Ascending='TRUE'/></OrderBy>
                   </Query>
                   <RowLimit Paged='TRUE'>$BatchSize</RowLimit>
                </View>"

            Write-host -f Cyan "`t Processing Document Library: '$($List.Title)' with $($List.ItemCount) Item(s)"

            Do {
                # Get List items
                $ListItems = $List.GetItems($Query)
                $Ctx.Load($ListItems)
                $Ctx.ExecuteQuery()

                # Filter Files
                $Files = $ListItems | Where { $_.FileSystemObjectType -eq "File" }

                # Iterate through each file and get data
                $DocumentInventory = @()
                Foreach ($Item in $Files)
                {
                    $File = $Item.File
                    $Ctx.Load($File)
                    $Ctx.ExecuteQuery()

                    $DocumentData = New-Object PSObject
                    $DocumentData | Add-Member NoteProperty SiteName($Web.Title)
                    $DocumentData | Add-Member NoteProperty SiteURL($SiteURL)
                    $DocumentData | Add-member NoteProperty -name "SiteCreatedDate" -Value ($CreatedDate)
                    $DocumentData | Add-Member NoteProperty SiteOwner($Site.Owner.Email)
                    $DocumentData | Add-Member NoteProperty DocLibraryName($List.Title)
                    $DocumentData | Add-Member NoteProperty FileName($File.Name)
                    $DocumentData | Add-Member NoteProperty FileURL($File.ServerRelativeUrl)
                    $DocumentData | Add-Member NoteProperty CreatedBy($Item["Author"].Email)
                    $DocumentData | Add-Member NoteProperty CreatedOn($File.TimeCreated)
                    $DocumentData | Add-Member NoteProperty ModifiedBy($Item["Editor"].Email)
                    $DocumentData | Add-Member NoteProperty LastModifiedOn($File.TimeLastModified)
                    $DocumentData | Add-Member NoteProperty Size-KB([math]::Round($File.Length/1KB))
                                                        

                    # Add the result to an Array
                    $DocumentInventory += $DocumentData
                }

                # Export the result to a CSV file
                $DocumentInventory | Export-CSV $ReportOutput -NoTypeInformation -Append
                $Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition
            } While ($Query.ListItemCollectionPosition -ne $null)
        }

        # Iterate through each subsite of the current web and call the function recursively
        ForEach ($Subweb in $Web.Webs)
        {
            # Call the function recursively to process all subsites underneath the current web
            Get-SPODocumentInventory -SiteURL $Subweb.url
            Start-Sleep -Seconds 1  # Pause for each subsite
            }
    }
    ###########################################
        Catch {
         $ErrorMessage = "Error Generating Document Inventory for site $SiteURL and subsite $($Subweb.url)! $_.Exception.Message" 
        Write-Host -f Red $ErrorMessage

        # Log the error to a text file
        $ErrorLogPath = "C:\temp\ErrorLog.txt"
        $ErrorMessage | Out-File -FilePath $ErrorLogPath -Append   # 12/1
        Continue  # 12/1

        # Throw the error again to propagate it up the call stack
        throw $_
    }
}

    #############################################
      

# Config Parameters
#$SiteCollURL = "https://contoso.sharepoint.com"
$SiteCollURL = "https://contoso.sharepoint.com/sites/devtest"


$ReportOutput = "C:\temp\sites-inv.csv"
$BatchSize = 2000

<# Setup Credentials to connect manual
 $Cred = Get-Credential
 $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)#>


################################################################
# Setup Credentials to connect automated
$UserName="******@contoso.com"
$Password = "testingpwd123"
 
$SecurePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
$Cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $UserName, $SecurePassword #>
 
#####################################################################


# Delete the Output Report, if it exists
if (Test-Path $ReportOutput) { Remove-Item $ReportOutput }

# Call the function
Get-SPODocumentInventory $SiteCollURL

Microsoft 365 and Office | SharePoint | Development
Microsoft 365 and Office | SharePoint | For business | Windows
{count} votes

2 answers

Sort by: Most helpful
  1. Ling Zhou_MSFT 23,620 Reputation points Microsoft External Staff
    2023-12-20T01:50:02.45+00:00

    Hi @SR VSP,

    Thank you for your reply.

    Here Are the steps to fetch all the site owners for all the sites in the Tenant:

    1.Install the Azure AD Module

    2.Please try this SharePoint Online PowerShell:

    $AdminCenterURL = "https://Crescent-admin.sharepoint.com/"
    $CSVPath = "C:\Your Path\SiteOwners.csv"
      
    #Cred
    $UserName="******@Crescent.onmicrosoft.com"
    $Password = "Password"
    $SecurePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
    $Cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $UserName, $SecurePassword #>
     
    #Connect to SharePoint Online and Azure AD
    Connect-SPOService -url $AdminCenterURL -Credential $Cred
    Connect-AzureAD -Credential $Cred | Out-Null
    #Get all Site Collections
    $Sites = Get-SPOSite -Limit ALL
     
    $SiteOwners = @()
    #Get Site Owners for each site collection
    $Sites | ForEach-Object {
        If($_.Template -like 'GROUP*')
        {
            $Site = Get-SPOSite -Identity $_.URL
            #Get Group Owners
            $GroupOwners = (Get-AzureADGroupOwner -ObjectId $Site.GroupID | Select -ExpandProperty UserPrincipalName) -join "; "      
        }
        Else
        {
            $GroupOwners = $_.Owner
        }
        #Collect Data
        $SiteOwners += New-Object PSObject -Property @{
        'Site Title' = $_.Title
        'URL' = $_.Url
        'Owner(s)' = $GroupOwners
        }
    }
    #Get Site Owners
    $SiteOwners
     
    #Export Site Owners report to CSV
    $SiteOwners | Export-Csv -path $CSVPath -NoTypeInformation
    

    If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

  2. Ling Zhou_MSFT 23,620 Reputation points Microsoft External Staff
    2023-12-19T08:27:52.1833333+00:00

    Hi @SR VSP,

    Thank you for posting in this community.

    Please try this PnP PowerShell to get owner group members of a site:

    #Config Variables
    $AdminCenterURL = "https://crescent-admin.sharepoint.com/"
    $SiteURL="https://crescent.sharepoint.com/sites/SiteName"
    $GroupName= "Your Site Name Owners"
     
    #Connect to SharePoint Online
    Get-SPOUser -Site $SiteURL -Group $GroupName | Select DisplayName, LoginName | Export-csv -NoTypeInformation -Path "C:\Your Path\GroupUsers.csv"
    

    If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.