SPO.ps1
# Functions for SharePoint Online # Jul 17th 2019 function Get-SPOSiteGroups { <# .SYNOPSIS Gets list of groups of SharePoint Online site .DESCRIPTION Gets list of groups of SharePoint Online site the user has access to. .Parameter Site Url of the SharePoint site .Parameter AuthHeader SharePoint Online authentication header .Example PS C:\>$auth=Get-AADIntSPOAuthenticationHeader -Site https://company.sharepoint.com PS C:\>Get-AADIntSPOSiteGroups -Site https://company.sharepoint.com/sales -AuthHeader $auth #> [cmdletbinding()] Param( [Parameter(Mandatory=$True)] [String]$Site, [Parameter(Mandatory=$False)] [String]$AuthHeader, [Parameter(Mandatory=$False)] [String]$AccessToken ) Process { # Check the site url if($Site.EndsWith("/")) { $Site=$Site.Substring(0,$Site.Length-1) } $siteDomain=$Site.Split("/")[2] if(![string]::IsNullOrEmpty($AuthHeader)) { # Create a WebSession object $siteSession = Create-WebSession -SetCookieHeader $AuthHeader -Domain $siteDomain } else { # Get from cache if not provided $AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -Resource $site -ClientId "9bc3ab49-b65d-410a-85ad-de819febfddc" $headers=@{ "Authorization" = "Bearer $AccessToken" } } # Invoke the request $response=Invoke-WebRequest -UseBasicParsing -Uri "$Site/_api/web/sitegroups" -Method Get -WebSession $siteSession -ErrorAction SilentlyContinue -Headers $headers if($response.StatusCode -eq 200) { [xml]$response=$response.Content $users=New-Object System.Collections.ArrayList # Loop through the entries foreach($entry in $response.feed.entry) { $attributes = @{} $attributes["Id"] = $entry.content.properties.Id.'#Text' $attributes["IsHiddenInUI"] = $entry.content.properties.IsHiddenInUI.'#Text' -eq "true" $attributes["LoginName"] = $entry.content.properties.LoginName $attributes["Title"] = $entry.content.properties.Title $attributes["PrincipalType"] = $entry.content.properties.PrincipalType.'#Text' $attributes["OwnerTitle"] = $entry.content.properties.OwnerTitle $attributes["Description"] = $entry.content.properties.Description.'#Text' $attributes["AllowMembersEditMembership"] = $entry.content.properties.AllowMembersEditMembership.'#Text' -eq "true" $attributes["AllowRequestToJoinLeave"] = $entry.content.properties.AllowRequestToJoinLeave.'#Text' -eq "true" $attributes["AutoAcceptRequestToJoinLeave"] = $entry.content.properties.AutoAcceptRequestToJoinLeave.'#Text' -eq "true" $attributes["OnlyAllowMembersViewMembership"] = $entry.content.properties.OnlyAllowMembersViewMembership.'#Text' -eq "true" $users+=New-Object PSObject -Property $attributes } # Return return $users } } } # Jul 17th 2019 function Get-SPOSiteUsers { <# .SYNOPSIS Gets list of users of SharePoint Online site .DESCRIPTION Gets list of users of SharePoint Online site the user has access to. .Parameter Site Url of the SharePoint site .Parameter AuthHeader SharePoint Online authentication header .Example PS C:\>$auth=Get-AADIntSPOAuthenticationHeader -Site https://company.sharepoint.com PS C:\>Get-AADIntSPOSiteUsers -Site https://company.sharepoint.com/sales -AuthHeader $auth #> [cmdletbinding()] Param( [Parameter(Mandatory=$True)] [String]$Site, [Parameter(Mandatory=$False)] [String]$AuthHeader, [Parameter(Mandatory=$False)] [String]$AccessToken ) Process { # Check the site url if($Site.EndsWith("/")) { $Site=$Site.Substring(0,$Site.Length-1) } $siteDomain=$Site.Split("/")[2] if(![string]::IsNullOrEmpty($AuthHeader)) { # Create a WebSession object $siteSession = Create-WebSession -SetCookieHeader $AuthHeader -Domain $siteDomain } else { # Get from cache if not provided $AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -Resource "https://$Tenant.sharepoint.com/" -ClientId "9bc3ab49-b65d-410a-85ad-de819febfddc" $headers=@{ "Authorization" = "Bearer $AccessToken" } } # Invoke the request $response=Invoke-WebRequest -UseBasicParsing -Uri "$Site/_api/web/siteusers" -Method Get -WebSession $siteSession -Headers $headers -ErrorAction SilentlyContinue if($response.StatusCode -eq 200) { [xml]$response=$response.Content $users=New-Object System.Collections.ArrayList # Loop through the entries foreach($entry in $response.feed.entry) { $attributes = @{} $attributes["Id"] = $entry.content.properties.Id.'#Text' $attributes["IsHiddenInUI"] = $entry.content.properties.IsHiddenInUI.'#Text' -eq "true" $attributes["LoginName"] = $entry.content.properties.LoginName $attributes["Title"] = $entry.content.properties.Title $attributes["PrincipalType"] = $entry.content.properties.PrincipalType.'#Text' $attributes["Email"] = $entry.content.properties.Email $attributes["IsEmailAuthenticationGuestUser"] = $entry.content.properties.IsEmailAuthenticationGuestUser.'#Text' -eq "true" $attributes["IsShareByEmailGuestUser"] = $entry.content.properties.IsShareByEmailGuestUser.'#Text' -eq "true" $attributes["IsSiteAdmin"] = $entry.content.properties.IsSiteAdmin.'#Text' -eq "true" $attributes["NameId"] = $entry.content.properties.UserId.NameId $attributes["NameIdIssuer"] = $entry.content.properties.UserId.NameIdIssuer if($entry.content.properties.UserPrincipalName.GetType().Name -eq "String") { $attributes["UserPrincipalName"] = $entry.content.properties.UserPrincipalName } else { $attributes["UserPrincipalName"] = "" } $users+=New-Object PSObject -Property $attributes } # Return return $users } } } # Jul 18th 2019 function Get-SPOUserProperties { <# .SYNOPSIS Gets properties of SharePoint Online user .DESCRIPTION Gets properties of SharePoint Online user using PeopleManager API .Parameter Site Url of the SharePoint site .Parameter User SharePoint Online authentication header .Parameter AuthHeader LoginName of the user in format "i:0i.t|00000003-0000-0ff1-ce00-000000000000|app@sharepoint" .Example PS C:\>$auth=Get-AADIntSPOAuthenticationHeader -Site https://company.sharepoint.com PS C:\>Get-AADIntSPOUserProperties -Site https://company.sharepoint.com/sales -AuthHeader $auth -User "i:0i.t|00000003-0000-0ff1-ce00-000000000000|app@sharepoint" #> [cmdletbinding()] Param( [Parameter(Mandatory=$True)] [String]$Site, [Parameter(Mandatory=$True)] [String]$User, [Parameter(Mandatory=$True)] [String]$AuthHeader ) Process { # Check the site url if($Site.EndsWith("/")) { $Site=$Site.Substring(0,$Site.Length-1) } $User=$User.Replace("#","%23") $siteDomain=$Site.Split("/")[2] # Create a WebSession object $siteSession = Create-WebSession -SetCookieHeader $AuthHeader -Domain $siteDomain # Invoke the request $response=Invoke-WebRequest -UseBasicParsing -Uri "$Site/_api/sp.userprofiles.peoplemanager/getpropertiesfor(@v)?@v='$User'" -Method Get -WebSession $siteSession -ErrorAction SilentlyContinue if($response.StatusCode -eq 200) { [xml]$response=$response.Content $entry=$response.entry $attributes = [ordered]@{} $attributes["Updated"] = $response.entry.Updated $attributes["Author"] = $response.entry.Author.Name $properties = $response.entry.content.properties $attributes["AccountName"] = $properties.AccountName $attributes["DirectReports"] = Create-ListFromCollection $properties.DirectReports $attributes["DisplayName"] = $properties.DisplayName $attributes["Email"] = $properties.Email $attributes["ExtendedManagers"] = Create-ListFromCollection $properties.ExtendedManagers $attributes["ExtendedReports"] = Create-ListFromCollection $properties.ExtendedReports $attributes["IsFollowed"] = $properties.IsFollowed -eq "true" #$attributes["LatestPost"] = $properties.LatestPost $attributes["Peers"] = Create-ListFromCollection $properties.Peers #$attributes["PersonalSiteHostUrl"] = $properties.PersonalSiteHostUrl $attributes["PersonalUrl"] = [System.Net.WebUtility]::UrlDecode($properties.PersonalUrl) $attributes["PictureUrl"] = [System.Net.WebUtility]::UrlDecode($properties.PictureUrl) $attributes["UserUrl"] = [System.Net.WebUtility]::UrlDecode($properties.UserUrl) $attributes["Title"] = $properties.Title # Loop through the userprofile fields foreach($up in $properties.UserProfileProperties.Element) { $name = $up.Key $value = $up.Value $attributes[$name] = $value } # Return New-Object PSObject -Property $attributes } } } # Jun 10th 2020 function Get-SPOSiteUserProperties { <# .SYNOPSIS Gets the SPO user properties .DESCRIPTION Gets the SPO user properties .Parameter Site Url of the SharePoint site .Parameter AuthHeader SharePoint Online authentication header .Parameter AccessToken SharePoint Online Access Token .Example PS C:\>$auth=Get-AADIntSPOAuthenticationHeader -Site https://company.sharepoint.com PS C:\>Get-AADIntSPOSiteGroups -Site https://company.sharepoint.com/sales -AuthHeader $auth .Example PS C:\>$at=Get-AADIntAccessTokenForSPO PS C:\>Get-AADIntSPOSiteGroups -Site https://company.sharepoint.com/sales -AccessToken $at #> [cmdletbinding()] Param( [Parameter(Mandatory=$True)] [String]$Site, [Parameter(Mandatory=$True)] [String]$UserName, [Parameter(Mandatory=$False)] [String]$AuthHeader, [Parameter(Mandatory=$False)] [String]$AccessToken ) Process { # Check the site url if($Site.EndsWith("/")) { $Site=$Site.Substring(0,$Site.Length-1) } $siteDomain=$Site.Split("/")[2] # Check the username format if(!$UserName.StartsWith("i")) { $UserName="i:0%23.f|membership|$UserName" } if(![string]::IsNullOrEmpty($AuthHeader)) { # Create a WebSession object $siteSession = Create-WebSession -SetCookieHeader $AuthHeader -Domain $siteDomain } else { # Get from cache if not provided $AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -Resource "https://$Tenant.sharepoint.com/" -ClientId "9bc3ab49-b65d-410a-85ad-de819febfddc" $headers=@{ "Authorization" = "Bearer $AccessToken" } } # Invoke the request $response=Invoke-WebRequest -UseBasicParsing -Uri "$Site/_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=@v)?@v='$UserName'" -Method Get -WebSession $siteSession -ErrorAction SilentlyContinue -Headers $headers if($response.StatusCode -eq 200) { # Get the response [xml]$response=$response.Content # Create the attributes varialbe $attributes=@{} # Loop through the elements foreach($element in $response.entry.content.properties.UserProfileProperties.element) { $key=$element.Key $value=$element.Value $attributes[$key] = $value } # Sort by the key $attributes_sorted=[ordered]@{} $entries = $attributes.GetEnumerator() | sort Key foreach($entry in $entries) { $attributes_sorted[$entry.Name]=$entry.Value } # Return return New-Object psobject -Property $attributes_sorted } } } # Jun 10th 2020 function Set-SPOSiteUserProperty { <# .SYNOPSIS Sets the SPO user property .DESCRIPTION Sets the SPO user property .Parameter Site Url of the SharePoint site .Parameter AuthHeader SharePoint Online authentication header .Parameter AccessToken SharePoint Online Access Token .Parameter Property Property name .Parameter Value Property value .Example PS C:\>$auth=Get-AADIntSPOAuthenticationHeader -Site https://company.sharepoint.com PS C:\>Set-AADIntSPOUserProperty -Site https://company.sharepoint.com/sales -AuthHeader $auth -UserName user@company.com -Property "AboutMe" -Value "I'm a happy SPO user!" .Example PS C:\>$at=Get-AADIntAccessTokenForSPO PS C:\>Set-AADIntSPOUserProperty -Site https://company.sharepoint.com/sales -AccessToken $at -UserName user@company.com -Property "AboutMe" -Value "I'm a happy SPO user!" #> [cmdletbinding()] Param( [Parameter(Mandatory=$True)] [String]$Site, [Parameter(Mandatory=$True)] [String]$UserName, [Parameter(Mandatory=$False)] [String]$AuthHeader, [Parameter(Mandatory=$False)] [String]$AccessToken, [Parameter(Mandatory=$True)] [String]$Property, [Parameter(Mandatory=$False)] [String]$Value ) Process { # Get the digest #$digest = Get-SPODigest -AccessToken $AccessToken -Cookie $Cookie -Site $Site # Set the headers $headers=@{ # "X-RequestDigest" = $digest } # Check the site url if($Site.EndsWith("/")) { $Site=$Site.Substring(0,$Site.Length-1) } $siteDomain=$Site.Split("/")[2] # Check the username format if(!$UserName.StartsWith("i")) { $UserName="i:0#.f|membership|$UserName" } if(![string]::IsNullOrEmpty($AuthHeader)) { # Create a WebSession object $siteSession = Create-WebSession -SetCookieHeader $AuthHeader -Domain $siteDomain } else { # Get from cache if not provided $AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -Resource "https://$Tenant.sharepoint.com/" -ClientId "9bc3ab49-b65d-410a-85ad-de819febfddc" $headers["Authorization"] = "Bearer $AccessToken" } # Create the body $body=@{ "accountName" = "$UserName" "propertyName" = $Property "propertyValue" = $Value } # Invoke the request $response=Invoke-WebRequest -UseBasicParsing -Uri "$Site/_api/SP.UserProfiles.PeopleManager/SetSingleValueProfileProperty" -Method Post -WebSession $siteSession -ErrorAction SilentlyContinue -Headers $headers -ContentType "application/json" -Body ($body | ConvertTo-Json) if($response.StatusCode -eq 200) { # All good, nothing to return :) } } } function Get-SPOSettings { <# .SYNOPSIS Gets SharePoint Online settings .DESCRIPTION Gets SharePoint Online settings .Parameter AccessToken SharePoint Online Access Token .Parameter Tenant The tenant name of the organization, ie. company.onmicrosoft.com -> "company" .Example PS C:\>Get-AADIntAccessTokenForSPO -Admin -SaveToCache -Tenant company PS C:\>Get-AADIntSPOSettings -Tenant Company _ObjectType_ : Microsoft.Online.SharePoint.TenantAdministration.Tenant _ObjectIdentity_ : 4b09819f-80c3-b000-9cfe-8c850fbea6d5|908bed80-a04a-4433-b4a0-883d9847d110:908c17b8-5ebe-450c-9073-15e52aa1739b Tenant AIBuilderEnabled : False AIBuilderSiteInfoList : {} AIBuilderSiteList : {} AIBuilderSiteListFileName : AllowCommentsTextOnEmailEnabled : True AllowDownloadingNonWebViewableFiles : True AllowedDomainListForSyncClient : {} AllowEditing : True AllowGuestUserShareToUsersNotInSiteCollection : False AllowLimitedAccessOnUnmanagedDevices : False AllowSelectSGsInODBListInTenant : AnyoneLinkTrackUsers : False ApplyAppEnforcedRestrictionsToAdHocRecipients : True BccExternalSharingInvitations : False ... #> [cmdletbinding()] Param( [Parameter(Mandatory=$False)] [String]$AccessToken, [Parameter(Mandatory=$True)] [String]$Tenant ) Process { # Get from cache if not provided $AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -Resource "https://$Tenant-admin.sharepoint.com/" -ClientId "9bc3ab49-b65d-410a-85ad-de819febfddc" $body=@" <Request xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="Javascript Library"> <Actions> <ObjectPath Id="1" ObjectPathId="0" /> <Query Id="2" ObjectPathId="0"> <Query SelectAllProperties="true"> <Properties /> </Query> </Query> </Actions> <ObjectPaths> <Constructor Id="0" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /> </ObjectPaths> </Request> "@ $headers=@{ "Authorization" = "Bearer $AccessToken" } # Invoke the request $response=Invoke-RestMethod -UseBasicParsing -Uri "https://$Tenant-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery" -Method Post -Body $body -Headers $headers if($response.count -gt 4) { $response[4] } } } # Oct 1st 2022 by Sapir Fed function Set-SPOSiteMembers { <# .SYNOPSIS Add a member into a site (also adding the member to the correlated Azure AD group) .DESCRIPTION Add a member into a site (also adding the member to the correlated AzureAD group) .Parameter Site Url of the SharePoint site .Parameter AuthHeader SharePoint Online authentication header .Parameter SiteName Name of the specific site on SharePoint .Parameter UserPrincipalName UserPrincipalName of the AzureAD user you wish to add to the site .Example PS C:\>$auth=Get-AADIntSPOAuthenticationHeader -Site https://company.sharepoint.com PS C:\>Set-AADIntSPOSiteMembers -Site https://company.sharepoint.com -AuthHeader $auth -SiteName CompanyWiki -UserPrincipalName user@company.com User user@company.com was added to group CompanyWiki! #> [cmdletbinding()] Param( [Parameter(Mandatory=$True)] [String]$Site, [Parameter(Mandatory=$True)] [String]$AuthHeader, [Parameter(Mandatory=$True)] [String]$SiteName, [Parameter(Mandatory=$True)] [String]$UserPrincipalName ) Process { # Check the site url if($Site.EndsWith("/")) { $Site=$Site.Substring(0,$Site.Length-1) } $siteDomain=$Site.Split("/")[2] # Create a WebSession object $siteSession = Create-WebSession -SetCookieHeader $AuthHeader -Domain $siteDomain # Invoke the request tp get groupId and digest $response=Invoke-WebRequest -UseBasicParsing -Uri "$($Site)/sites/$($siteName)?sw=auth" -Method GET -WebSession $siteSession -ErrorAction SilentlyContinue -Headers $headers # Validate response $baseContent = $response.BaseResponse if($baseContent.StatusCode -eq "OK" -and $baseContent.ResponseUri -eq "$($Site)/sites/$($siteName)?sw=auth") { $requestContent = $response.Content # Parse digest $tempValue = $requestContent -match 'formDigestValue":"(.*?")' $digestTemp = $Matches[1] $digest = $digestTemp.Split('"')[0] $newheaders=@{ "X-RequestDigest" = $digest } # Parse groupId $tempValue = $requestContent -match 'groupId":"(.*?")' $groupidTemp = $Matches[1] $groupid = $groupidTemp.Split('"')[0] # Invoke the request to add a member to the SharePoint site $newresponse=Invoke-WebRequest -UseBasicParsing -Uri "$($Site)/sites/$($siteName)/_api/SP.Directory.DirectorySession/Group('$($groupid)')/Members/Add(objectId='00000000-0000-0000-0000-000000000000', principalName='$($UserPrincipalName)')" -Method POST -WebSession $siteSession -ErrorAction SilentlyContinue -Headers $newheaders -ContentType "application/json" # Validate response if($newresponse.StatusCode -eq 201 -and $newresponse.StatusDescription -eq "Created") { Write-Host "User $($UserPrincipalName) was added to group $($siteName)!" } else { Write-Error "Cannot Add user to the group." } } else { Write-Error "An error occurred while executing the request to the site." } } } |