REST

SharePoint RestShow Users List

On 28/10/2025

 

Listuseer

 

 


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);
        }
    }
}

document.body.innerHTML = `<div id="tableContainer" class="table-wrapper"></div>`;

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); 

 

Permissions

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.

Addfieldtocontenttype

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": "*"
}
Updateitemct

Sharepoint REST

On 19/02/2024

PnP references

msdn PNP

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'

test code

/_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')}')
GetfolderVerify 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')}')

Createfolder