Forum Discussion

MubinAbd123's avatar
MubinAbd123
Copper Contributor
Aug 23, 2023

PowerShell script for SharePoint Audit

Hi all,

I've been trying to run a script on PowerShell that will loop through each site on my company SharePoint and get all the users in each site and their user permission for the site (read, write, owner, etc.).

Initially I ran this script:

#Site collection URL
$AdminSiteURL = "my site"
$CSVPath = "my path"

#Connect to SharePoint Online Admin Center
Connect-PnPOnline -Url $AdminSiteURL -UseWebLogin

#Array to store group data from all site collections
$AllGroupsData = @()

#Get all site collections in the SharePoint environment
$SiteCollections = Get-PnPTenantSite

#Loop through each site collection
foreach ($SiteCollection in $SiteCollections) {
$SiteURL = $SiteCollection.Url
Write-Host "Processing Site Collection: $SiteURL"

#Connect to the current site collection
Connect-PnPOnline -Url $SiteURL -UseWebLogin

#Get All Groups from the site collection - Exclude Hidden, Limited Access, and SharingLinks Groups
$Groups = Get-PnPSiteGroup | Where { $_.LoginName -notlike "Limited Access*" -and $_.LoginName -notlike "SharingLinks*"}

$GroupsData = @()
foreach ($Group in $Groups) {
$GroupsData += New-Object PSObject -Property @{
'Group Name' = $Group.Title
'Permissions' = $Group.Roles -join ","
'Users' = $Group.Users -join ","
}
}

#Add the group data of the current site collection to the array for all site collections
$AllGroupsData += $GroupsData
}

#Export the data to CSV
$AllGroupsData | Export-Csv $CSVPath -NoTypeInformation

Write-Host "Group data for all site collections has been exported to: $CSVPath"


This returned the permissions of some users that were on the site but not part of the site group. For the the users who were part of the site group, they showed up on the report as GUID's like this ('4cbc76d6-7da9-42bb-a403-85594b1a4cf9').

I then edited the script to display user names instead of GUID's using this script:

#Site collection URL
$AdminSiteURL = "my site"
$CSVPath = "my path"

#Connect to SharePoint Online Admin Center
Connect-PnPOnline -Url $AdminSiteURL -UseWebLogin

#Array to store group data from all site collections
$AllGroupsData = @()

#Get all site collections in the SharePoint environment
$SiteCollections = Get-PnPTenantSite

#Loop through each site collection
foreach ($SiteCollection in $SiteCollections) {
$SiteURL = $SiteCollection.Url
Write-Host "Processing Site Collection: $SiteURL"

#Connect to the current site collection
Connect-PnPOnline -Url $SiteURL -UseWebLogin

#Get All Groups from the site collection - Exclude Hidden, Limited Access, and SharingLinks Groups
$Groups = Get-PnPSiteGroup | Where { $_.LoginName -notlike "Limited Access*" -and $_.LoginName -notlike "SharingLinks*"}

$GroupsData = @()
foreach ($Group in $Groups) {
$Users = $Group.Users | ForEach-Object {
$UserGUID = $_.Id
$User = Get-PnPUserProfileProperty -Account $UserGUID -PropertyName 'PreferredName'
$User.PreferredName
}

$GroupsData += New-Object PSObject -Property @{
'Group Name' = $Group.Title
'Permissions' = $Group.Roles -join ","
'Users' = $Users -join ","
}
}

#Add the group data of the current site collection to the array for all site collections
$AllGroupsData += $GroupsData
}

#Export the data to CSV
$AllGroupsData | Export-Csv $CSVPath -NoTypeInformation

Write-Host "Group data for all site collections has been exported to: $CSVPath"

 

However, this resulted in the users showing up as commas on the report like this ',' or ',,'. 

My understanding is that this suggests that there might be an issue with how the user data is being processed and concatenated and that it's possible that the '$Group.Users' array contains empty or null values, leading to these commas in the output.

If anyone could provide me with any information on how I could resolve this, I would be very grateful. 

  • LeonPavesic's avatar
    LeonPavesic
    Silver Contributor

    Hi MubinAbd123,

    It's good that you've attempted to convert user GUIDs to user names, but it seems there might still be a hiccup in how the user data is processed. Your approach of using Get-PnPUserProfileProperty for each user to fetch the 'PreferredName' property is solid, but it could be failing for some reason. Here's how you can enhance that part of your script:

     

    $Users = $Group.Users | ForEach-Object {
        $UserGUID = $_.Id
        $User = Get-PnPUserProfileProperty -Account $UserGUID -PropertyName 'PreferredName'
        if ($User -ne $null) {
            $User.PreferredName
        }
    }

     

    By adding an if condition to check if the user data is not null before attempting to extract the preferred name, you can prevent empty or null values from causing issues.

    Empty Values Resulting in Commas: The commas you're seeing in the output are likely due to empty values in the $Users array. When you join an array using .Join(","), empty values can lead to those extra commas. The improvement you made in the previous step should help with this as well.

    By filtering out null or empty values using the if condition, you should be able to avoid these unnecessary commas.

    Give this revised version a shot, and it should help you handle the user GUID to user name conversion and prevent empty values from causing those extra commas in the output.

     

    # Site collection URL
    $AdminSiteURL = "my site"
    $CSVPath = "my path"
    
    # Connect to SharePoint Online Admin Center
    Connect-PnPOnline -Url $AdminSiteURL -UseWebLogin
    
    # Array to store group data from all site collections
    $AllGroupsData = @()
    
    # Get all site collections in the SharePoint environment
    $SiteCollections = Get-PnPTenantSite
    
    # Loop through each site collection
    foreach ($SiteCollection in $SiteCollections) {
        $SiteURL = $SiteCollection.Url
        Write-Host "Processing Site Collection: $SiteURL"
    
        # Connect to the current site collection
        Connect-PnPOnline -Url $SiteURL -UseWebLogin
    
        # Get All Groups from the site collection - Exclude Hidden, Limited Access, and SharingLinks Groups
        $Groups = Get-PnPSiteGroup | Where { $_.LoginName -notlike "Limited Access*" -and $_.LoginName -notlike "SharingLinks*" }
    
        $GroupsData = @()
        foreach ($Group in $Groups) {
            $Users = $Group.Users | ForEach-Object {
                $UserGUID = $_.Id
                $User = Get-PnPUserProfileProperty -Account $UserGUID -PropertyName 'PreferredName'
                if ($User -ne $null) {
                    $User.PreferredName
                }
            }
    
            $GroupsData += New-Object PSObject -Property @{
                'Group Name' = $Group.Title
                'Permissions' = $Group.Roles -join ","
                'Users' = $Users -join ","
            }
        }
    
        # Add the group data of the current site collection to the array for all site collections
        $AllGroupsData += $GroupsData
    }
    
    # Export the data to CSV
    $AllGroupsData | Export-Csv $CSVPath -NoTypeInformation
    
    Write-Host "Group data for all site collections has been exported to: $CSVPath"

     

     

    Please click Mark as Best Response & Like if my post helped you to solve your issue.
    This will help others to find the correct solution easily. It also closes the item.


    If the post was useful in other ways, please consider giving it Like.


    Kindest regards,


    Leon Pavesic

Share