├── Add-SiteCollectionAdminInODFB.ps1 ├── Create-CustomPermissionLevel.ps1 ├── Create-DocumentLibrary.ps1 ├── Create-FoldersAndSUBFoldersInODFB.ps1 ├── Get-AllTeamsUserIsPartOf.ps1 ├── Get-CheckedOutFiles.ps1 ├── Get-DeletedFilesInfo.ps1 ├── Get-EmptyFolders.ps1 ├── Get-LargeFiles.ps1 ├── Get-LikesAndCommentsCountFromPages.ps1 ├── Get-ListItemAttachmentNames.ps1 ├── Get-MSTeamsReport.ps1 ├── Get-MissingMetadataInSite.ps1 ├── Get-NestedFoldersAndFiles.ps1 ├── Get-NestedFoldersAndFilesForOneDocLib.ps1 ├── Get-ODFBUrlFromCsvFile.ps1 ├── Get-SitePolicy.ps1 ├── Get-SitesAndSubsites.ps1 ├── Get-SpecificFiles.ps1 ├── Get-TeamsInfo.ps1 ├── LICENSE ├── New-FolderPerMonth.ps1 ├── New-FolderPerMonthWithNumber.ps1 ├── README.md ├── Remove-SiteCollectionAdminFromODFB.ps1 ├── Request-SPOPersonalSiteWithCsvFile.ps1 ├── Set-UserODFBStorageUsingCSVFile.ps1 └── Split-SPODataIntoTwoColumns.ps1 /Add-SiteCollectionAdminInODFB.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | This script will ADD a second Site Collection Admin (SCA) on each users' Onedrive For Business in Office 365. 4 | .DESCRIPTION 5 | Script will add a second Site Collection Admin (SCA) on each users' ODFB in O365. 6 | Script will NOT override other SCA on user's ODFB - simply add the SCA mentioned under "$SecondAdmin" parameter. 7 | 8 | +++ IMPORTANT +++ The .CSV file needs to contain a column with header titled "OneDriveUrl" 9 | 10 | .EXAMPLE 11 | .\Add-SiteCollectionAdminInODFB.ps1 -TenantName -AdminAcct -SecondAdmin <2nd_SCA_acct> -ODFBCsvFile 12 | .EXAMPLE 13 | .\Add-SiteCollectionAdminInODFB.ps1 (if no parameters are entered, you will be prompted for them) 14 | 15 | ========================================== 16 | Author: Veronique Lengelle (@VeronicaGeek) 17 | Date: 02 Jan 2017 18 | Version: 1.0 19 | ========================================== 20 | #> 21 | [CmdletBinding()] 22 | param( 23 | [Parameter(Mandatory=$true,HelpMessage="This is the name of the O365 tenant",Position=1)] 24 | [string]$TenantName, 25 | [Parameter(Mandatory=$true,HelpMessage="This is the O365 Admin account to log into the tenant",Position=2)] 26 | [string]$AdminAcct, 27 | [Parameter(Mandatory=$true,HelpMessage="This is the account to ADD on each ODFB",Position=3)] 28 | [string]$SecondAdmin, 29 | [Parameter(Mandatory=$true,HelpMessage="This is the CSV file containing the ODFB Urls",Position=4)] 30 | [string]$ODFBCsvFile 31 | ) 32 | # URL for your organization's SPO admin service 33 | $AdminURI = "https://$TenantName-admin.sharepoint.com" 34 | 35 | #Import Urls 36 | $UrlLocation = Import-Csv $ODFBCsvFile 37 | 38 | #Connect to SPO 39 | Connect-SPOService -Url $AdminURI -Credential $AdminAcct 40 | Write-Host "Connected to SharePoint Online" -f Green 41 | 42 | foreach($Url in $UrlLocation){ 43 | $CorrectSitePath = ($Url.OneDriveUrl).trimend("/") 44 | Set-SPOUser -Site $CorrectSitePath -LoginName $SecondAdmin -IsSiteCollectionAdmin $true 45 | } 46 | 47 | Write-Host "Account $SecondAdmin added." -f Green 48 | -------------------------------------------------------------------------------- /Create-CustomPermissionLevel.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Create custom permission level 4 | .DESCRIPTION 5 | Create a custom permission level in SharePoint Online 6 | .EXAMPLE 7 | PS C:\> .\Create-CustomPermissionLevel.ps1 8 | This will start the script and create a copy of the READ perm. level in the sites defined in your CSV file. 9 | .INPUTS 10 | Inputs (if any) 11 | .OUTPUTS 12 | Output (if any) 13 | .NOTES 14 | PLEASE REFER TO MY BLOG POST FOR MORE INFO ABOUT THE SCRIPT + ITS PURPOSE FOR YOUR BUSINESS NEEDS. 15 | https://veronicageek.com/office-365/sharepoint-online/create-custom-permissions-for-multiple-site-collections-in-spo-using-powershell-pnp/2019/05/ 16 | #> 17 | #Connect to SPO admin center --> Change to your TENANT NAME 18 | $creds = Get-Credential 19 | Connect-PnPOnline -Url https://-admin.sharepoint.com -Credentials $creds 20 | 21 | #Import sites from .csv --> Change to your filepath 22 | $mySites = Import-Csv -Path 'YOUR_FILE_PATH_LOCATION' 23 | 24 | #Create all for each site 25 | foreach ($site in $mySites) { 26 | 27 | #Connect to each site 28 | Write-Host "Connecting to $($site.SiteUrl)" -ForegroundColor Green 29 | Connect-PnPOnline -Url $site.SiteUrl 30 | 31 | #Create the NEW permission level (clone the 'READ' default permissions) 32 | $PermToClone = Get-PnPRoleDefinition -Identity "Read" 33 | $addPnPRoleDefinitionSplat = @{ 34 | Include = 'ManagePersonalViews', 'UpdatePersonalWebParts', 'AddDelPrivateWebParts' 35 | Description = "Copy of Read + Personal Permissions" 36 | RoleName = "myCustomPermLevel" 37 | Clone = $PermToClone 38 | } 39 | Add-PnPRoleDefinition @addPnPRoleDefinitionSplat 40 | } -------------------------------------------------------------------------------- /Create-DocumentLibrary.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Create a document library using SharePoint PnP. 4 | .DESCRIPTION 5 | This script will create a document library under the site collection you decide to connect to, and will display on the Quick Launch. 6 | .EXAMPLE 7 | .\Create-DocumentLibrary.ps1 -SiteCollection -LibraryName 8 | .EXAMPLE 9 | .\Create-DocumentLibrary.ps1 -SiteCollection https://.sharepoint.com/sites/test -LibraryName "My New Library" 10 | .NOTES 11 | This script is using SharePoint Practices & Patterns (PnP). For more information please refer to the official documentation 12 | located here: https://msdn.microsoft.com/en-us/pnp_powershell/pnp-powershell-overview 13 | 14 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 15 | +++ PRE-REQS +++ Download and install the SharePoint PnP modules: https://github.com/SharePoint/PnP-PowerShell 16 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 17 | 18 | #> 19 | [CmdletBinding()] 20 | Param 21 | ( 22 | [Parameter(Mandatory=$true,Position=1)] 23 | [string]$SiteCollection, 24 | [Parameter(Mandatory=$true,Position=2)] 25 | [string]$LibraryName 26 | ) 27 | try{ 28 | #Connect to SPO Site Collection 29 | Connect-PnPOnline -Url $SiteCollection -Credentials (Get-Credential) -ErrorAction Stop 30 | } 31 | catch{ 32 | Write-Error "Site Collection or Credentials not valid. Please check again." 33 | break 34 | } 35 | 36 | New-PnPList -Title $LibraryName -Template DocumentLibrary -OnQuickLaunch 37 | 38 | #Show lists/libraries in the Site Collection 39 | Get-PnPList 40 | -------------------------------------------------------------------------------- /Create-FoldersAndSUBFoldersInODFB.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | This script will create 2 folders + 2 sub-folders into each users' ODFB provided in a CSV file. 4 | .DESCRIPTION 5 | This script will create 2 folders + 2 sub-folders into each users' ODFB provided in a CSV file and will be called FOLDER1 and FOLDER2, but you can add more if wanted. 6 | 7 | +++ PRE-REQUISITES +++ 8 | >> The .CSV file needs to contain a column with header titled "UserPrincipalName" 9 | >> SharePoint Online SDK Components and SPO Management Shell installed on the machine running the script 10 | >> The account provided in the variable $AdminAccount needs to be added as Site Collection Admin to each ODFB PRIOR to running this script (in order to have permission to create the folders) 11 | 12 | .EXAMPLE 13 | .\Create-FoldersAndSUBFoldersInODFB.ps1 -AdminAccount -SPOAcct -TenantName -CsvFileLocation 14 | .EXAMPLE 15 | .\Create-FoldersAndSUBFoldersInODFB.ps1 (if no parameters are entered, you will be prompted for them) 16 | 17 | ========================================== 18 | Author: Veronique Lengelle (@VeronicaGeek) 19 | Date: 03 Jan 2017 20 | Version: 1.0 21 | ========================================== 22 | #> 23 | [CmdletBinding()] 24 | param( 25 | [Parameter(Mandatory=$true,HelpMessage="This is the Admin account to connect to SPO to run the script",Position=1)] 26 | [string]$AdminAcct, 27 | [Parameter(Mandatory=$true,HelpMessage="This is the Admin account added as a SCA on each ODFB",Position=2)] 28 | [string]$SPOAcct, 29 | [Parameter(Mandatory=$true,HelpMessage="This is the O365 tenant name",Position=3)] 30 | [string]$TenantName, 31 | [Parameter(Mandatory=$true,HelpMessage="This is the location of the CSV file containing all the users",Position=4)] 32 | [string]$CsvFileLocation 33 | ) 34 | #Script started at 35 | $startTime = "{0:G}" -f (Get-date) 36 | Write-Host "*** Script started on $startTime ***" -f White -b DarkYellow 37 | 38 | #Loading assemblies 39 | [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client") 40 | [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime") 41 | [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.UserProfiles") 42 | 43 | #Declare Variables 44 | $Password = Read-Host -Prompt "Please enter your O365 Admin password" -AsSecureString 45 | $Users = Import-Csv -Path $CsvFileLocation 46 | 47 | 48 | ForEach ($User in $Users) { 49 | $creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($AdminAcct,$Password) 50 | 51 | #Split UPN in 2 parts 52 | $SplitUPN = ($User.UserPrincipalName).IndexOf("@") 53 | $Left = ($User.UserPrincipalName).Substring(0, $SplitUPN) 54 | $Right = ($User.UserPrincipalName).Substring($SplitUPN+1) 55 | 56 | #Get the username without the @domain.com part 57 | $shortUserName = ($User.UserPrincipalName) -replace "@"+$Right 58 | 59 | #Modify the UPN to replace dot by underscore to match perso URL 60 | $ShortUPNUnderscore = $shortUserName.Replace(".","_") 61 | 62 | Write-Host "** Creating folders for"$user.UserPrincipalName -f Yellow 63 | 64 | #Transform domain with underscore to match perso URL 65 | $DomainUnderscore = $Right.Replace(".", "_") 66 | 67 | #Use the $shortUsername to build the full path 68 | $spoOD4BUrl = ("https://$TenantName-my.sharepoint.com/personal/"+ $ShortUPNUnderscore + "_"+ $DomainUnderscore) 69 | Write-Host ("URL is: " + $spoOD4BUrl) -f Gray 70 | 71 | $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($spoOD4BUrl) 72 | $ctx.RequestTimeout = 16384000 73 | $ctx.Credentials = $creds 74 | $ctx.ExecuteQuery() 75 | 76 | $web = $ctx.Web 77 | $ctx.Load($web) 78 | 79 | #Target the Document library in user's ODFB 80 | $spoDocLibName = "Documents" 81 | $spoList = $web.Lists.GetByTitle($spoDocLibName) 82 | $ctx.Load($spoList.RootFolder) 83 | 84 | #Create FOLDER1 85 | $spoFolder = $spoList.RootFolder 86 | $Folder1 = "FOLDER1" 87 | $newFolder = $spoFolder.Folders.Add($Folder1) 88 | $web.Context.Load($newFolder) 89 | $web.Context.ExecuteQuery() 90 | 91 | #Create 2x SUB-Folders in FOLDER1 92 | $SubFolder1 = "SubFolder1" 93 | $newSubFolder1 = $newFolder.Folders.Add($SubFolder1) 94 | $web.Context.Load($newSubFolder1) 95 | $web.Context.ExecuteQuery() 96 | 97 | $SubFolder2 = "SubFolder2" 98 | $newSubFolder2 = $newFolder.Folders.Add($SubFolder2) 99 | $web.Context.Load($newSubFolder2) 100 | $web.Context.ExecuteQuery() 101 | 102 | 103 | #Create FOLDER2 104 | $Folder2 = "FOLDER2" 105 | $newFolder2 = $spoFolder.Folders.Add($Folder2) 106 | $web.Context.Load($newFolder2) 107 | $web.Context.ExecuteQuery() 108 | 109 | 110 | #Create 2x SUB-Folders in FOLDER2 111 | $SubFolder3 = "SubFolder3" 112 | $newSubFolder3 = $newFolder2.Folders.Add($SubFolder3) 113 | $web.Context.Load($newSubFolder3) 114 | $web.Context.ExecuteQuery() 115 | 116 | $SubFolder4 = "SubFolder4" 117 | $newSubFolder4 = $newFolder2.Folders.Add($SubFolder4) 118 | $web.Context.Load($newSubFolder4) 119 | $web.Context.ExecuteQuery() 120 | } 121 | 122 | Write-Host "Folders created " -f Green 123 | 124 | #Script finished at 125 | $endTime = "{0:G}" -f (Get-date) 126 | Write-Host "*** Script finished on $endTime ***" -f White -b DarkYellow 127 | Write-Host "Time elapsed: $(New-Timespan $startTime $endTime)" -f White -b DarkRed 128 | 129 | -------------------------------------------------------------------------------- /Get-AllTeamsUserIsPartOf.ps1: -------------------------------------------------------------------------------- 1 | # This script will retrieve all Teams a user is part of (including the role) 2 | # MORE INFO on my Blog Post: https://veronicageek.com/powershell/powershell-for-o365/get-all-teams-a-user-is-part-of-using-powershell-pnp/2020/10/ 3 | #################################################################################################################################################### 4 | 5 | #Connect to Teams & Azure AD 6 | Connect-PnPOnline -Scopes "Group.ReadWrite.All" -Credentials "" 7 | 8 | #Log file to export results 9 | $logFile = "C:\users\$env:USERNAME\desktop\AllTeamsUserIn.csv" 10 | 11 | #Store all the Teams 12 | $allTeams = Get-PnPTeamsTeam 13 | $results = @() 14 | 15 | $userToFind = "user123@domain.com" 16 | $userToFindInAD = Get-PnPAADUser | Where-Object ({ $_.UserPrincipalName -match $userToFind }) 17 | $userToFindID = $userToFindInAD.Id 18 | 19 | 20 | #Loop through the TEAMS 21 | foreach ($team in $allTeams) { 22 | $allTeamsUsers = (Get-PnPTeamsUser -Team $team.DisplayName) 23 | 24 | #Loop through users TARGETING THE USER ID TO MATCH 25 | foreach ($teamUser in $allTeamsUsers) { 26 | if ($teamUser.Id -match $userToFindID) { 27 | 28 | $results += [pscustomobject]@{ 29 | userName = $userToFindInAD.UserPrincipalName 30 | userDisplayName = $userToFindInAD.DisplayName 31 | userRole = $teamUser.UserType 32 | Team = $team.DisplayName 33 | teamVisibility = $team.Visibility 34 | } 35 | } 36 | } 37 | } 38 | $results | Export-Csv -Path $logFile -NoTypeInformation 39 | 40 | -------------------------------------------------------------------------------- /Get-CheckedOutFiles.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Get the checked out files. 4 | .DESCRIPTION 5 | Get the checked out files from multiple sites in SharePoint Online. 6 | Provide a CSV file with all your sites, and the script will loop through each sites and document libraries. 7 | .EXAMPLE 8 | PS C:\> .\Get-CheckedOutFiles.ps1 9 | Retrieve a list of all documents currently checked out in the sites you provided in the CSV, with the name of the person it's checked out to. 10 | .INPUTS 11 | Inputs (if any) 12 | .OUTPUTS 13 | Output (if any) 14 | .NOTES 15 | Your CSV file must contain headers called "SiteUrl" (full URL of the site) and "SiteName" (Name of your site) for this script. 16 | Or change to your own & modify the script accordingly. 17 | #> 18 | #Start Time 19 | $startTime = "{0:G}" -f (Get-date) 20 | Write-Host "*** Script started on $startTime ***" -f Black -b DarkYellow 21 | 22 | # +++ CHANGE TO YOUR VALUES +++ 23 | $tenantName = "" 24 | $sitesCSV = "> | Where-Object {($_.Title -like "documen*")} 40 | 41 | foreach ($list in $allLists) { 42 | $allDocs = (Get-PnPListItem -List $list) 43 | 44 | foreach ($doc in $allDocs) { 45 | 46 | if ($null -ne $doc.FieldValues.CheckoutUser.LookupValue) { 47 | $result += [PSCustomObject][ordered]@{ 48 | Site = $site.SiteName 49 | Library = $list.Title 50 | FileName = $doc["FileLeafRef"] 51 | CheckedOutTo = $doc.FieldValues.CheckoutUser.LookupValue 52 | FullLocation = $doc["FileRef"] 53 | } 54 | } 55 | } 56 | } 57 | } 58 | $result | Export-Csv -Path $logFile -NoTypeInformation 59 | 60 | #End Time 61 | $endTime = "{0:G}" -f (Get-date) 62 | Write-Host "*** Script finished on $endTime ***" -f Black -b DarkYellow 63 | Write-Host "Time elapsed: $(New-Timespan $startTime $endTime)" -f White -b DarkRed 64 | -------------------------------------------------------------------------------- /Get-DeletedFilesInfo.ps1: -------------------------------------------------------------------------------- 1 | Connect-PnPOnline -Url "https://.sharepoint.com/sites/" -Credentials 2 | 3 | $allDeletedItems = Get-PnPRecycleBinItem 4 | $results = @() 5 | 6 | foreach($item in $allDeletedItems){ 7 | $userID = (Get-PnPAzureADUser | Where-Object {$_.DisplayName -match $item.DeletedByName}).Id 8 | 9 | $results += [pscustomobject]@{ 10 | fileName = $item.LeafName 11 | deletedBy = $item.DeletedByName 12 | deletedDate = $item.DeletedDate 13 | userID = $userID 14 | } 15 | } 16 | $results 17 | -------------------------------------------------------------------------------- /Get-EmptyFolders.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Get empty folders. 4 | .DESCRIPTION 5 | Get the empty folders from a specific SharePoint Online site. 6 | .EXAMPLE 7 | PS C:\> .\Get-EmptyFolders.ps1 8 | This script will retrieve all the empty folders from a specific site collection in SharePoint Online 9 | .INPUTS 10 | Inputs (if any) 11 | .OUTPUTS 12 | Output (if any) 13 | .NOTES 14 | More info on my blog post: https://veronicageek.com/office-365/sharepoint-online/find-empty-folders-in-a-sharepoint-site-using-powershell-pnp/2020/02/ 15 | #> 16 | #Connect to SPO 17 | Connect-PnPOnline -Url "https://.sharepoint.com/sites/" 18 | 19 | #Store in variable all the document libraries in the site 20 | $DocLibrary = Get-PnPList | Where-Object { $_.BaseTemplate -eq 101 } 21 | $LogFile = "C:\users\$env:USERNAME\Desktop\SPOEmptyFolders.csv" 22 | 23 | $results = @() 24 | foreach ($DocLib in $DocLibrary) { 25 | #Get list of all folders in the document library 26 | $AllItems = Get-PnPListItem -PageSize 1000 -List $DocLib -Fields "SMTotalFileStreamSize", "Author" 27 | 28 | #Loop through each files/folders in the document library for >50Mb 29 | foreach ($Item in $AllItems) { 30 | if ((([uint64]$Item["SMTotalFileStreamSize"]) -eq 0)) { 31 | Write-Host "Empty folder:" $Item["FileLeafRef"] -ForegroundColor Yellow 32 | 33 | #Creating new object to export in .csv file 34 | $results += [pscustomobject][ordered] @{ 35 | CreatedDate = [DateTime]$Item["Created_x0020_Date"] 36 | FileName = $Item["FileLeafRef"] 37 | CreatedBy = $Item.FieldValues.Author.LookupValue 38 | FilePath = $Item["FileRef"] 39 | SizeInMB = ($Item["SMTotalFileStreamSize"] / 1MB).ToString("N") 40 | LastModifiedBy = $Item.FieldValues.Editor.LookupValue 41 | EditorEmail = $Item.FieldValues.Editor.Email 42 | LastModifiedDate = [DateTime]$Item["Modified"] 43 | } 44 | }#end of IF statement 45 | } 46 | } 47 | $results | Export-Csv -Path $LogFile -NoTypeInformation -------------------------------------------------------------------------------- /Get-LargeFiles.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Get large files. 4 | .DESCRIPTION 5 | Get large files in SharePoint Online. 6 | .EXAMPLE 7 | PS C:\> .\Get-Largefiles.ps1 8 | This script will retrieve large files in SharePoint Online (i.e.: >50Mb) 9 | .INPUTS 10 | Inputs (if any) 11 | .OUTPUTS 12 | Output (if any) 13 | .NOTES 14 | More info on my blog post: https://veronicageek.com/office-365/sharepoint-online/retrieve-files-bigger-than-50mb-in-a-sharepoint-online-site-using-powershell-pnp/2019/04/ 15 | #> 16 | #Connect to SPO --->> CHANGE TO YOUR TENANT NAME & SITE 17 | Connect-PnPOnline -Url "https://.sharepoint.com/sites/" 18 | 19 | #Store in variable all the document libraries in the site 20 | $DocLibrary = Get-PnPList | Where-Object { $_.BaseTemplate -eq 101 } 21 | $LogFile = "C:\users\$env:USERNAME\Desktop\SPOLargeFiles.csv" 22 | 23 | $results = @() 24 | foreach ($DocLib in $DocLibrary) { 25 | #Get list of all folders in the document library 26 | $AllItems = Get-PnPListItem -List $DocLib -Fields "SMTotalFileStreamSize" 27 | 28 | #Loop through each files/folders in the document library for >50Mb 29 | foreach ($Item in $AllItems) { 30 | if ((([int]$Item["SMTotalFileStreamSize"]) -ge 50000000) -and ($Item["FileLeafRef"] -like "*.*")) { 31 | Write-Host "File found:" $Item["FileLeafRef"] -ForegroundColor Yellow 32 | 33 | #Creating new object to export in .csv file 34 | $results += [pscustomobject] @{ 35 | FileName = $Item["FileLeafRef"] 36 | FilePath = $Item["FileRef"] 37 | SizeInMB = ($Item["SMTotalFileStreamSize"] / 1MB).ToString("N") 38 | LastModifiedBy = $Item.FieldValues.Editor.LookupValue 39 | EditorEmail = $Item.FieldValues.Editor.Email 40 | LastModifiedDate = [DateTime]$Item["Modified"] 41 | } 42 | }#end of IF statement 43 | } 44 | } 45 | $results | Export-Csv -Path $LogFile -NoTypeInformation -------------------------------------------------------------------------------- /Get-LikesAndCommentsCountFromPages.ps1: -------------------------------------------------------------------------------- 1 | #Connect to SPO site 2 | Connect-PnPOnline -Url "https://.sharepoint.com/sites/" 3 | 4 | #Store pages into a variable 5 | $sitePagesGallery = Get-PnPList -Identity "Site Pages" 6 | 7 | #Export to a file 8 | $logFile = "C:\users\$env:USERNAME\Desktop\LikesAndComments.csv" 9 | 10 | #Get the pages details 11 | $results = @() 12 | 13 | foreach ($item in $sitePagesGallery) { 14 | $allPages = Get-PnPListItem -List $sitePagesGallery -Fields "FileLeafRef", "Title", "ID", "FileRef", "_CommentCount", "_LikeCount" 15 | 16 | #Choose the properties to export 17 | foreach ($page in $allPages) { 18 | $results += New-Object -TypeName psobject -Property @{ 19 | Title = $page["Title"] 20 | ID = $page.ID 21 | FullPath = $page["FileRef"] 22 | NumOfComments = $page["_CommentCount"] 23 | NumOfLikes = $page["_LikeCount"] 24 | } 25 | } 26 | } 27 | $results | Export-Csv -Path $logFile -NoTypeInformation 28 | -------------------------------------------------------------------------------- /Get-ListItemAttachmentNames.ps1: -------------------------------------------------------------------------------- 1 | #Connect to SPO --> CHANGE TO YOUR TENANT NAME & SITE 2 | Connect-PnPOnline -Url https://.sharepoint.com/sites/ 3 | 4 | #Variables 5 | $results = @() 6 | $allLists = Get-PnPList | Where-Object { $_.BaseTemplate -eq 100 } 7 | 8 | #Loop thru each lists 9 | foreach ($list in $allLists) { 10 | $allItems = Get-PnPListItem -List $list.Title 11 | 12 | #Loop thru thru each item in the list(s) 13 | foreach ($item in $allItems) { 14 | $allProps = Get-PnPProperty -ClientObject $item -Property "AttachmentFiles" 15 | 16 | #Loop thru each property and grab the ones we want! 17 | foreach ($prop in $allProps) { 18 | $results += [pscustomobject][ordered]@{ 19 | ListName = $list.Title 20 | ItemName = $item["Title"] 21 | ItemCreatedBy = $item.FieldValues.Author.LookupValue 22 | ItemLastModifiedBy = $item.FieldValues.Editor.LookupValue 23 | AttachmentNames = $prop.FileName 24 | ServerRelativeUrl = $prop.ServerRelativeUrl 25 | } 26 | } 27 | } 28 | } 29 | $results | Export-Csv -Path "" -NoTypeInformation -------------------------------------------------------------------------------- /Get-MSTeamsReport.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Create a report for Microsoft Teams. 4 | .DESCRIPTION 5 | This script will create a report for Microsoft Teams. 6 | .NOTES 7 | Make sure you have the correct permissions from a AzureAD app perspective, as well as the correct permissions from an M365/Teams admin perspective. 8 | This script is also using the "ImportExcel" module, which can be found here: https://www.powershellgallery.com/packages/ImportExcel/7.8.1 9 | .EXAMPLE 10 | Get-MSTeamsReport -TenantName contoso 11 | This will generate a report for the tenant "contoso" and save it to the path specified in the $reportLocation variable (currently set to the user's Desktop). 12 | #> 13 | 14 | function Get-MSTeamsReport { 15 | [CmdletBinding()] 16 | param ( 17 | [Parameter(Mandatory=$true, HelpMessage="Your tenant name (e.g. contoso)")] 18 | [string]$TenantName 19 | ) 20 | 21 | #Report placed onto the user's desktop 22 | $reportLocation = "C:\Users\$env:USERNAME\Desktop\" 23 | $startTime = Get-Date -Format MM-dd-yyyy-HH-mm-ss 24 | $TeamsDataFile = $reportLocation + "MSTeamsReport_$TenantName_$startTime.xlsx" 25 | 26 | #Get the MS Teams information 27 | Write-Host "Retrieving the information. Be patient..." -ForegroundColor Yellow 28 | 29 | $TeamsData = @() 30 | $allTeams = Get-PnPTeamsTeam 31 | 32 | foreach($team in $allTeams){ 33 | $TeamsData += [pscustomobject][ordered] @{ 34 | DisplayName = $team.DisplayName 35 | GroupId = $team.GroupId 36 | Owners = (Get-PnPTeamsUser -Team $team.GroupId -Role Owner).UserPrincipalName -Join ";" 37 | Visibility = $team.Visibility 38 | NbOfChannels = (Get-PnPTeamsChannel -Team $team.DisplayName).Count #Includes Private Channels! 39 | IsArchived = $team.IsArchived 40 | } 41 | } 42 | 43 | #Creating the workbook in a variable called "$myWorkbook" 44 | $myWorkbook = $TeamsData | Export-Excel -Path $TeamsDataFile -WorksheetName "TeamsReportData" -AutoSize -AutoFilter -BoldTopRow -FreezeTopRow -PassThru 45 | 46 | #Formatting the "NbOfChannels" with RED bkgrd if >= 100 47 | $TeamsDataWS = $myWorkbook.Workbook.Worksheets["TeamsReportData"] 48 | Set-Format -WorkSheet $TeamsDataWS -Range "E2:E550000" -NumberFormat "0" -AutoFit 49 | Add-ConditionalFormatting -WorkSheet $TeamsDataWS -Range "E2:E550000" -RuleType GreaterThanOrEqual -ConditionValue '100' -ForeGroundColor White -BackgroundColor "Red" 50 | Set-CellStyle -WorkSheet $TeamsDataWS -LastColumn 1 -Pattern Solid -Color LightGray 51 | 52 | #Exporting the data 53 | Export-Excel -ExcelPackage $myWorkbook -Show 54 | 55 | Write-Host "Report created : $TeamsDataFile" -ForegroundColor Cyan 56 | } 57 | 58 | #Run the function 59 | Get-MSTeamsReport -TenantName contoso 60 | -------------------------------------------------------------------------------- /Get-MissingMetadataInSite.ps1: -------------------------------------------------------------------------------- 1 | #Connect to SPO 2 | Connect-PnPOnline -Url "https://.sharepoint.com/sites/" -Credentials 3 | 4 | #variables 5 | $allLibs = Get-PnPList 6 | $results = @() 7 | 8 | foreach($lib in $allLibs){ 9 | $allDocs = Get-PnPListItem -List $lib 10 | 11 | foreach($doc in $allDocs){ 12 | $allRequiredFields = Get-PnPField -List $lib | Where-Object {$_.Required -eq $true} #Giving an array 13 | 14 | foreach($field in $allRequiredFields){ 15 | if ($null -eq $doc.FieldValues["$($field.InternalName)"]) { 16 | 17 | $results += [pscustomobject]@{ 18 | FileName = $doc.FieldValues.FileLeafRef 19 | CreatedBy = $doc.FieldValues.Author.LookupValue 20 | MissingMetadata = $field.Title 21 | FileLocation = $lib.Title 22 | } 23 | } 24 | } 25 | } 26 | } 27 | $results 28 | -------------------------------------------------------------------------------- /Get-NestedFoldersAndFiles.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Export info from a SharePoint site. 4 | .DESCRIPTION 5 | This script will loop through a Site Collection & export the number of nested folders, files count, folder size (and more) from all document libraries. 6 | .EXAMPLE 7 | PS C:\> .\Get-NestedFoldersAndFiles.ps1 8 | .INPUTS 9 | Inputs (if any) 10 | .OUTPUTS 11 | System.Object[] 12 | .NOTES 13 | How to use this script is available on my blog at: 14 | https://veronicageek.com/sharepoint/sharepoint-2013/get-nested-folders-files-count-folder-size-and-more-in-spo-document-libraries-using-powershell-pnp/2019/09/ 15 | #> 16 | #Connect to SPO -- Change to your tenant name and site 17 | Connect-PnPOnline -Url "https://.sharepoint.com/sites/" 18 | 19 | #Target multiple lists 20 | $allLists = Get-PnPList | Where-Object { $_.BaseTemplate -eq 101 } 21 | 22 | #Store the results 23 | $results = @() 24 | 25 | foreach ($row in $allLists) { 26 | $allItems = Get-PnPListItem -List $row.Title -Fields "FileLeafRef", "SMTotalFileStreamSize", "FileDirRef", "FolderChildCount", "ItemChildCount" 27 | 28 | foreach ($item in $allItems) { 29 | 30 | #Narrow down to folder type only 31 | if (($item.FileSystemObjectType) -eq "Folder") { 32 | $results += New-Object psobject -Property @{ 33 | FileType = $item.FileSystemObjectType #This will return a column with "Folder" 34 | RootFolder = $item["FileDirRef"] 35 | LibraryName = $row.Title 36 | FolderName = $item["FileLeafRef"] 37 | FullPath = $item["FileRef"] 38 | FolderSizeInMB = ($item["SMTotalFileStreamSize"] / 1MB).ToString("N") 39 | NbOfNestedFolders = $item["FolderChildCount"] 40 | NbOfFiles = $item["ItemChildCount"] 41 | } 42 | } 43 | } 44 | } 45 | #Export the results 46 | $results | Export-Csv -Path "C:\Users\$env:USERNAME\Desktop\NestedFoldersForMULTIPLEdoclibs.csv" -NoTypeInformation 47 | -------------------------------------------------------------------------------- /Get-NestedFoldersAndFilesForOneDocLib.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Export info from a SharePoint site. 4 | .DESCRIPTION 5 | This script will loop through the specific document library & export the number of nested folders, files count, folder size (and more). 6 | .EXAMPLE 7 | PS C:\> .\Get-NestedFoldersAndFilesForOneDocLib.ps1 8 | .INPUTS 9 | Inputs (if any) 10 | .OUTPUTS 11 | System.Object[] 12 | .NOTES 13 | How to use this script is available on my blog at: 14 | https://veronicageek.com/sharepoint/sharepoint-2013/get-nested-folders-files-count-folder-size-and-more-in-spo-document-libraries-using-powershell-pnp/2019/09/ 15 | #> 16 | #Connect to SPO -- Change to your tenant name and site 17 | Connect-PnPOnline -Url "https://.sharepoint.com/sites/" 18 | 19 | #Target a specific lists -- Change to YOUR OWN LIST NAME 20 | $myList = "/Shared Documents" 21 | 22 | #Store the results 23 | $results = @() 24 | 25 | foreach ($row in $myList) { 26 | $allItems = Get-PnPListItem -List $myList -Fields "FileLeafRef", "SMTotalFileStreamSize", "FileDirRef", "FolderChildCount", "ItemChildCount" 27 | 28 | foreach ($item in $allItems) { 29 | 30 | #Narrow down to folder type only 31 | if (($item.FileSystemObjectType) -eq "Folder") { 32 | $results += New-Object psobject -Property @{ 33 | FileType = $item.FileSystemObjectType #This will return a column with "Folder" 34 | RootFolder = $item["FileDirRef"] 35 | LibraryName = $myList 36 | FolderName = $item["FileLeafRef"] 37 | FullPath = $item["FileRef"] 38 | FolderSizeInMB = ($item["SMTotalFileStreamSize"] / 1MB).ToString("N") 39 | NbOfNestedFolders = $item["FolderChildCount"] 40 | NbOfFiles = $item["ItemChildCount"] 41 | } 42 | } 43 | } 44 | } 45 | #Export the results 46 | $results | Export-Csv -Path "C:\Users\$env:USERNAME\Desktop\NestedFoldersForONEdoclib.csv" -NoTypeInformation 47 | -------------------------------------------------------------------------------- /Get-ODFBUrlFromCsvFile.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Retrieve user's OneDrive for Business URL if provisioned. 4 | .DESCRIPTION 5 | This script will retrieve the user's OneDrive for Business URL in Office 365 (if they have been provisioned) looping through the names on your Csv file. 6 | If the OneDrive for Business has not been provisioned (URL not available), then it won't appear on the output file. 7 | .EXAMPLE 8 | .\Get-ODFBUrlFromCsvFile.ps1 -AdminAccount -CsvFileLocation 9 | .EXAMPLE 10 | .\Get-ODFBUrlFromCsvFile.ps1 (if no parameters are entered, you will be prompted for them) 11 | .INPUTS 12 | Csv File 13 | .OUTPUTS 14 | A Csv file will be created and placed on the desktop for easy access (called Provisioned_ODFBUrl.csv). 15 | .NOTES 16 | - The input file (your Csv file with users) MUST contain a header column named "UserPrincipalName". 17 | - This script uses CSOM so the SharePoint Online SDK components need to be installed prior to running this script. 18 | ** Download available from the official Microsoft website: https://www.microsoft.com/en-gb/download/details.aspx?id=42038 19 | #> 20 | [CmdletBinding()] 21 | param( 22 | [Parameter(Mandatory=$true,HelpMessage="Office 365 Admin account with correct permissions",Position=1)] 23 | [string]$AdminAccount, 24 | [Parameter(Mandatory=$true,HelpMessage="Office 365 tenant name",Position=2)] 25 | [string]$TenantName, 26 | [Parameter(Mandatory=$true,HelpMessage="Location of the CSV file containing all the users to check",Position=3)] 27 | [string]$CsvFileLocation 28 | ) 29 | #Configure Site URL and User 30 | $SiteURL = "https://$TenantName-my.sharepoint.com" 31 | 32 | #Add references to SharePoint client assemblies and authenticate to O365 site required for CSOM 33 | Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll" 34 | Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll" 35 | Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.UserProfiles.dll" 36 | 37 | $Password = Read-Host -Prompt "Please enter your Password" -AsSecureString 38 | $Creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($AdminAccount,$Password) 39 | 40 | #Bind to Site Collection 41 | $Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL) 42 | $Context.Credentials = $Creds 43 | 44 | #Identify users in the Site Collection 45 | $Users = $Context.Web.SiteUsers 46 | $Context.Load($Users) 47 | $Context.ExecuteQuery() 48 | 49 | #Create People Manager object to retrieve profile data 50 | $PeopleManager = New-Object Microsoft.SharePoint.Client.UserProfiles.PeopleManager($Context) 51 | 52 | #Import Csv file and match with users from tenant 53 | $csv = Import-Csv $CsvFileLocation 54 | $csvlist = $csv.UserPrincipalName -join "|" 55 | $users = $Users.LoginName | Where-Object {$_ -match $csvlist} 56 | 57 | Foreach ($User in $Users) 58 | { 59 | $UserProfile = $PeopleManager.GetPropertiesFor($User) 60 | $Context.Load($UserProfile) 61 | $Context.ExecuteQuery() 62 | If ($UserProfile.Email -ne $null) 63 | { 64 | #Write-Host "User:" $User.UserPrincipalName -ForegroundColor Green 65 | $UserProfile.UserProfileProperties 66 | #Write-Host "" 67 | } 68 | } 69 | 70 | #Create People Manager object to retrieve profile data 71 | $Output = "C:\users\$env:USERNAME\Desktop\Provisioned_ODFBUrl.csv" 72 | 73 | #Format the Csv output file 74 | $Headings = "UserPrincipalName","OneDriveURL" 75 | $Headings -join "," | Out-File -Encoding default -FilePath $Output 76 | 77 | $PeopleManager = New-Object Microsoft.SharePoint.Client.UserProfiles.PeopleManager($Context) 78 | Foreach ($User in $Users) 79 | { 80 | $UserProfile = $PeopleManager.GetPropertiesFor($User) 81 | $Context.Load($UserProfile) 82 | $Context.ExecuteQuery() 83 | If ($UserProfile.Email -ne $null) 84 | { 85 | $UPP = $UserProfile.UserProfileProperties 86 | $Properties = $UPP.'SPS-UserPrincipalName',$UserProfile.PersonalUrl 87 | $Properties -join "," | Out-File -Encoding default -Append -FilePath $Output 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Get-SitePolicy.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Get site policies in SharePoint Online. 4 | .DESCRIPTION 5 | Get all the site policies for each site collections in SharePoint Online. 6 | .EXAMPLE 7 | PS C:\> .\Get-SitePolicy.ps1 8 | This command will retrieve all the site policies for each site collections on the tenant (access to the site collection required) 9 | .INPUTS 10 | Inputs (if any) 11 | .OUTPUTS 12 | Output (if any) 13 | .NOTES 14 | More detail on my blog post: https://veronicageek.com/sharepoint/sharepoint-2013/retrieve-site-policies-in-sharepoint-online-using-powershell-pnp/2018/08/ 15 | #> 16 | #Connect to SPO (creds in the Credential Manager) 17 | Connect-PnPOnline -Url "https://-admin.sharepoint.com" 18 | 19 | #Get all the site policies 20 | $Results = @() 21 | $AllSC = Get-PnPTenantSite 22 | 23 | foreach ($sc in $AllSC) { 24 | Write-Host "Connecting to" $sc.Url -ForegroundColor Green 25 | Try { 26 | Connect-PnPOnline -Url ($sc).Url -Credentials $creds -ErrorAction Stop 27 | $Policy = Get-PnPSitePolicy 28 | $SCProps = @{ 29 | Url = $sc.Url 30 | Name = $Policy.Name 31 | Description = $Policy.Description 32 | } 33 | $Results += New-Object PSObject -Property $SCProps 34 | } 35 | catch { 36 | Write-Host "You don't have access to this Site Collection" -ForegroundColor Red 37 | } 38 | 39 | } #end foreach 40 | $Results | Select-Object Url, Name, Description 41 | -------------------------------------------------------------------------------- /Get-SitesAndSubsites.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | This script will retrieve site collections and subsites. 4 | .DESCRIPTION 5 | This script will retrieve all Site Collections and subsites (top level) and export to a .csv file on the user's desktop. 6 | .INPUTS 7 | Inputs (if any) 8 | .OUTPUTS 9 | System.Object[] 10 | .NOTES 11 | This script uses the SharePoint PnP module: https://github.com/SharePoint/PnP-PowerShell 12 | #> 13 | #Connect to SPO admin center -- CHANGE TO YOUR TENANT NAME 14 | $creds = Get-Credential 15 | Connect-PnPOnline -Url https://.sharepoint.com -Credentials $creds 16 | 17 | #Get all Site Collections in tenant + subsites 18 | $results = @() 19 | $allMySites = Get-PnPTenantSite 20 | 21 | foreach ($SC in $allMySites) { 22 | Write-Host "Connecting to $($SC.Url)" -ForegroundColor Green 23 | try { 24 | Connect-PnPOnline -Url $SC.Url -Credentials $creds 25 | 26 | $SiteColTitle = $SC.Title 27 | $SiteColUrl = $SC.Url 28 | $Subsites = Get-PnPSubWebs 29 | 30 | $Properties = @{ 31 | SiteColName = $SiteColTitle 32 | SiteColUrl = $SiteColUrl 33 | SubsiteName = ($Subsites.Title | Out-String).Trim() 34 | SubsiteUrl = ($Subsites.ServerRelativeUrl | Out-String).Trim() 35 | } 36 | $results += New-Object psobject -Property $Properties 37 | } 38 | catch { 39 | Write-Host "You don't have access to this Site Collection." -ForegroundColor Red 40 | } 41 | } 42 | $results | Select-Object SiteColName, SiteColUrl, SubsiteName, SubsiteUrl | Export-Csv -Path "C:\Users\$env:USERNAME\Desktop\SitesAndSubsites.csv" -NoTypeInformation 43 | -------------------------------------------------------------------------------- /Get-SpecificFiles.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Export specific files from a site. 4 | .DESCRIPTION 5 | This script will export specific files from a site, looping through each document libraries. 6 | .EXAMPLE 7 | PS C:\> Get-SpecificFiles.ps1 8 | .INPUTS 9 | Inputs (if any) 10 | .OUTPUTS 11 | Output (if any) 12 | .NOTES 13 | This script uses SharePoint PowerShell PnP available on Github: 14 | https://github.com/SharePoint/PnP-PowerShell 15 | 16 | Using this script is detailed in my blog post located here: 17 | https://veronicageek.com/office-365/sharepoint-online/retrieve-files-with-a-specific-name-in-a-sharepoint-online-site-using-powershell-pnp/2019/06/ 18 | #> 19 | 20 | #Connect to SPO 21 | $creds = Get-Credential 22 | Connect-PnPOnline -Url https://.sharepoint.com/sites/ -Credentials $creds ### Change to your specific site ### 23 | 24 | #Output path 25 | $outputPath = "C:\users\$env:USERNAME\Desktop\specificFiles.csv" 26 | 27 | #Store in variable all the document libraries in the site 28 | $DocLibs = Get-PnPList | Where-Object { $_.BaseTemplate -eq 101 } 29 | 30 | #Loop thru each document library & folders 31 | $results = @() 32 | foreach ($DocLib in $DocLibs) { 33 | $AllItems = Get-PnPListItem -List $DocLib -Fields "FileRef", "File_x0020_Type", "FileLeafRef" 34 | 35 | #Loop through each item 36 | foreach ($Item in $AllItems) { 37 | ## Change *ABC* and *BCD* to your own requirements 38 | if (($Item["FileLeafRef"] -like "*ABC*") -or ($Item["FileLeafRef"] -like "*BCD*")) { 39 | Write-Host "File found. Path:" $Item["FileRef"] -ForegroundColor Green 40 | 41 | #Creating new object to export in .csv file 42 | $results += New-Object PSObject -Property @{ 43 | Path = $Item["FileRef"] 44 | FileName = $Item["FileLeafRef"] 45 | FileExtension = $Item["File_x0020_Type"] 46 | } 47 | } 48 | } 49 | } 50 | $results | Export-Csv -Path $outputPath -NoTypeInformation 51 | -------------------------------------------------------------------------------- /Get-TeamsInfo.ps1: -------------------------------------------------------------------------------- 1 | ## This script will report on each Team the following info: Teams names, Privacy settings, Channel names, and Tab names 2 | ## MORE INFO on my blog post: https://veronicageek.com/powershell/powershell-for-o365/get-teams-channels-tabs-and-privacy-settings-using-teams-pnp-powershell/2020/07/ 3 | ####################################################################################################################################################################### 4 | 5 | # Connect to Teams PnP 6 | Connect-PnPOnline -Scopes "Group.ReadWrite.All" -Credentials "" 7 | 8 | #Store variables 9 | $results = @() 10 | $allTeams = Get-PnPTeamsTeam 11 | 12 | #Loop through each Team 13 | foreach($team in $allTeams){ 14 | $allChannels = Get-PnPTeamsChannel -Team $team.DisplayName 15 | 16 | #Loop through each Channel 17 | foreach($channel in $allChannels){ 18 | $allTabs = Get-PnPTeamsTab -Team $team.DisplayName -Channel $channel 19 | 20 | #Loop through each Tab + get the info! 21 | foreach($tab in $allTabs){ 22 | $results += [pscustomobject][ordered]@{ 23 | Team = $team.DisplayName 24 | Visibility = $team.Visibility 25 | ChannelName = $channel.DisplayName 26 | tabName = $tab.DisplayName 27 | } 28 | } 29 | } 30 | } 31 | $results | Export-Csv -Path "C:\users\$env:USERNAME\Desktop\TeamsTabs.csv" -NoTypeInformation 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 VeronicaGeek 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /New-FolderPerMonth.ps1: -------------------------------------------------------------------------------- 1 | #This function will create a folder per month in the site & library of your choice 2 | ################################################################################### 3 | 4 | function New-FolderPerMonth { 5 | [CmdletBinding()] 6 | param ( 7 | [Parameter(Mandatory = $true, HelpMessage = "Site Url to connect to", Position = 0)] 8 | [string]$SiteUrl, 9 | [Parameter(Mandatory = $true, HelpMessage = "List to create the folders in", Position = 1)] 10 | [string]$Library 11 | ) 12 | #Connect to the designated site 13 | Connect-PnPOnline -Url $SiteUrl 14 | 15 | #Create the folders 16 | for ($i = 1; $i -le 12; $i++) { 17 | Add-PnPFolder -Name (Get-Culture).DateTimeFormat.GetMonthName($i) -Folder $Library 18 | } 19 | } 20 | 21 | New-FolderPerMonth -SiteUrl "https://.sharepoint.com/sites/" -Library "" 22 | -------------------------------------------------------------------------------- /New-FolderPerMonthWithNumber.ps1: -------------------------------------------------------------------------------- 1 | #This function will create a folder per month with the number in from of it, in the site & library of your choice 2 | #MORE INFO ON MY BLOG: https://veronicageek.com/powershell/powershell-for-o365/create-folders-with-months-name-in-sharepoint-online-using-powershell-pnp/2020/10/ 3 | ##################################################################################################################### 4 | 5 | function New-FolderPerMonthWithNumber { 6 | [CmdletBinding()] 7 | param ( 8 | [Parameter(Mandatory = $true, HelpMessage = "Site Url to connect to", Position = 0)] 9 | [string]$SiteUrl, 10 | [Parameter(Mandatory = $true, HelpMessage = "List to create the folders in", Position = 1)] 11 | [string]$Library 12 | ) 13 | #Connect to the designated site 14 | Connect-PnPOnline -Url $SiteUrl 15 | 16 | #Create the folders 17 | foreach ($monthsNumber in @(1..12)) { 18 | $monthNumFormatted = "{0:d2}" -f $monthsNumber 19 | 20 | Add-PnPFolder -Name ($monthNumFormatted + "_" + (Get-Culture).DateTimeFormat.GetMonthName($monthNumFormatted)) -Folder $Library 21 | 22 | } 23 | } 24 | 25 | New-FolderPerMonthWithNumber -SiteUrl "https://.sharepoint.com/sites/" -Library "" 26 | 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # O365_SPO_PowerShellScripts 2 | PowerShell scripts related to SharePoint Online in Microsoft 365 3 | -------------------------------------------------------------------------------- /Remove-SiteCollectionAdminFromODFB.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | This script will REMOVE a second Site Collection Admin (SCA) from each users' ODFB 4 | .DESCRIPTION 5 | Script will REMOVE a second Site Collection Admin (SCA) from each users' ODFB. 6 | Script will NOT override other SCA on user's ODFB - simply REMOVE the SCA mentioned below under "$SecondAdmin" 7 | 8 | +++ IMPORTANT +++ The .CSV file needs to contain a column with header titled "OneDriveUrl" 9 | 10 | .EXAMPLE 11 | .\Remove-SiteCollectionAdminFromODFB.ps1 -TenantName -AdminAcct -SecondAdmin <2nd_SCA_acct> -ODFBCsvFile 12 | .EXAMPLE 13 | .\Remove-SiteCollectionAdminFromODFB.ps1 (if no parameters are entered, you will be prompted for them) 14 | 15 | ========================================== 16 | Author: Veronique Lengelle (@VeronicaGeek) 17 | Date: 02 Jan 2017 18 | Version: 1.0 19 | ========================================== 20 | #> 21 | [CmdletBinding()] 22 | param( 23 | [Parameter(Mandatory=$true,HelpMessage="This is the name of the O365 tenant",Position=1)] 24 | [string]$TenantName, 25 | [Parameter(Mandatory=$true,HelpMessage="This is the O365 Admin account to log into the tenant",Position=2)] 26 | [string]$AdminAcct, 27 | [Parameter(Mandatory=$true,HelpMessage="This is the account to ADD on each ODFB",Position=3)] 28 | [string]$SecondAdmin, 29 | [Parameter(Mandatory=$true,HelpMessage="This is the CSV file containing the ODFB Urls",Position=4)] 30 | [string]$ODFBCsvFile 31 | ) 32 | # URL for your organization's SPO admin service 33 | $AdminURI = "https://$TenantName-admin.sharepoint.com" 34 | 35 | #Import Urls 36 | $UrlLocation = Import-Csv $ODFBCsvFile 37 | 38 | #Connect to SPO 39 | Connect-SPOService -Url $AdminURI -Credential $AdminAcct 40 | Write-Host "Connected to SharePoint Online" -f Green 41 | 42 | foreach($Url in $UrlLocation){ 43 | $CorrectSitePath = ($Url.OneDriveUrl).trimend("/") 44 | Set-SPOUser -Site $CorrectSitePath -LoginName $SecondAdmin -IsSiteCollectionAdmin $false 45 | } 46 | 47 | Write-Host "Account $SecondAdmin removed." -f Green 48 | -------------------------------------------------------------------------------- /Request-SPOPersonalSiteWithCsvFile.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | This script will pre-provision users' ODFB in O365 contained in a CSV file. 4 | .DESCRIPTION 5 | This script will pre-provision users' ODFB in O365 from a CSV file where there's a MSFT hard limit of 200 users. 6 | ** MORE INFO: https://technet.microsoft.com/en-us/library/dn792367.aspx ** 7 | 8 | +++ IMPORTANT +++ The .CSV file needs to contain a column with header titled "UserPrincipalName" 9 | 10 | .EXAMPLE 11 | .\Request-SPOPersonalSiteWithCsvFile.ps1 -TenantName -CsvFileLocation 12 | .EXAMPLE 13 | .\Request-SPOPersonalSiteWithCsvFile.ps1 (if no parameters are entered, you will be prompted for them) 14 | #> 15 | [CmdletBinding()] 16 | param( 17 | [Parameter(Mandatory=$true,HelpMessage="This is the name of the O365 tenant",Position=1)] 18 | [string]$TenantName, 19 | [Parameter(Mandatory=$true,HelpMessage="This is the location of the CSV file containing all the users to check",Position=2)] 20 | [string]$CsvFileLocation 21 | ) 22 | #Script started at 23 | $startTime = "{0:G}" -f (Get-date) 24 | Write-Host "*** Script started on $startTime ***" -f White -b DarkYellow 25 | 26 | #Connect to SPO 27 | $O365Cred = Get-Credential 28 | Connect-SPOService -Url https://$TenantName-admin.sharepoint.com -Credential $O365Cred 29 | Write-host "Connected to SPO. Starting the provisioning process..." -f Yellow 30 | 31 | #Pre-provision ODFB 32 | $emails = Import-Csv $CsvFileLocation 33 | 34 | foreach ($UserPrincipalName in $emails){ 35 | Request-SPOPersonalSite -UserEmails $emails.UserPrincipalName -NoWait 36 | } 37 | 38 | Write-Host "All done." -f Green 39 | 40 | #Script finished at 41 | $endTime = "{0:G}" -f (Get-date) 42 | Write-Host "*** Script finished on $endTime ***" -f White -b DarkYellow 43 | Write-Host "Time elapsed: $(New-Timespan $startTime $endTime)" -f White -b DarkRed 44 | -------------------------------------------------------------------------------- /Set-UserODFBStorageUsingCSVFile.ps1: -------------------------------------------------------------------------------- 1 | ## This script will change the user's ODFB storage quota and quota warning using the CSV file YOU provide, and export the users having issues. 2 | ## MORE INFO ON MY BLOG POST: https://veronicageek.com/microsoft-365/onedrive-for-business/change-specific-users-onedrive-for-business-default-storage-quota-using-powershell-pnp-with-error-handling-for-different-outcomes/2020/10/ 3 | ######################################################################################################################## 4 | 5 | #Connect to SPO 6 | Connect-PnPOnline -Url "https://-admin.sharepoint.com" 7 | 8 | #Import CSV file with usernames 9 | $usernames = Import-Csv -Path "" 10 | 11 | #Results for storing the users not found (or not provisioned) 12 | $results = @() 13 | $logFile = "C:\users\$env:USERNAME\Desktop\usersNotFound.csv" 14 | 15 | #Script 16 | foreach($user in $usernames){ 17 | try{ 18 | Set-PnPUserOneDriveQuota -Account $user.username -Quota $user.newQuota -QuotaWarning $user.newWarning -ErrorAction Stop | Out-Null 19 | } 20 | 21 | catch [Microsoft.SharePoint.Client.ServerException] { 22 | Write-Host "User not found: $($user.username)" -ForegroundColor Cyan 23 | Write-Warning $error[0] 24 | 25 | if ($error[0].Exception -like "*Unknown Error*"){ 26 | $results += [pscustomobject]@{ 27 | userNotFound = $user.username 28 | ODFBProvisioned = "No" 29 | userInTenant = "Yes" 30 | } 31 | } 32 | else { 33 | $results += [pscustomobject]@{ 34 | userNotFound = $user.username 35 | ODFBProvisioned = "N/A" 36 | userInTenant = "No" 37 | } 38 | } 39 | } 40 | } 41 | $results | Export-Csv -Path $logFile -NoTypeInformation 42 | -------------------------------------------------------------------------------- /Split-SPODataIntoTwoColumns.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Split data into 2 columns. 4 | .DESCRIPTION 5 | Split data from one (1) column into two (2) columns. 6 | .INPUTS 7 | Inputs (if any) 8 | .OUTPUTS 9 | Output (if any) 10 | .NOTES 11 | This script works well combined with a Power Automate flow for new items created in the list. 12 | In this example, we take the column FullName, and split it into 2 columns (FirstName + LastName) 13 | 14 | More details on my blog post: https://veronicageek.com/office-365/sharepoint-online/split-data-into-2-columns-in-spo-using-powershell-pnp-and-use-power-automate-for-new-items/2019/11/ 15 | #> 16 | 17 | #Connect to SPO 18 | Connect-PnPOnline -Url "https://.sharepoint.com/sites/" 19 | 20 | #Store your list into a variable 21 | $myList = Get-PnPList -Identity "" 22 | 23 | 24 | #Get all items from the list + Store the results 25 | $results = @() 26 | $allItems = Get-PnPListItem -List $myList -Fields "FullName", "FirstName", "LastName" 27 | foreach ($item in $allItems) { 28 | $splitFullName = $item["FullName"].Split(" ") 29 | $FirstNameSplit = $splitFullName[0] 30 | $LastNameSplit = $splitFullName[1] 31 | 32 | $results += [pscustomobject][ordered]@{ 33 | FullName = $item["FullName"] 34 | FirstName = $item["FirstName"] 35 | LastName = $item["LastName"] 36 | } 37 | #Modify each current item in the list 38 | Set-PnPListItem -List "Clients" -Identity $item -Values @{"FirstName" = $FirstNameSplit; "LastName" = $LastNameSplit } 39 | } 40 | $results 41 | 42 | --------------------------------------------------------------------------------