SharepointOnLine
Usefull informations for Sharepoint On Line
SharePoint List Json Formating
On 09/12/2024
JSON Formatting in SharePoint Online: A Comprehensive Guide
JSON formatting in SharePoint Online enables users to customize the visual presentation of list and library data without requiring complex code. It allows for dynamic styling, icons, calculated values, and even conditional formatting based on field data. In this article, we’ll explore JSON formatting basics, advanced examples, limitations, and best practices.
What is JSON Formatting in SharePoint Online?
JSON formatting is a declarative approach to customize how fields, rows, or views appear in SharePoint lists and libraries. It involves writing JSON code that defines the logic and styling based on field values.
Examples of JSON Formatting
1. Change Background Color Based on Approval Status
If the field "ApprovalStatus" has a value of `"pending"`, set the background color to yellow. JSON Code:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"style": {
"background-color": "=if(@currentField == 'pending', '#FFFF00', '')",
"padding": "5px"
},
"txtContent": "@currentField"
}
2. Display an Alert Icon if Cost Equals 100 Add a warning icon next to the Cost field if its value is `100`. JSON Code:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"children": [
{
"elmType": "span",
"txtContent": "@currentField"
},
{
"elmType": "span",
"style": {
"margin-left": "10px",
"color": "red"
},
"attributes": {
"iconName": "Warning"
},
"condition": "=if(@currentField == 100, true, false)"
}
]
}
3. Concatenate Two Fields Combine two text fields, FirstName and LastName, into a single formatted output. JSON Code:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"txtContent": "='Full Name: ' + [$FirstName] + ' ' + [$LastName]"
}
4. Add 3 Days to a Date Field Display a date that is 3 days later than the value in a field called StartDate. JSON Code:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"txtContent": "=formatDate(addDays(@currentField, 3), 'yyyy-MM-dd')"
}
Limitations of JSON Formatting
1. Read-Only:
- JSON formatting is purely visual; it does not change the actual field value or data in the list.
2. Complex Logic:
- While simple conditions are supported, JSON formatting cannot handle complex business logic or external data calls.
3. Limited Interactivity:
- JSON formatting cannot create interactive elements like buttons with advanced event handling.
4. Field Dependencies:
- If a calculated field is hidden in the view, JSON that relies on it may break.
5. Performance Impact:
- Excessive formatting, especially on large lists, may slow down rendering.
Best Practices for JSON Formatting
1. Keep it Simple:
- Avoid overly complex JSON. Keep the code readable and maintainable.
2. Validate JSON:
- Use online JSON validators or tools like VS Code with JSON extensions to catch syntax errors.
3. Optimize for Performance:
- Test formatting on large lists to ensure it doesn’t degrade performance.
4. Use Conditional Logic:
- Use `if` statements sparingly and test all possible conditions.
5. Test Across Browsers:
- Ensure formatting looks consistent across browsers, especially for icons and colors.
6. Document Your JSON:
- Add comments (externally, as SharePoint JSON doesn’t support comments) to document logic and purpose.
Conclusion
JSON formatting in SharePoint Online is a powerful tool to enhance list and library views. By applying dynamic styling and conditional logic, you can improve data visualization and user experience. However, its read-only nature and complexity for advanced scenarios mean it’s best suited for lightweight customizations.
By following best practices and understanding its limitations, you can use JSON formatting effectively in your SharePoint projects.
SharePoint get by Rest List Role DefinitionBindings
On 28/10/2024
let currentSort = { column: null, direction: 'asc' }; // Store the current sort state
// Creates the style element
function createStyleElement(id, content) {
var style = document.createElement("style");
style.type = "text/css";
style.id = id;
style.innerHTML = content;
if (style.styleSheet) {
style.styleSheet.cssText = content;
} else {
let st = document.getElementById(id);
if (st == undefined) {
var head = document.head || document.getElementsByTagName("head")[i];
head.appendChild(style);
} else {
st.innerHTML = content;
}
}
return style;
}
// Function to filter the table based on dropdown selection
function filterTable(columnIndex, value) {
let table, tr, td, i, select, selectedValue, txtValue;
table = document.querySelector("table");
tr = table.getElementsByTagName("tbody")[0].getElementsByTagName("tr");
select = table.getElementsByTagName("select")[columnIndex];
//debugger;
selectedValue = value;
// Loop through all table rows and hide those that don't match the filter
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[columnIndex];
if (td) {
txtValue = td.textContent || td.innerText;
if (selectedValue === "" || txtValue === selectedValue) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
function sortTable(columnIndex, direction) {
let table, rows, switching, i, x, y, shouldSwitch;
table = document.querySelector("table");
switching = true;
let tbody = table.querySelector("tbody");
// Set the current sort state
currentSort.column = columnIndex;
currentSort.direction = direction;
while (switching) {
switching = false;
rows = tbody.rows;
for (i = 0; i < rows.length - 1; i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("td")[columnIndex];
y = rows[i + 1].getElementsByTagName("td")[columnIndex];
let isNumber = false;
if (!isNaN(x.innerHTML)) {
// Check if rows should switch based on ascending or descending order
if (direction === 'asc') {
if (parseFloat(x.innerHTML) > parseFloat(y.innerHTML)) {
shouldSwitch = true;
break;
}
} else if (direction === 'desc') {
if (parseFloat(x.innerHTML) < parseFloat(y.innerHTML)) {
shouldSwitch = true;
break;
}
}
}
else {
// Check if rows should switch based on ascending or descending order
if (direction === 'asc') {
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
} else if (direction === 'desc') {
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
}
}
}
// Function to generate the table
function generateTableFromJson2(jsonArray, select, addHeaders = true) {
const style = `
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 8px 12px;
text-align: left;
border: 1px solid #ddd;
}
tbody tr{
max-height: 15px;
}
th {
background-color: #f4f4f4;
color: #000;
}
/* Scrollable table wrapper */
.table-wrapper {
max-height: 800px;
overflow-y: auto;
border: 1px solid #ddd;
}
/* Style for dropdowns in header */
select {
width: 100%;
padding: 4px;
margin-top: 5px;
}
/* Style for the sorting arrows */
.sort-arrows {
cursor: pointer;
margin-left: 5px;
}
`;
createStyleElement("fdiStyle", style);
// Create table element
let table = document.createElement('table');
// Create table header
let header = table.createTHead();
let headerRow = header.insertRow(0);
// Get keys (headers) from the first object in the JSON array
//let keys = Object.keys(jsonArray[0]);
let keys = select.split(",");
if (addHeaders) {
keys.forEach((key, index) => {
if (key !== "__metadata") {
let th = document.createElement('th');
th.innerHTML = key;
// Create a dropdown (select) for filtering
let select = document.createElement('select');
select.addEventListener('change', function () {
const selectedValue = select.value;
filterTable(index, selectedValue);
});
// Populate dropdown with unique values from the JSON data
let uniqueValues = [...new Set(jsonArray.map(item => item[key]))];
// Add a default "All" option for no filter
let optionAll = document.createElement('option');
optionAll.value = "";
optionAll.text = `All`;
select.appendChild(optionAll);
// Create an option for each unique value
if (typeof (uniqueValues[0]) === typeof (1)) {
const pp = uniqueValues.sort((a, b) => {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
});
pp.forEach(value => {
let option = document.createElement('option');
option.value = value;
option.text = value;
select.appendChild(option);
});
} else
uniqueValues.sort().forEach(value => {
let option = document.createElement('option');
option.value = value;
option.text = value;
select.appendChild(option);
});
// Sort arrows for sorting the columns
let upArrow = document.createElement('span');
upArrow.innerHTML = '⬆️';
upArrow.classList.add('sort-arrows');
upArrow.onclick = () => sortTable(index, 'asc');
let downArrow = document.createElement('span');
downArrow.innerHTML = '⬇️';
downArrow.classList.add('sort-arrows');
downArrow.onclick = () => sortTable(index, 'desc');
th.appendChild(select); // Append the dropdown to the header
th.appendChild(upArrow); // Append the dropdown to the header
th.appendChild(downArrow); // Append the dropdown to the header
headerRow.appendChild(th);
}
});
}
// Create table body and populate rows with data
let tbody = document.createElement('tbody');
jsonArray.forEach((item) => {
let row = tbody.insertRow();
keys = select.split(",");
keys.forEach((key) => {
let cell = row.insertCell();
if (key !== "__metadata") {
cell.setAttribute("nowrap", "nowrap");
if (key === "RoleDefinitionBindings") {
cell.appendChild(generateTableFromJson2(item.RoleDefinitionBindings.results, "Name,Id", false));
} else if (key.indexOf("/") > 0) {
cell.innerHTML = item[key.split("/")[0]][key.split("/")[1]]
} else
cell.innerHTML = item[key]; // Insert each value from the JSON into the table cell
}
});
});
// Append the body to the table
table.appendChild(tbody);
return table;
}
function removeSlasches(select, datas) {
const ret = [];
const fields = select.split(',');
for (let i = 0; i < datas.length; i++) {
const toAdd = {};
for (let j = 0; j < fields.length; j++) {
if (fields[j].indexOf('/') > 0) {
const splitted = fields[j].split('/');
toAdd[splitted.join('')] = datas[i][splitted[0]][splitted[1]];
} else
toAdd[fields[j]] = datas[i][fields[j]];
}
ret.push(toAdd);
}
console.log("removeSlasches", ret);
return ret;
}
// Function to get permissions for a SharePoint group
async function getSharePointPermissions(siteUrl, select) {
// REST API endpoint to get group permissions
const endpoint = `${siteUrl}`;
// Fetch options with headers for authentication and response format
const fetchOptions = {
method: 'GET',
headers: {
'Accept': 'application/json;odata=verbose'
}
};
console.log("endpoint", endpoint);
// Send the asynchronous GET request to the REST API endpoint
const response = await fetch(endpoint, fetchOptions);
// Check if the response is OK (status code 200)
if (!response.ok) {
throw new Error(`Error fetching permissions: ${response.statusText}`);
}
// Parse the JSON response to extract permission data
const data = await response.json();
// Extract role assignments (permissions)
const roleAssignments = data.d.results;
console.log('roleAssignments', roleAssignments);
console.log(JSON.stringify(roleAssignments));
const D1 = removeSlasches(select, roleAssignments)
const pattern2 = /\//g;
console.log("json111", JSON.stringify(D1));
const table = generateTableFromJson2(D1, select.replace(pattern2, ""));
// Append the table to the container
document.getElementById('tableContainer').appendChild(table);
}
// Usage example: Replace 'your-group-id' and 'your-site-url' with actual values
const select = "Member/Title,Member/Id,Member/LoginName,RoleDefinitionBindings";
let siteUrl = 'https://mySite.sharepoint.com/sites/Dev_wf';
siteUrl += `/_api/web/roleassignments/?$expand=RoleDefinitionBindings,Member&$select=${select}`; // Replace with the actual site URL
document.body.innerHTML = `<div id="tableContainer" class="table-wrapper"></div>`; await getSharePointPermissions(siteUrl, select);
Power Apps Limit 500 WorkArround
On 25/09/2024
Power Apps Limit WorkArround 500
The column Id hit type is counter, we cannot use it to filter if we have more than 500 items with "<" ou ">"
But with created we can use delegation with > and <
You can build a pagination with date filtering
App loading
button next
button previous
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
Manage SharePoint/ Teams Permissions
On 09/09/2024
How to manage SharePoint / Teams permissions
In every Teams, in background there is a SharePoint site.
How to access SharePoint associated with Teams
Browse your Teams files
Check user / Office 365 group permission
On SharePoint site advanced permissions page you can check user / Office 365 group permissions
SharePoint standard defaults groups
On SharePoint Site creation, by default 3 groups are created
By default, all content on the SharePoint site inherits permissions from the parent SharePoint site.
Allow only a few members or group for a folder
You can set specific permissions in SharePoint / Teams for :
For each person / groups, you can set permission level :
Allow only a few members or group for a folder
By defaut the folder inherits parent folder or library permission, to break permissions and apply new ones :
Create specific permissions (Read / write but not delete)
By default in SharePoint we have 5 permissions levels
You can clic on default permission level to affine them but
it’s not a good practice
.
To add a new permission level (in site permissions)
Share / give permission to external user
Sharing with external users governance is managed at Tenant level
By default a Teams “private channel” cannot be Shared with externals users / domain
With public site or channel, your can Share your SharePoint site :
vvvvvx
ccc
SharePoint Format Date In View With JSON
On 06/09/2024
Format date background color in your SharePoint list with JSON
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"txtContent": "@currentField",
"style": {
"background-color":
{
"operator": "?",
"operands": [
{
"operator": ">=",/*if the date is greater than tomorrow 24x60x60x1000 = 86400000 = 1day */
"operands": [
"@currentField",
{
"operator": "+",
"operands": [
"@now",
86400000
]
}
]
},
"red",
{
"operator": "?",
"operands": [
{
"operator": "<=",/*if the date is less than today - 60 days*/
"operands": [
"@currentField",
{
"operator": "-",
"operands": [
"@now",
5184000000 /* 86400000 x 60 */
]
}
]
},
"yellow",
"transparent"
]
}
]
}
}
}
Gestion des droits dans SharePoint On line Bonnes Pratiques Conseils
On 06/09/2024
La gestion des droits et des autorisations dans SharePoint Online est un aspect crucial pour garantir la sécurité et l'efficacité de la collaboration au sein d'une organisation. Une bonne gestion des droits aide à maintenir la confidentialité des données, réduit le risque d’erreurs et garantit que les utilisateurs peuvent accéder aux informations dont ils ont besoin, sans compromettre la sécurité.
Voici un aperçu des bonnes pratiques et des mauvaises pratiques en matière de gestion des droits dans SharePoint Online.
Bonnes Pratiques de Gestion des Droits dans SharePoint Online
1. Utiliser les Groupes de Sécurité et de SharePoint
- Bonnes pratiques : Utilisez des groupes SharePoint ou des groupes de sécurité pour gérer les autorisations au lieu d’attribuer des droits directement à des utilisateurs individuels. Les groupes facilitent l’administration des droits et permettent une gestion plus efficace des utilisateurs.
- Exemple : Créer des groupes comme "Contributeurs", "Lecteurs", "Admins" pour les différents niveaux d’accès et affecter les utilisateurs à ces groupes.
- Pourquoi ? : Il est plus facile de gérer les autorisations en fonction des rôles et des équipes. Vous pouvez ajouter ou retirer des utilisateurs des groupes sans devoir réviser chaque autorisation individuellement.
2. Hériter des Autorisations
- Bonnes pratiques : Par défaut, les sites, les bibliothèques de documents et les listes héritent des autorisations de leur site parent. Cela permet de garder les autorisations cohérentes et plus faciles à gérer. Rompez l'héritage uniquement lorsqu'il est absolument nécessaire.
- Pourquoi ? : Limiter les ruptures d’héritage rend la gestion des autorisations plus simple et cohérente. Cela aide à réduire les erreurs liées à des autorisations mal configurées sur des objets individuels.
3. Appliquer le Principe du Moindre Droit (Least Privilege)
- Bonnes pratiques : Donnez aux utilisateurs uniquement les permissions dont ils ont besoin pour accomplir leur travail. Par exemple, si un utilisateur a seulement besoin de lire des documents, ne lui donnez pas des droits de modification.
- Pourquoi ? : Cela réduit les risques d’erreurs humaines et améliore la sécurité en limitant l'accès inutile aux fonctionnalités ou aux données sensibles.
4. Utiliser les Modèles de Permissions Standard
- Bonnes pratiques : Utilisez les modèles de permissions par défaut fournis par SharePoint, tels que "Contributeur", "Lecteur", "Propriétaire", au lieu de créer des niveaux de permissions personnalisés. Les permissions standard sont bien connues et bien documentées, facilitant la gestion.
- Pourquoi ? : Les modèles standards garantissent une bonne compréhension des rôles et réduisent la complexité de la gestion des autorisations.
5. Effectuer des Audits et des Revues Périodiques des Permissions
- Bonnes pratiques : Révisez régulièrement les autorisations sur les sites SharePoint pour s'assurer que les utilisateurs n'ont pas plus de permissions que nécessaire, et que les anciennes autorisations inutiles sont révoquées.
- Pourquoi ? : Avec le temps, des utilisateurs peuvent accumuler des permissions inutiles, ce qui augmente le risque de fuites de données ou d’accès non autorisé.
6. Utiliser la Gestion des Accès Conditionnels et Azure AD
- Bonnes pratiques : Pour les entreprises utilisant Azure Active Directory, configurez des politiques d'accès conditionnel qui obligent l'utilisation de la Multi-Factor Authentication (MFA) et des restrictions d'accès basées sur l'emplacement.
- Pourquoi ? : Ces pratiques renforcent la sécurité en s'assurant que seuls les utilisateurs autorisés, se connectant de manière sécurisée, ont accès à vos données SharePoint.
7. Documenter les Modifications de Permissions
- Bonnes pratiques : Chaque changement d'autorisation doit être documenté, en notant pourquoi il a été effectué, par qui et pour quelle durée. Cette documentation aide lors d'audits futurs ou de la résolution de problèmes.
- Pourquoi ? : Cela facilite la gestion à long terme, permet de retracer les modifications en cas de problème et contribue à la conformité des données.
Mauvaises Pratiques de Gestion des Droits dans SharePoint Online
1. Donner des Permissions Directes à des Utilisateurs Individuels
- Mauvaise pratique : Attribuer des droits directement à des utilisateurs au lieu d'utiliser des groupes.
- Pourquoi c'est un problème ? : Gérer les autorisations devient difficile lorsque les utilisateurs quittent l'organisation ou changent de rôle. Cela rend également la gestion des droits plus complexe et propice aux erreurs.
2. Rompre l'Héritage des Permissions Trop Souvent
- Mauvaise pratique : Rompre l'héritage des autorisations à plusieurs niveaux (par exemple, sur des fichiers ou des sous-dossiers individuels).
- Pourquoi c'est un problème ? : Cela complique énormément la gestion des permissions. Vous pouvez perdre le contrôle de qui a accès à quoi, et il devient facile de faire des erreurs en octroyant ou en révoquant des droits.
3. Donner Trop de Permissions (Trop de Propriétaires)
- Mauvaise pratique : Donner des droits de propriétaire ou des droits d'édition à trop de personnes.
- Pourquoi c'est un problème ? : Les propriétaires peuvent modifier des paramètres critiques, ce qui peut affecter la structure du site et les permissions des autres utilisateurs. Cela augmente également le risque d’erreurs ou d’accès non autorisé à des informations sensibles.
4. Ne Pas Révoquer les Permissions des Anciens Utilisateurs
- Mauvaise pratique : Ne pas retirer les autorisations d’utilisateurs qui ne sont plus actifs dans le projet ou l'organisation.
- Pourquoi c'est un problème ? : Des anciens utilisateurs peuvent encore avoir accès à des informations sensibles. Cela représente un risque de sécurité majeur, surtout si ces utilisateurs ne sont plus sous votre contrôle.
5. Ne Pas Gérer les Permissions sur les Documents Sensibles
- Mauvaise pratique : Donner des droits larges sur des documents sensibles sans les protéger spécifiquement (par exemple, via une bibliothèque dédiée avec des permissions restreintes).
- Pourquoi c'est un problème ? : Cela peut conduire à des fuites de données, où des utilisateurs qui n’ont pas besoin d’accéder à des documents critiques y ont tout de même accès.
6. Ne Pas Utiliser les Groupes O365/AAD pour Simplifier la Gestion
- Mauvaise pratique : Ne pas intégrer les groupes Office 365/Azure Active Directory pour la gestion des droits SharePoint.
- Pourquoi c'est un problème ? : Ne pas tirer parti des groupes centralisés complique la gestion des utilisateurs et peut entraîner des redondances ou des erreurs de permissions.
7. Manque de Documentation sur les Modifications des Permissions
- Mauvaise pratique : Modifier les autorisations sans documentation claire.
- Pourquoi c'est un problème ? : En l'absence de documentation, il devient difficile de savoir qui a modifié quoi, pourquoi et quand. Cela complique les audits et rend le diagnostic des problèmes d’accès plus long.
Conclusion
La gestion des droits dans SharePoint Online doit être effectuée avec soin pour assurer la sécurité et l'efficacité. En suivant les bonnes pratiques, vous pouvez éviter des problèmes tels que des accès non autorisés, des erreurs de configuration, et des difficultés de gestion à long terme. Évitez les mauvaises pratiques qui peuvent entraîner une confusion dans la gestion des permissions et augmenter le risque de failles de sécurité.
Une gestion rigoureuse des droits est cruciale pour protéger les informations sensibles et assurer que les utilisateurs accèdent seulement aux ressources nécessaires à leur travail.
Sharepoint REST roleassignments Break
On 14/05/2024
roleassignments
_api/lists/getByTitle('myLList')/items(2)/roleassignments/addroleassignment(principalid=15)},roledefid=1073741826)
break role inheritance
_api/lists/getByTitle('@{triggerBody()?['ListTitle']}')/items(@{int(triggerBody()['ItemId'])})/breakroleinheritance(copyRoleAssignments=false,clearSubscopes=true)
get role assigments ids
/_api/Web/RoleDefinitions?$select=Name,Description,Id
Name Description Id
Full ControlHas full control.1073741829
DesignCan view, add, update, delete, approve, and customize.1073741828
EditCan add, edit and delete lists; can view, add, update and delete list items and documents.1073741830
ContributeCan view, add, update, and delete list items and documents.1073741827
ReadCan view pages and list items and download documents.1073741826
Restricted ViewCan view pages, list items, and documents. Documents can be viewed in the browser but not downloaded.1073741832
Limited AccessCan view specific lists, document libraries, list items, folders, or documents when given permissions.1073741825
System.LimitedViewnull1073741924
System.LimitedEditnull1073741925
JSON Formatting Show File Size
On 03/05/2023
Show File size in kilo bytes in sharepoint list
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"attributes": {
},
"style": {
"flex-directon": "row",
"justify-content": "left",
"align-items": "center",
"flex-wrap": "nowrap"
},
"children": [
{
"elmType": "span",
"txtContent": "=[$File_x0020_Size]/1000 + ' kbytes'"
}
]
}
On 05/04/2023
Create certification for azure app
# Create certificate
$mycert = New-SelfSignedCertificate -DnsName "myCertificate.org" -CertStoreLocation "cert:\CurrentUser\My" -NotAfter (Get-Date).AddYears(1) -KeySpec KeyExchange
$mypwd = ConvertTo-SecureString -String "myCertificatePsw" -Force -AsPlainText
# Export certificate to .pfx file
$mycert | Export-PfxCertificate -FilePath myCertificate.pfx -Password $mypwd
# Export certificate to .cer file
$mycert | Export-Certificate -FilePath myCertificate.cer
Connect to site
$url = "https://m365x6422vvvvd.sharepoint.com/";
$appId = "868d7a0c-a3dc-45af-b4a7-f72a70f61a60";
$thumbprint = "A17177BB0E8A465F6AD08B0CEAE2F369C46D6481";
$tenantId = "3533ab30-c2f0-48fd-b4c5-f5dc6ca77ec3"
Connect-PnPOnline -Url $url -Tenant $tenantId -Thumbprint $thumbprint -ClientId $appId
Export audit
premission required
Office 365 Management APIs (3) :: ActivityFeed.Read
possible filters
- FilePreviewed
- FileAccessed
- SignInEvent
- FileModifiedExtended
- FileUploaded
- PageViewed
- PagePrefetched
- FileCheckedIn
- FileModified
- FolderCreated
- ListUpdated
- ListViewed
$ele = Get-PnPUnifiedAuditLog -ContentType SharePoint -StartTime (Get-Date).AddDays(-2) -EndTime (Get-Date).AddDays(-1)
$ele = Get-PnPUnifiedAuditLog -ContentType SharePoint
$ele = Get-PnPUnifiedAuditLog -ContentType SharePoint | Where-Object {$_.Operation -eq "PageViewed"} | Select-Object CreationTime,Operation,Workload,UserId,ObjectId,SourceFileName,SiteUrl,SourceFileExtension,SourceRelativeUrl
$ele | Export-Csv -Path "Audit_3.csv" -Encodin:UTF8 -NoTypeInformation -Delimiter ";"
with sharepoint search request
kqlQuery = "ContentTypeId:0x0101009D1CB255DA76424F860D91F20E6C4118*";//news
kqlQuery = "ContentTypeId:0x0101* language=fr ViewsLastMonths3=0";//documents
kqlQuery = "ContentTypeId:0x0101* ViewsLifeTime=0";
var seletvvv = "Title,ViewsLifeTimeUniqueUsers,ViewsLifeTime,language,Created,Size,Path,LastModifiedTime,ViewsLastMonths3,ViewsLastMonths3Unique,LastAnalyticsUpdateTime";
&sortlist='Size:descending'
&sortlist='ViewsLifeTime:descending'
Connect Sharepoint With AppID Certificate
On 21/03/2023
Connect to Sharepoint using app registration and certificate
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Graph;
using PnP.Core.Auth;
using PnP.Core.Auth.Services.Builder.Configuration;
using PnP.Core.Services;
using PnP.Core.Services.Builder.Configuration;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
namespace HGH.Buisiness4
{
public class SPTools2 : IDisposable
{
private IHost _host;
public SPTools2()
{
}
public async Task Connect(string appId, string tenantId, string siteUrl, string thumbprint, StoreName storeName, StoreLocation storeLocation)
{
try
{
_host = Host.CreateDefaultBuilder()
.ConfigureServices((hostingContext, services) =>
{
// Add the PnP Core SDK library
services.AddPnPCore(options =>
{
options.Sites.Add("SiteToWorkWith", new PnPCoreSiteOptions
{
SiteUrl = siteUrl
});
});
services.AddPnPCoreAuthentication(
options =>
{
// Configure an Authentication Provider relying on Windows Credential Manager
options.Credentials.Configurations.Add("x509certificate",
new PnPCoreAuthenticationCredentialConfigurationOptions
{
ClientId = appId,
TenantId = tenantId,
X509Certificate = new PnPCoreAuthenticationX509CertificateOptions
{
StoreName = storeName,
StoreLocation = storeLocation,
Thumbprint = thumbprint
}
});
// Configure the default authentication provider
options.Credentials.DefaultConfiguration = "x509certificate";
// Map the site defined in AddPnPCore with the
// Authentication Provider configured in this action
options.Sites.Add("SiteToWorkWith",
new PnPCoreAuthenticationSiteOptions
{
AuthenticationProviderName = "x509certificate"
});
});
})
// Let the builder know we're running in a console
.UseConsoleLifetime()
// Add services to the container
.Build();
await _host.StartAsync();
}
catch (Exception ex)
{
Console.WriteLine($"ERROR SPTools2 appId {appId} siteUrl {siteUrl} thumbprint {thumbprint} {ex}");
throw new Exception($"ERROR SPTools2 appId {appId} siteUrl {siteUrl} thumbprint {thumbprint}", ex);
}
return 1;
}
public async Task LoadWeb()
{
try
{
// Optionally create a DI scope
using (var scope = _host.Services.CreateScope())
{
// Obtain a PnP Context factory
var pnpContextFactory = scope.ServiceProvider
.GetRequiredService();
// Use the PnP Context factory to get a PnPContext for the given configuration
using (var context = await pnpContextFactory.CreateAsync("SiteToWorkWith"))
{
// Retrieving web with lists and masterpageurl loaded ==> SharePoint REST query
var web = await context.Web.GetAsync(p => p.Title, p => p.Lists,
p => p.MasterUrl);
Console.WriteLine($"Web Title {web.Title} Loaded");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"ERROR LoadWeb{ex}");
throw new Exception($"ERROR LoadWeb ", ex);
}
return 1;
}
public void Dispose()
{
if (_host != null)
_host.Dispose();
}
}
}
Powershell Import Export Fields
On 03/02/2023
Write-Output 'Connexion Portail'
# Connect-PnPOnline -Url $siteUrl -Tenant $aadDomain -Thumbprint $certifThumbprint -ClientId $appId
function ExportFieldsToCsv {
Param(
[string]$listTitle,
[string]$csvFilename,
[boolean]$includeHidden = $false
)
#$list = Get-PnPList -Identity $list
if ([string]::IsNullOrEmpty($listTitle)) {
$fields = Get-PnPField
$aFieldToExports = @();
for ($i = 0 ; $i -lt $fields.Length ; $i++) {
$field = $fields[$i];
$aFieldToExport = New-Object -TypeName PSObject -Property @{
'Title' = $field.Title;
'InternalName' = $field.InternalName;
'Id' = $field.Id;
'TypeAsString' = $field.TypeAsString;
'Hidden' = $field.Hidden;
'StaticName' = $field.StaticName;
'Required' = $field.Required;
'Description' = $field.Description;
'TypeDisplayName' = $field.TypeDisplayName;
'Group' = $field.Group;
}
$aFieldToExports += $aFieldToExport
$aFieldToExports | Export-Csv -Path "$($csvFilename)" -Encodin:UTF8 -NoTypeInformation -Delimiter ";"
}
}
else {
<# Action when all if and elseif conditions are false #>
}
}
function ExportFieldsToXml {
Param(
[string]$listTitle,
[string]$xmlFilename,
[boolean]$includeHidden = $false
)
#$list = Get-PnPList -Identity $list
if ([string]::IsNullOrEmpty($listTitle)) {
$fields = Get-PnPField
$stringBuilder = New-Object System.Text.StringBuilder
$null = $stringBuilder.AppendLine("")
for ($i = 0 ; $i -lt $fields.Length ; $i++) {
$field = $fields[$i];
$null = $stringBuilder.AppendLine($field.SchemaXml);
}
$null = $stringBuilder.AppendLine("")
$stringBuilder.ToString() | Out-File -FilePath "$($xmlFilename)" -Encodin:UTF8 -Append
}
}
function ImportFields {
Param(
[string]$listTitle,
[string]$xmlFilePath,
[boolean]$includeHidden = $false
)
[XML]$xmlfile = Get-Content -Path $xmlFilePath -Encoding:UTF8
if ([string]::IsNullOrEmpty($listTitle)) {
foreach ($field in $xmlfile.fields.Field) {
Write-Host $field.Name
$exists = Get-PnPField -Identity $field.Name -ErrorAction:SilentlyContinue
if ($null -eq $exists) {
Write-Host "$($field.Name) is null"
Add-PnPFieldFromXml -FieldXml $field.OuterXml
Write-Host "$($field.Name) added"
}
else {
Write-Host "$($field.Name) exists"
}
}
}
else {
foreach ($field in $xmlfile.fields.Field) {
$siteField = Get-PnPField -Identity $field.Name -ErrorAction:SilentlyContinue
$listField = Get-PnPField -Identity $field.Name -List $listTitle -ErrorAction:SilentlyContinue
if ($null -eq $siteField -and $null -eq $listField) {
Write-Host "$($field.Name) is null"
Add-PnPFieldFromXml -FieldXml $field.OuterXml
Add-PnPField -List $listTitle -Field $field.Name
Write-Host "$($field.Name) added"
}
elseif($null -eq $listField){
Write-Host "$($field.Name) exists"
Add-PnPField -List $listTitle -Field $siteField.InternalName
Write-Host "$($field.Name) added to $($listTitle)"
}
}
}
}
Power Automate Check User Exists
On 24/01/2022
/_api/web/ensureuser
content-type application/json; odata=verbose
{'logonName': '@{variables('userMailToCheck')}'}
@{outputs('Send_an_HTTP_request_to_SharePoint')['statusCode']}
Nintex 2016 Issue CodeTypeReferenceExpression
On 08/02/2021
Nintex 2016 Issue CodeTypeReferenceExpression
SharePoint Foundation Workflow Infrastructure Unexpected RunWorkflow:
Microsoft.SharePoint.SPException: CompilerError Line="-1" Column="-1" Text="Type System.CodeDom.CodeBinaryOperatorExpression is not marked as authorized in the application configuration file.
Error saving from workflow export file.: Nintex.Workflow.NWSavingWorkflowException: Erreur lors de la publication du flux de travail Text="Le type System.CodeDom.CodeTypeReferenceExpression n'est pas indiqué comme étant autorisé dans le fichier de configuration de l'application."
You should add below red line in each web.config form your farm except central admin
<authorizedType Assembly="System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Namespace="System.CodeDom" TypeName="CodeTypeReferenceExpression" Authorized="True" />
<authorizedType Assembly="System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Namespace="System.CodeDom" TypeName="CodeTypeReferenceExpression" Authorized="True" />
</targetFx>
</authorizedTypes>
<authorizedRuleTypes>
<targetFx version="v4.0">
--------------------------------
Nintex.Workflow.NWException: Erreur lors de la lecture du paramètre 'SMTPServerPort' depuis la base de données de configuration. Vérifiez que vos bases de données Nintex Workflow sont à jour.
Nintex.Workflow.NWException: Error reading 'SMTPServerPort' parameter from configuration database. Make sure your Nintex Workflow databases are up to date.
To solve this issue, i executed this command line in an powershell admin instance
NWAdmin.exe -o UpgradeDatabases "Server=[serverName];Database=[dbName];Trusted_Connection=True;" -isConfig
For update workflow and forms Nintex configuration databases
Sharepoint Online Missing Icons
On 09/12/2020
Sharepoint missing icon on SPFX developpements
Some ican can be missing per exemple on :
SPFX missing icon as <i data-icon-name="Tag" class="ms-Button-icon icon-167" role="presentation" aria-hidden="true"></i>
So you simply have to add this code below after yours imports
import { initializeIcons } from 'office-ui-fabric-react/lib/Icons';
initializeIcons();
On 08/09/2020
Basic CSOM caml query
<View>
<Query>
<Where>
<Eq>
<FieldRef Name='Matricule'/>
<Value Type='Text'>90136794</Value>
</Eq>
</Where>
<OrderBy><FieldRef Name='ID' Ascending='True'/></OrderBy>
</Query>
<ViewFields>
<FieldRef Name='Matricule' />
<FieldRef Name='Email' />
</ViewFields>
<RowLimit>2</RowLimit>
</View>
Query Null Text fields or not
<Where>
<IsNotNull>
<FieldRef Name="Famille"/>
</IsNotNull>
</Where>
<Where>
<IsNull>
<FieldRef Name="Famille"/>
</IsNull>
</Where>
by ID
<Where>
<Eq>
<FieldRef Name='ID'/>
<Value Type='Counter'>645</Value>
</Eq>
</Where>
Get tasks by itemId (relatedItems in tasks list)
<Where>
<Eq>
<FieldRef Name='RelatedItems'/>
<Value Type='RelatedItems'>""ItemId"":435,</Value>
</Eq>
</Where>
boolean / Yes/No
<Eq><FieldRef Name='YourFieldName'/><Value Type='Boolean'>1</Value></Eq>
Comparators
<Eq> => equals
<Neq> => not equals
<Lt> => Less than
<Leq> => less or equal
<Gt> greater than
<Geq> greater or equal
<Contains>
<BeginsWith>
Errors
-
Sharepoint error Error in my cases One or more field types are not installed properly. Go to the list settings page to delete these fields. Fields in your query are not in list Cannot complete this action.
Please try again.
Syntax error in your query
On 02/09/2020
Override native css
:global(#spLeftNav) {
display: none;
}
:global(.CanvasZone) {
max-width: 100%;
}
Is member of
import 'core-js/modules/es6.string.includes.js';
import 'core-js/modules/es6.number.is-nan.js';
import 'core-js/es6/array';
import 'es6-map/implement';
import { sp,SPRest } from '@pnp/sp';
import { IWebPartContext } from '@microsoft/sp-webpart-base';
import * as React from 'react';
class PeopleService {
private _context: IWebPartContext;
private _localPnPSetup: SPRest;
public constructor(webPartContext: IWebPartContext) {
this._context = webPartContext;
// To limit the payload size, we set odata=nometadata
// We just need to get list items here
// We use a local configuration to avoid conflicts with other Web Parts
this._localPnPSetup = sp.configure({
headers: {
Accept: 'application/json; odata=nometadata',
},
}, this._context.pageContext.web.absoluteUrl);
}
public async isMemberOf(group: string): Promise{
let groups = await this._localPnPSetup.web.currentUser.groups.get();
let ret: boolean = false;
groups.map(grp =>{
if(grp.LoginName == group)
ret = true;
});
return ret;
}
public async isMemberOfanyGroup(groupNames: string[]): Promise{
let groups = await this._localPnPSetup.web.currentUser.groups.get();
let ret: boolean = false;
groups.map(grp =>{
groupNames.map(name =>{
console.log("name : '" + name + "' grp : '" + grp.LoginName + "'");
if(grp.LoginName == name)
ret = true;
});
});
return ret;
}
}
export default PeopleService;
Taxonomy, get tags, add tags
import { IWebPartContext } from '@microsoft/sp-webpart-base';
import { Session, ITermStore, ITermSet, ITermData, ITerm } from '@pnp/sp-taxonomy';
class TaxonomyService {
private _context: IWebPartContext;
public constructor(webPartContext: IWebPartContext) {
this._context = webPartContext;
}
public async getTags() : Promise{
console.log("Session");
const taxonomy = new Session(this._context.pageContext.site.absoluteUrl);
const store: any = taxonomy.termStores.getByName("Taxonomy_Wf8XzHaRobdAERjvvke+Tg==");
let datas = await store.getTermSetById("c18ff3e6-e4a8-4dcb-85f5-51171f4bbc11").terms.select('Name', 'Id', 'Parent').get();
let ret: string[] = [];
for(let i = 0 ; i < datas.length ; i++)
ret.push(datas[i]);
return datas;
}
public async addNewTag(tag){
const taxonomy = new Session(this._context.pageContext.site.absoluteUrl);
const store: any = taxonomy.termStores.getByName("Taxonomy_Wf8XzHaRobdAERjvvke+Tg==");
let datas = await store.getTermSetById("c18ff3e6-e4a8-4dcb-85f5-51171f4bbc11");
const term: ITerm & ITermData = await datas.addTerm(tag, 1036, true);
}
}
export default TaxonomyService;
On 02/09/2020
CSOM delete items by id range
Get items
public ListItemCollection GetItems(string listRelativUrl, string where, string orderBy, string viewFields, int rowlimit = 100)
{
string xmlView = "";
try
{
List lst = CurrentWeb.GetList(CurrentWeb.ServerRelativeUrl + listRelativUrl);
StringBuilder vf = new StringBuilder();
if (!string.IsNullOrEmpty(viewFields))
{
vf.Append("<ViewFields>");
foreach (string fieldName in viewFields.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
{
vf.Append($"<FieldRef Name='{fieldName.Trim()}' />");
}
vf.Append("</ViewFields>");
}
CamlQuery camlQuery = new CamlQuery();
camlQuery = new CamlQuery();
Logger.LogInfo($"listRelativUrl {listRelativUrl} : <View><Query>{where}{orderBy}</Query>{vf.ToString()}<RowLimit>{rowlimit}</RowLimit></View>");
xmlView = $"<View><Query>{where}{orderBy}</Query>{vf.ToString()}<RowLimit>{rowlimit}</RowLimit></View>";
camlQuery.ViewXml = xmlView;
ListItemCollection coll = lst.GetItems(camlQuery);
SPContext.Load(coll);
SPContext.ExecuteQuery();
Logger.Log($"coll.Count : '{coll.Count}' : camlQuery.ViewXml {camlQuery.ViewXml}");
return coll;
}
catch (ServerException ex1)
{
Logger.LogError($"Error ServerException Common.Sharepoint.SPTools.GetItems url '{_url}' login : '{_login}' " +
$" listRelativUrl '{listRelativUrl}' where '{where}' orderBy '{orderBy}' rowlimit '{rowlimit}' xmlView : '{xmlView}' Exception '{ex1}'");
throw;
}
catch (Exception ex)
{
Logger.LogError($"Error .Common.Sharepoint.SPTools.GetItems url '{_url}' login : '{_login}' " +
$" listRelativUrl '{listRelativUrl}' where '{where}' orderBy '{orderBy}' rowlimit '{rowlimit}' xmlView : '{xmlView}' Exception '{ex}'");
throw;
}
}
delete items
public int DeleteItemByIdRange(string listRelativeUrl, int rowLimit, int from, int to = -1)
{
int deleted = 0;
try
{
string req = "";
if (to == -1)
req = $"<Where><Geq><FieldRef Name='ID'/><Value Type='Counter'>{from}</Value></Geq></Where>";
else
{
if (from > to)
throw new Exception($"DeleteItemByIdRange from should be < than to listRelativeUrl '{listRelativeUrl}' from '{from}' to '{to}'");
req = $"<Where><And><Geq><FieldRef Name='ID' /><Value Type='Counter'>{from}</Value></Geq><Leq><FieldRef Name='ID' /><Value Type='Counter'>{to}</Value></Leq></And></Where>";
}
ListItemCollection coll = GetItems(listRelativeUrl, req, "", "ID", rowLimit);
while (coll.Count > 0)
{
string id = coll[0].Id.ToString();
coll[0].DeleteObject();
this.ExecuteQuery($"DeleteItemByIdRange listRelativeUrl '{listRelativeUrl}' from '{from}' to '{to}' Id = '{id}'");
deleted++;
}
return deleted;
}
catch (Exception ex)
{
Logger.LogError($"Error Sharepoint.SPTools.DeleteItemByIdRange from id '{from}' to id '{to}' url '{_url}' login : '{_login}' Exception '{ex}'");
throw;
}
}
catch ServerException to get more details on CSOM exceptions
SPFX pnp Taxonomy with internet explorer 11
On 26/06/2020
SPFX webpart query Taxonomy / Term store with @pnp/sp-taxonomy on ie / internet explorer
Your package.json must contains at least :
"@pnp/polyfill-ie11": "1.0.0",
"@pnp/sp": "1.2.7",
"@pnp/sp-clientsvc": "^1.3.9",
"@pnp/sp-taxonomy": "^1.3.9",
"@types/es6-promise": "0.0.33"
In your service where you want to query Term store, you should import :
import 'core-js/modules/es6.string.includes.js';
import 'core-js/modules/es6.number.is-nan.js';
import 'core-js/es6/array';
import 'es6-map/implement';
import { Session } from '@pnp/sp-taxonomy';
On 18/06/2020
Power plateform
Power automate flow
Functions
Check date is null
if(equals(triggerBody()?['myDate'], null),'[myDate is null]', formatDateTime(triggerBody()?['myDate'], 'dd/MM/yyyy'))
Power apps
Display view on query string value
If ( !IsBlank(Param("taskDisplay")) && Param("taskDisplay")="true"; Navigate(DevTasksView;ScreenTransition.Cover) )
set variable value (separator in english is , in french ;)
Set(CurrentToShow; "loppement") ;; Set(CurrentButton; "DEV")
Addind header like this
{
"Accept": "application/json; odata=verbose",
"content-type": "application/json; odata=verbose",
"X-HTTP-Method": "MERGE",
"If-Match": "*"
}
On 10/06/2020
Microsoft Flow hot to get item by lookup and send a mail, with lookup details
Initialize variable
Get lookup datas
Extract approver datas
{
"type": "object",
"properties": {
"@@odata.type": {
"type": "string"
},
"Claims": {
"type": "string"
},
"DisplayName": {
"type": "string"
},
"Email": {
"type": "string"
}
}
}
Append datas to an array
Create an html table
Send the mail
Sharepoint Online Web Templates
On 11/01/2019
Name | Title | Category | Compatiblity Level |
STS#3 | Site d’équipe | Collaboration | 15 |
STS#0 | Site d’équipe (expérience classique) | Collaboration | 15 |
BLOG#0 | Blog | Collaboration | 15 |
BDR#0 | Centre de documents | Entreprise | 15 |
DEV#0 | Site de développeur | Collaboration | 15 |
OFFILE#1 | Centre des enregistrements | Entreprise | 15 |
EHS#1 | Site d’équipe - Configuration SharePoint Online | Entreprise | 15 |
SRCHCEN#0 | Centre de recherche d’entreprise | Entreprise | 15 |
BLANKINTERNETCONTAINER#0 | Portail de publication | Publication | 15 |
ENTERWIKI#0 | Wiki d’entreprise | Publication | 15 |
PROJECTSITE#0 | Site de projet | Collaboration | 15 |
COMMUNITY#0 | Site communautaire | Collaboration | 15 |
COMMUNITYPORTAL#0 | Portail communautaire | Entreprise | 15 |
SITEPAGEPUBLISHING#0 | Site de communication | Publication | 15 |
SRCHCENTERLITE#0 | Centre de recherche de base | Entreprise | 15 |
List templates
ID | Template Name | Description | SP2016 | SP2013 | SP2010 | SP2007 |
-1 | InvalidType | Not used. | Yes | Yes | Yes | Yes |
0 | NoListTemplate | unspecified list type. | Yes | Yes | Yes | No |
100 | GenericList | Custom list. | Yes | Yes | Yes | Yes |
101 | DocumentLibrary | Document library. | Yes | Yes | Yes | Yes |
102 | Survey | Survey. | Yes | Yes | Yes | Yes |
103 | Links | Links. | Yes | Yes | Yes | Yes |
104 | Announcements | Announcements. | Yes | Yes | Yes | Yes |
105 | Contacts | Contacts. | Yes | Yes | Yes | Yes |
106 | Events | Calendar. | Yes | Yes | Yes | Yes |
107 | Tasks | Tasks. | Yes | Yes | Yes | Yes |
108 | DiscussionBoard | Discussion board. | Yes | Yes | Yes | Yes |
109 | PictureLibrary | Picture library. | Yes | Yes | Yes | Yes |
110 | DataSources | Data sources for a site. | Yes | Yes | Yes | Yes |
111 | WebTemplateCatalog | Site template gallery. | Yes | Yes | Yes | Yes |
112 | UserInformation | User Information. | Yes | Yes | Yes | Yes |
113 | WebPartCatalog | Web Part gallery. | Yes | Yes | Yes | Yes |
114 | ListTemplateCatalog | List Template gallery. | Yes | Yes | Yes | Yes |
115 | XMLForm | XML Form library. | Yes | Yes | Yes | Yes |
116 | MasterPageCatalog | Master Page gallery. | Yes | Yes | Yes | Yes |
117 | NoCodeWorkflows | No Code Workflows. | Yes | Yes | Yes | Yes |
118 | WorkflowProcess | Custom Workflow Process. | Yes | Yes | Yes | Yes |
119 | WebPageLibrary | Wiki Page Library. | Yes | Yes | Yes | Yes |
120 | CustomGrid | Custom grid for a list. | Yes | Yes | Yes | Yes |
121 | SolutionCatalog | Solutions. | Yes | Yes | Yes | No |
122 | NoCodePublic | No Code Public Workflow. | Yes | Yes | Yes | No |
123 | ThemeCatalog | Themes. | Yes | Yes | Yes | No |
124 | DesignCatalog | DesignCatalog. | Yes | Yes | No | No |
125 | AppDataCatalog | AppDataCatalog. | Yes | Yes | No | No |
130 | DataConnection Library |
Data connection library for sharing information about external data connections. | Yes | Yes | Yes | Yes |
140 | WorkflowHistory | Workflow History. | Yes | Yes | Yes | Yes |
150 | GanttTasks | Project Tasks. | Yes | Yes | Yes | Yes |
151 | HelpLibrary | Help Library. | Yes | Yes | No | No |
160 | AccessRequest | Access Request List. | Yes | Yes | No | No |
171 | TasksWithTimeline AndHierarchy |
Tasks with Timeline and Hierarchy. | Yes | Yes | No | No |
175 | MaintenanceLogs | Maintenance Logs Library. | Yes | Yes | No | No |
200 | Meetings | Meeting Series (Meeting). | Yes | Yes | Yes | Yes |
201 | Agenda | Agenda (Meeting). | Yes | Yes | Yes | Yes |
202 | MeetingUser | Attendees (Meeting). | Yes | Yes | Yes | Yes |
204 | Decision | Decisions (Meeting). | Yes | Yes | Yes | Yes |
207 | MeetingObjective | Objectives (Meeting). | Yes | Yes | Yes | Yes |
210 | TextBox | Text Box (Meeting). | Yes | Yes | Yes | Yes |
211 | ThingsToBring | Things To Bring (Meeting). | Yes | Yes | Yes | Yes |
212 | HomePageLibrary | Workspace Pages (Meeting). | Yes | Yes | Yes | Yes |
301 | Posts | Posts (Blog). | Yes | Yes | Yes | Yes |
302 | Comments | Comments (Blog). | Yes | Yes | Yes | Yes |
303 | Categories | Categories (Blog). | Yes | Yes | Yes | Yes |
402 | Facility | Facility. | Yes | Yes | Yes | No |
403 | Whereabouts | Whereabouts. | Yes | Yes | Yes | No |
404 | CallTrack | Call Track. | Yes | Yes | Yes | No |
405 | Circulation | Circulation. | Yes | Yes | Yes | No |
420 | Timecard | Timecard. | Yes | Yes | Yes | No |
421 | Holidays | Holidays. | Yes | Yes | Yes | No |
499 | IMEDic | IME (Input Method Editor) Dictionary. | Yes | Yes | Yes | No |
600 | ExternalList | External. | Yes | Yes | Yes | No |
700 | MySiteDocument Library |
MySiteDocumentLibrary. | Yes | Yes | No | No |
1100 | IssueTracking | Issue tracking. | Yes | Yes | Yes | Yes |
1200 | AdminTasks | Administrator Tasks. | Yes | Yes | Yes | Yes |
1220 | HealthRules | Health Rules. | Yes | Yes | Yes | No |
1221 | HealthReports | Health Reports. | Yes | Yes | Yes | No |
1230 | DeveloperSiteDraft Apps |
Draft Apps library in Developer Site. | Yes | Yes | No | No |
3100 | AccessApp | Yes | No | No | No | |
3101 | AlchemyMobileForm | Yes | No | No | No | |
3102 | AlchemyApproval Workflow |
Yes | No | No | No | |
3300 | SharingLinks | Yes | No | No | No | |
Total | 64 | 60 | 52 | 38 |