Blog

Seisme 4e college

On 28/09/2025

QCM : Les Séismes (Niveau 4e)

Question 1 sur 20
 

Sharepoint React SPFX issue scss missing

On 24/09/2025

in my react code below i have and an error : Cannot find module '../View.module.scss' or its corresponding type declarations.
import styles from './View.module.scss';

 

To solve it verify this fils exists

View.module.scss.ts was missing with code below, so i add it

require("./View.module.css");
const styles = {
  genericView: 'genericView_c46baf68',
  countryview: 'countryview_c46baf68',
  tableContainer: 'tableContainer_c46baf68',
  filterLabel: 'filterLabel_c46baf68',
  cell: 'cell_c46baf68',
  buttonCell: 'buttonCell_c46baf68',
  clearButton: 'clearButton_c46baf68',
  detailsList: 'detailsList_c46baf68',
  detailsListValue: 'detailsListValue_c46baf68',
  iconGreen: 'iconGreen_c46baf68',
  iconRed: 'iconRed_c46baf68',
  field: 'field_c46baf68',
  fieldLabel: 'fieldLabel_c46baf68',
  fieldLabelContainer: 'fieldLabelContainer_c46baf68',
  fieldValue: 'fieldValue_c46baf68',
  fieldLower: 'fieldLower_c46baf68',
  spinnerContainer: 'spinnerContainer_c46baf68',
  noItems: 'noItems_c46baf68',
  callout: 'callout_c46baf68',
  viewDescription: 'viewDescription_c46baf68',
  emptyItem: 'emptyItem_c46baf68',
  statusActive: 'statusActive_c46baf68',
  statusInactive: 'statusInactive_c46baf68',
  statusDissolved: 'statusDissolved_c46baf68'
};

export default styles;

Pnp PowerShell Export Import Site

On 02/07/2025

 

Define JSON configuration https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/configuring-the-pnp-provisioning-engine

Connect-PnPOnline -Url $siteUrl -ClientId $clientId -Tenant $tenantName -Thumbprint $cert
 

$xml = Get-PnPSiteTemplate -Out $SchmaXMLPath -Configuration $configPath

# Invoke-PnPSiteTemplate -Path $SchmaXMLPath



{
  "$schema": "https://aka.ms/sppnp-extract-configuration-schema",
  "handlers": [
    "ContentTypes",
    "Fields",
    "Lists"
  ],
  "persistAssetFiles": false,
  "lists": {
    "lists": [
      {
        "title": "Eutelsat Entity",
        "includeItems": false,
        "query": {
          "includeAttachments": false
        }
      }
    ]
  },
  "contentTypes": {
    "groups": [
      "Market Access"
    ]
  }
}

# remove particular nodes
$SchmaXMLPathDest = "MA_pmsatEntity_15.xml"
[xml]$xmlContent = Get-Content $SchmaXMLPath 
Clear-Host
# Define the namespace if needed (common in SharePoint XML)
$nsmgr = New-Object System.Xml.XmlNamespaceManager($xmlContent.NameTable)
# Add the namespace you are using in the XML document. Use "ns" as a prefix here.
$nsmgr.AddNamespace("pnp", "http://schemas.dev.office.com/PnP/2022/09/ProvisioningSchema")

# Use XPath to select fields. Adjust the XPath query based on your XML structure.
$fields = $xmlContent.SelectNodes("//Field", $nsmgr)

Write-Host "cout $($fields.Count)"
# Iterate over fields and remove those whose InternalName starts with an underscore
for ($i = $fields.Count - 1; $i -ge 0; $i--) {
    $internalName = $fields[$i].Attributes["Name"].Value
    if ($internalName -like "_*") {
        # Remove the field from its parent node
        $fields[$i].ParentNode.RemoveChild($fields[$i]) | Out-Null
        continue;
    }
    $internalName = $fields[$i].Attributes["Group"].Value
    if ($internalName -eq "_Hidden") {
        # Remove the field from its parent node
        $fields[$i].ParentNode.RemoveChild($fields[$i]) | Out-Null
    }
}


$fields = $xmlContent.SelectNodes("//pnp:ContentType", $nsmgr)
for ($i = $fields.Count - 1; $i -ge 0; $i--) {
    $internalName = $fields[$i].Attributes["Name"].Value
    if ($internalName -ne "MA_EutelsatEntity") {
        # Remove the field from its parent node
        $fields[$i].ParentNode.RemoveChild($fields[$i]) | Out-Null
    }
}


# Save the modified XML back to a file
$xmlContent.Save("{0}\template\test2.xml" -f (get-location))

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

PowerShell Compaire Property Items

On 26/05/2025


$ret1 = "PO-REQ-..2101.docx"
# $ret2 = "PO-RE..-2101.pdf"

$url1 = "https://test.sharepoint.com/sites/test/procedures";

$url2 = "https://test.sharepoint.com/sites/test/procedures"
Clear-Host
function ToPdf {
    param($fileName)

    $paths = $fileName.Split(".")
    if ($paths.Count -eq 2) {
        return "$($paths[0]).pdf"
    }
    if ($paths.Count -gt 2) {
        $ret = "";
        for ($i = 0 ; $i -lt $paths.Count - 1 ; $i++) {
            $ret += "$($paths[$i])" + "."
        }
        $ret += "pdf"
        return $ret
    }
    throw "Error : $($fileName)"
}



$list = "Work Instructions - Sources"
$list2 = "Work Instructions"
$ColumnsToCompaire = "Csc_Domain"
$ColumnRef = ""
$select = "Title,FileLeafRef,Csc_Domain,FileDirRef"

$buildSelet = ""
foreach ($col in ($select -split ",")) {
    $buildSelet += ""
}
$buildSelet += ""
$con1 = Connect-PnPOnline -Url $url1 -ReturnConnection -UseWebLogin
$con2 = Connect-PnPOnline -Url $url2 -ReturnConnection -UseWebLogin

$list1 = Get-PnPList -Identity $list -Connection $con1
Write-Host "list 1 : $($list1.ItemCount)"

$query = "<View Scope='RecursiveAll'><RowLimit>1000</RowLimit><OrderBy><FieldRef Name='Modified' Ascending='FALSE' /></OrderBy><Query><Where><Neq><FieldRef Name='FSObjType' /><Value Type='Integer'>1</Value></Neq></Where></Query>$($select)</View>"
$items1 = Get-PnPListItem -List $list -Connection $con1 -Query $query
$items2 = Get-PnPListItem -List $list2 -Connection $con2 -Query $query 

foreach ($item in $items1) {
    if ("$($item[$ColumnsToCompaire] )".Trim().ToLower() -eq "") {
        continue;
    }
    Write-Host ""
    Write-Host "list 1 : $($list1.ItemCount) item $($item.Id) ------------------"
    foreach ($col in ($select -split ",")) {
        Write-Host "item $($item.Id) '$($col)' : '$($item[$col])'"
        "item 1 $($item.Id) '$($col)' : '$($item[$col])'" | Out-File -LiteralPath ".\log\myLog_1.txt" -Encoding utf8 -Append
    }

    #$found = $items2 | Where-Object {$_.FileLeafRef -eq $item["FileLeafRef"]} #) -and $_.FileDirRef -eq $item["FileDirRef"]
    $founds = @();
    
    $toFound = ToPdf -fileName $item["FileLeafRef"]
    foreach ($found in $items2) {
        if ("$($toFound)".Trim().ToLower() -eq "$($found["FileLeafRef"])".Trim().ToLower()) {
            $founds += $found 
        }
    }

    if ($null -eq $founds) {
        Write-Error "File Error : $($item["FileLeafRef"]))" -ForegroundColor Yellow
    }
    elseif ($founds.Count -eq 0) {
        Write-Host "File ne found $($($item["FileLeafRef"])) -> $($toFound)" -ForegroundColor Yellow
        "File ne found $($($item["FileLeafRef"])) -> $($toFound)" | Out-File -LiteralPath ".\log\myLog_NotFound.txt" -Encoding utf8 -Append
    }
    elseif ($founds.Count -gt 1) {
        Write-Error "More than 1 file"
    }
    elseif ($founds.Count -eq 1) {
        if ($item[$ColumnsToCompaire] -ne $founds[0][$ColumnsToCompaire]) {
            Write-Host "to update"
            "to update  $($item.Id) '$($toFound)' - origine : '$($item[$ColumnsToCompaire])' - pdf : '$($founds[0][$ColumnsToCompaire])'" | Out-File -LiteralPath ".\log\myLog_2.txt" -Encoding utf8 -Append
            Set-PnPListItem -UpdateType SystemUpdate -Identity $founds[0].Id  -Connection $con2 -List $list2 -Values @{$ColumnsToCompaire = $item[$ColumnsToCompaire] }
            Write-Host "updated"
        }
    }
}

Javascript Generate PDF

On 01/04/2025

<html>
<head>
<style>
.button {
  background-color: white;
  border: none;
  Border-radius:5px;
  color: black;
  padding: 15px 32px;
 border: 2px solid #008CBA; 
 text-align: center;
  font-weight : bold ;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
  top: 38%;
  right: 27%;
  position:absolute;
}
.button:hover {
  background-color: #008CBA;
  color: white;
}
.imagestyle{
    width: 50%;
    margin-left: 20%;
    position: absolute;
    top: -105px;
    display:none;

}
@media print {
@page {
      size:auto;
      margin:.5rem 0;
}
  #printPageButton {
    display: none;
  }
  #imagestyleId{
      display:block;
  }
 [data-automation-id^=QuickLinksWebPart]{
     display: none !important;
  }
  [data-automation-id=TitleTextId]{
     padding-top: 100px;
  }

  [data-automation-id=CanvasSection]{
     top: -140px;
  }
}
</style>
</head>
<body>
<script type="text/javascript">
function generatePdf() {
 const pageTitle = document.title;
 const printTitle = 'Mandate ' + pageTitle;
 document.title = printTitle;
 window.print();
 document.title = pageTitle;
 return false;
}
</script>

<input type="button" class="button" 
id="printPageButton"
value="Generate Mandate" onclick="generatePdf()">
<img src="tlstLogo.png" class="imagestyle" id="imagestyleId"/>

 

</body>
</html>