REST
SharePoint RestShow Users List
On 28/10/2025

let currentSort = { column: null, direction: 'asc' }; // Store the current sort state
// Creates the style element
function createStyleElement(id, content) {
var style = document.createElement("style");
style.type = "text/css";
style.id = id;
style.innerHTML = content;
if (style.styleSheet) {
style.styleSheet.cssText = content;
} else {
let st = document.getElementById(id);
if (st == undefined) {
var head = document.head || document.getElementsByTagName("head")[i];
head.appendChild(style);
} else {
st.innerHTML = content;
}
}
return style;
}
// Function to filter the table based on dropdown selection
function filterTable(columnIndex, value) {
let table, tr, td, i, select, selectedValue, txtValue;
table = document.querySelector("table");
tr = table.getElementsByTagName("tbody")[0].getElementsByTagName("tr");
select = table.getElementsByTagName("select")[columnIndex];
//debugger;
selectedValue = value;
// Loop through all table rows and hide those that don't match the filter
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[columnIndex];
if (td) {
txtValue = td.textContent || td.innerText;
if (selectedValue === "" || txtValue === selectedValue) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
function sortTable(columnIndex, direction) {
let table, rows, switching, i, x, y, shouldSwitch;
table = document.querySelector("table");
switching = true;
let tbody = table.querySelector("tbody");
// Set the current sort state
currentSort.column = columnIndex;
currentSort.direction = direction;
while (switching) {
switching = false;
rows = tbody.rows;
for (i = 0; i < rows.length - 1; i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("td")[columnIndex];
y = rows[i + 1].getElementsByTagName("td")[columnIndex];
let isNumber = false;
if (!isNaN(x.innerHTML)) {
// Check if rows should switch based on ascending or descending order
if (direction === 'asc') {
if (parseFloat(x.innerHTML) > parseFloat(y.innerHTML)) {
shouldSwitch = true;
break;
}
} else if (direction === 'desc') {
if (parseFloat(x.innerHTML) < parseFloat(y.innerHTML)) {
shouldSwitch = true;
break;
}
}
}
else {
// Check if rows should switch based on ascending or descending order
if (direction === 'asc') {
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
} else if (direction === 'desc') {
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
}
}
}
// Function to generate the table
function generateTableFromJson2(jsonArray, select, addHeaders = true) {
const style = `
body{
background-color: #f8f8f8;
}
.parentDiv{
height:400px;
overflow-x:scroll;
white-space: nowrap;
}
ul
{
list-style-type: none;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 8px 12px;
text-align: left;
border: 1px solid #ddd;
}
tbody tr{
max-height: 15px;
}
th {
background-color: #f4f4f4;
color: #000;
}
/* Scrollable table wrapper */
.table-wrapper {
height: 800px;
overflow-y: auto;
border: 1px solid #ddd;
overflow-x:scroll;
}
/* Style for dropdowns in header */
select {
width: 100%;
padding: 4px;
margin-top: 5px;
}
/* Style for the sorting arrows */
.sort-arrows {
cursor: pointer;
margin-left: 5px;
}
`;
createStyleElement("fdiStyle", style);
// Create table element
let table = document.createElement('table');
// Create table header
let header = table.createTHead();
let headerRow = header.insertRow(0);
// Get keys (headers) from the first object in the JSON array
//let keys = Object.keys(jsonArray[0]);
let keys = select.split(",");
if (addHeaders) {
keys.forEach((key, index) => {
if (key !== "__metadata") {
let th = document.createElement('th');
th.innerHTML = key;
// Create a dropdown (select) for filtering
let select = document.createElement('select');
select.addEventListener('change', function () {
const selectedValue = select.value;
filterTable(index, selectedValue);
});
// Populate dropdown with unique values from the JSON data
let uniqueValues = [...new Set(jsonArray.map(item => item[key]))];
// Add a default "All" option for no filter
let optionAll = document.createElement('option');
optionAll.value = "";
optionAll.text = `All`;
select.appendChild(optionAll);
// Create an option for each unique value
if (typeof (uniqueValues[0]) === typeof (1)) {
const pp = uniqueValues.sort((a, b) => {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
});
pp.forEach(value => {
let option = document.createElement('option');
option.value = value;
option.text = value;
select.appendChild(option);
});
} else
uniqueValues.sort().forEach(value => {
let option = document.createElement('option');
option.value = value;
option.text = value;
select.appendChild(option);
});
// Sort arrows for sorting the columns
let upArrow = document.createElement('span');
upArrow.innerHTML = '⬆️';
upArrow.classList.add('sort-arrows');
upArrow.onclick = () => sortTable(index, 'asc');
let downArrow = document.createElement('span');
downArrow.innerHTML = '⬇️';
downArrow.classList.add('sort-arrows');
downArrow.onclick = () => sortTable(index, 'desc');
th.appendChild(select); // Append the dropdown to the header
th.appendChild(upArrow); // Append the dropdown to the header
th.appendChild(downArrow); // Append the dropdown to the header
headerRow.appendChild(th);
}
});
}
// Create table body and populate rows with data
let tbody = document.createElement('tbody');
jsonArray.forEach((item) => {
let row = tbody.insertRow();
keys = select.split(",");
keys.forEach((key) => {
let cell = row.insertCell();
if (key !== "__metadata") {
cell.setAttribute("nowrap", "nowrap");
if (key === "permissions") {
if (item.permissions !== undefined && item.permissions.length > 0) {
const ul = document.createElement('ul');
item.permissions.forEach((perm) => {
let li = document.createElement('li');
const tablePerm = document.createElement('table');
const tbodyPrem = document.createElement('tbody');
let rowPrem = tbodyPrem.insertRow();
let cellPerm = rowPrem.insertCell();
//member
cellPerm.appendChild(generateTableFromJson2([perm.Member], "LoginName,Title", false))
//perms
cellPerm = rowPrem.insertCell();
cellPerm.appendChild(generateTableFromJson2(perm.RoleDefinitionBindings.results, "Name", false));
tablePerm.appendChild(tbodyPrem);
li.appendChild(tablePerm);
ul.appendChild(li);
});
cell.appendChild(ul);
} else {
cell.innerHTML = " ";
}
} else if (key.indexOf("/") > 0) {
cell.innerHTML = item[key.split("/")[0]][key.split("/")[1]]
} else
cell.innerHTML = item[key]; // Insert each value from the JSON into the table cell
}
});
});
// Append the body to the table
table.appendChild(tbody);
return table;
}
function removeSlasches(select, datas) {
const ret = [];
const fields = select.split(',');
for (let i = 0; i < datas.length; i++) {
const toAdd = {};
for (let j = 0; j < fields.length; j++) {
if (fields[j].indexOf('/') > 0) {
const splitted = fields[j].split('/');
toAdd[splitted.join('')] = datas[i][splitted[0]][splitted[1]];
} else
toAdd[fields[j]] = datas[i][fields[j]];
}
ret.push(toAdd);
}
console.log("removeSlasches", ret);
return ret;
}
async function GetDigestValue(siteUrl) {//
const fetchOptions = {
method: 'POST',
headers: {
'Accept': 'application/json;odata=verbose',
'Content-type': 'application/json;odata=verbose'
}
};
const response = await fetch(siteUrl + "/_api/contextinfo", fetchOptions);
return (await response.json()).d.GetContextWebInformation.FormDigestValue;
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function ExecuteQuery(req, fetchOptions, maxRetry = 3, wait = 1, trynum = 1) {
console.log("ExecuteQuery", req, fetchOptions, maxRetry, wait, trynum);
if (trynum >= maxRetry) {
console.log("ExecuteQuery Error", req);
console.log("ExecuteQuery Error", fetchOptions);
throw new Error(`ExecuteQuery error! maxRetry >= trynum`);
}
try {
let startDate = new Date();
let diffMinutes = 0;
respList1 = await fetch(req, fetchOptions);
endDate = new Date();
const diffMs = endDate - startDate;
diffMinutes = Math.floor(diffMs / (1000));
console.log(`seconds ${diffMinutes} queryNumber ${trynum}`)
//avoid 429 too much queries
if (!respList1.ok && respList1.status == 429) {
const errorDetails = await respList1.text(); // Get error details from the response
let err = JSON.parse(errorDetails);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
await sleep(wait * 10);// * trynum
return await ExecuteQuery(req, fetchOptions, maxRetry, (wait * 5), ++trynum);
} else if (!respList1.ok && respList1.status == 503) {//avoid 503 server unavailable / connections error
const errorDetails = await respList1.text(); // Get error details from the response
let err = JSON.parse(errorDetails);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
await sleep(wait * 10);// * trynum
return await ExecuteQuery(req, fetchOptions, maxRetry, (wait * 5), ++trynum);
} else if (!respList1.ok && respList1.status == 403) {//avoid 403 reload page in another tab
//debugger;
window.open(_spPageContextInfo.webAbsoluteUrl, '_blank')
const errorDetails = await respList1.text(); // Get error details from the response
let err = JSON.parse(errorDetails);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
await sleep(wait * 10);// * trynum
window.open(_spPageContextInfo.webAbsoluteUrl, '_blank')
return await ExecuteQuery(req, fetchOptions, maxRetry, (wait * 5), ++trynum);
} else if (!respList1.ok) {
console.log("ExecuteQuery Error", respList1);
const errorDetails = await respList1.text(); // Get error details from the response
console.log("ExecuteQuery Error", respList1);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${errorDetails}`);
let err = JSON.parse(errorDetails);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
console.log(err.error.message.value);
throw new Error(`HTTP error! Status: ${respList1.status}`);
}
return respList1
} catch (error) {
console.log(error);
throw new Error(`HTTP error! Status: ${error}`);
}
}
const siteUrl = _spPageContextInfo.webAbsoluteUrl;
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
};
//get web server relative url
let resp = await ExecuteQuery(`${siteUrl}/_api/web?$select=ServerRelativeUrl`, fetchOptions);
let usrType1 = await resp.json();
console.log(usrType1.d);
const webRelativeUrl = usrType1.d.ServerRelativeUrl;
//get user list
resp = await ExecuteQuery(`${siteUrl}/_api/web/lists?$select=RootFolder/ServerRelativeUrl,Id&$expand=RootFolder`, fetchOptions);
usrType1 = await resp.json();
let userListId = "";
usrType1.d.results.forEach(list => {
if (list.RootFolder.ServerRelativeUrl.toLowerCase() === (webRelativeUrl + "/_api/web/siteuserinfolist").toLowerCase() ||
list.RootFolder.ServerRelativeUrl.toLowerCase() === (webRelativeUrl + "/_catalogs/users").toLowerCase()) {
userListId = list.Id;
}
});
if(userListId === ""){
console.log("list not found");
throw new Error("list not found");
}
resp = await ExecuteQuery(`${siteUrl}/_api/web/lists(guid'${userListId}')/items?$select=FirstName,IsActive,LastName,UserName,Modified,Author/Title,JobTitle,Department,IsSiteAdmin,EMail,Title,Name,ContentTypeDisp,Deleted,PrincipalCount,ID&$expand=Author`, fetchOptions);
let j = await resp.json();
console.log(j.d);
resp = await ExecuteQuery(`${siteUrl}/_api/web/siteusers?$select=ID,PrincipalType,IsShareByEmailGuestUser`, fetchOptions);
const usrType = await resp.json();
j.d.results.forEach(element => {
//debugger;
const usr = usrType.d.results.find(u => u.Id === element.ID);
//console.log("usrType", usrType);
if (usr !== undefined) {
element.PrincipalType = usr.PrincipalType;
element.IsShareByEmailGuestUser = usr.IsShareByEmailGuestUser;
} else {
element.PrincipalType = -1;
element.IsShareByEmailGuestUser = false;
}
});
document.body.innerHTML = ``;
const table = generateTableFromJson2(j.d.results, "EMail,Title,PrincipalType,IsShareByEmailGuestUser,Name,IsActive,FirstName,LastName,UserName,Modified,Author/Title,JobTitle,Department,IsSiteAdmin,Deleted,ID");
// Append the table to the container
document.getElementById('tableContainer').appendChild(table);
Sharepoint Audit List Permissions batch
On 17/10/2025
const siteUrl = _spPageContextInfo.webAbsoluteUrl;
const listUrl = "Shared%20Documents";
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function generateGuid() {
await sleep(10);// * trynum
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
async function getRequestDigest() {
const fetchOptions = {
method: "POST",
headers: { Accept: "application/json;odata=verbose" },
credentials: "include",
};
const data = (await (await ExecuteQuery(`${siteUrl}/_api/contextinfo`, fetchOptions)).json());
return data.d.GetContextWebInformation.FormDigestValue;
}
async function ExecuteQuery(req, fetchOptions, maxRetry = 3, wait = 10000, trynum = 1) {
console.log("ExecuteQuery", req, fetchOptions, maxRetry, wait, trynum);
if (trynum >= maxRetry) {
console.log("ExecuteQuery Error", req);
console.log("ExecuteQuery Error", fetchOptions);
throw new Error(`ExecuteQuery error! maxRetry >= trynum`);
}
try {
let startDate = new Date();
let diffMinutes = 0;
respList1 = await fetch(req, fetchOptions);
endDate = new Date();
const diffMs = endDate - startDate;
diffMinutes = Math.floor(diffMs / (1000));
console.log(`seconds ${diffMinutes} queryNumber ${trynum}`)
//avoid 429 too much queries
if (!respList1.ok && respList1.status == 429) {
const errorDetails = await respList1.text(); // Get error details from the response
let err = JSON.parse(errorDetails);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
await sleep(wait * 2);// * trynum
if (fetchOptions.method === "POST") {
//regnerate the digest
fetchOptions["X-RequestDigest"] = await getRequestDigest();
}
return await ExecuteQuery(req, fetchOptions, maxRetry, (wait * 5), ++trynum);
}
//avoid 503 server unavailable / connections error
if (!respList1.ok && respList1.status == 503) {
const errorDetails = await respList1.text(); // Get error details from the response
let err = JSON.parse(errorDetails);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
await sleep(1000 * wait);// wait 10 seconds
if (fetchOptions.method === "POST") {
//regnerate the digest
fetchOptions["X-RequestDigest"] = await getRequestDigest();
}
return await ExecuteQuery(req, fetchOptions, maxRetry, (wait * 5), ++trynum);
}
//avoid 403 reload page in another tab
if (!respList1.ok && respList1.status == 403) {
//debugger;
window.open(siteUrl, '_blank')
const errorDetails = await respList1.text(); // Get error details from the response
let err = JSON.parse(errorDetails);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
console.log("waiting due to error 403");
await sleep(10000);// wait 10 seconds
window.open(siteUrl, '_blank')
await sleep(1000 * wait);// wait 10 seconds
if (fetchOptions.method === "POST") {
//regnerate the digest
fetchOptions["X-RequestDigest"] = await getRequestDigest();
}
return await ExecuteQuery(req, fetchOptions, maxRetry, (wait * 5), ++trynum);
}
if (!respList1.ok) {
console.log("ExecuteQuery Error", respList1);
const errorDetails = await respList1.text(); // Get error details from the response
console.log("ExecuteQuery Error", respList1);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${errorDetails}`);
let err = JSON.parse(errorDetails);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
console.log(err.error.message.value);
throw new Error(`HTTP error! Status: ${respList1.status}`);
}
return respList1
} catch (error) {
console.log(error);
throw new Error(`HTTP error! Status: ${error}`);
}
}
async function GetFolderSize(siteUrl, listUrl1, query) {
// Fetch options with headers for authentication and response format
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
};
//get web relativeUrl
var req = `${siteUrl}/_api/web?$select=ServerRelativeUrl`;
const webServerRelativUrl = (await (await ExecuteQuery(req, fetchOptions)).json()).d.ServerRelativeUrl;
// get total items count
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/?$select=ItemCount`;
const ItemsCount = (await (await ExecuteQuery(req, fetchOptions)).json()).d.ItemCount;
let query1 = "";
if (`${query}`.trim() !== "") {
query1 = `&$filter=${query}`;
query = ` and ${query}`;
}
//get firstId
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items?$select=Id&$top=1&$orderby=Id asc${query1}`;
console.log("req", req);
const firstId = (await (await ExecuteQuery(req, fetchOptions)).json()).d.results[0].Id;
console.log("firstId", firstId);
//get lastId
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items?$select=Id&$top=1&$orderby=Id desc${query1}`;
console.log("last", req);
const lastId = (await (await ExecuteQuery(req, fetchOptions)).json()).d.results[0].Id;
console.log("lastId", lastId);
let startId = firstId;
let endId = firstId + 5000;
var allItems = [];
console.log(`startId ${startId} endId ${endId} lastId ${lastId}`);//FileSizeDisplay
console.log("query", query);//_UIVersionString File_x0020_Size
const startDate = new Date();
let endDate = new Date();
let diffMinutes = 0;
let queryNumber = 1;
do {
//to avoid 429 error
if (queryNumber % 10 == 0) {
console.log(`sleep 1 minute queryNumber ${queryNumber}`);
await sleep(60000); // 60 000 ms = 1 minute
}
var select = "?$select=File/Length,File/UIVersionLabel,File_x0020_Type,Id,HasUniqueRoleAssignments,FileRef,FileLeafRef,FileDirRef,Created,Modified,Author/Title,Author/EMail,Editor/Title,Editor/EMail,ContentTypeId";
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items${select}&$filter=Id ge ${startId} and Id lt ${endId} and Id le ${lastId}${query}&$orderby=Id asc&$top=5000&$expand=File,Author,Editor`;
console.log("req", req);
// Send the asynchronous GET request to the REST API endpoint /_api/site/usage
let respList1 = null;
try {
respList1 = await ExecuteQuery(req, fetchOptions);
endDate = new Date();
queryNumber++;
} catch (error) {
console.log("error", error);
return allItems;
}
const items = (await respList1.json()).d.results;
allItems.push(...items);
startId += 5000;
endId += 5000;
const diffMs = endDate - startDate;
diffMinutes = Math.floor(diffMs / (1000 * 60));
console.log(`startId ${startId} endId ${endId} lastId ${lastId} diffMinutes ${diffMinutes} queryNumber ${queryNumber}, ItemsCount : ${ItemsCount}`)
await sleep(1500); // 1,5 second
//debugger;
}
while (startId <= lastId);
return allItems;
}
async function batchFetchPermissions(queriess) {
const queries = [...queriess];
console.log("batchFetchPermissions", queries);
const batchBoundary = "batch_" + await generateGuid();
const batchBody = queries.map((query) => {
return `
--${batchBoundary}
Content-Type: application/http
Content-Transfer-Encoding: binary
GET ${query.req} HTTP/1.1
Accept: application/json;odata=verbose
`;
}).join("\n") + `\n--${batchBoundary}--`;
const digest = await getRequestDigest();//
console.log("batchBody", batchBody.length);
const headers = {
Accept: "application/json;odata=verbose",
"X-RequestDigest": digest,
"Content-Type": `multipart/mixed; boundary="${batchBoundary}"`,
};
const response = await fetch(`${siteUrl}/_api/$batch`, {
method: "POST",
headers,
body: batchBody,
});
const text = await response.text(); // Parse response manually (multipart)
const responses = text.split("HTTP/1.1 200 OK");
const results1 = [];
for (let k = 1; k < responses.length; k++) {
const parts = responses[k].split("\r\n\r\n")[1];
// The JSON is the last part after the headers
let jsonString = parts[parts.length - 1];
// Parse the JSON
jsonString = parts.split("\r\n")[0];
const d = {
Id: `${queries[k - 1].Id}`,
Index: k,
result: JSON.parse(jsonString.trim()).d
}
results1.push(d);
}
return [...results1];
}
const maxBatch = 20;
async function LoadUniquePermissions(items) {
let batchCount = 0;
let requests = [];
var req = `${siteUrl}/_api/web?$select=ServerRelativeUrl`;
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
};
const perms = [];
const webServerRelativUrl = (await (await ExecuteQuery(req, fetchOptions)).json()).d.ServerRelativeUrl;
for (let i = 0; i < items.length; i++) {
items[i].permId = await generateGuid();
if (items[i].HasUniqueRoleAssignments) {
requests.push({
Id: items[i].permId,
req: `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl}')/items(${items[i].Id})/RoleAssignments?$expand=Member,RoleDefinitionBindings&$select=Member/Id,Member/LoginName,Member/Title,RoleDefinitionBindings/Name`
});
batchCount++;
}
if (requests.length === maxBatch) {
perms.push(await batchFetchPermissions(requests));
requests = [];
}
}
if (requests.length > 0) {
perms.push(await batchFetchPermissions(requests));
requests = [];
}
for (let i = 0; i < items.length; i++) {
const perm = perms.flat().filter(f => `${f.Id}` == `${items[i].permId}`);
if (items[i].HasUniqueRoleAssignments && perm.length === 1) {
items[i].permissions = perm[0].result.results;
}
}
console.log("with perm", items);
return items;
}
const disgest = await getRequestDigest();
console.log("disgest", disgest);
const items = await GetFolderSize(siteUrl, listUrl, "Id le 145000");//(Id eq 225 or Id eq 226) Id gt 270
const rest = await LoadUniquePermissions(items);
SharePoint Get Doc Lib Size avoid error 429
On 10/10/2025
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function ExecuteQuery(req, fetchOptions, maxRetry = 3, wait = 1, trynum = 1) {
console.log("ExecuteQuery", req, fetchOptions, maxRetry, wait, trynum);
if (trynum >= maxRetry) {
console.log("ExecuteQuery Error", req);
console.log("ExecuteQuery Error", fetchOptions);
throw new Error(`ExecuteQuery error! maxRetry >= trynum`);
}
try {
let startDate = new Date();
let diffMinutes = 0;
respList1 = await fetch(req, fetchOptions);
endDate = new Date();
const diffMs = endDate - startDate;
diffMinutes = Math.floor(diffMs / (1000));
console.log(`seconds ${diffMinutes} queryNumber ${trynum}`)
//avoid 429 too much queries
if (!respList1.ok && respList1.status == 429) {
const errorDetails = await respList1.text(); // Get error details from the response
let err = JSON.parse(errorDetails);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
await sleep(wait * 10);// * trynum
return await ExecuteQuery(req, fetchOptions, maxRetry, (wait * 5), ++trynum);
}
//avoid 503 server unavailable / connections error
if (!respList1.ok && respList1.status == 503) {
const errorDetails = await respList1.text(); // Get error details from the response
let err = JSON.parse(errorDetails);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
await sleep(wait * 10);// * trynum
return await ExecuteQuery(req, fetchOptions, maxRetry, (wait * 5), ++trynum);
}
//avoid 403 reload page in another tab
if (!respList1.ok && respList1.status == 403) {
//debugger;
window.open(_spPageContextInfo.webAbsoluteUrl, '_blank')
const errorDetails = await respList1.text(); // Get error details from the response
let err = JSON.parse(errorDetails);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
await sleep(wait * 10);// * trynum
window.open(_spPageContextInfo.webAbsoluteUrl, '_blank')
return await ExecuteQuery(req, fetchOptions, maxRetry, (wait * 5), ++trynum);
}
if (!respList1.ok) {
console.log("ExecuteQuery Error", respList1);
const errorDetails = await respList1.text(); // Get error details from the response
console.log("ExecuteQuery Error", respList1);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${errorDetails}`);
let err = JSON.parse(errorDetails);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
console.log(err.error.message.value);
throw new Error(`HTTP error! Status: ${respList1.status}`);
}
return respList1
} catch (error) {
console.log(error);
throw new Error(`HTTP error! Status: ${error}`);
}
}
async function GetFolderSize(siteUrl, listUrl1, query) {
// Fetch options with headers for authentication and response format
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
};
//get web relativeUrl
var req = `${siteUrl}/_api/web?$select=ServerRelativeUrl`;
const webServerRelativUrl = (await (await ExecuteQuery(req, fetchOptions)).json()).d.ServerRelativeUrl;
// get total items count
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/?$select=ItemCount`;
const ItemsCount = (await (await ExecuteQuery(req, fetchOptions)).json()).d.ItemCount;
let query1 = "";
if (`${query}`.trim() !== "") {
query1 = `&$filter=${query}`;
query = ` and ${query}`;
}
//get firstId
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items?$select=Id&$top=1&$orderby=Id asc${query1}`;
console.log("req", req);
const firstId = (await (await ExecuteQuery(req, fetchOptions)).json()).d.results[0].Id;
console.log("firstId", firstId);
//get lastId
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items?$select=Id&$top=1&$orderby=Id desc${query1}`;
console.log("last", req);
const lastId = (await (await ExecuteQuery(req, fetchOptions)).json()).d.results[0].Id;
console.log("lastId", lastId);
let startId = firstId;
let endId = firstId + 5000;
var allItems = [];
console.log(`startId ${startId} endId ${endId} lastId ${lastId}`);//FileSizeDisplay
console.log("query", query);//_UIVersionString File_x0020_Size
const startDate = new Date();
let endDate = new Date();
let diffMinutes = 0;
let queryNumber = 1;
do {
//to avoid 429 error
if (queryNumber % 10 == 0) {
console.log(`sleep 1 minute queryNumber ${queryNumber}`);
await sleep(60000); // 60 000 ms = 1 minute
}
var select = "?$select=File/Length,File/UIVersionLabel,File_x0020_Type,Id,HasUniqueRoleAssignments,FileRef,FileLeafRef,FileDirRef,Created,Modified,Author/Title,Author/EMail,Editor/Title,Editor/EMail,ContentTypeId";
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items${select}&$filter=Id ge ${startId} and Id lt ${endId} and Id le ${lastId}${query}&$orderby=Id asc&$top=5000&$expand=File,Author,Editor`;
console.log("req", req);
// Send the asynchronous GET request to the REST API endpoint /_api/site/usage
let respList1 = null;
try {
respList1 = await ExecuteQuery(req, fetchOptions);
endDate = new Date();
queryNumber++;
} catch (error) {
console.log("error", error);
return allItems;
}
const items = (await respList1.json()).d.results;
allItems.push(...items);
startId += 5000;
endId += 5000;
const diffMs = endDate - startDate;
diffMinutes = Math.floor(diffMs / (1000 * 60));
console.log(`startId ${startId} endId ${endId} lastId ${lastId} diffMinutes ${diffMinutes} queryNumber ${queryNumber}, ItemsCount : ${ItemsCount}`)
await sleep(1500); // 1,5 second
//debugger;
}
while (startId <= lastId);
//console.log("allItems", allItems);
console.log("queryNumber", queryNumber);
return allItems;
}
let totalSize = 0
const siteUrl = _spPageContextInfo.webAbsoluteUrl;
const items = await GetFolderSize(siteUrl, "Shared%20Documents", "");//startswith(ContentTypeId,'0x0101')
//calculate file Size
let separator = ";"
let csv = `Id${separator}HasUniqueRoleAssignments${separator}FromParent${separator}Title${separator}FileRef${separator}FileDirRef${separator}FileLeafRef${separator}Created${separator}CreatedMin${separator}Modified${separator}ModifiedMin${separator}AuthorTitle${separator}AuthorEMail${separator}EditorTitle${separator}EditorEMail${separator}FileLength${separator}MB${separator}GB${separator}FileUIVersionLabel${separator}File_x0020_Type${separator}ContentTypeId${separator}count\n`;
//display lastID
if (items !== undefined && items !== null && items.length > 0) {
console.log(`lastId ${items[items.length - 1].Id}`);
}
//check child
//get folders with unique permissions
const folder = items.filter(file => file.HasUniqueRoleAssignments && file.ContentTypeId.startsWith('0x0120'));
for (let k = 0; k < folder.length; k++) {
for (let i = 0; i < items.length; i++) {
if(items[i].FromParent == undefined)
items[i].FromParent = false;
if (items[i].HasUniqueRoleAssignments == false && items[i].FileDirRef.startsWith(folder[k].FileRef)) {
items[i].HasUniqueRoleAssignments = true;
items[i].FromParent = true;
}
}
}
for (let i = 0; i < items.length; i++) {
csv += `${items[i].Id}${separator}`;
csv += `${items[i].HasUniqueRoleAssignments}${separator}`;
csv += `${items[i].FromParent}${separator}`;
csv += `${items[i].Title}${separator}`;
csv += `${items[i].FileRef}${separator}`;
csv += `${items[i].FileDirRef}${separator}`;
csv += `${items[i].FileLeafRef}${separator}`;
csv += `${items[i].Created}${separator}`;
csv += `${items[i].Created.substring(0, 10)}${separator}`;
csv += `${items[i].Modified}${separator}`;
csv += `${items[i].Modified.substring(0, 10)}${separator}`;
csv += `${items[i].Author.Title}${separator}`;
csv += `${items[i].Author.EMail}${separator}`;
csv += `${items[i].Editor.Title}${separator}`;
csv += `${items[i].Editor.EMail}${separator}`;
//if is a file
if (items[i].File != undefined && items[i].File.Length != undefined) {
totalSize += parseInt(items[i].File.Length);
csv += `${items[i].File.Length}${separator}`;
csv += `${(items[i].File.Length / (1024 * 1024)).toFixed(2)}${separator}`;
csv += `${(items[i].File.Length / (1024 * 1024 * 1024)).toFixed(2)}${separator}`;
csv += `${items[i].File.UIVersionLabel}${separator}`;
csv += `${items[i].File_x0020_Type}${separator}`;
}
else {
//is folder
csv += `${separator}`;
csv += `${separator}`;
csv += `${separator}`;
csv += `${separator}`;
csv += `${separator}`;
}
csv += (`${items[i].ContentTypeId}`.startsWith('0x0120') ? "folder" : `${items[i].ContentTypeId}`);
csv += `${separator}1\n`;
}
const totalSizeGB = (totalSize / (1024 * 1024 * 1024)).toFixed(2);
console.log("totalSize B", totalSize);
console.log("total size MB", (totalSize / (1024 * 1024)).toFixed(2));
console.log("total size GB", totalSizeGB);
console.log("items length", items.length);
console.log("csv", csv);
console.log("items", items);
Get SharePoint Document Library Size
On 09/10/2025
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function GetFolderSize(siteUrl, listUrl1, query) {
// Fetch options with headers for authentication and response format
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
};
// get web relativeUrl
var req = `${siteUrl}/_api/web?$select=ServerRelativeUrl`;
const webServerRelativUrl = (await (await fetch(req, fetchOptions)).json()).d.ServerRelativeUrl;
let query1 = "";
if (`${query}`.trim() !== "") {
query1 = `&$filter=${query}`;
query = ` and ${query}`;
}
// get firstId
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items?$select=Id&$top=1&$orderby=Id asc`;
console.log("req", req);
const firstId = 0;
console.log("firstId", firstId);
// get lastId
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items?$select=Id&$top=1&$orderby=Id desc`;
console.log("last", req);
const lastId = (await (await fetch(req, fetchOptions)).json()).d.results[0].Id;
console.log("lastId", lastId);
let startId = firstId;
let endId = firstId + 5000;
var allItems = [];
console.log(`startId ${startId} endId ${endId} lastId ${lastId}`);
console.log("query", query);
const startDate = new Date();
let endDate = new Date();
let diffMinutes = 0;
let queryNumber = 0;
do {
// to avoid 429 error
if(queryNumber % 10 == 0){
await sleep(60000); // 60 000 ms = 1 minute
}
var select = "?$select=File/Length";
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items${select}&$filter=Id ge ${startId} and Id lt ${endId}${query}&$orderby=Id asc&$top=5000&$expand=File`;
console.log("req", req);
let respList1 = null;
try {
respList1 = await fetch(req, fetchOptions);
if (!respList1.ok) {
const errorDetails = await respList1.text();
console.error(`HTTP error! Status: ${respList1.status}, Details: ${errorDetails}`);
let err = JSON.parse(errorDetails);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
console.log(err.error.message.value);
throw new Error(`HTTP error! Status: ${respList1.status}`);
}
endDate = new Date();
queryNumbercatch (error) {
console.log("error", error);
return null;
}
const items = (await respList1.json()).d.results;
allItems.push(...items);
startId += 5000;
endId += 5000;
const diffMs = endDate - startDate;
diffMinutes = Math.floor(diffMs / (1000 * 60));
console.log(`startId ${startId} endId ${endId} lastId ${lastId} diffMinutes ${diffMinutes} queryNumber ${queryNumber}`)
}
while (endId < lastId);
console.log("queryNumber", queryNumber);
return allItems;
}
let totalSize = 0
const siteUrl = "Your site Url";
const items = await GetFolderSize(siteUrl, "Your doclib Name", "startswith(ContentTypeId,'0x0101')");
// calculate file Size
for (let i = 0; i < items.length; i++) {
if (items[i].File != undefined && items[i].File.Length != undefined) {
totalSize += parseInt(items[i].File.Length);
}
}
const totalSizeGB = (totalSize / (1024 * 1024 * 1024)).toFixed(2);
console.log("totalSize B", totalSize);
console.log("total size MB", (totalSize / (1024 * 1024)).toFixed(2));
console.log("total size GB", totalSizeGB);
console.log("items length", items.length);
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function GetFolderSize(siteUrl, listUrl1, query) {
// Fetch options with headers for authentication and response format
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
};
//get web relativeUrl
var req = `${siteUrl}/_api/web?$select=ServerRelativeUrl`;
const webServerRelativUrl = (await (await fetch(req, fetchOptions)).json()).d.ServerRelativeUrl;
let query1 = "";
if (`${query}`.trim() !== "") {
query1 = `&$filter=${query}`;
query = ` and ${query}`;
}
//get firstId
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items?$select=Id&$top=1&$orderby=Id asc`;
console.log("req", req);
const firstId = 0;
console.log("firstId", firstId);
//get lastId
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items?$select=Id&$top=1&$orderby=Id desc`;
console.log("last", req);
const lastId = (await (await fetch(req, fetchOptions)).json()).d.results[0].Id;
console.log("lastId", lastId);
let startId = firstId;
let endId = firstId + 5000;
var allItems = [];
console.log(`startId ${startId} endId ${endId} lastId ${lastId}`);//FileSizeDisplay
console.log("query", query);//_UIVersionString File_x0020_Size
const startDate = new Date();
let endDate = new Date();
let diffMinutes = 0;
let queryNumber = 0;
do {
//to avoid 429 error
if(queryNumber % 10 == 0){
await sleep(60000); // 60 000 ms = 1 minute
}
var select = "?$select=File/Length";
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items${select}&$filter=Id ge ${startId} and Id lt ${endId}${query}&$orderby=Id asc&$top=5000&$expand=File`;
console.log("req", req);
// Send the asynchronous GET request to the REST API endpoint /_api/site/usage
let respList1 = null;
try {
respList1 = await fetch(req, fetchOptions);
if (!respList1.ok) {
const errorDetails = await respList1.text(); // Get error details from the response
console.error(`HTTP error! Status: ${respList1.status}, Details: ${errorDetails}`);
let err = JSON.parse(errorDetails);
console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
console.log(err.error.message.value);
throw new Error(`HTTP error! Status: ${respList1.status}`);
}
endDate = new Date();
queryNumber++;
} catch (error) {
console.log("error", error);
return null;
}
const items = (await respList1.json()).d.results;
allItems.push(...items);
startId += 5000;
endId += 5000;
const diffMs = endDate - startDate;
diffMinutes = Math.floor(diffMs / (1000 * 60));
console.log(`startId ${startId} endId ${endId} lastId ${lastId} diffMinutes ${diffMinutes} queryNumber ${queryNumber}`)
}
while (endId < lastId);
//console.log("allItems", allItems);
console.log("queryNumber", queryNumber);
return allItems;
}
let totalSize = 0
const siteUrl = "Your site Url";
const items = await GetFolderSize(siteUrl, "Your doclib Name", "startswith(ContentTypeId,'0x0101')");
//calculate file Size
for (let i = 0; i < items.length; i++) {
if (items[i].File != undefined && items[i].File.Length != undefined) {
totalSize += parseInt(items[i].File.Length);
}
}
const totalSizeGB = (totalSize / (1024 * 1024 * 1024)).toFixed(2);
console.log("totalSize B", totalSize);
console.log("total size MB", (totalSize / (1024 * 1024)).toFixed(2));
console.log("total size GB", totalSizeGB);
console.log("items length", items.length);
//console.log("items", items);
Sharepoint Rest Get User ID By Mail
On 23/06/2025
async function GetDigestValue(siteUrl) {//
const fetchOptions = {
method: 'POST',
headers: {
'Accept': 'application/json;odata=verbose',
'Content-type': 'application/json;odata=verbose'
}
};
const response = await fetch(siteUrl + "/_api/contextinfo", fetchOptions);
return (await response.json()).d.GetContextWebInformation.FormDigestValue;
}
async function EnsureUser(siteUrl, userEmail) {
const digest = await GetDigestValue(siteUrl);
console.log("digest", digest);
const body = {
'logonName': `i:0#.f|membership|${userEmail}`
}
const response = await fetch(`${siteUrl}/_api/web/ensureuser?$select=Id`, {
method: "POST",
headers: {
"Accept": "application/json;odata=verbose",
"Content-Type": "application/json;odata=verbose",
"X-RequestDigest": digest
},
body: JSON.stringify({
'logonName': `i:0#.f|membership|${userEmail}`
})
});
console.log("response", response);
const userData = await response.json();
return userData.d.Id;
}
async function getUserIdByEmail(siteUrl, userEmail) {
try {
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose',
'Content-type': 'application/json;odata=verbose'
}
};
const response = await fetch(siteUrl + `/_api/web/siteusers/getbyemail('${encodeURIComponent(userEmail)}')`, fetchOptions);
const data = await response.json();
console.log("getUserByEmail data", data);
return data.d.Id;
} catch (error) {
console.log("getUserByEmail Error", error);
return null;
}
}
let siteUrl1 = "https://eutelsatgroup.sharepoint.com/sites/fdiSandBox";
let email1 = "ffdietrich-ext@eutelsat.com";
let ret = await EnsureUser(siteUrl1, email1);
console.log("response", ret);
const siteUrl = "https://test.sharepoint.com/sites/Dev_wf";
const email = "fpalmo@test.com";
console.log("response", ret0);
const ret = await EnsureUser(siteUrl, email);
const ret0 = await getUserIdByEmail(siteUrl, email);
console.log("response", ret);
Show Lists Roleassignments
On 27/05/2025
// Fonction pour récupérer tous les RoleDefinitionBindings
async function getRoleDefinitionBindings(list, Id, Title, ServerRelativeUrl, ItemsCount, Hidden, HasUniqueRoleAssignments) {
let p = `vdfvd`;//$${apiGet}
const getPai = `${list}/roleassignments?$expand=Member/users,RoleDefinitionBindings`;
console.log("request", getPai);
const response = await fetch(getPai, {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
});
const data = await response.json();
data.d.results;
console.log(data.d.results);
const ret = [];
for (let i = 0; i < data.d.results.length; i++) {
var perm = data.d.results[i];
const toAdd = {};
toAdd.ListId = Id;
toAdd.ListTitle = Title;
toAdd.ListServerRelativeUrl = ServerRelativeUrl;
toAdd.ItemsCount = ItemsCount;
toAdd.Hidden = Hidden;
toAdd.HasUniqueRoleAssignments = HasUniqueRoleAssignments;
toAdd.Id = perm.Member.Id;
toAdd.LoginName = perm.Member.LoginName;
toAdd.Email = perm.Member.Email ?? "";
toAdd.Description = perm.Member.Description;
toAdd.Title = perm.Member.Title;
toAdd.IsHiddenInUI = perm.Member.IsHiddenInUI;
toAdd.PrincipalId = perm.Member.PrincipalId;
toAdd.PrincipalType = perm.Member.PrincipalType;
//users bu group
if (perm.Member.Users !== undefined && perm.Member.Users !== null && perm.Member.Users.results.length > 0) {
toAdd.Users = [];
for (let j = 0; j < perm.Member.Users.results.length; j++) {
const u = perm.Member.Users.results[j];
toAdd.Users.push({
Email: u.Email,
Id: u.Id,
Title: u.Title,
UserPrincipalName: u.UserPrincipalName,
IsSiteAdmin: u.IsSiteAdmin,
IsShareByEmailGuestUser: u.IsShareByEmailGuestUser
});
}
}
toAdd.RoleDefinitionBindings = ""
if (perm.RoleDefinitionBindings !== undefined && perm.RoleDefinitionBindings !== null && perm.RoleDefinitionBindings.results.length > 0) {
for (let j = 0; j < 1; j++) {
const r = perm.RoleDefinitionBindings.results[j];
toAdd.RoleDefinitionBindings = r.Name;
}
}
ret.push(toAdd);
}
console.log(ret);
return ret;
}
let url = "https://test.sharepoint.com/sites/csc";
let lists = `${url}/_api/web/lists?$select=Hidden,Title,RootFolder/ServerRelativeUrl,Id,ItemCount,HasUniqueRoleAssignments&$expand=RootFolder`;//&$filter=Hidden eq false
let response = await fetch(lists, {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
});
let data = await response.json();
let datas = [];
for (let z = 0; z < data.d.results.length; z++) {//
const lst = data.d.results[z];
console.log("lst", lst);
const datas1 = await getRoleDefinitionBindings(`${url}/_api/web/lists(guid'${lst.Id}')`, lst.Id, lst.Title, lst.RootFolder.ServerRelativeUrl, lst.ItemCount, lst.Hidden, lst.HasUniqueRoleAssignments);
console.log(datas1);
for (let u = 0; u < datas1.length; u++) {
datas.push(datas1[u]);
}
}
console.log("datas", datas);
let csv = "ListId;ListTitle;ListServerRelativeUrl;ItemsCount;Hidden;HasUniqueRoleAssignments;MemberTitle;MemberEmail;MemberLoginName;MemberId;MemberDescription;Permission;TopLevel;UserMail;UserTitle;UserId;UserUserPrincipalName;IsSiteAdmin;IsShareByEmailGuestUser\n";
for (let k = 0; k < datas.length; k++) {
const d = datas[k];
let member = "";
member += `${d.ListId};`
member += `${d.ListTitle};`
member += `${d.ListServerRelativeUrl};`
member += `${d.ItemsCount};`
member += `${d.Hidden};`
member += `${d.HasUniqueRoleAssignments};`
member += `${d.Title};`
member += `${d.Email};`
member += `${d.LoginName};`
member += `${d.Id};`
member += `${d.Description ?? ""};`
member += `${d.RoleDefinitionBindings};`
csv += `${member}true;;;;;;\n`;
//debugger;
if (d.Users !== undefined) {
for (let j = 0; j < d.Users.length; j++) {
const user = d.Users[j];
let u = `${member}false;`;
u += `${user.Email};`;
u += `${user.Title};`;
u += `${user.Id};`;
u += `${user.UserPrincipalName ?? ""};`;
u += `${user.IsSiteAdmin};`;
u += `${user.IsShareByEmailGuestUser}`;
csv += `${u}\n`
}
}
}
console.log(csv);
Get Web Role Assignments
On 27/05/2025
// Fonction pour récupérer tous les RoleDefinitionBindings
async function getRoleDefinitionBindings(apiGet, type) {
let p = `vdfvd`;//$${apiGet}
const getPai = `${apiGet}/roleassignments?$expand=Member/users,RoleDefinitionBindings`;
const response = await fetch(getPai, {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
});
const data = await response.json();
data.d.results;
console.log(data.d.results);
const ret = [];
for (let i = 0; i < data.d.results.length; i++) {
var perm = data.d.results[i];
const toAdd = {};
toAdd.type = type;
toAdd.Id = perm.Member.Id;
toAdd.LoginName = perm.Member.LoginName;
toAdd.Email = perm.Member.Email ?? "";
toAdd.Description = perm.Member.Description;
toAdd.Title = perm.Member.Title;
toAdd.IsHiddenInUI = perm.Member.IsHiddenInUI;
toAdd.PrincipalId = perm.Member.PrincipalId;
toAdd.PrincipalType = perm.Member.PrincipalType;
//users bu group
if (perm.Member.Users !== undefined && perm.Member.Users !== null && perm.Member.Users.results.length > 0) {
toAdd.Users = [];
for (let j = 0; j < perm.Member.Users.results.length; j++) {
const u = perm.Member.Users.results[j];
toAdd.Users.push({
Email: u.Email,
Id: u.Id,
Title: u.Title,
UserPrincipalName: u.UserPrincipalName,
IsSiteAdmin: u.IsSiteAdmin,
IsShareByEmailGuestUser: u.IsShareByEmailGuestUser
});
}
}
//debugger;
// = [];
toAdd.RoleDefinitionBindings = ""
if (perm.RoleDefinitionBindings !== undefined && perm.RoleDefinitionBindings !== null && perm.RoleDefinitionBindings.results.length > 0) {
for (let j = 0; j < 1; j++) {
const r = perm.RoleDefinitionBindings.results[j];
toAdd.RoleDefinitionBindings = r.Name;
// toAdd.RoleDefinitionBindings = {
// Name: r.Name,
// Hidden: r.Hidden,
// Description: r.Description,
// RoleTypeKind: r.RoleTypeKind,
// Order: r.Order
// };
}
}
ret.push(toAdd);
}
console.dir("ret", ret);
console.log(ret);
return ret;
}
let url = "https://test.sharepoint.com/sites/csc";
debugger;
const datas = await getRoleDefinitionBindings(`${url}/_api/web`, "SiteCollection");
let csv = "type;MemberTitle;MemberEmail;MemberLoginName;MemberId;MemberDescription;Permission;TopLevel;UserMail;UserTitle;UserId;UserUserPrincipalName;IsSiteAdmin;IsShareByEmailGuestUser\n";
for (let k = 0; k < datas.length; k++) {
const d = datas[k];
let member = "";
member += `${d.type};`
member += `${d.Title};`
member += `${d.Email};`
member += `${d.LoginName};`
member += `${d.Id};`
member += `${d.Description ?? ""};`
member += `${d.RoleDefinitionBindings};`
csv += `${member}true;;;;;;\n`;
//debugger;
if (d.Users !== undefined) {
for (let j = 0; j < d.Users.length; j++) {
const user = d.Users[j];
let u = `${member}false;`;
u += `${user.Email};`;
u += `${user.Title};`;
u += `${user.Id};`;
u += `${user.UserPrincipalName ?? ""};`;
u += `${user.IsSiteAdmin};`;
u += `${user.IsShareByEmailGuestUser}`;
csv += `${u}\n`
}
}
}
console.log(csv);
Sharepoint Rest Compaire 2 Lists Fields
On 25/03/2025
// Fonction pour comparer les champs de deux listes SharePoint
async function compareSharePointLists(urlSite1, urlSite2, ListRelativeUrl1, ListRelativeUrl2) {
// Fonction auxiliaire pour obtenir les champs de la liste
async function getListFields(urlSite, ListRelativeUrl) {
const response = await fetch(`${urlSite}/_api/web/lists/getbytitle('${ListRelativeUrl}')/fields?$select=InternalName,TypeAsString`, {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose',
},
});
if (!response.ok) {
throw new Error(`Error fetching fields for list at ${ListRelativeUrl}: ${response.statusText}`);
}
const data = await response.json();
return data.d.results;
}
try {
// Obtenir les champs des deux listes
const fields1 = await getListFields(urlSite1, ListRelativeUrl1);
const fields2 = await getListFields(urlSite2, ListRelativeUrl2);
// Comparer les champs
fields1.forEach(field1 => {
const matchingField = fields2.find(field2 => field2.InternalName === field1.InternalName);
if (!matchingField) {
console.log(`Le champ ${field1.InternalName} est manquant dans ${ListRelativeUrl2} de ${urlSite2}`);
} else if (field1.TypeAsString !== matchingField.TypeAsString) {
console.log(`Le type de champ ${field1.InternalName} ne correspond pas dans ${ListRelativeUrl2} de ${urlSite2} : ${field1.TypeAsString} vs ${matchingField.TypeAsString}`);
}
});
fields2.forEach(field2 => {
const matchingField = fields1.find(field1 => field1.InternalName === field2.InternalName);
if (!matchingField) {
console.log(`Le champ ${field2.InternalName} type ${field2.TypeAsString} est manquant dans ${ListRelativeUrl1} de ${urlSite1}`);
}
});
} catch (error) {
console.error('Erreur lors de la comparaison des champs des listes :', error);
}
}
// Example usage
compareSharePointLists(
'https://test.sharepoint.com/sites/DoceboMigration',
'https://test2.sharepoint.com/sites/fdiSandBox',
'testConfiguration',
'fdiTasks');
Sharepoint List Groups And Permissions
On 24/03/2025
// Function to list all SharePoint groups of a site collection with their permission levels
async function listSharePointGroupsWithPermissions(siteUrl, targetDivId) {
// Check if the siteUrl and targetDivId are provided
if (!siteUrl || !targetDivId) {
console.error("Site URL and target div ID must be provided.");
// L'URL du site et l'ID de la div cible doivent être fournis.
return;
}
// Construct the REST API URL to get the groups
const groupsEndpoint = `${siteUrl}/_api/web/sitegroups`;
try {
// Fetch the groups from the SharePoint site
const groupsResponse = await fetch(groupsEndpoint, {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose',
},
});
// Check if the response is ok
if (!groupsResponse.ok) {
throw new Error(`Error fetching groups: ${groupsResponse.statusText}`);
// Erreur lors de la récupération des groupes :
}
// Parse the JSON response
const groupsData = await groupsResponse.json();
const groups = groupsData.d.results;
// Get the target div element
const targetDiv = document.getElementById(targetDivId);
if (!targetDiv) {
throw new Error(`Target div with ID ${targetDivId} not found.`);
// Div cible avec l'ID introuvable.
}
// Clear the target div
targetDiv.innerHTML = '';
const permsEndpoint = `${siteUrl}/_api/web/roleassignments?$expand=Member/users,RoleDefinitionBindings`;
const permsResponse = await fetch(permsEndpoint, {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose',
},
})
const permsData = await permsResponse.json();
const roleAssignments = permsData.d.results;
if (!permsResponse.ok) {
throw new Error(`Error fetching roleassignments ${group.Title}: ${permsResponse.statusText}`);
// Erreur lors de la récupération des utilisateurs pour le groupe
}
// Iterate through each group and display its information
for (const group of groups) {
// Fetch the role assignments for the group
// Fetch the users in the group
const usersEndpoint = `${siteUrl}/_api/web/sitegroups(${group.Id})/users`;
const usersResponse = await fetch(usersEndpoint, {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose',
},
});
// Check if the response is ok
if (!usersResponse.ok) {
throw new Error(`Error fetching users for group ${group.Title}: ${usersResponse.statusText}`);
// Erreur lors de la récupération des utilisateurs pour le groupe
}
// Parse the JSON response
const usersData = await usersResponse.json();
const users = usersData.d.results;
// Create a div for the group
const groupDiv = document.createElement('div');
groupDiv.className = 'group';
console.log(group.Title);
// Create a header for the group
const groupHeader = document.createElement('h3');
groupHeader.textContent = `Group: ${group.Title}`;
// Groupe :
groupDiv.appendChild(groupHeader);
// Create a list for the permission levels
console.log("permissionsList", roleAssignments, group);
const permissionsList = document.createElement('ul');
roleAssignments.forEach(roleAssignment => {
if(roleAssignment.PrincipalId == group.Id){
//Description Name
roleAssignment.RoleDefinitionBindings.results.forEach(RoleDefinitionBinding => {
//RoleDefinitionBindings.results
const permissionItem = document.createElement('li');
permissionItem.textContent = `Permission Level: '${RoleDefinitionBinding.Name}' ${RoleDefinitionBinding.Description}`;
// Niveau de permission :
permissionsList.appendChild(permissionItem);
});
}
});
groupDiv.appendChild(permissionsList);
// Create a list for the users in the group
const usersList = document.createElement('ul');
users.forEach(user => {
const userItem = document.createElement('li');
userItem.textContent = `User: ${user.Title}`;
// Utilisateur :
usersList.appendChild(userItem);
});
groupDiv.appendChild(usersList);
// Append the group div to the target div
targetDiv.appendChild(groupDiv);
}
} catch (error) {
// Log the error to the console
console.error(`Error: ${error.message}`);
// Erreur :
// Optionally, display the error message in the target div
const targetDiv = document.getElementById(targetDivId);
if (targetDiv) {
targetDiv.innerHTML = `
Error: ${error.message}
`; //
Erreur : } } } // Example usage await listSharePointGroupsWithPermissions('https://test.sharepoint.com/sites/ssss', 'vpc_WebPart.unknown.a90bc6dc-fba2-4b5c-b7e2-f72005f01a14');
SharePoint Get All Documents Permissions
On 13/12/2024
Get all RoleAssignments from a document library even more than 5000 elements
only when HasUniqueRoleAssignments == true
let currentSort = { column: null, direction: 'asc' }; // Store the current sort state
// Creates the style element
function createStyleElement(id, content) {
var style = document.createElement("style");
style.type = "text/css";
style.id = id;
style.innerHTML = content;
if (style.styleSheet) {
style.styleSheet.cssText = content;
} else {
let st = document.getElementById(id);
if (st == undefined) {
var head = document.head || document.getElementsByTagName("head")[i];
head.appendChild(style);
} else {
st.innerHTML = content;
}
}
return style;
}
// Function to filter the table based on dropdown selection
function filterTable(columnIndex, value) {
let table, tr, td, i, select, selectedValue, txtValue;
table = document.querySelector("table");
tr = table.getElementsByTagName("tbody")[0].getElementsByTagName("tr");
select = table.getElementsByTagName("select")[columnIndex];
//debugger;
selectedValue = value;
// Loop through all table rows and hide those that don't match the filter
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[columnIndex];
if (td) {
txtValue = td.textContent || td.innerText;
if (selectedValue === "" || txtValue === selectedValue) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
function sortTable(columnIndex, direction) {
let table, rows, switching, i, x, y, shouldSwitch;
table = document.querySelector("table");
switching = true;
let tbody = table.querySelector("tbody");
// Set the current sort state
currentSort.column = columnIndex;
currentSort.direction = direction;
while (switching) {
switching = false;
rows = tbody.rows;
for (i = 0; i < rows.length - 1; i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("td")[columnIndex];
y = rows[i + 1].getElementsByTagName("td")[columnIndex];
let isNumber = false;
if (!isNaN(x.innerHTML)) {
// Check if rows should switch based on ascending or descending order
if (direction === 'asc') {
if (parseFloat(x.innerHTML) > parseFloat(y.innerHTML)) {
shouldSwitch = true;
break;
}
} else if (direction === 'desc') {
if (parseFloat(x.innerHTML) < parseFloat(y.innerHTML)) {
shouldSwitch = true;
break;
}
}
}
else {
// Check if rows should switch based on ascending or descending order
if (direction === 'asc') {
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
} else if (direction === 'desc') {
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
}
}
}
// Function to generate the table
function generateTableFromJson2(jsonArray, select, addHeaders = true) {
const style = `
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 8px 12px;
text-align: left;
border: 1px solid #ddd;
}
tbody tr{
max-height: 15px;
}
th {
background-color: #f4f4f4;
color: #000;
}
/* Scrollable table wrapper */
.table-wrapper {
max-height: 800px;
overflow-y: auto;
border: 1px solid #ddd;
}
/* Style for dropdowns in header */
select {
width: 100%;
padding: 4px;
margin-top: 5px;
}
/* Style for the sorting arrows */
.sort-arrows {
cursor: pointer;
margin-left: 5px;
}
`;
createStyleElement("fdiStyle", style);
// Create table element
let table = document.createElement('table');
// Create table header
let header = table.createTHead();
let headerRow = header.insertRow(0);
// Get keys (headers) from the first object in the JSON array
//let keys = Object.keys(jsonArray[0]);
let keys = select.split(",");
if (addHeaders) {
keys.forEach((key, index) => {
if (key !== "__metadata") {
let th = document.createElement('th');
th.innerHTML = key;
// Create a dropdown (select) for filtering
let select = document.createElement('select');
select.addEventListener('change', function () {
const selectedValue = select.value;
filterTable(index, selectedValue);
});
// Populate dropdown with unique values from the JSON data
let uniqueValues = [...new Set(jsonArray.map(item => item[key]))];
// Add a default "All" option for no filter
let optionAll = document.createElement('option');
optionAll.value = "";
optionAll.text = `All`;
select.appendChild(optionAll);
// Create an option for each unique value
if (typeof (uniqueValues[0]) === typeof (1)) {
const pp = uniqueValues.sort((a, b) => {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
});
pp.forEach(value => {
let option = document.createElement('option');
option.value = value;
option.text = value;
select.appendChild(option);
});
} else
uniqueValues.sort().forEach(value => {
let option = document.createElement('option');
option.value = value;
option.text = value;
select.appendChild(option);
});
// Sort arrows for sorting the columns
let upArrow = document.createElement('span');
upArrow.innerHTML = '⬆️';
upArrow.classList.add('sort-arrows');
upArrow.onclick = () => sortTable(index, 'asc');
let downArrow = document.createElement('span');
downArrow.innerHTML = '⬇️';
downArrow.classList.add('sort-arrows');
downArrow.onclick = () => sortTable(index, 'desc');
th.appendChild(select); // Append the dropdown to the header
th.appendChild(upArrow); // Append the dropdown to the header
th.appendChild(downArrow); // Append the dropdown to the header
headerRow.appendChild(th);
}
});
}
// Create table body and populate rows with data
let tbody = document.createElement('tbody');
jsonArray.forEach((item) => {
let row = tbody.insertRow();
keys = select.split(",");
keys.forEach((key) => {
let cell = row.insertCell();
if (key !== "__metadata") {
cell.setAttribute("nowrap", "nowrap");
if (key === "RoleDefinitionBindings") {
cell.appendChild(generateTableFromJson2(item.RoleDefinitionBindings.results, "Name,Id", false));
} else if (key.indexOf("/") > 0) {
cell.innerHTML = item[key.split("/")[0]][key.split("/")[1]]
} else
cell.innerHTML = item[key]; // Insert each value from the JSON into the table cell
}
});
});
// Append the body to the table
table.appendChild(tbody);
return table;
}
function removeSlasches(select, datas) {
const ret = [];
const fields = select.split(',');
for (let i = 0; i < datas.length; i++) {
const toAdd = {};
for (let j = 0; j < fields.length; j++) {
if (fields[j].indexOf('/') > 0) {
const splitted = fields[j].split('/');
toAdd[splitted.join('')] = datas[i][splitted[0]][splitted[1]];
} else
toAdd[fields[j]] = datas[i][fields[j]];
}
ret.push(toAdd);
}
console.log("removeSlasches", ret);
return ret;
}
async function GetPermissionsInFolder(siteUrl, listUrl1, query) {
// Fetch options with headers for authentication and response format
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
};
//get web relativeUrl
var req = `${siteUrl}/_api/web?$select=ServerRelativeUrl`;
const webServerRelativUrl = (await (await fetch(req, fetchOptions)).json()).d.ServerRelativeUrl;
let query1 = "";
if (`${query}`.trim() !== "") {
query1 = `&$filter=${query}`;
query = ` and ${query}`;
}
//get firstId
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items?$select=Id&$top=1&$orderby=Id asc`;
console.log("req", req);
const firstId = 0;//(await (await fetch(req, fetchOptions)).json()).d.results[0].Id;
console.log("firstId", firstId);
//get lastId
//req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items?$select=Id&$filter=Id gt 170 and Id lt 533&$top=1&$orderby=Id desc`;
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items?$select=Id&$top=1&$orderby=Id desc`;
console.log("last", req);
const lastId = (await (await fetch(req, fetchOptions)).json()).d.results[0].Id;
console.log("lastId", lastId);
let startId = firstId;
let endId = firstId + 5000;
var allItems = [];
console.log(`startId ${startId} endId ${endId} lastId ${lastId}`)
console.log("query", query);
do {
var select = "?$select=FileDirRef,RoleAssignments,HasUniqueRoleAssignments,Id,Title,FileLeafRef,Modified,Created";
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items${select}&$filter=Id ge ${startId} and Id lt ${endId}${query}&$orderby=Id asc&$top=5000`;
console.log("req", req);
// Send the asynchronous GET request to the REST API endpoint
var respList1 = await fetch(req, fetchOptions);
const items = (await respList1.json()).d.results;
//get only items with unique permissions
const withUniquePermissions = items.filter(user => user.HasUniqueRoleAssignments);
console.log("withUniquePermissions", withUniquePermissions.length);
allItems.push(...items);
startId += 5000;
endId += 5000;
console.log(`startId ${startId} endId ${endId} lastId ${lastId}`)
}
while (endId < lastId);
return allItems;
}
async function batchFetchPermissions(siteUrl, itemIds, listUrl1) {
const batchBoundary = "batch_" + new Date().getTime();
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
};
const webServerRelativUrl = (await (await fetch(`${siteUrl}/_api/web?$select=ServerRelativeUrl`, fetchOptions)).json()).d.ServerRelativeUrl;
console.log("itemIds", itemIds);
const results = [];
const batchBody = itemIds.map((item) => {
return `
--${batchBoundary}
Content-Type: application/http
Content-Transfer-Encoding: binary
GET ${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items(${item.Id})/RoleAssignments?$expand=Member,RoleDefinitionBindings HTTP/1.1
Accept: application/json;odata=verbose
`;
}).join("\n") + `\n--${batchBoundary}--`;
const digest = await GetDigestValue(siteUrl);//
console.log("batchBody", batchBody);
const headers = {
Accept: "application/json;odata=verbose",
"X-RequestDigest": digest,
"Content-Type": `multipart/mixed; boundary="${batchBoundary}"`,
};
console.log("itemIds", itemIds.length);
const response = await fetch(`${siteUrl}/_api/$batch`, {
method: "POST",
headers,
body: batchBody,
});
const text = await response.text(); // Parse response manually (multipart)
const responses = text.split("HTTP/1.1 200 OK");
let index = 0;
for (let k = 1; k < responses.length; k++) {
const parts = responses[k].split("\r\n\r\n")[1];
// The JSON is the last part after the headers
let jsonString = parts[parts.length - 1];
// Parse the JSON
jsonString = parts.split("\r\n")[0];
const jsonData = JSON.parse(jsonString.trim());
console.log("forEach jsonData", jsonData);
results.push({
"Index": index,
"item": itemIds[index],
"permissions": permissionParser(jsonData)
});
index++;
}
console.log("results", results);
return results;
}
function permissionParser(perms) {
const res = perms.d.results;
const permes = [];
res.map((m) => {
const a = {
"userName": m.Member.Email ? m.Member.Email : m.Member.Title,
permissions: []
};
a.permissions.push(m.RoleDefinitionBindings.results.map((b) => { return b.Name }));
permes.push(a);
});
return permes;
}
async function GetDigestValue(siteUrl) {//
const fetchOptions = {
method: 'POST',
headers: {
'Accept': 'application/json;odata=verbose',
'Content-type': 'application/json;odata=verbose'
}
};
const response = await fetch(siteUrl + "/_api/contextinfo", fetchOptions);
return (await response.json()).d.GetContextWebInformation.FormDigestValue;
}
function chunkArray(array, chunkSize) {
let result = [];
for (let i = 0; i < array.length; i += chunkSize) {
// Utilise slice pour découper le tableau
result.push(array.slice(i, i + chunkSize));
}
return result;
}
const siteUrl = _spPageContextInfo.webAbsoluteUrl || "https://test.sharepoint.com/sites/BIPvvvv";
const withUniquePermissions = await GetPermissionsInFolder(siteUrl, "Shared%20Documents", "");
//"startswith(FileDirRef, '/sites/BIPvvvv/Shared%20Documents/General/07%20-%20Release%201')"
console.log("withUniquePermissions", withUniquePermissions);
console.log("withUniquePermissions length", withUniquePermissions.length);
const permmissionItemsAll = [];
if (withUniquePermissions.length > 0) {
const withUniquePermissionsCutted = chunkArray(withUniquePermissions, 30);
for (let i = 0; i < withUniquePermissionsCutted.length; i++) {
//debugger;
const permmissionItems = await batchFetchPermissions(siteUrl, withUniquePermissionsCutted[i], "Shared%20Documents");
permmissionItemsAll.push(...permmissionItems)
}
console.log("permmissionItems", permmissionItemsAll);
}
/*
*/
//FileDirRef,RoleAssignments,HasUniqueRoleAssignments,Id,Title,FileLeafRef,Modified,Created
const toDisplay = [];
let csv = "Id;Title;Modified;Created;UserPermission;Permissions;FileLeafRef;FileDirRef\n";
for (let i = 0; i < permmissionItemsAll.length; i++) {
const permmissionItem = permmissionItemsAll[i];
for (let j = 0; j < permmissionItem.permissions.length; j++) {
for (let k = 0; k < permmissionItem.permissions[j].permissions.length; k++) {
//debugger;
const item = {
"Id": permmissionItem.item.Id,
"FileDirRef": permmissionItem.item.FileDirRef,
"HasUniqueRoleAssignments": permmissionItem.item.HasUniqueRoleAssignments,
"Title": permmissionItem.item.Title,
"FileLeafRef": permmissionItem.item.FileLeafRef,
"FileDirRef": permmissionItem.item.FileDirRef,
"Modified": permmissionItem.item.Modified,
"Created": permmissionItem.item.Created,
"UserPermission": permmissionItem.permissions[j].userName,
"Permissions": permmissionItem.permissions[j].permissions[k]
}
csv += `${item.Id};${item.Title};${item.Modified};${item.Created};${item.UserPermission};${item.Permissions};${item.FileLeafRef};${item.FileDirRef}` + "\n";
toDisplay.push(item);
}
}
}
const table = generateTableFromJson2(toDisplay, "Id,Title,Modified,Created,UserPermission,Permissions,FileLeafRef,FileDirRef");
console.log("csv", csv);
// Append the table to the container
document.getElementById('tableContainer').appendChild(table);
navigator.clipboard.writeText(csv);
SharePoint Rest Get All Items In A folder even more than 5000
On 11/12/2024
async function GetPermissionsInFolder(siteUrl, listUrl1, query) {
// Fetch options with headers for authentication and response format
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
};
//get web relativeUrl
var req = `${siteUrl}/_api/web?$select=ServerRelativeUrl`;
const webServerRelativUrl = (await (await fetch(req, fetchOptions)).json()).d.ServerRelativeUrl;
let query1 = "";
if (`${query}`.trim() !== "") {
query1 = `&$filter=${query}`;
query = ` and ${query}`;
}
//get firstId
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items?$select=Id&$top=1&$orderby=Id asc`;
console.log("req", req);
const firstId = 0;//(await (await fetch(req, fetchOptions)).json()).d.results[0].Id;
console.log("firstId", firstId);
//get lastId
//req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items?$select=Id&$filter=Id gt 170 and Id lt 533&$top=1&$orderby=Id desc`;
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items?$select=Id&$top=1&$orderby=Id desc`;
console.log("last", req);
const lastId = (await (await fetch(req, fetchOptions)).json()).d.results[0].Id;
console.log("lastId", lastId);
let startId = firstId;
let endId = firstId + 5000;
var allItems = [];
console.log(`startId ${startId} endId ${endId} lastId ${lastId}`)
console.log("query", query);
do {
var select = "?$select=FileDirRef,RoleAssignments,HasUniqueRoleAssignments,Id,Title,FileLeafRef,Modified,Created";
req = `${siteUrl}/_api/web/getlist('${webServerRelativUrl}/${listUrl1}')/items${select}&$filter=Id ge ${startId} and Id lt ${endId}${query}&$orderby=Id asc&$top=5000`;
console.log("req", req);
// Send the asynchronous GET request to the REST API endpoint
var respList1 = await fetch(req, fetchOptions);
const items = (await respList1.json()).d.results;
allItems.push(...items);
startId += 5000;
endId += 5000;
console.log(`startId ${startId} endId ${endId} lastId ${lastId}`)
}
while (endId < lastId);
return allItems;
}
const siteUrl = _spPageContextInfo.webAbsoluteUrl;
const items = await GetPermissionsInFolder(siteUrl, "Shared%20Documents", "");
console.log("items", items);
console.log("items length", items.length);
SharePoint get by Rest List Role DefinitionBindings
On 28/10/2024
let currentSort = { column: null, direction: 'asc' }; // Store the current sort state
// Creates the style element
function createStyleElement(id, content) {
var style = document.createElement("style");
style.type = "text/css";
style.id = id;
style.innerHTML = content;
if (style.styleSheet) {
style.styleSheet.cssText = content;
} else {
let st = document.getElementById(id);
if (st == undefined) {
var head = document.head || document.getElementsByTagName("head")[i];
head.appendChild(style);
} else {
st.innerHTML = content;
}
}
return style;
}
// Function to filter the table based on dropdown selection
function filterTable(columnIndex, value) {
let table, tr, td, i, select, selectedValue, txtValue;
table = document.querySelector("table");
tr = table.getElementsByTagName("tbody")[0].getElementsByTagName("tr");
select = table.getElementsByTagName("select")[columnIndex];
//debugger;
selectedValue = value;
// Loop through all table rows and hide those that don't match the filter
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[columnIndex];
if (td) {
txtValue = td.textContent || td.innerText;
if (selectedValue === "" || txtValue === selectedValue) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
function sortTable(columnIndex, direction) {
let table, rows, switching, i, x, y, shouldSwitch;
table = document.querySelector("table");
switching = true;
let tbody = table.querySelector("tbody");
// Set the current sort state
currentSort.column = columnIndex;
currentSort.direction = direction;
while (switching) {
switching = false;
rows = tbody.rows;
for (i = 0; i < rows.length - 1; i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("td")[columnIndex];
y = rows[i + 1].getElementsByTagName("td")[columnIndex];
let isNumber = false;
if (!isNaN(x.innerHTML)) {
// Check if rows should switch based on ascending or descending order
if (direction === 'asc') {
if (parseFloat(x.innerHTML) > parseFloat(y.innerHTML)) {
shouldSwitch = true;
break;
}
} else if (direction === 'desc') {
if (parseFloat(x.innerHTML) < parseFloat(y.innerHTML)) {
shouldSwitch = true;
break;
}
}
}
else {
// Check if rows should switch based on ascending or descending order
if (direction === 'asc') {
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
} else if (direction === 'desc') {
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
}
}
}
// Function to generate the table
function generateTableFromJson2(jsonArray, select, addHeaders = true) {
const style = `
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 8px 12px;
text-align: left;
border: 1px solid #ddd;
}
tbody tr{
max-height: 15px;
}
th {
background-color: #f4f4f4;
color: #000;
}
/* Scrollable table wrapper */
.table-wrapper {
max-height: 800px;
overflow-y: auto;
border: 1px solid #ddd;
}
/* Style for dropdowns in header */
select {
width: 100%;
padding: 4px;
margin-top: 5px;
}
/* Style for the sorting arrows */
.sort-arrows {
cursor: pointer;
margin-left: 5px;
}
`;
createStyleElement("fdiStyle", style);
// Create table element
let table = document.createElement('table');
// Create table header
let header = table.createTHead();
let headerRow = header.insertRow(0);
// Get keys (headers) from the first object in the JSON array
//let keys = Object.keys(jsonArray[0]);
let keys = select.split(",");
if (addHeaders) {
keys.forEach((key, index) => {
if (key !== "__metadata") {
let th = document.createElement('th');
th.innerHTML = key;
// Create a dropdown (select) for filtering
let select = document.createElement('select');
select.addEventListener('change', function () {
const selectedValue = select.value;
filterTable(index, selectedValue);
});
// Populate dropdown with unique values from the JSON data
let uniqueValues = [...new Set(jsonArray.map(item => item[key]))];
// Add a default "All" option for no filter
let optionAll = document.createElement('option');
optionAll.value = "";
optionAll.text = `All`;
select.appendChild(optionAll);
// Create an option for each unique value
if (typeof (uniqueValues[0]) === typeof (1)) {
const pp = uniqueValues.sort((a, b) => {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
});
pp.forEach(value => {
let option = document.createElement('option');
option.value = value;
option.text = value;
select.appendChild(option);
});
} else
uniqueValues.sort().forEach(value => {
let option = document.createElement('option');
option.value = value;
option.text = value;
select.appendChild(option);
});
// Sort arrows for sorting the columns
let upArrow = document.createElement('span');
upArrow.innerHTML = '⬆️';
upArrow.classList.add('sort-arrows');
upArrow.onclick = () => sortTable(index, 'asc');
let downArrow = document.createElement('span');
downArrow.innerHTML = '⬇️';
downArrow.classList.add('sort-arrows');
downArrow.onclick = () => sortTable(index, 'desc');
th.appendChild(select); // Append the dropdown to the header
th.appendChild(upArrow); // Append the dropdown to the header
th.appendChild(downArrow); // Append the dropdown to the header
headerRow.appendChild(th);
}
});
}
// Create table body and populate rows with data
let tbody = document.createElement('tbody');
jsonArray.forEach((item) => {
let row = tbody.insertRow();
keys = select.split(",");
keys.forEach((key) => {
let cell = row.insertCell();
if (key !== "__metadata") {
cell.setAttribute("nowrap", "nowrap");
if (key === "RoleDefinitionBindings") {
cell.appendChild(generateTableFromJson2(item.RoleDefinitionBindings.results, "Name,Id", false));
} else if (key.indexOf("/") > 0) {
cell.innerHTML = item[key.split("/")[0]][key.split("/")[1]]
} else
cell.innerHTML = item[key]; // Insert each value from the JSON into the table cell
}
});
});
// Append the body to the table
table.appendChild(tbody);
return table;
}
function removeSlasches(select, datas) {
const ret = [];
const fields = select.split(',');
for (let i = 0; i < datas.length; i++) {
const toAdd = {};
for (let j = 0; j < fields.length; j++) {
if (fields[j].indexOf('/') > 0) {
const splitted = fields[j].split('/');
toAdd[splitted.join('')] = datas[i][splitted[0]][splitted[1]];
} else
toAdd[fields[j]] = datas[i][fields[j]];
}
ret.push(toAdd);
}
console.log("removeSlasches", ret);
return ret;
}
// Function to get permissions for a SharePoint group
async function getSharePointPermissions(siteUrl, select) {
// REST API endpoint to get group permissions
const endpoint = `${siteUrl}`;
// Fetch options with headers for authentication and response format
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
};
console.log("endpoint", endpoint);
// Send the asynchronous GET request to the REST API endpoint
const response = await fetch(endpoint, fetchOptions);
// Check if the response is OK (status code 200)
if (!response.ok) {
throw new Error(`Error fetching permissions: ${response.statusText}`);
}
// Parse the JSON response to extract permission data
const data = await response.json();
// Extract role assignments (permissions)
const roleAssignments = data.d.results;
console.log('roleAssignments', roleAssignments);
console.log(JSON.stringify(roleAssignments));
const D1 = removeSlasches(select, roleAssignments)
const pattern2 = /\//g;
console.log("json111", JSON.stringify(D1));
const table = generateTableFromJson2(D1, select.replace(pattern2, ""));
// Append the table to the container
document.getElementById('tableContainer').appendChild(table);
}
// Usage example: Replace 'your-group-id' and 'your-site-url' with actual values
const select = "Member/Title,Member/Id,Member/LoginName,RoleDefinitionBindings";
let siteUrl = 'https://mySite.sharepoint.com/sites/Dev_wf';
siteUrl += `/_api/web/roleassignments/?$expand=RoleDefinitionBindings,Member&$select=${select}`; // Replace with the actual site URL
document.body.innerHTML = `<div id="tableContainer" class="table-wrapper"></div>`; await getSharePointPermissions(siteUrl, select);

Power Automate Add Field To ContentType
On 03/10/2024
Power Automate Add Field To ContentType (reference Microsoft)
Note the following restrictions on adding a field (column) to a content type using the REST service:
- Site Columns cannot be added to a content type using the REST service.
- You can add a field to a site content type only if the field already exists on the parent content type.
- You can add a field to a content type associated with a list only if the field already exists on the list. To add a completely new field to a list content type, you have to first add it to the list and then add it to the content type in a separate call to the REST service.

Invalid - Must not be used. The value = 0.
Integer - Specifies that the field contains an integer value. The value = 1.
Text - Specifies that the field contains a single line of text. The value = 2.
Note - Specifies that the field contains multiple lines of text. The value = 3.
DateTime - Specifies that the field contains a date and time value or a date-only value. The value = 4.
Counter - Specifies that the field contains a monotonically increasing integer. The value = 5.
Choice - Specifies that the field contains a single value from a set of specified values. The value = 6.
Lookup - Specifies that the field is a lookup field. The value = 7.
Boolean - Specifies that the field contains a Boolean value. The value = 8.
Number - Specifies that the field contains a floating-point number value. The value = 9.
Currency - Specifies that the field contains a currency value. The value = 10.
URL - Specifies that the field contains a URI and an optional description of the URI. The value = 11.
Computed - Specifies that the field is a computed field. The value = 12.
Threading - Specifies that the field indicates the thread for a discussion item in a threaded view of a discussion board. The value = 13.
Guid - Specifies that the field contains a GUID value. The value = 14.
MultiChoice - Specifies that the field contains one or more values from a set of specified values. The value = 15.
GridChoice - Specifies that the field contains rating scale values for a survey list. The value = 16.
Calculated - Specifies that the field is a calculated field. The value = 17.
File - Specifies that the field contains the leaf name of a document as a value. The value = 18.
Attachments - Specifies that the field indicates whether the list item has attachments. The value = 19.
User - Specifies that the field contains one or more users and groups as values. The value = 20.
Recurrence - Specifies that the field indicates whether a meeting in a calendar list recurs. The value = 21.
CrossProjectLink - Specifies that the field contains a link between projects in a Meeting Workspace site. The value = 22.
ModStat - Specifies that the field indicates moderation status. The value = 23.
Error - Specifies that the type of the field was set to an invalid value. The value = 24.
ContentTypeId - Specifies that the field contains a content type identifier as a value. The value = 25.
PageSeparator - Specifies that the field separates questions in a survey list onto multiple pages. The value = 26.
ThreadIndex - Specifies that the field indicates the position of a discussion item in a threaded view of a discussion board. The value = 27.
WorkflowStatus - Specifies that the field indicates the status of a workflow instance on a list item. The value = 28.
AllDayEvent - Specifies that the field indicates whether a meeting in a calendar list is an all-day event. The value = 29.
WorkflowEventType - Specifies that the field contains the most recent event in a workflow instance. The value = 30.
MaxItems - Must not be used. The value = 31.
Get User Permissions By Mail And Javascript
On 09/09/2024
Get User Permissions By Mail And Javascript
let siteUrl = "https://mayTenant.sharepoint.com/sites/test"
async function getUserPermissions(siteUrl, userMail) {
// REST API endpoint to get group permissions
const endpoint = `${siteUrl}/_api/web/siteusers?$filter=Email eq '${userMail}'&$select=Id`;
//const endpoint = `${siteUrl}/_api/web/siteusers?$filter=Email eq '${userMail}'&$select=LoginName`;
// Fetch options with headers for authentication and response format
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
};
console.log("endpoint", endpoint);
// Send the asynchronous GET request to the REST API endpoint
const response = await fetch(endpoint, fetchOptions);
// Check if the response is OK (status code 200)
if (!response.ok) {
throw new Error(`Error fetching permissions: ${response.statusText}`);
}
// Parse the JSON response to extract permission data
const data = await response.json();
console.log("data", data);
if (data.d.results.length === 0) {
console.log("user not found", userMail);
} else {
const userId = `${data.d.results[0].Id}`;
for (const user in data.d.results) {
console.log("user", userMail);
}
let ret = "";
const endpoint2 = `${siteUrl}/_api/web//RoleAssignments/GetByPrincipalId(${userId})/RoleDefinitionBindings`;
// Send the asynchronous GET request to the REST API endpoint
const response2 = await fetch(endpoint2, fetchOptions);
const data2 = await response2.json();
console.log("data2", data2);
for (let i = 0; i < data2.d.results.length; i++) {
ret += `User ${data2.d.results[0].Name} : ${data2.d.results[0].Description}\r\n`;
}
//by groups
const getGroupsEndPoint = `${siteUrl}/_api/web/GetUserById(${userId})/groups?$select=Id,Title`;
const response3 = await fetch(getGroupsEndPoint, fetchOptions);
const data3 = await response3.json();
console.log("data3", data3);
for (let i = 0; i < data3.d.results.length; i++) {
//get group permissions
const endpoint4 = `${siteUrl}/_api/web//RoleAssignments/GetByPrincipalId(${data3.d.results[i].Id})/RoleDefinitionBindings`;
const response4 = await fetch(endpoint4, fetchOptions);
const data4 = await response4.json();
console.log("data4", data4);
for (let j = 0; j < data4.d.results.length; j++) {
ret += `Group ${data3.d.results[i].Title} Id ${data3.d.results[i].Id} : ${data4.d.results[j].Name} : ${data4.d.results[j].Description}. ` + "\r\n";
}
}
return `${ret}.`;
}
return null;
}
await getUserPermissions(siteUrl, "test-ext@test.com");
Permissions to Check:
Here are some common permissions encoded in the High and Low values:
- ViewListItems: 0x00000001
- AddListItems: 0x00000002
- EditListItems: 0x00000004
- DeleteListItems: 0x00000008
- OpenItems: 0x00000010
- ViewVersions: 0x00000020
- CancelCheckout: 0x00000040
- ManagePermissions: 0x00010000
- ManageWeb: 0x00040000
SharePoint List Users And Their Groups By JS to CSV
On 06/09/2024
let siteUrl = '';
async function getUsersGroups(siteUrl) {
// REST API endpoint to get group permissions
const endpoint = `${siteUrl}`;
// Fetch options with headers for authentication and response format
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
};
console.log("endpoint", endpoint);
// Send the asynchronous GET request to the REST API endpoint
const response = await fetch(endpoint, fetchOptions);
// Check if the response is OK (status code 200)
if (!response.ok) {
throw new Error(`Error fetching permissions: ${response.statusText}`);
}
// Parse the JSON response to extract permission data
const data = await response.json();
console.log("data", data);
let csv = "Title;Email;LoginName;Id;IsSiteAdmin;UserOnly;GroupTitle;GroupId;Owner;Description;AllowMembersEditMembership;AllowRequestToJoinLeave;AutoAcceptRequestToJoinLeave;GroupId;Limited\r\n";
for (const user of data.d.results) {
//debugger;
if (user.Groups && user.Groups.results && user.Groups.results.length > 0) {
csv += `${user.Title};${user.Email};${user.LoginName};${user.Id};${user.IsSiteAdmin};true;;;;;;;;;NoLimited\r\n`;
for (const group of user.Groups.results) {
let limited = "not"
if (`${group.Title}`.indexOf("imited") > 0) {
limited = "Limited";
}
csv += `${user.Title};${user.Email};${user.LoginName};${user.Id};${user.IsSiteAdmin};group;${group.Title};${group.Id};${group.OwnerTitle};${group.Description};${group.AllowMembersEditMembership};${group.AllowRequestToJoinLeave};${group.AutoAcceptRequestToJoinLeave};${group.Id};${limited}\r\n`;
}
} else
csv += `${user.Title};${user.Email};${user.LoginName};${user.Id};${user.IsSiteAdmin};noGroup;;;;;;;;;noGroup\r\n`;
}
console.log("csv", csv);
}
let query = `/_api/web/siteusers?$select=IsSiteAdmin,Email,Id,LoginName,Title&$expand=Groups`;
await getUsersGroups(siteUrl + query);
Get SharePoint Web Permissions
On 05/09/2024
Gets sharepoint roleassignements and display page, and createcsv text
// The content of the stylesheet
const styleSheetContent = '
.container {
display: grid;
row-gap: 10px;
/* 20px gap between rows */
column-gap: 10px;
/* 10px gap between columns */
grid-template-columns: 1fr 1fr 1fr 1fr;
padding-bottom: 5px;
}
.container2 {
display: grid;
row-gap: 10px;
/* 20px gap between rows */
column-gap: 10px;
/* 10px gap between columns */
grid-template-columns: 1fr 1fr 1fr;
padding-bottom: 5px;
}
.container .header {
text-align: center;
border: 1px solid black;
}
.container .data {
border: 1px solid black;
}
';
// Creates the style element
function createStyleElement(id, content) {
var style = document.createElement("style");
style.type = "text/css";
style.id = id;
style.innerHTML = content;
if (style.styleSheet) {
style.styleSheet.cssText = content;
} else {
let st = document.getElementById(id);
if(st == undefined){
var head = document.head || document.getElementsByTagName("head")[0];
head.appendChild(style);
} else {
st.innerHTML = content;
}
}
return style;
}
// Function to get permissions for a SharePoint group
async function getSharePointPermissions(siteUrl) {
// REST API endpoint to get group permissions
const endpoint = '${siteUrl}';
// Fetch options with headers for authentication and response format
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
};
console.log("endpoint", endpoint);
// Send the asynchronous GET request to the REST API endpoint
const response = await fetch(endpoint, fetchOptions);
// Check if the response is OK (status code 200)
if (!response.ok) {
throw new Error('Error fetching permissions: ${response.statusText}');
}
// Parse the JSON response to extract permission data
const data = await response.json();
// Extract role assignments (permissions)
const roleAssignments = data.d.results;
console.log('roleAssignments: ', data.d.results);
createStyleElement("fdiStyle", styleSheetContent);
let repportCSV = 'Title;LoginName;Id;Role_Name;Role_Description;Role;Id';
repportCSV += "\r\n";
document.body.innerHTML = '<div class="container">
<div class="header">Title</div>
<div class="header">LoginName</div>
<div class="header">Id</div>
<div class="header">Role
<div class="container2">
<div class="data">Name</div>
<div class="data">Description</div>
<div class="data">Id</div>
</div>
</div>
</div>';
// Report permissions
roleAssignments.forEach(roleAssignment => {
const member = roleAssignment.Member;
const roleBindings = roleAssignment.RoleDefinitionBindings.results;
repportCSV+= '${member.Title};${member.LoginName};${member.Id}';
let div = '
<div class="container">
<div class="data">${member.Title}</div>
<div class="data">${member.LoginName}</div>
<div class="data">${member.Id}</div>';
roleBindings.forEach(role => {
repportCSV+= ';${role.Name};${role.Description};${role.Id}';
repportCSV += "\r\n";
div += '
<div class="container2">
<div class="data">${role.Name}</div>
<div class="data">${role.Description}</div>
<div class="data">${role.Id}</div>
</div>
';
console.log(' - Role: ${role.Name}');
});
div += "";
document.body.innerHTML += div;
});
console.log("datas", repportCSV);
}
// Usage example: 'your-site-url' with actual values
let siteUrl = '';
siteUrl += '/_api/web/roleassignments/?$expand=RoleDefinitionBindings,Member&$select=Member/Title,Member/Id,Member/LoginName'; // Replace with the actual site URL
getSharePointPermissions(siteUrl);
SharePoint Restore File Version
On 03/06/2024
/_api/web/getlist('/sites/MySite/MyDocLib')/items(341)/File/versions/restoreByLabel(versionlabel='5.0')
Power Automate Update ListItem ContentType
On 06/05/2024
Power Automate Update ListItem ContentType
With "Send an HTTP request to SharePoint"
Headers :
{ "Accept": "application/json; odata=verbose", "content-type": "application/json; odata=verbose", "X-HTTP-Method": "MERGE", "If-Match": "*" }![]()
Sharepoint REST
On 19/02/2024
PnP references
Get field in list
/_api/Web/Lists/getbytitle('Pages')/Fields?$select=InternalName,Id,Hidden,TypeAsString,Required&$filter=InternalName eq 'Title'
Get list content types
Get contentType fields
/_api/Web/Lists/getbytitle('Pages')/ContentTypes('0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF390028D78BF8D3054E38BEF0590B43C4BA0E00572E4F21E9A2274ABC0C3A6B4238D562')/fields?$filter=(Hidden eq false)and (Group ne '_Hidden')&$select= InternalName,Hidden,Required,Title,TypeAsString,Required,Id,Group
Query search
/_api/search/query?querytext='Path:https://mcn365.sharepoint.com/sites/a_IntranetPays_42/sitePages/*'&selectproperties='Title,Path'
/_api/search/query?querytext='owstaxIdJiveTags:GP0*+OR+owstaxIdJiveCategories:GP0*'&rowsperpage=0&rowlimit=5&selectproperties='Title%2cowstaxIdJiveCategories%2cowstaxIdJiveTags'&sortlist='Rank:descending%2cmodifiedby:ascending'&clienttype='ContentSearchRegular'">https://mcncs36sddcsdcsint.com/sites/a_IntranetPays_42/_api/search/query?querytext='owstaxIdJiveTags:GP0*+OR+owstaxIdJiveCategories:GP0*'&rowsperpage=0&rowlimit=5&selectproperties='Title%2cowstaxIdJiveCategories%2cowstaxIdJiveTags'&sortlist='Rank:descending%2cmodifiedby:ascending'&clienttype='ContentSearchRegular'
/_api/Web/Lists/getbytitle('Pages')/ContentTypes('0x010100C568DB52D9D0A1d37AF390028D78BF8D3054E38BEF0590B43C4BA0E00572E4F21E9A2274ABC0C3A6B4238D562')/fields?$filter=(Hidden eq false)and (Group ne '_Hidden')&$select= InternalName,Hidden,Required,Title,TypeAsString,Required,Id,Group
query user multi
/_api/web/lists/getbytitle('ResponsableRegions')/items(1)?$select=ResponsablesRegions/EMail,Id&$expand=ResponsablesRegions
get fields
/_api/web/lists/GetByTitle('Liste des chantiers')/fields?$filter=Hidden eq false&$orderby=Title&$select=Title,InternalName,TypeAsString,Hidden
PowerAutomate Add Folder
On 10/02/2023
Powerautomate get folder by url
/_api/web/GetFolderByServerRelativeUrl('@{variables('WebserverRelativeUrl')}/@{variables('DoclibUrl')}/Fiche_@{variables('FicheId')}')Verify status (exists = 200, does not exists = 404)
@{outputs('HttpGetFolder')['statusCode']}
{
"Accept": "application/json; odata=verbose",
"content-type": "application/json; odata=verbose" "If-Match": "*"
}
Create folder
/_api/web/folders/add('@{variables('DoclibUrl')}/Fiche_@{variables('FicheId')}')

Verify status (exists = 200, does not exists = 404)